SisMaker пре 3 година
родитељ
комит
f7b8320b1a
16 измењених фајлова са 139 додато и 103 уклоњено
  1. +1
    -1
      README.md
  2. +30
    -2
      include/eWSrv.hrl
  3. +4
    -0
      src/eWSrv.erl
  4. +5
    -5
      src/example/wsEgHandover.erl
  5. +15
    -15
      src/example/wsEgHer.erl
  6. +2
    -2
      src/example/wsEgMiddleware.erl
  7. +1
    -1
      src/test/elli_http_tests.erl
  8. +1
    -1
      src/test/elli_test.erl
  9. +25
    -25
      src/test/elli_tests.erl
  10. +4
    -4
      src/wsSrv/elli.erl
  11. +2
    -0
      src/wsSrv/wsHer.erl
  12. +38
    -38
      src/wsSrv/wsHttp.erl
  13. +1
    -1
      src/wsSrv/wsMiddleware.erl
  14. +2
    -2
      src/wsSrv/wsMiddlewareCompress.erl
  15. +1
    -1
      src/wsSrv/wsNet.erl
  16. +7
    -5
      src/wsSrv/wsReq.erl

+ 1
- 1
README.md Прегледај датотеку

@ -39,7 +39,7 @@ A minimal callback module could look like this:
handle(Req, _Args) ->
%% Delegate to our handler function
handle(Req#req.method, elli_request:path(Req), Req).
handle(Req#req.method, wsReq:path(Req), Req).
handle('GET', [<<"hello">>, <<"world">>], _Req) ->
%% Reply with a normal response. `ok' can be used instead of `200'

+ 30
- 2
include/eWSrv.hrl Прегледај датотеку

@ -1,3 +1,28 @@
-define(DefWsOpts, [
binary
, {packet, 4}
, {active, false}
, {reuseaddr, true}
, {nodelay, false}
, {delay_send, true}
, {send_timeout, 15000}
, {keepalive, true}
, {exit_on_close, true}
, {back_log, 1024}
]).
-export_type([wsOpt/0]).
-type wsOpt() ::
{aptCnt, non_neg_integer()} |
{tcpOpts, [gen_tcp:listen_option()]} |
{sslOpts, [ssl:ssl_option()]} |
{sslHSTet, timeout()} |
{udpOpts, [gen_udp:option()]} |
{proxyPt, boolean()} |
{proxyPtTet, timeout() |
{wsMod, module()}
}.
-record(req, {
method :: elli:http_method(),
scheme :: undefined | binary(),
@ -6,15 +31,18 @@
path :: [binary()],
args :: [{binary(), any()}],
raw_path :: binary(),
version :: elli_http:version(),
version :: wsHttp:version(),
headers :: elli:headers(),
original_headers :: elli:headers(),
body :: elli:body(),
pid :: pid(),
socket :: undefined | elli_tcp:socket(),
socket :: undefined | wsNet:socket(),
callback :: wsHer:callback()
}).
-define(EXAMPLE_CONF, [{callback, elli_example_callback}, {callback_args, []}]).

+ 4
- 0
src/eWSrv.erl Прегледај датотеку

@ -2,3 +2,7 @@
%% API
-export([]).
startHttp() ->

src/wsSrv/elli_example_callback_handover.erl → src/example/wsEgHandover.erl Прегледај датотеку

@ -1,4 +1,4 @@
-module(elli_example_callback_handover).
-module(wsEgHandover).
-export([init/2, handle/2, handle_event/3]).
-include("wsCom.hrl").
@ -7,7 +7,7 @@
%% @doc Return `{ok, handover}' if `Req''s path is `/hello/world',
%% otherwise `ignore'.
init(Req, _Args) ->
case elli_request:path(Req) of
case wsReq:path(Req) of
[<<"hello">>, <<"world">>] ->
{ok, handover};
_ ->
@ -20,20 +20,20 @@ init(Req, _Args) ->
Args :: wsHer:callback_args(),
Result :: wsHer:result().
handle(Req, Args) ->
handle(elli_request:method(Req), elli_request:path(Req), Req, Args).
handle(wsReq:method(Req), wsReq:path(Req), Req, Args).
handle('GET', [<<"hello">>, <<"world">>], Req, _Args) ->
Body = <<"Hello World!">>,
Size = integer_to_binary(size(Body)),
Headers = [{"Connection", "close"}, {"Content-Length", Size}],
elli_http:send_response(Req, 200, Headers, Body),
wsHttp:send_response(Req, 200, Headers, Body),
{close, <<>>};
handle('GET', [<<"hello">>], Req, _Args) ->
%% Fetch a GET argument from the URL.
Name = elli_request:get_arg(<<"name">>, Req, <<"undefined">>),
Name = wsReq:get_arg(<<"name">>, Req, <<"undefined">>),
{ok, [], <<"Hello ", Name/binary>>}.

src/wsSrv/elli_example_callback.erl → src/example/wsEgHer.erl Прегледај датотеку

@ -6,7 +6,7 @@
%%% completed a request, there was a parsing error or your handler
%%% threw an error, {@link handle_event/3} is called.
-module(elli_example_callback).
-module(wsEgHer).
-export([handle/2, handle_event/3]).
-export([chunk_loop/1]).
@ -27,7 +27,7 @@
Req :: elli:req(),
_Args :: wsHer:callback_args(),
Result :: wsHer:result().
handle(Req, _Args) -> handle(Req#req.method, elli_request:path(Req), Req).
handle(Req, _Args) -> handle(Req#req.method, wsReq:path(Req), Req).
%% @doc Route `Method' and `Path' to the appropriate clause.
@ -73,25 +73,25 @@ handle('GET', [<<"hello">>, <<"world">>], _Req) ->
handle('GET', [<<"hello">>], Req) ->
%% Fetch a GET argument from the URL.
Name = elli_request:get_arg(<<"name">>, Req, <<"undefined">>),
Name = wsReq:get_arg(<<"name">>, Req, <<"undefined">>),
{ok, [], <<"Hello ", Name/binary>>};
handle('POST', [<<"hello">>], Req) ->
%% Fetch a POST argument from the POST body.
Name = elli_request:post_arg(<<"name">>, Req, <<"undefined">>),
Name = wsReq:post_arg(<<"name">>, Req, <<"undefined">>),
%% Fetch and decode
City = elli_request:post_arg_decoded(<<"city">>, Req, <<"undefined">>),
City = wsReq:post_arg_decoded(<<"city">>, Req, <<"undefined">>),
{ok, [], <<"Hello ", Name/binary, " of ", City/binary>>};
handle('GET', [<<"hello">>, <<"iolist">>], Req) ->
%% Iolists will be kept as iolists all the way to the socket.
Name = elli_request:get_arg(<<"name">>, Req),
Name = wsReq:get_arg(<<"name">>, Req),
{ok, [], [<<"Hello ">>, Name]};
handle('GET', [<<"type">>], Req) ->
Name = elli_request:get_arg(<<"name">>, Req),
Name = wsReq:get_arg(<<"name">>, Req),
%% Fetch a header.
case elli_request:get_header(<<"Accept">>, Req, <<"text/plain">>) of
case wsReq:get_header(<<"Accept">>, Req, <<"text/plain">>) of
<<"text/plain">> ->
{ok, [{<<"content-type">>, <<"text/plain; charset=ISO-8859-1">>}],
<<"name: ", Name/binary>>};
@ -121,13 +121,13 @@ handle('GET', [<<"crash">>], _Req) ->
handle('GET', [<<"decoded-hello">>], Req) ->
%% Fetch a URI decoded GET argument from the URL.
Name = elli_request:get_arg_decoded(<<"name">>, Req, <<"undefined">>),
Name = wsReq:get_arg_decoded(<<"name">>, Req, <<"undefined">>),
{ok, [], <<"Hello ", Name/binary>>};
handle('GET', [<<"decoded-list">>], Req) ->
%% Fetch a URI decoded GET argument from the URL.
[{<<"name">>, Name}, {<<"foo">>, true}] =
elli_request:get_args_decoded(Req),
wsReq:get_args_decoded(Req),
{ok, [], <<"Hello ", Name/binary>>};
@ -152,7 +152,7 @@ handle('GET', [<<"sendfile">>, <<"range">>], Req) ->
%% range with sendfile, otherwise send the entire file when
%% no range is present, or respond with a 416 if the range is invalid.
F = "README.md",
{ok, [], {file, F, elli_request:get_range(Req)}};
{ok, [], {file, F, wsReq:get_range(Req)}};
handle('GET', [<<"compressed">>], _Req) ->
%% Body with a byte size over 1024 are automatically gzipped by
@ -177,7 +177,7 @@ handle('GET', [<<"chunked">>], Req) ->
%% close the response.
%%
%% Return immediately {chunk, Headers} to signal we want to chunk.
Ref = elli_request:chunk_ref(Req),
Ref = wsReq:chunk_ref(Req),
spawn(fun() -> ?MODULE:chunk_loop(Ref) end),
{chunk, [{<<"Content-Type">>, <<"text/event-stream">>}]};
@ -185,7 +185,7 @@ handle('GET', [<<"shorthand">>], _Req) ->
{200, <<"hello">>};
handle('GET', [<<"ip">>], Req) ->
{<<"200 OK">>, elli_request:peer(Req)};
{<<"200 OK">>, wsReq:peer(Req)};
handle('GET', [<<"304">>], _Req) ->
%% A "Not Modified" response is exactly like a normal response (so
@ -218,11 +218,11 @@ chunk_loop(Ref) ->
%% When `N == 0', call {@link elli_request:close_chunk/1.
%% elli_request:close_chunk(Ref)}.
chunk_loop(Ref, 0) ->
elli_request:close_chunk(Ref);
wsReq:close_chunk(Ref);
chunk_loop(Ref, N) ->
timer:sleep(10),
case elli_request:send_chunk(Ref, [<<"chunk">>, integer_to_binary(N)]) of
case wsReq:send_chunk(Ref, [<<"chunk">>, integer_to_binary(N)]) of
ok -> ok;
{error, Reason} -> ?wsErr("error in sending chunk: ~p~n", [Reason])
end,

src/wsSrv/elli_example_middleware.erl → src/example/wsEgMiddleware.erl Прегледај датотеку

@ -1,5 +1,5 @@
%% @hidden
-module(elli_example_middleware).
-module(wsEgMiddleware).
-export([handle/2, handle_event/3]).
-behaviour(wsHer).
@ -9,7 +9,7 @@
%%
handle(Req, _Args) ->
do_handle(elli_request:path(Req)).
do_handle(wsReq:path(Req)).
do_handle([<<"middleware">>, <<"short-circuit">>]) ->
{200, [], <<"short circuit!">>};

+ 1
- 1
src/test/elli_http_tests.erl Прегледај датотеку

@ -14,7 +14,7 @@ chunk_loop_test_() ->
chunk_loop_wrapper(Here) ->
fun() ->
Result = elli_http:chunk_loop({some_type, some_socket}),
Result = wsHttp:chunk_loop({some_type, some_socket}),
Here ! Result,
ok
end.

src/wsSrv/elli_test.erl → src/test/elli_test.erl Прегледај датотеку

@ -21,7 +21,7 @@
call(Method, Path, Headers, Body, Opts) ->
Callback = proplists:get_value(callback, Opts),
CallbackArgs = proplists:get_value(callback_args, Opts),
Req = elli_http:mk_req(Method, {abs_path, Path}, Headers, Headers,
Req = wsHttp:mk_req(Method, {abs_path, Path}, Headers, Headers,
Body, {1, 1}, undefined, {Callback, CallbackArgs}),
ok = Callback:handle_event(elli_startup, [], CallbackArgs),
Callback:handle(Req, CallbackArgs).

+ 25
- 25
src/test/elli_tests.erl Прегледај датотеку

@ -122,23 +122,23 @@ accessors_test_() ->
[
%% POST /foo/bar
?_assertMatch(RawPath, elli_request:raw_path(Req1)),
?_assertMatch(Headers, elli_request:headers(Req1)),
?_assertMatch(Method, elli_request:method(Req1)),
?_assertMatch(Body, elli_request:body(Req1)),
?_assertMatch(Args, elli_request:post_args_decoded(Req1)),
?_assertMatch(undefined, elli_request:post_arg(<<"foo">>, Req1)),
?_assertMatch(undefined, elli_request:post_arg_decoded(<<"foo">>, Req1)),
?_assertMatch(Name, elli_request:post_arg_decoded(<<"name">>, Req1)),
?_assertMatch(RawPath, wsReq:raw_path(Req1)),
?_assertMatch(Headers, wsReq:headers(Req1)),
?_assertMatch(Method, wsReq:method(Req1)),
?_assertMatch(Body, wsReq:body(Req1)),
?_assertMatch(Args, wsReq:post_args_decoded(Req1)),
?_assertMatch(undefined, wsReq:post_arg(<<"foo">>, Req1)),
?_assertMatch(undefined, wsReq:post_arg_decoded(<<"foo">>, Req1)),
?_assertMatch(Name, wsReq:post_arg_decoded(<<"name">>, Req1)),
%% GET /foo/bar
?_assertMatch(Headers, elli_request:headers(Req2)),
?_assertMatch(Headers, wsReq:headers(Req2)),
?_assertMatch(Args, elli_request:get_args(Req2)),
?_assertMatch(undefined, elli_request:get_arg_decoded(<<"foo">>, Req2)),
?_assertMatch(Name, elli_request:get_arg_decoded(<<"name">>, Req2)),
?_assertMatch([], elli_request:post_args(Req2)),
?_assertMatch(Args, wsReq:get_args(Req2)),
?_assertMatch(undefined, wsReq:get_arg_decoded(<<"foo">>, Req2)),
?_assertMatch(Name, wsReq:get_arg_decoded(<<"name">>, Req2)),
?_assertMatch([], wsReq:post_args(Req2)),
?_assertMatch({error, not_supported}, elli_request:chunk_ref(#req{}))
?_assertMatch({error, not_supported}, wsReq:chunk_ref(#req{}))
].
@ -628,7 +628,7 @@ body_qs_test() ->
{<<"found">>, true}],
Body = <<"foo=bar&baz=bang&found">>,
Headers = [{<<"content-type">>, <<"application/x-www-form-urlencoded">>}],
?assertMatch(Expected, elli_request:body_qs(#req{body = Body,
?assertMatch(Expected, wsReq:body_qs(#req{body = Body,
original_headers = Headers,
headers = Headers})).
@ -659,22 +659,22 @@ to_proplist_test() ->
{pid, self()},
{socket, socket},
{callback, {mod, []}}],
?assertEqual(Prop, elli_request:to_proplist(Req)).
?assertEqual(Prop, wsReq:to_proplist(Req)).
is_request_test() ->
?assert(elli_request:is_request(#req{})),
?assertNot(elli_request:is_request({req, foobar})).
?assert(wsReq:is_request(#req{})),
?assertNot(wsReq:is_request({req, foobar})).
query_str_test_() ->
MakeReq = fun(Path) -> #req{raw_path = Path} end,
[
%% For empty query strings, expect `query_str` to return an empty binary.
?_assertMatch(<<>>, elli_request:query_str(MakeReq(<<"/foo">>))),
?_assertMatch(<<>>, elli_request:query_str(MakeReq(<<"/foo?">>))),
?_assertMatch(<<>>, wsReq:query_str(MakeReq(<<"/foo">>))),
?_assertMatch(<<>>, wsReq:query_str(MakeReq(<<"/foo?">>))),
%% Otherwise it should return everything to the right hand side of `?`.
?_assertMatch(<<"bar=baz&baz=bang">>,
elli_request:query_str(MakeReq(<<"/foo?bar=baz&baz=bang">>)))
wsReq:query_str(MakeReq(<<"/foo?bar=baz&baz=bang">>)))
].
@ -687,10 +687,10 @@ get_range_test_() ->
ByteRangeSet = [{bytes, 0, 99}, {bytes, 500, 999}, {suffix, 800}],
[?_assertMatch(ByteRangeSet, elli_request:get_range(Req)),
?_assertMatch([{offset, 200}], elli_request:get_range(OffsetReq)),
?_assertMatch([], elli_request:get_range(UndefReq)),
?_assertMatch(parse_error, elli_request:get_range(BadReq))].
[?_assertMatch(ByteRangeSet, wsReq:get_range(Req)),
?_assertMatch([{offset, 200}], wsReq:get_range(OffsetReq)),
?_assertMatch([], wsReq:get_range(UndefReq)),
?_assertMatch(parse_error, wsReq:get_range(BadReq))].
normalize_range_test_() ->
Size = 1000,

+ 4
- 4
src/wsSrv/elli.erl Прегледај датотеку

@ -40,7 +40,7 @@
-type response_code() :: 100..999.
-record(state, {socket :: elli_tcp:socket(),
-record(state, {socket :: wsNet:socket(),
acceptors :: ets:tid(),
open_reqs = 0 :: non_neg_integer(),
options = [] :: [{_, _}], % TODO: refine
@ -150,7 +150,7 @@ init([Opts]) ->
%% tables, etc.
ok = Callback:handle_event(elli_startup, [], CallbackArgs),
{ok, Socket} = elli_tcp:listen(SockType, Port, [binary,
{ok, Socket} = wsNet:listen(SockType, Port, [binary,
{ip, IPAddress},
{reuseaddr, true},
{backlog, 32768},
@ -160,7 +160,7 @@ init([Opts]) ->
Acceptors = ets:new(acceptors, [private, set]),
[begin
Pid = elli_http:start_link(self(), Socket, Options, {Callback, CallbackArgs}),
Pid = wsHttp:start_link(self(), Socket, Options, {Callback, CallbackArgs}),
ets:insert(Acceptors, {Pid})
end
|| _ <- lists:seq(1, MinAcceptors)],
@ -246,7 +246,7 @@ remove_acceptor(State, Pid) ->
-spec start_add_acceptor(State0 :: state()) -> State1 :: state().
start_add_acceptor(State) ->
Pid = elli_http:start_link(self(), State#state.socket,
Pid = wsHttp:start_link(self(), State#state.socket,
State#state.options, State#state.callback),
add_acceptor(State, Pid).

+ 2
- 0
src/wsSrv/wsHer.erl Прегледај датотеку

@ -1,5 +1,7 @@
-module(wsHer).
-include("eWSrv.hrl").
-callback init(Req :: elli:req(), Args :: callback_args()) -> {ok, standard | handover}.
-callback handle(Req :: elli:req(), callback_args()) -> result().

src/wsSrv/elli_http.erl → src/wsSrv/wsHttp.erl Прегледај датотеку

@ -3,7 +3,7 @@
%% An elli_http process blocks in elli_tcp:accept/2 until a client
%% connects. It then handles requests on that connection until it's
%% closed either by the client timing out or explicitly by the user.
-module(elli_http).
-module(wsHttp).
-include("eWSrv.hrl").
-include("wsCom.hrl").
@ -41,7 +41,7 @@
-spec start_link(Server, ListenSocket, Options, Callback) -> pid() when
Server :: pid(),
ListenSocket :: elli_tcp:socket(),
ListenSocket :: wsNet:socket(),
Options :: proplists:proplist(),
Callback :: wsHer:callback().
start_link(Server, ListenSocket, Options, Callback) ->
@ -54,11 +54,11 @@ start_link(Server, ListenSocket, Options, Callback) ->
%% timeout, loop to allow code upgrades of this module.
-spec accept(Server, ListenSocket, Options, Callback) -> ok when
Server :: pid(),
ListenSocket :: elli_tcp:socket(),
ListenSocket :: wsNet:socket(),
Options :: proplists:proplist(),
Callback :: wsHer:callback().
accept(Server, ListenSocket, Options, Callback) ->
case catch elli_tcp:accept(ListenSocket, Server, accept_timeout(Options)) of
case catch wsNet:accept(ListenSocket, Server, accept_timeout(Options)) of
{ok, Socket} ->
t(accepted),
?MODULE:keepalive_loop(Socket, Options, Callback);
@ -85,7 +85,7 @@ keepalive_loop(Socket, NumRequests, Buffer, Options, Callback) ->
?MODULE:keepalive_loop(Socket, NumRequests + 1,
NewBuffer, Options, Callback);
{close, _} ->
elli_tcp:close(Socket),
wsNet:close(Socket),
ok
end.
@ -93,7 +93,7 @@ keepalive_loop(Socket, NumRequests, Buffer, Options, Callback) ->
%% Returns the appropriate connection token and any buffer containing (parts of)
%% the next request.
-spec handle_request(Socket, PrevBin, Options, Callback) -> ConnToken when
Socket :: elli_tcp:socket(),
Socket :: wsNet:socket(),
PrevBin :: binary(),
Options :: proplists:proplist(),
Callback :: wsHer:callback(),
@ -182,7 +182,7 @@ handle_response(Req, Buffer, {file, ResponseCode, UserHeaders,
{error, FileError} ->
handle_event(Mod, file_error, [FileError], Args),
send_server_error(Req#req.socket),
elli_tcp:close(Req#req.socket),
wsNet:close(Req#req.socket),
exit(normal);
Size ->
t(send_start),
@ -235,7 +235,7 @@ send_response(Req, Code, Headers, UserBody) ->
Response = [ResponseHeaders,
Body],
case elli_tcp:send(Req#req.socket, Response) of
case wsNet:send(Req#req.socket, Response) of
ok -> ok;
{error, Closed} when Closed =:= closed orelse Closed =:= enotconn ->
#req{callback = {Mod, Args}} = Req,
@ -260,15 +260,15 @@ send_file(#req{callback = {Mod, Args}} = Req, Code, Headers, Filename, Range) ->
{error, FileError} ->
handle_event(Mod, file_error, [FileError], Args),
send_server_error(Req#req.socket),
elli_tcp:close(Req#req.socket),
wsNet:close(Req#req.socket),
exit(normal)
end,
ok.
do_send_file(Fd, {Offset, Length}, #req{callback = {Mod, Args}} = Req, Headers) ->
try elli_tcp:send(Req#req.socket, Headers) of
try wsNet:send(Req#req.socket, Headers) of
ok ->
case elli_tcp:sendfile(Fd, Req#req.socket, Offset, Length, []) of
case wsNet:sendfile(Fd, Req#req.socket, Offset, Length, []) of
{ok, BytesSent} -> s(file, BytesSent), ok;
{error, Closed} when Closed =:= closed orelse
Closed =:= enotconn ->
@ -292,7 +292,7 @@ send_server_error(Socket) ->
send_rescue_response(Socket, Code, Body) ->
Response = http_response(Code, Body),
elli_tcp:send(Socket, Response).
wsNet:send(Socket, Response).
%% @doc Execute the user callback, translating failure into a proper response.
execute_callback(#req{callback = {Mod, Args}} = Req) ->
@ -346,7 +346,7 @@ end .
start_chunk_loop(Socket) ->
%% Set the socket to active so we receive the tcp_closed message
%% if the client closes the connection
elli_tcp:setopts(Socket, [{active, once}]),
wsNet:setopts(Socket, [{active, once}]),
?MODULE:chunk_loop(Socket).
chunk_loop(Socket) ->
@ -356,18 +356,18 @@ chunk_loop(Socket) ->
{error, client_closed};
{chunk, close} ->
case elli_tcp:send(Socket, <<"0\r\n\r\n">>) of
case wsNet:send(Socket, <<"0\r\n\r\n">>) of
ok ->
elli_tcp:close(Socket),
wsNet:close(Socket),
ok;
{error, Closed} when Closed =:= closed orelse
Closed =:= enotconn ->
{error, client_closed}
end;
{chunk, close, From} ->
case elli_tcp:send(Socket, <<"0\r\n\r\n">>) of
case wsNet:send(Socket, <<"0\r\n\r\n">>) of
ok ->
elli_tcp:close(Socket),
wsNet:close(Socket),
From ! {self(), ok},
ok;
{error, Closed} when Closed =:= closed orelse
@ -400,7 +400,7 @@ send_chunk(Socket, Data) ->
Response = [integer_to_list(Size, 16),
<<"\r\n">>, Data, <<"\r\n">>],
s(chunks, iolist_size(Response)),
elli_tcp:send(Socket, Response)
wsNet:send(Socket, Response)
end.
@ -426,30 +426,30 @@ get_request_(Socket, Buffer, Options, {Mod, Args} = Callback) ->
{ok, {http_error, _}, _} ->
handle_event(Mod, request_parse_error, [Buffer], Args),
send_bad_request(Socket),
elli_tcp:close(Socket),
wsNet:close(Socket),
exit(normal);
{ok, {http_response, _, _, _}, _} ->
elli_tcp:close(Socket),
wsNet:close(Socket),
exit(normal)
end.
recv_request(Socket, Buffer, Options, {Mod, Args} = _Callback) ->
case elli_tcp:recv(Socket, 0, request_timeout(Options)) of
case wsNet:recv(Socket, 0, request_timeout(Options)) of
{ok, Data} ->
<<Buffer/binary, Data/binary>>;
{error, timeout} ->
handle_event(Mod, request_timeout, [], Args),
elli_tcp:close(Socket),
wsNet:close(Socket),
exit(normal);
{error, Closed} when Closed =:= closed orelse
Closed =:= enotconn ->
handle_event(Mod, request_closed, [], Args),
elli_tcp:close(Socket),
wsNet:close(Socket),
exit(normal)
end.
-spec get_headers(Socket, V, Buffer, Opts, Callback) -> Headers when
Socket :: elli_tcp:socket(),
Socket :: wsNet:socket(),
V :: version(),
Buffer :: binary(),
Opts :: proplists:proplist(),
@ -464,7 +464,7 @@ get_headers(Socket, _, {Headers, _}, HeadersCount, _Opts, {Mod, Args})
when HeadersCount >= 100 ->
handle_event(Mod, bad_request, [{too_many_headers, Headers}], Args),
send_bad_request(Socket),
elli_tcp:close(Socket),
wsNet:close(Socket),
exit(normal);
get_headers(Socket, Buffer, {Headers, ParsedHeaders}, Count, Opts, {Mod, Args} = Callback) ->
case erlang:decode_packet(httph_bin, Buffer, []) of
@ -478,19 +478,19 @@ get_headers(Socket, Buffer, {Headers, ParsedHeaders}, Count, Opts, {Mod, Args} =
{ok, {http_error, _}, Rest} ->
get_headers(Socket, Rest, {Headers, ParsedHeaders}, Count, Opts, Callback);
{more, _} ->
case elli_tcp:recv(Socket, 0, header_timeout(Opts)) of
case wsNet:recv(Socket, 0, header_timeout(Opts)) of
{ok, Data} ->
get_headers(Socket, <<Buffer/binary, Data/binary>>,
{Headers, ParsedHeaders}, Count, Opts, Callback);
{error, Closed} when Closed =:= closed orelse
Closed =:= enotconn ->
handle_event(Mod, client_closed, [receiving_headers], Args),
elli_tcp:close(Socket),
wsNet:close(Socket),
exit(normal);
{error, timeout} ->
handle_event(Mod, client_timeout,
[receiving_headers], Args),
elli_tcp:close(Socket),
wsNet:close(Socket),
exit(normal)
end
end.
@ -506,7 +506,7 @@ get_headers(Socket, Buffer, {Headers, ParsedHeaders}, Count, Opts, {Mod, Args} =
%% buffered too much and get parts of the next pipelined request. In
%% that case, push it back in the buffer and handle the first request.
-spec get_body(Socket, Headers, Buffer, Opts, Callback) -> FullBody when
Socket :: undefined | elli_tcp:socket(),
Socket :: undefined | wsNet:socket(),
Headers :: elli:headers(),
Buffer :: binary(),
Opts :: proplists:proplist(),
@ -541,16 +541,16 @@ get_body(Socket, Headers, Buffer, Opts, Callback) ->
end.
do_get_body(Socket, Buffer, Opts, N, {Mod, Args}) ->
case elli_tcp:recv(Socket, N, body_timeout(Opts)) of
case wsNet:recv(Socket, N, body_timeout(Opts)) of
{ok, Data} ->
{<<Buffer/binary, Data/binary>>, <<>>};
{error, Closed} when Closed =:= closed orelse Closed =:= enotconn ->
handle_event(Mod, client_closed, [receiving_body], Args),
ok = elli_tcp:close(Socket),
ok = wsNet:close(Socket),
exit(normal);
{error, timeout} ->
handle_event(Mod, client_timeout, [receiving_body], Args),
ok = elli_tcp:close(Socket),
ok = wsNet:close(Socket),
exit(normal)
end.
@ -564,7 +564,7 @@ maybe_send_continue(Socket, Headers) ->
case get_header(?EXPECT_HEADER, Headers, undefined) of
<<"100-continue">> ->
Response = http_response(100),
elli_tcp:send(Socket, Response);
wsNet:send(Socket, Response);
_Other ->
ok
end.
@ -580,16 +580,16 @@ do_check_max_size(Socket, ContentLength, Buffer, MaxSize, {Mod, Args})
when ContentLength > MaxSize ->
handle_event(Mod, bad_request, [{body_size, ContentLength}], Args),
do_check_max_size_x2(Socket, ContentLength, Buffer, MaxSize),
elli_tcp:close(Socket),
wsNet:close(Socket),
exit(normal);
do_check_max_size(_, _, _, _, _) -> ok.
do_check_max_size_x2(Socket, ContentLength, Buffer, MaxSize)
when ContentLength < MaxSize * 2 ->
OnSocket = ContentLength - size(Buffer),
elli_tcp:recv(Socket, OnSocket, 60000),
wsNet:recv(Socket, OnSocket, 60000),
Response = http_response(413),
elli_tcp:send(Socket, Response);
wsNet:send(Socket, Response);
do_check_max_size_x2(_, _, _, _) -> ok.
-spec mk_req(Method, PathTuple, Headers, Headers, Body, V, Socket, Callback) -> Req when
@ -598,7 +598,7 @@ do_check_max_size_x2(_, _, _, _) -> ok.
Headers :: elli:headers(),
Body :: elli:body(),
V :: version(),
Socket :: elli_tcp:socket() | undefined,
Socket :: wsNet:socket() | undefined,
Callback :: wsHer:callback(),
Req :: elli:req().
mk_req(Method, PathTuple, Headers, ParsedHeaders, Body, V, Socket, {Mod, Args} = Callback) ->
@ -613,7 +613,7 @@ mk_req(Method, PathTuple, Headers, ParsedHeaders, Body, V, Socket, {Mod, Args} =
handle_event(Mod, request_parse_error,
[{Reason, {Method, PathTuple}}], Args),
send_bad_request(Socket),
elli_tcp:close(Socket),
wsNet:close(Socket),
exit(normal)
end.

src/wsSrv/elli_middleware.erl → src/wsSrv/wsMiddleware.erl Прегледај датотеку

@ -36,7 +36,7 @@
%%%
%%% `elli_middleware' does not add any significant overhead.
-module(elli_middleware).
-module(wsMiddleware).
-behaviour(wsHer).
-export([init/2, handle/2, handle_event/3]).

src/wsSrv/elli_middleware_compress.erl → src/wsSrv/wsMiddlewareCompress.erl Прегледај датотеку

@ -1,5 +1,5 @@
%%% @doc Response compression as Elli middleware.
-module(elli_middleware_compress).
-module(wsMiddlewareCompress).
-export([postprocess/3]).
-include("wsCom.hrl").
@ -46,7 +46,7 @@ compress(Body, Req) ->
end.
accepted_encoding(Req) ->
hd(binary:split(elli_request:get_header(<<"Accept-Encoding">>, Req, <<>>),
hd(binary:split(wsReq:get_header(<<"Accept-Encoding">>, Req, <<>>),
[<<",">>, <<";">>], [global])).
-spec should_compress(Body, Threshold) -> boolean() when

src/wsSrv/elli_tcp.erl → src/wsSrv/wsNet.erl Прегледај датотеку

@ -1,7 +1,7 @@
%%% @doc Wrapper for plain and SSL sockets.
%%% Based on `mochiweb_socket.erl'.
-module(elli_tcp).
-module(wsNet).
-export([listen/3, accept/3, recv/3, send/2, close/1,
setopts/2, sendfile/5, peername/1]).

src/wsSrv/elli_request.erl → src/wsSrv/wsReq.erl Прегледај датотеку

@ -1,8 +1,10 @@
-module(elli_request).
-module(wsReq).
-include("eWSrv.hrl").
-include("wsCom.hrl").
-export([send_chunk/2
-export([
send_chunk/2
, async_send_chunk/2
, chunk_ref/1
, close_chunk/1
@ -70,7 +72,7 @@ host(#req{host = Host}) -> Host.
port(#req{port = Port}) -> Port.
peer(#req{socket = Socket} = _Req) ->
case elli_tcp:peername(Socket) of
case wsNet:peername(Socket) of
{ok, {Address, _}} ->
list_to_binary(inet_parse:ntoa(Address));
{error, _} ->
@ -111,9 +113,9 @@ body_qs(#req{body = <<>>}) -> [];
body_qs(#req{body = Body} = Req) ->
case get_header(<<"Content-Type">>, Req) of
<<"application/x-www-form-urlencoded">> ->
elli_http:split_args(Body);
wsHttp:split_args(Body);
<<"application/x-www-form-urlencoded;", _/binary>> -> % ; charset=...
elli_http:split_args(Body);
wsHttp:split_args(Body);
_ ->
erlang:error(badarg)
end.

Loading…
Откажи
Сачувај