aboutsummaryrefslogtreecommitdiffstats
path: root/src/gun.erl
diff options
context:
space:
mode:
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(),