Skip to content

Commit

Permalink
Fix get request
Browse files Browse the repository at this point in the history
  • Loading branch information
fernandoareias committed Feb 2, 2025
1 parent 563f58e commit 66efe95
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 15 deletions.
13 changes: 13 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "erlang",
"request": "launch",
"name": "Debug Erlang",
"cwd": "${workspaceFolder}",
"startmodule": "web_server_request_listener",
"args": []
}
]
}
11 changes: 11 additions & 0 deletions http/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>First web page </title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
4 changes: 3 additions & 1 deletion rebar.config
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{erl_opts, [debug_info]}.

{deps, []}.
{deps, [
{meck, "0.9.2"}
]}.

{shell, [
%% {config, "config/sys.config"},
Expand Down
9 changes: 8 additions & 1 deletion rebar.lock
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
[].
{"1.2.0",
[{<<"meck">>,{pkg,<<"meck">>,<<"0.9.2">>},0}]}.
[
{pkg_hash,[
{<<"meck">>, <<"85CCBAB053F1DB86C7CA240E9FC718170EE5BDA03810A6292B5306BF31BAE5F5">>}]},
{pkg_hash_ext,[
{<<"meck">>, <<"81344F561357DC40A8344AFA53767C32669153355B626EA9FCBC8DA6B3045826">>}]}
].
51 changes: 38 additions & 13 deletions src/web_server_http_parser.erl
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ code_change(_OldVsn, State, _Extra) ->
process_request(Data, Connection) ->
io:format("[~p] - Processing request...", [calendar:local_time()]),
{Method, Path, Headers} = parse_request(Data),
io:format("[~p] - Method: ~p | Path: ~p | Headers: ~p", [calendar:local_time(), Method, Path, Headers]),
io:format("[~p] - Method: ~p | Path: ~p ", [calendar:local_time(), Method, Path]),
Authenticated = check_authentication(Headers),
case handle_path(Path, Authenticated) of
{ok, Content, ContentType} ->
Expand Down Expand Up @@ -85,10 +85,9 @@ parse_request_line(RequestLine) ->

parse_headers(Lines) ->
lists:foldl(fun(Line, Acc) ->
case string:find(Line, ": ") of
{ok, _} ->
[Key, Value] = string:split(Line, ": ", parts),
[{Key, Value} | Acc];
case binary:split(Line, <<": ">>) of
[Key, Value] ->
[{binary_to_list(Key), binary_to_list(Value)} | Acc];
_ ->
io:format("[~p] - Ignoring invalid header line: ~p~n", [calendar:local_time(), Line]),
Acc
Expand All @@ -97,7 +96,6 @@ parse_headers(Lines) ->


check_authentication(Headers) ->
%% Check for Authorization header
case lists:keyfind("Authorization", 1, Headers) of
{_, Value} ->
["Basic", Encoded] = string:split(Value, " ", parts),
Expand All @@ -115,11 +113,28 @@ handle_path(Path, _) ->
{error, _} ->
{error, not_found}
end.

send_response(Connection, Status, ContentType, Body) ->
Headers = io_lib:format("[~p] - HTTP/1.1 ~s~nContent-Type: ~s~n~n",
[calendar:local_time(), Status, ContentType]),
gen_tcp:send(Connection, Headers ++ Body).
{{Year, Month, Day}, {Hour, Minute, Second}} = erlang:universaltime(),
Date = io_lib:format("~s, ~2..0w ~s ~4..0w ~2..0w:~2..0w:~2..0w GMT",
[day_of_week(Year, Month, Day), Day, month(Month), Year, Hour, Minute, Second]),

BinaryBody = iolist_to_binary(Body),

ContentLength = integer_to_list(byte_size(BinaryBody)),

Headers = [
"HTTP/1.1 ", Status, ?CRLF,
"Date: ", Date, ?CRLF,
"Server: MyErlangServer", ?CRLF,
"Content-Type: ", ContentType, ?CRLF,
"Content-Length: ", ContentLength, ?CRLF,
"Connection: close", ?CRLF,
?CRLF
],

Response = list_to_binary([Headers, BinaryBody]),
io:format("Sending response body ~p ~n", [BinaryBody]),
gen_tcp:send(Connection, Response).

content_type(Path) ->
case filename:extension(Path) of
Expand All @@ -129,8 +144,18 @@ content_type(Path) ->
_ -> "application/octet-stream"
end.

not_found_response() ->
<<"<html><head><title>Not Found</title></head><body>Not Found</body></html>">>.

unauthorized_response() ->
"<html><head><title>Unauthorized</title></head><body>Unauthorized</body></html>".
<<"<html><head><title>Unauthorized</title></head><body>Unauthorized</body></html>">>.

not_found_response() ->
"<html><head><title>Not Found</title></head><body>Not Found</body></html>".
day_of_week(Y, M, D) ->
Days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
DayNum = calendar:day_of_the_week(Y, M, D),
lists:nth(DayNum, Days).

month(M) ->
Months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
lists:nth(M, Months).
36 changes: 36 additions & 0 deletions test/web_server_request_listener_tests.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
-module(web_server_request_listener_tests).
-include_lib("eunit/include/eunit.hrl").

%% Testa a inicialização do gen_server
start_link_test_() ->
{setup,
fun setup/0, % executada antes dos testes
fun cleanup/1, % executada após os testes
fun tests/1}. % executa o teste

setup() ->
{ok, Pid} = web_server_request_listener:start_link(),
io:format("Starting gen_server PID %s", Pid),
Pid.

%% Função de cleanup: para o gen_server
cleanup(Pid) ->
web_server_request_listener:stop(),
io:format("Ending the gen_server PID %s", Pid),
ok.

%% Testes
tests(Pid) ->
[?_assert(erlang:is_process_alive(Pid)),
?_test(test_handle_call(Pid)),
?_test(test_handle_cast(Pid))].

%% Testa uma chamada síncrona (handle_call/3)
test_handle_call(Pid) ->
{reply, ok, _State} = gen_server:call(Pid, test_call),
?assertEqual(ok, ok).

%% Testa uma mensagem assíncrona (handle_cast/2)
test_handle_cast(Pid) ->
gen_server:cast(Pid, test_cast),
?assertEqual(ok, ok).

0 comments on commit 66efe95

Please sign in to comment.