diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gun.erl | 69 | ||||
-rw-r--r-- | src/gun_http.erl | 9 | ||||
-rw-r--r-- | src/gun_http2.erl | 11 |
3 files changed, 51 insertions, 38 deletions
diff --git a/src/gun.erl b/src/gun.erl index 1e83979..10ae2a7 100644 --- a/src/gun.erl +++ b/src/gun.erl @@ -49,7 +49,10 @@ -export([put/3]). -export([put/4]). -export([put/5]). --export([request/4]). + +%% Generic requests interface. +-export([headers/4]). +-export([headers/5]). -export([request/5]). -export([request/6]). @@ -316,11 +319,11 @@ shutdown(ServerPid) -> -spec delete(pid(), iodata()) -> reference(). delete(ServerPid, Path) -> - request(ServerPid, <<"DELETE">>, Path, []). + request(ServerPid, <<"DELETE">>, Path, [], <<>>). -spec delete(pid(), iodata(), headers()) -> reference(). delete(ServerPid, Path, Headers) -> - request(ServerPid, <<"DELETE">>, Path, Headers). + request(ServerPid, <<"DELETE">>, Path, Headers, <<>>). -spec delete(pid(), iodata(), headers(), req_opts()) -> reference(). delete(ServerPid, Path, Headers, ReqOpts) -> @@ -328,11 +331,11 @@ delete(ServerPid, Path, Headers, ReqOpts) -> -spec get(pid(), iodata()) -> reference(). get(ServerPid, Path) -> - request(ServerPid, <<"GET">>, Path, []). + request(ServerPid, <<"GET">>, Path, [], <<>>). -spec get(pid(), iodata(), headers()) -> reference(). get(ServerPid, Path, Headers) -> - request(ServerPid, <<"GET">>, Path, Headers). + request(ServerPid, <<"GET">>, Path, Headers, <<>>). -spec get(pid(), iodata(), headers(), req_opts()) -> reference(). get(ServerPid, Path, Headers, ReqOpts) -> @@ -340,11 +343,11 @@ get(ServerPid, Path, Headers, ReqOpts) -> -spec head(pid(), iodata()) -> reference(). head(ServerPid, Path) -> - request(ServerPid, <<"HEAD">>, Path, []). + request(ServerPid, <<"HEAD">>, Path, [], <<>>). -spec head(pid(), iodata(), headers()) -> reference(). head(ServerPid, Path, Headers) -> - request(ServerPid, <<"HEAD">>, Path, Headers). + request(ServerPid, <<"HEAD">>, Path, Headers, <<>>). -spec head(pid(), iodata(), headers(), req_opts()) -> reference(). head(ServerPid, Path, Headers, ReqOpts) -> @@ -352,11 +355,11 @@ head(ServerPid, Path, Headers, ReqOpts) -> -spec options(pid(), iodata()) -> reference(). options(ServerPid, Path) -> - request(ServerPid, <<"OPTIONS">>, Path, []). + request(ServerPid, <<"OPTIONS">>, Path, [], <<>>). -spec options(pid(), iodata(), headers()) -> reference(). options(ServerPid, Path, Headers) -> - request(ServerPid, <<"OPTIONS">>, Path, Headers). + request(ServerPid, <<"OPTIONS">>, Path, Headers, <<>>). -spec options(pid(), iodata(), headers(), req_opts()) -> reference(). options(ServerPid, Path, Headers, ReqOpts) -> @@ -364,9 +367,11 @@ options(ServerPid, Path, Headers, ReqOpts) -> -spec patch(pid(), iodata(), headers()) -> reference(). patch(ServerPid, Path, Headers) -> - request(ServerPid, <<"PATCH">>, Path, Headers). + headers(ServerPid, <<"PATCH">>, Path, Headers). --spec patch(pid(), iodata(), headers(), iodata()) -> reference(). +-spec patch(pid(), iodata(), headers(), iodata() | req_opts()) -> reference(). +patch(ServerPid, Path, Headers, ReqOpts) when is_map(ReqOpts) -> + headers(ServerPid, <<"PATCH">>, Path, Headers, ReqOpts); patch(ServerPid, Path, Headers, Body) -> request(ServerPid, <<"PATCH">>, Path, Headers, Body). @@ -376,9 +381,11 @@ patch(ServerPid, Path, Headers, Body, ReqOpts) -> -spec post(pid(), iodata(), headers()) -> reference(). post(ServerPid, Path, Headers) -> - request(ServerPid, <<"POST">>, Path, Headers). + headers(ServerPid, <<"POST">>, Path, Headers). --spec post(pid(), iodata(), headers(), iodata()) -> reference(). +-spec post(pid(), iodata(), headers(), iodata() | req_opts()) -> reference(). +post(ServerPid, Path, Headers, ReqOpts) when is_map(ReqOpts) -> + headers(ServerPid, <<"POST">>, Path, Headers, ReqOpts); post(ServerPid, Path, Headers, Body) -> request(ServerPid, <<"POST">>, Path, Headers, Body). @@ -388,9 +395,11 @@ post(ServerPid, Path, Headers, Body, ReqOpts) -> -spec put(pid(), iodata(), headers()) -> reference(). put(ServerPid, Path, Headers) -> - request(ServerPid, <<"PUT">>, Path, Headers). + headers(ServerPid, <<"PUT">>, Path, Headers). --spec put(pid(), iodata(), headers(), iodata()) -> reference(). +-spec put(pid(), iodata(), headers(), iodata() | req_opts()) -> reference(). +put(ServerPid, Path, Headers, ReqOpts) when is_map(ReqOpts) -> + headers(ServerPid, <<"PUT">>, Path, Headers, ReqOpts); put(ServerPid, Path, Headers, Body) -> request(ServerPid, <<"PUT">>, Path, Headers, Body). @@ -398,9 +407,19 @@ put(ServerPid, Path, Headers, Body) -> put(ServerPid, Path, Headers, Body, ReqOpts) -> request(ServerPid, <<"PUT">>, Path, Headers, Body, ReqOpts). --spec request(pid(), iodata(), iodata(), headers()) -> reference(). -request(ServerPid, Method, Path, Headers) -> - request(ServerPid, Method, Path, Headers, <<>>, #{}). +%% Generic requests interface. + +-spec headers(pid(), iodata(), iodata(), headers()) -> reference(). +headers(ServerPid, Method, Path, Headers) -> + headers(ServerPid, Method, Path, Headers, #{}). + +%% @todo Accept header names as maps. +-spec headers(pid(), iodata(), iodata(), headers(), req_opts()) -> reference(). +headers(ServerPid, Method, Path, Headers, ReqOpts) -> + StreamRef = make_ref(), + ReplyTo = maps:get(reply_to, ReqOpts, self()), + gen_statem:cast(ServerPid, {headers, ReplyTo, StreamRef, Method, Path, Headers}), + StreamRef. -spec request(pid(), iodata(), iodata(), headers(), iodata()) -> reference(). request(ServerPid, Method, Path, Headers, Body) -> @@ -729,15 +748,17 @@ connected(info, keepalive, State=#state{protocol=Protocol, protocol_state=ProtoS ProtoState2 = Protocol:keepalive(ProtoState), {keep_state, keepalive_timeout(State#state{protocol_state=ProtoState2})}; %% Public HTTP interface. +connected(cast, {headers, ReplyTo, StreamRef, Method, Path, Headers}, + State=#state{origin_host=Host, origin_port=Port, + protocol=Protocol, protocol_state=ProtoState}) -> + ProtoState2 = Protocol:headers(ProtoState, + StreamRef, ReplyTo, Method, Host, Port, Path, Headers), + {keep_state, State#state{protocol_state=ProtoState2}}; connected(cast, {request, ReplyTo, StreamRef, Method, Path, Headers, Body}, State=#state{origin_host=Host, origin_port=Port, protocol=Protocol, protocol_state=ProtoState}) -> - ProtoState2 = case Body of - <<>> -> Protocol:request(ProtoState, - StreamRef, ReplyTo, Method, Host, Port, Path, Headers); - _ -> Protocol:request(ProtoState, - StreamRef, ReplyTo, Method, Host, Port, Path, Headers, Body) - end, + ProtoState2 = Protocol:request(ProtoState, + StreamRef, ReplyTo, Method, Host, Port, Path, Headers, Body), {keep_state, State#state{protocol_state=ProtoState2}}; %% @todo Do we want to reject ReplyTo if it's not the process %% who initiated the connection? For both data and cancel. diff --git a/src/gun_http.erl b/src/gun_http.erl index 57f72c7..5229a6d 100644 --- a/src/gun_http.erl +++ b/src/gun_http.erl @@ -20,7 +20,7 @@ -export([handle/2]). -export([close/2]). -export([keepalive/1]). --export([request/8]). +-export([headers/8]). -export([request/9]). -export([data/5]). -export([connect/5]). @@ -330,7 +330,7 @@ keepalive(State=#http_state{socket=Socket, transport=Transport, out=head}) -> keepalive(State) -> State. -request(State=#http_state{socket=Socket, transport=Transport, version=Version, +headers(State=#http_state{socket=Socket, transport=Transport, version=Version, out=head}, StreamRef, ReplyTo, Method, Host, Port, Path, Headers) -> Host2 = case Host of {local, _SocketPath} -> <<>>; @@ -509,10 +509,7 @@ request_io_from_headers(Headers) -> {_, Length} -> {body, cow_http_hd:parse_content_length(Length)}; _ -> - case lists:keymember(<<"content-type">>, 1, Headers) of - true -> body_chunked; - false -> head - end + body_chunked end. response_io_from_headers(<<"HEAD">>, _, _, _) -> diff --git a/src/gun_http2.erl b/src/gun_http2.erl index 6538083..f5cf834 100644 --- a/src/gun_http2.erl +++ b/src/gun_http2.erl @@ -20,7 +20,7 @@ -export([handle/2]). -export([close/2]). -export([keepalive/1]). --export([request/8]). +-export([headers/8]). -export([request/9]). -export([data/5]). -export([cancel/3]). @@ -240,19 +240,14 @@ keepalive(State=#http2_state{socket=Socket, transport=Transport}) -> Transport:send(Socket, cow_http2:ping(0)), State. -request(State=#http2_state{socket=Socket, transport=Transport, +headers(State=#http2_state{socket=Socket, transport=Transport, http2_machine=HTTP2Machine0, streams=Streams}, StreamRef, ReplyTo, Method, Host, Port, Path, Headers0) -> - IsFin0 = case (false =/= lists:keyfind(<<"content-type">>, 1, Headers0)) - orelse (false =/= lists:keyfind(<<"content-length">>, 1, Headers0)) of - true -> nofin; - false -> fin - end, {ok, StreamID, HTTP2Machine1} = cow_http2_machine:init_stream( iolist_to_binary(Method), HTTP2Machine0), {ok, PseudoHeaders, Headers} = prepare_headers(State, Method, Host, Port, Path, Headers0), {ok, IsFin, HeaderBlock, HTTP2Machine} = cow_http2_machine:prepare_headers( - StreamID, HTTP2Machine1, IsFin0, PseudoHeaders, Headers), + StreamID, HTTP2Machine1, nofin, PseudoHeaders, Headers), Transport:send(Socket, cow_http2:headers(StreamID, IsFin, HeaderBlock)), Stream = #stream{id=StreamID, ref=StreamRef, reply_to=ReplyTo}, State#http2_state{http2_machine=HTTP2Machine, streams=[Stream|Streams]}. |