diff options
Diffstat (limited to 'src/cowboy_req.erl')
-rw-r--r-- | src/cowboy_req.erl | 99 |
1 files changed, 36 insertions, 63 deletions
diff --git a/src/cowboy_req.erl b/src/cowboy_req.erl index bdebddd..4ec42f9 100644 --- a/src/cowboy_req.erl +++ b/src/cowboy_req.erl @@ -46,7 +46,6 @@ -export([method/1]). -export([version/1]). -export([peer/1]). --export([peer_addr/1]). -export([host/1]). -export([host_info/1]). -export([port/1]). @@ -230,29 +229,6 @@ version(Req) -> peer(Req) -> {Req#http_req.peer, Req}. -%% @doc Returns the peer address calculated from headers. --spec peer_addr(Req) -> {inet:ip_address(), Req} when Req::req(). -peer_addr(Req = #http_req{}) -> - {RealIp, Req1} = header(<<"x-real-ip">>, Req), - {ForwardedForRaw, Req2} = header(<<"x-forwarded-for">>, Req1), - {{PeerIp, _PeerPort}, Req3} = peer(Req2), - ForwardedFor = case ForwardedForRaw of - undefined -> - undefined; - ForwardedForRaw -> - case re:run(ForwardedForRaw, "^(?<first_ip>[^\\,]+)", - [{capture, [first_ip], binary}]) of - {match, [FirstIp]} -> FirstIp; - _Any -> undefined - end - end, - {ok, PeerAddr} = if - is_binary(RealIp) -> inet_parse:address(binary_to_list(RealIp)); - is_binary(ForwardedFor) -> inet_parse:address(binary_to_list(ForwardedFor)); - true -> {ok, PeerIp} - end, - {PeerAddr, Req3}. - %% @doc Return the host binary string. -spec host(Req) -> {binary(), Req} when Req::req(). host(Req) -> @@ -426,61 +402,61 @@ parse_header_default(_Name) -> undefined. -spec parse_header(binary(), Req, any()) -> {ok, any(), Req} | {undefined, binary(), Req} | {error, badarg} when Req::req(). -parse_header(Name, Req, Default) when Name =:= <<"accept">> -> +parse_header(Name = <<"accept">>, Req, Default) -> parse_header(Name, Req, Default, fun (Value) -> cowboy_http:list(Value, fun cowboy_http:media_range/2) end); -parse_header(Name, Req, Default) when Name =:= <<"accept-charset">> -> +parse_header(Name = <<"accept-charset">>, Req, Default) -> parse_header(Name, Req, Default, fun (Value) -> cowboy_http:nonempty_list(Value, fun cowboy_http:conneg/2) end); -parse_header(Name, Req, Default) when Name =:= <<"accept-encoding">> -> +parse_header(Name = <<"accept-encoding">>, Req, Default) -> parse_header(Name, Req, Default, fun (Value) -> cowboy_http:list(Value, fun cowboy_http:conneg/2) end); -parse_header(Name, Req, Default) when Name =:= <<"accept-language">> -> +parse_header(Name = <<"accept-language">>, Req, Default) -> parse_header(Name, Req, Default, fun (Value) -> cowboy_http:nonempty_list(Value, fun cowboy_http:language_range/2) end); -parse_header(Name, Req, Default) when Name =:= <<"authorization">> -> +parse_header(Name = <<"authorization">>, Req, Default) -> parse_header(Name, Req, Default, fun (Value) -> cowboy_http:token_ci(Value, fun cowboy_http:authorization/2) end); -parse_header(Name, Req, Default) when Name =:= <<"content-length">> -> +parse_header(Name = <<"content-length">>, Req, Default) -> parse_header(Name, Req, Default, fun cowboy_http:digits/1); -parse_header(Name, Req, Default) when Name =:= <<"content-type">> -> +parse_header(Name = <<"content-type">>, Req, Default) -> parse_header(Name, Req, Default, fun cowboy_http:content_type/1); parse_header(Name = <<"cookie">>, Req, Default) -> parse_header(Name, Req, Default, fun cowboy_http:cookie_list/1); -parse_header(Name, Req, Default) when Name =:= <<"expect">> -> +parse_header(Name = <<"expect">>, Req, Default) -> parse_header(Name, Req, Default, fun (Value) -> cowboy_http:nonempty_list(Value, fun cowboy_http:expectation/2) end); parse_header(Name, Req, Default) - when Name =:= <<"if-match">>; Name =:= <<"if-none-match">> -> + when Name =:= <<"if-match">>; + Name =:= <<"if-none-match">> -> parse_header(Name, Req, Default, fun cowboy_http:entity_tag_match/1); parse_header(Name, Req, Default) when Name =:= <<"if-modified-since">>; Name =:= <<"if-unmodified-since">> -> parse_header(Name, Req, Default, fun cowboy_http:http_date/1); -parse_header(Name, Req, Default) when Name =:= <<"sec-websocket-protocol">> -> +parse_header(Name, Req, Default) + when Name =:= <<"sec-websocket-protocol">>; + Name =:= <<"x-forwarded-for">> -> parse_header(Name, Req, Default, fun (Value) -> cowboy_http:nonempty_list(Value, fun cowboy_http:token/2) end); %% @todo Extension parameters. -parse_header(Name, Req, Default) when Name =:= <<"transfer-encoding">> -> - parse_header(Name, Req, Default, - fun (Value) -> - cowboy_http:nonempty_list(Value, fun cowboy_http:token_ci/2) - end); -parse_header(Name, Req, Default) when Name =:= <<"upgrade">> -> +parse_header(Name, Req, Default) + when Name =:= <<"transfer-encoding">>; + Name =:= <<"upgrade">> -> parse_header(Name, Req, Default, fun (Value) -> cowboy_http:nonempty_list(Value, fun cowboy_http:token_ci/2) @@ -566,7 +542,7 @@ set_meta(Name, Value, Req=#http_req{meta=Meta}) -> %% Request Body API. %% @doc Return whether the request message has a body. --spec has_body(cowboy_req:req()) -> boolean(). +-spec has_body(req()) -> boolean(). has_body(Req) -> case lists:keyfind(<<"content-length">>, 1, Req#http_req.headers) of {_, <<"0">>} -> @@ -613,11 +589,11 @@ init_stream(TransferDecode, TransferState, ContentDecode, Req) -> {ok, Req#http_req{body_state= {stream, 0, TransferDecode, TransferState, ContentDecode}}}. -%% @equiv stream_body(Req, 1000000) +%% @equiv stream_body(1000000, Req) -spec stream_body(Req) -> {ok, binary(), Req} | {done, Req} | {error, atom()} when Req::req(). stream_body(Req) -> - stream_body(Req, 1000000). + stream_body(1000000, Req). %% @doc Stream the request's body. %% @@ -633,10 +609,10 @@ stream_body(Req) -> %% %% You can limit the size of the chunks being returned by using the %% second argument which is the size in bytes. It defaults to 1000000 bytes. --spec stream_body(Req, non_neg_integer()) -> {ok, binary(), Req} +-spec stream_body(non_neg_integer(), Req) -> {ok, binary(), Req} | {done, Req} | {error, atom()} when Req::req(). -stream_body(Req=#http_req{body_state=waiting, version=Version, - transport=Transport, socket=Socket}, MaxLength) -> +stream_body(MaxLength, Req=#http_req{body_state=waiting, version=Version, + transport=Transport, socket=Socket}) -> {ok, ExpectHeader, Req1} = parse_header(<<"expect">>, Req), case ExpectHeader of [<<"100-continue">>] -> @@ -648,37 +624,35 @@ stream_body(Req=#http_req{body_state=waiting, version=Version, end, case parse_header(<<"transfer-encoding">>, Req1) of {ok, [<<"chunked">>], Req2} -> - stream_body(Req2#http_req{body_state= + stream_body(MaxLength, Req2#http_req{body_state= {stream, 0, fun cowboy_http:te_chunked/2, {0, 0}, - fun cowboy_http:ce_identity/1}}, - MaxLength); + fun cowboy_http:ce_identity/1}}); {ok, [<<"identity">>], Req2} -> {Length, Req3} = body_length(Req2), case Length of 0 -> {done, Req3#http_req{body_state=done}}; Length -> - stream_body(Req3#http_req{body_state= + stream_body(MaxLength, Req3#http_req{body_state= {stream, Length, fun cowboy_http:te_identity/2, {0, Length}, - fun cowboy_http:ce_identity/1}}, - MaxLength) + fun cowboy_http:ce_identity/1}}) end end; -stream_body(Req=#http_req{body_state=done}, _) -> +stream_body(_, Req=#http_req{body_state=done}) -> {done, Req}; -stream_body(Req=#http_req{buffer=Buffer}, _) +stream_body(_, Req=#http_req{buffer=Buffer}) when Buffer =/= <<>> -> transfer_decode(Buffer, Req#http_req{buffer= <<>>}); -stream_body(Req, MaxLength) -> - stream_body_recv(Req, MaxLength). +stream_body(MaxLength, Req) -> + stream_body_recv(MaxLength, Req). --spec stream_body_recv(Req, non_neg_integer()) +-spec stream_body_recv(non_neg_integer(), Req) -> {ok, binary(), Req} | {error, atom()} when Req::req(). -stream_body_recv(Req=#http_req{ +stream_body_recv(MaxLength, Req=#http_req{ transport=Transport, socket=Socket, buffer=Buffer, - body_state={stream, Length, _, _, _}}, MaxLength) -> + body_state={stream, Length, _, _, _}}) -> %% @todo Allow configuring the timeout. case Transport:recv(Socket, min(Length, MaxLength), 5000) of {ok, Data} -> transfer_decode(<< Buffer/binary, Data/binary >>, @@ -697,8 +671,8 @@ transfer_decode(Data, Req=#http_req{body_state={stream, _, TransferDecode, TransferState2, ContentDecode}}); %% @todo {header(s) for chunked more -> - stream_body_recv(Req#http_req{buffer=Data, body_state={stream, - 0, TransferDecode, TransferState, ContentDecode}}, 0); + stream_body_recv(0, Req#http_req{buffer=Data, body_state={stream, + 0, TransferDecode, TransferState, ContentDecode}}); {more, Length, Data2, TransferState2} -> content_decode(ContentDecode, Data2, Req#http_req{body_state={stream, Length, @@ -1015,8 +989,7 @@ reply(Status, Headers, Body, Req=#http_req{ reply_may_compress(Status, Headers, Body, Req, RespHeaders, HTTP11Headers, Method) -> BodySize = iolist_size(Body), - {ok, Encodings, Req2} - = cowboy_req:parse_header(<<"accept-encoding">>, Req), + {ok, Encodings, Req2} = parse_header(<<"accept-encoding">>, Req), CanGzip = (BodySize > 300) andalso (false =:= lists:keyfind(<<"content-encoding">>, 1, Headers)) |