mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 12:20:24 +00:00
REST: Allow generate_etag to return undefined
This allows conditionally generating an etag.
This commit is contained in:
parent
ec12c2f051
commit
defce46fdf
4 changed files with 29 additions and 2 deletions
|
@ -379,7 +379,7 @@ and that the request shouldn't be repeated.
|
||||||
----
|
----
|
||||||
generate_etag(Req, State) -> {Result, Req, State}
|
generate_etag(Req, State) -> {Result, Req, State}
|
||||||
|
|
||||||
Result :: binary() | {weak | strong, binary()}
|
Result :: binary() | {weak | strong, binary()} | undefined
|
||||||
Default - no etag value
|
Default - no etag value
|
||||||
----
|
----
|
||||||
|
|
||||||
|
@ -389,6 +389,10 @@ When a binary is returned, the value is automatically
|
||||||
parsed to a tuple. The binary must be in the same
|
parsed to a tuple. The binary must be in the same
|
||||||
format as the etag header, including quotes.
|
format as the etag header, including quotes.
|
||||||
|
|
||||||
|
It is possible to conditionally generate an etag.
|
||||||
|
When no etag can be generated, `undefined` should
|
||||||
|
be returned.
|
||||||
|
|
||||||
=== is_authorized
|
=== is_authorized
|
||||||
|
|
||||||
[source,erlang]
|
[source,erlang]
|
||||||
|
@ -730,6 +734,9 @@ listed here, like the authorization header.
|
||||||
|
|
||||||
== Changelog
|
== Changelog
|
||||||
|
|
||||||
|
* *2.11*: The `generate_etag` callback can now return
|
||||||
|
`undefined` to conditionally avoid generating
|
||||||
|
an etag.
|
||||||
* *2.9*: An `AcceptCallback` can now return `{created, URI}` or
|
* *2.9*: An `AcceptCallback` can now return `{created, URI}` or
|
||||||
`{see_other, URI}`. The return value `{true, URI}`
|
`{see_other, URI}`. The return value `{true, URI}`
|
||||||
is deprecated.
|
is deprecated.
|
||||||
|
|
|
@ -97,7 +97,7 @@
|
||||||
-optional_callbacks([forbidden/2]).
|
-optional_callbacks([forbidden/2]).
|
||||||
|
|
||||||
-callback generate_etag(Req, State)
|
-callback generate_etag(Req, State)
|
||||||
-> {binary() | {weak | strong, binary()}, Req, State}
|
-> {binary() | {weak | strong, binary()} | undefined, Req, State}
|
||||||
when Req::cowboy_req:req(), State::any().
|
when Req::cowboy_req:req(), State::any().
|
||||||
-optional_callbacks([generate_etag/2]).
|
-optional_callbacks([generate_etag/2]).
|
||||||
|
|
||||||
|
@ -1527,6 +1527,12 @@ generate_etag(Req, State=#state{etag=undefined}) ->
|
||||||
case unsafe_call(Req, State, generate_etag) of
|
case unsafe_call(Req, State, generate_etag) of
|
||||||
no_call ->
|
no_call ->
|
||||||
{undefined, Req, State#state{etag=no_call}};
|
{undefined, Req, State#state{etag=no_call}};
|
||||||
|
%% We allow the callback to return 'undefined'
|
||||||
|
%% to allow conditionally generating etags. We
|
||||||
|
%% handle 'undefined' the same as if the function
|
||||||
|
%% was not exported.
|
||||||
|
{undefined, Req2, State2} ->
|
||||||
|
{undefined, Req2, State2#state{etag=no_call}};
|
||||||
{Etag, Req2, State2} when is_binary(Etag) ->
|
{Etag, Req2, State2} when is_binary(Etag) ->
|
||||||
Etag2 = cow_http_hd:parse_etag(Etag),
|
Etag2 = cow_http_hd:parse_etag(Etag),
|
||||||
{Etag2, Req2, State2#state{etag=Etag2}};
|
{Etag2, Req2, State2#state{etag=Etag2}};
|
||||||
|
|
|
@ -34,6 +34,9 @@ generate_etag(Req=#{qs := <<"binary-weak-unquoted">>}, State) ->
|
||||||
generate_etag(Req=#{qs := <<"binary-strong-unquoted">>}, State) ->
|
generate_etag(Req=#{qs := <<"binary-strong-unquoted">>}, State) ->
|
||||||
ct_helper_error_h:ignore(cow_http_hd, parse_etag, 1),
|
ct_helper_error_h:ignore(cow_http_hd, parse_etag, 1),
|
||||||
{<<"etag-header-value">>, Req, State};
|
{<<"etag-header-value">>, Req, State};
|
||||||
|
%% Returning 'undefined' to indicate no etag.
|
||||||
|
generate_etag(Req=#{qs := <<"undefined">>}, State) ->
|
||||||
|
{undefined, Req, State};
|
||||||
%% Simulate the callback being missing in other cases.
|
%% Simulate the callback being missing in other cases.
|
||||||
generate_etag(#{qs := <<"missing">>}, _) ->
|
generate_etag(#{qs := <<"missing">>}, _) ->
|
||||||
no_call.
|
no_call.
|
||||||
|
|
|
@ -571,6 +571,17 @@ generate_etag_missing(Config) ->
|
||||||
false = lists:keyfind(<<"etag">>, 1, Headers),
|
false = lists:keyfind(<<"etag">>, 1, Headers),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
generate_etag_undefined(Config) ->
|
||||||
|
doc("The etag header must not be sent when "
|
||||||
|
"the generate_etag callback returns undefined."),
|
||||||
|
ConnPid = gun_open(Config),
|
||||||
|
Ref = gun:get(ConnPid, "/generate_etag?undefined", [
|
||||||
|
{<<"accept-encoding">>, <<"gzip">>}
|
||||||
|
]),
|
||||||
|
{response, _, 200, Headers} = gun:await(ConnPid, Ref),
|
||||||
|
false = lists:keyfind(<<"etag">>, 1, Headers),
|
||||||
|
ok.
|
||||||
|
|
||||||
generate_etag_binary_strong(Config) ->
|
generate_etag_binary_strong(Config) ->
|
||||||
doc("The etag header must be sent when the generate_etag "
|
doc("The etag header must be sent when the generate_etag "
|
||||||
"callback returns a strong binary. (RFC7232 2.3)"),
|
"callback returns a strong binary. (RFC7232 2.3)"),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue