mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 12:20:24 +00:00
Add support for lists in cowboy_req:set_resp_headers
This is meant to be used with clients such as Gun to simplify proxying and similar operations. The set-cookie header must not be set this way so there is still some extra processing to be done to fully translate a Gun response into a Cowboy response.
This commit is contained in:
parent
f316a65906
commit
e8a1868033
4 changed files with 48 additions and 7 deletions
|
@ -11,7 +11,7 @@ cowboy_req:set_resp_headers - Set several response headers
|
||||||
set_resp_headers(Headers, Req :: cowboy_req:req())
|
set_resp_headers(Headers, Req :: cowboy_req:req())
|
||||||
-> Req
|
-> Req
|
||||||
|
|
||||||
Headers :: cowboy:http_headers()
|
Headers :: cowboy:http_headers() | [{binary(), iodata()}]
|
||||||
----
|
----
|
||||||
|
|
||||||
Set several headers to be sent with the response.
|
Set several headers to be sent with the response.
|
||||||
|
@ -32,8 +32,16 @@ instead of this function to set cookies.
|
||||||
|
|
||||||
Headers::
|
Headers::
|
||||||
|
|
||||||
Headers as a map with keys being lowercase binary strings,
|
Headers as a map with names being lowercase binary strings,
|
||||||
and values as binary strings.
|
and values as iodata; or as a list with the same requirements
|
||||||
|
for names and values.
|
||||||
|
+
|
||||||
|
When a list is given it is converted to its equivalent map,
|
||||||
|
with duplicate headers concatenated with a comma inserted
|
||||||
|
in-between. Support for lists is meant to simplify using
|
||||||
|
data from clients or other applications.
|
||||||
|
+
|
||||||
|
The set-cookie header must not be set using this function.
|
||||||
|
|
||||||
Req::
|
Req::
|
||||||
|
|
||||||
|
@ -48,6 +56,7 @@ otherwise the headers will not be sent in the response.
|
||||||
|
|
||||||
== Changelog
|
== Changelog
|
||||||
|
|
||||||
|
* *2.13*: The function now accepts a list of headers.
|
||||||
* *2.0*: Function introduced.
|
* *2.0*: Function introduced.
|
||||||
|
|
||||||
== Examples
|
== Examples
|
||||||
|
|
|
@ -726,8 +726,10 @@ set_resp_header(Name, Value, Req=#{resp_headers := RespHeaders}) ->
|
||||||
set_resp_header(Name,Value, Req) ->
|
set_resp_header(Name,Value, Req) ->
|
||||||
Req#{resp_headers => #{Name => Value}}.
|
Req#{resp_headers => #{Name => Value}}.
|
||||||
|
|
||||||
-spec set_resp_headers(cowboy:http_headers(), Req)
|
-spec set_resp_headers(cowboy:http_headers() | [{binary(), iodata()}], Req)
|
||||||
-> Req when Req::req().
|
-> Req when Req::req().
|
||||||
|
set_resp_headers(Headers, Req) when is_list(Headers) ->
|
||||||
|
set_resp_headers_list(Headers, Req, #{});
|
||||||
set_resp_headers(#{<<"set-cookie">> := _}, _) ->
|
set_resp_headers(#{<<"set-cookie">> := _}, _) ->
|
||||||
exit({response_error, invalid_header,
|
exit({response_error, invalid_header,
|
||||||
'Response cookies must be set using cowboy_req:set_resp_cookie/3,4.'});
|
'Response cookies must be set using cowboy_req:set_resp_cookie/3,4.'});
|
||||||
|
@ -736,6 +738,19 @@ set_resp_headers(Headers, Req=#{resp_headers := RespHeaders}) ->
|
||||||
set_resp_headers(Headers, Req) ->
|
set_resp_headers(Headers, Req) ->
|
||||||
Req#{resp_headers => Headers}.
|
Req#{resp_headers => Headers}.
|
||||||
|
|
||||||
|
set_resp_headers_list([], Req, Acc) ->
|
||||||
|
set_resp_headers(Acc, Req);
|
||||||
|
set_resp_headers_list([{<<"set-cookie">>, _}|_], _, _) ->
|
||||||
|
exit({response_error, invalid_header,
|
||||||
|
'Response cookies must be set using cowboy_req:set_resp_cookie/3,4.'});
|
||||||
|
set_resp_headers_list([{Name, Value}|Tail], Req, Acc) ->
|
||||||
|
case Acc of
|
||||||
|
#{Name := ValueAcc} ->
|
||||||
|
set_resp_headers_list(Tail, Req, Acc#{Name => [ValueAcc, <<", ">>, Value]});
|
||||||
|
_ ->
|
||||||
|
set_resp_headers_list(Tail, Req, Acc#{Name => Value})
|
||||||
|
end.
|
||||||
|
|
||||||
-spec resp_header(binary(), req()) -> binary() | undefined.
|
-spec resp_header(binary(), req()) -> binary() | undefined.
|
||||||
resp_header(Name, Req) ->
|
resp_header(Name, Req) ->
|
||||||
resp_header(Name, Req, undefined).
|
resp_header(Name, Req, undefined).
|
||||||
|
|
|
@ -43,12 +43,25 @@ do(<<"set_resp_headers">>, Req0, Opts) ->
|
||||||
<<"content-encoding">> => <<"compress">>
|
<<"content-encoding">> => <<"compress">>
|
||||||
}, Req0),
|
}, Req0),
|
||||||
{ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
|
{ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
|
||||||
|
do(<<"set_resp_headers_list">>, Req0, Opts) ->
|
||||||
|
Req = cowboy_req:set_resp_headers([
|
||||||
|
{<<"content-type">>, <<"text/plain">>},
|
||||||
|
{<<"content-encoding">>, <<"compress">>}
|
||||||
|
], Req0),
|
||||||
|
{ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
|
||||||
do(<<"set_resp_headers_cookie">>, Req0, Opts) ->
|
do(<<"set_resp_headers_cookie">>, Req0, Opts) ->
|
||||||
ct_helper:ignore(cowboy_req, set_resp_headers, 2),
|
ct_helper:ignore(cowboy_req, set_resp_headers, 2),
|
||||||
Req = cowboy_req:set_resp_headers(#{
|
Req = cowboy_req:set_resp_headers(#{
|
||||||
<<"set-cookie">> => <<"name=value">>
|
<<"set-cookie">> => <<"name=value">>
|
||||||
}, Req0),
|
}, Req0),
|
||||||
{ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
|
{ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
|
||||||
|
do(<<"set_resp_headers_list_cookie">>, Req0, Opts) ->
|
||||||
|
ct_helper:ignore(cowboy_req, set_resp_headers_list, 3),
|
||||||
|
Req = cowboy_req:set_resp_headers([
|
||||||
|
{<<"set-cookie">>, <<"name=value">>},
|
||||||
|
{<<"set-cookie">>, <<"name2=value2">>}
|
||||||
|
], Req0),
|
||||||
|
{ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
|
||||||
do(<<"set_resp_headers_http11">>, Req0, Opts) ->
|
do(<<"set_resp_headers_http11">>, Req0, Opts) ->
|
||||||
Req = cowboy_req:set_resp_headers(#{
|
Req = cowboy_req:set_resp_headers(#{
|
||||||
<<"connection">> => <<"custom-header, close">>,
|
<<"connection">> => <<"custom-header, close">>,
|
||||||
|
|
|
@ -858,11 +858,15 @@ set_resp_header(Config) ->
|
||||||
|
|
||||||
set_resp_headers(Config) ->
|
set_resp_headers(Config) ->
|
||||||
doc("Response using set_resp_headers."),
|
doc("Response using set_resp_headers."),
|
||||||
{200, Headers, <<"OK">>} = do_get("/resp/set_resp_headers", Config),
|
{200, Headers1, <<"OK">>} = do_get("/resp/set_resp_headers", Config),
|
||||||
true = lists:keymember(<<"content-type">>, 1, Headers),
|
true = lists:keymember(<<"content-type">>, 1, Headers1),
|
||||||
true = lists:keymember(<<"content-encoding">>, 1, Headers),
|
true = lists:keymember(<<"content-encoding">>, 1, Headers1),
|
||||||
|
{200, Headers2, <<"OK">>} = do_get("/resp/set_resp_headers_list", Config),
|
||||||
|
true = lists:keymember(<<"content-type">>, 1, Headers2),
|
||||||
|
true = lists:keymember(<<"content-encoding">>, 1, Headers2),
|
||||||
%% The set-cookie header is special. set_resp_cookie must be used.
|
%% The set-cookie header is special. set_resp_cookie must be used.
|
||||||
{500, _, _} = do_maybe_h3_error3(do_get("/resp/set_resp_headers_cookie", Config)),
|
{500, _, _} = do_maybe_h3_error3(do_get("/resp/set_resp_headers_cookie", Config)),
|
||||||
|
{500, _, _} = do_maybe_h3_error3(do_get("/resp/set_resp_headers_list_cookie", Config)),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
resp_header(Config) ->
|
resp_header(Config) ->
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue