aboutsummaryrefslogtreecommitdiffstats
path: root/src/gun.erl
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2019-01-06 17:01:41 +0100
committerLoïc Hoguin <[email protected]>2019-01-06 17:01:41 +0100
commitab4878838fafbd453b41d031c9224b2ee8d2d956 (patch)
tree432a9fa69523af7637c3eeab0435b625c70a2cbd /src/gun.erl
parenteee5a59bc1763fc2e1c8c6e7155939dd04d930b7 (diff)
downloadgun-ab4878838fafbd453b41d031c9224b2ee8d2d956.tar.gz
gun-ab4878838fafbd453b41d031c9224b2ee8d2d956.tar.bz2
gun-ab4878838fafbd453b41d031c9224b2ee8d2d956.zip
Lowercase header names automatically and accept more types
Header names can now be provided as binary, string or atom and Gun no longer requires them to be in lowercase. The list of headers can also be provided as a map as well.
Diffstat (limited to 'src/gun.erl')
-rw-r--r--src/gun.erl73
1 files changed, 43 insertions, 30 deletions
diff --git a/src/gun.erl b/src/gun.erl
index 55e70dd..75092f1 100644
--- a/src/gun.erl
+++ b/src/gun.erl
@@ -94,7 +94,9 @@
-export([not_connected/3]).
-export([connected/3]).
--type headers() :: [{binary(), iodata()}].
+-type req_headers() :: [{binary() | string() | atom(), iodata()}]
+ | #{binary() | string() | atom() => iodata()}.
+-export_type([req_headers/0]).
-type ws_close_code() :: 1000..4999.
-type ws_frame() :: close | ping | pong
@@ -320,11 +322,11 @@ shutdown(ServerPid) ->
delete(ServerPid, Path) ->
request(ServerPid, <<"DELETE">>, Path, [], <<>>).
--spec delete(pid(), iodata(), headers()) -> reference().
+-spec delete(pid(), iodata(), req_headers()) -> reference().
delete(ServerPid, Path, Headers) ->
request(ServerPid, <<"DELETE">>, Path, Headers, <<>>).
--spec delete(pid(), iodata(), headers(), req_opts()) -> reference().
+-spec delete(pid(), iodata(), req_headers(), req_opts()) -> reference().
delete(ServerPid, Path, Headers, ReqOpts) ->
request(ServerPid, <<"DELETE">>, Path, Headers, <<>>, ReqOpts).
@@ -332,11 +334,11 @@ delete(ServerPid, Path, Headers, ReqOpts) ->
get(ServerPid, Path) ->
request(ServerPid, <<"GET">>, Path, [], <<>>).
--spec get(pid(), iodata(), headers()) -> reference().
+-spec get(pid(), iodata(), req_headers()) -> reference().
get(ServerPid, Path, Headers) ->
request(ServerPid, <<"GET">>, Path, Headers, <<>>).
--spec get(pid(), iodata(), headers(), req_opts()) -> reference().
+-spec get(pid(), iodata(), req_headers(), req_opts()) -> reference().
get(ServerPid, Path, Headers, ReqOpts) ->
request(ServerPid, <<"GET">>, Path, Headers, <<>>, ReqOpts).
@@ -344,11 +346,11 @@ get(ServerPid, Path, Headers, ReqOpts) ->
head(ServerPid, Path) ->
request(ServerPid, <<"HEAD">>, Path, [], <<>>).
--spec head(pid(), iodata(), headers()) -> reference().
+-spec head(pid(), iodata(), req_headers()) -> reference().
head(ServerPid, Path, Headers) ->
request(ServerPid, <<"HEAD">>, Path, Headers, <<>>).
--spec head(pid(), iodata(), headers(), req_opts()) -> reference().
+-spec head(pid(), iodata(), req_headers(), req_opts()) -> reference().
head(ServerPid, Path, Headers, ReqOpts) ->
request(ServerPid, <<"HEAD">>, Path, Headers, <<>>, ReqOpts).
@@ -356,82 +358,93 @@ head(ServerPid, Path, Headers, ReqOpts) ->
options(ServerPid, Path) ->
request(ServerPid, <<"OPTIONS">>, Path, [], <<>>).
--spec options(pid(), iodata(), headers()) -> reference().
+-spec options(pid(), iodata(), req_headers()) -> reference().
options(ServerPid, Path, Headers) ->
request(ServerPid, <<"OPTIONS">>, Path, Headers, <<>>).
--spec options(pid(), iodata(), headers(), req_opts()) -> reference().
+-spec options(pid(), iodata(), req_headers(), req_opts()) -> reference().
options(ServerPid, Path, Headers, ReqOpts) ->
request(ServerPid, <<"OPTIONS">>, Path, Headers, <<>>, ReqOpts).
--spec patch(pid(), iodata(), headers()) -> reference().
+-spec patch(pid(), iodata(), req_headers()) -> reference().
patch(ServerPid, Path, Headers) ->
headers(ServerPid, <<"PATCH">>, Path, Headers).
--spec patch(pid(), iodata(), headers(), iodata() | req_opts()) -> reference().
+-spec patch(pid(), iodata(), req_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).
--spec patch(pid(), iodata(), headers(), iodata(), req_opts()) -> reference().
+-spec patch(pid(), iodata(), req_headers(), iodata(), req_opts()) -> reference().
patch(ServerPid, Path, Headers, Body, ReqOpts) ->
request(ServerPid, <<"PATCH">>, Path, Headers, Body, ReqOpts).
--spec post(pid(), iodata(), headers()) -> reference().
+-spec post(pid(), iodata(), req_headers()) -> reference().
post(ServerPid, Path, Headers) ->
headers(ServerPid, <<"POST">>, Path, Headers).
--spec post(pid(), iodata(), headers(), iodata() | req_opts()) -> reference().
+-spec post(pid(), iodata(), req_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).
--spec post(pid(), iodata(), headers(), iodata(), req_opts()) -> reference().
+-spec post(pid(), iodata(), req_headers(), iodata(), req_opts()) -> reference().
post(ServerPid, Path, Headers, Body, ReqOpts) ->
request(ServerPid, <<"POST">>, Path, Headers, Body, ReqOpts).
--spec put(pid(), iodata(), headers()) -> reference().
+-spec put(pid(), iodata(), req_headers()) -> reference().
put(ServerPid, Path, Headers) ->
headers(ServerPid, <<"PUT">>, Path, Headers).
--spec put(pid(), iodata(), headers(), iodata() | req_opts()) -> reference().
+-spec put(pid(), iodata(), req_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).
--spec put(pid(), iodata(), headers(), iodata(), req_opts()) -> reference().
+-spec put(pid(), iodata(), req_headers(), iodata(), req_opts()) -> reference().
put(ServerPid, Path, Headers, Body, ReqOpts) ->
request(ServerPid, <<"PUT">>, Path, Headers, Body, ReqOpts).
%% Generic requests interface.
--spec headers(pid(), iodata(), iodata(), headers()) -> reference().
+-spec headers(pid(), iodata(), iodata(), req_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().
+-spec headers(pid(), iodata(), iodata(), req_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}),
+ gen_statem:cast(ServerPid, {headers, ReplyTo, StreamRef,
+ Method, Path, normalize_headers(Headers)}),
StreamRef.
--spec request(pid(), iodata(), iodata(), headers(), iodata()) -> reference().
+-spec request(pid(), iodata(), iodata(), req_headers(), iodata()) -> reference().
request(ServerPid, Method, Path, Headers, Body) ->
request(ServerPid, Method, Path, Headers, Body, #{}).
-%% @todo Accept header names as maps.
--spec request(pid(), iodata(), iodata(), headers(), iodata(), req_opts()) -> reference().
+-spec request(pid(), iodata(), iodata(), req_headers(), iodata(), req_opts()) -> reference().
request(ServerPid, Method, Path, Headers, Body, ReqOpts) ->
StreamRef = make_ref(),
ReplyTo = maps:get(reply_to, ReqOpts, self()),
- gen_statem:cast(ServerPid, {request, ReplyTo, StreamRef, Method, Path, Headers, Body}),
+ gen_statem:cast(ServerPid, {request, ReplyTo, StreamRef,
+ Method, Path, normalize_headers(Headers), Body}),
StreamRef.
+normalize_headers([]) ->
+ [];
+normalize_headers([{Name, Value}|Tail]) when is_binary(Name) ->
+ [{string:lowercase(Name), Value}|normalize_headers(Tail)];
+normalize_headers([{Name, Value}|Tail]) when is_list(Name) ->
+ [{string:lowercase(unicode:characters_to_binary(Name)), Value}|normalize_headers(Tail)];
+normalize_headers([{Name, Value}|Tail]) when is_atom(Name) ->
+ [{string:lowercase(atom_to_binary(Name, latin1)), Value}|normalize_headers(Tail)];
+normalize_headers(Headers) when is_map(Headers) ->
+ normalize_headers(maps:to_list(Headers)).
+
%% Streaming data.
-spec data(pid(), reference(), fin | nofin, iodata()) -> ok.
@@ -449,11 +462,11 @@ data(ServerPid, StreamRef, IsFin, Data) ->
connect(ServerPid, Destination) ->
connect(ServerPid, Destination, [], #{}).
--spec connect(pid(), connect_destination(), headers()) -> reference().
+-spec connect(pid(), connect_destination(), req_headers()) -> reference().
connect(ServerPid, Destination, Headers) ->
connect(ServerPid, Destination, Headers, #{}).
--spec connect(pid(), connect_destination(), headers(), req_opts()) -> reference().
+-spec connect(pid(), connect_destination(), req_headers(), req_opts()) -> reference().
connect(ServerPid, Destination, Headers, ReqOpts) ->
StreamRef = make_ref(),
ReplyTo = maps:get(reply_to, ReqOpts, self()),
@@ -639,13 +652,13 @@ cancel(ServerPid, StreamRef) ->
ws_upgrade(ServerPid, Path) ->
ws_upgrade(ServerPid, Path, []).
--spec ws_upgrade(pid(), iodata(), headers()) -> reference().
+-spec ws_upgrade(pid(), iodata(), req_headers()) -> reference().
ws_upgrade(ServerPid, Path, Headers) ->
StreamRef = make_ref(),
gen_statem:cast(ServerPid, {ws_upgrade, self(), StreamRef, Path, Headers}),
StreamRef.
--spec ws_upgrade(pid(), iodata(), headers(), ws_opts()) -> reference().
+-spec ws_upgrade(pid(), iodata(), req_headers(), ws_opts()) -> reference().
ws_upgrade(ServerPid, Path, Headers, Opts) ->
ok = gun_ws:check_options(Opts),
StreamRef = make_ref(),