Browse Source

Document media type wildcard in content_types_accepted

Loïc Hoguin 5 years ago
parent
commit
28aee1f272

+ 5 - 1
doc/src/manual/cowboy_rest.asciidoc

@@ -184,7 +184,7 @@ content-type header of the response if the media type is text.
 ----
 ----
 content_types_accepted(Req, State) -> {Result, Req, State}
 content_types_accepted(Req, State) -> {Result, Req, State}
 
 
-Result     :: [{binary() | ParsedMime, AcceptCallback :: atom()}]
+Result     :: [{'*' | binary() | ParsedMime, AcceptCallback :: atom()}]
 ParsedMime :: {Type :: binary(), SubType :: binary(), '*' | Params}
 ParsedMime :: {Type :: binary(), SubType :: binary(), '*' | Params}
 Params     :: [{Key :: binary(), Value :: binary()}]
 Params     :: [{Key :: binary(), Value :: binary()}]
 
 
@@ -200,6 +200,8 @@ A media type is made of different parts. The media type
 `text/html;charset=utf-8` is of type `text`, subtype `html`
 `text/html;charset=utf-8` is of type `text`, subtype `html`
 and has a single parameter `charset` with value `utf-8`.
 and has a single parameter `charset` with value `utf-8`.
 
 
+The special value `'*'` can be used to accept any media type.
+
 // @todo Cowboy needs to ignore the boundary parameter for
 // @todo Cowboy needs to ignore the boundary parameter for
 // multipart, as we never want to match against it. Or allow
 // multipart, as we never want to match against it. Or allow
 // ignoring specific parameters at the very least.
 // ignoring specific parameters at the very least.
@@ -724,6 +726,8 @@ listed here, like the authorization header.
 
 
 == Changelog
 == Changelog
 
 
+* *2.7*: The media type wildcard in `content_types_accepted`
+         is now documented.
 * *2.6*: The callback `rate_limited` was added.
 * *2.6*: The callback `rate_limited` was added.
 * *2.1*: The `switch_handler` return value was added.
 * *2.1*: The `switch_handler` return value was added.
 * *1.0*: Behavior introduced.
 * *1.0*: Behavior introduced.

+ 1 - 1
src/cowboy_rest.erl

@@ -61,7 +61,7 @@
 -optional_callbacks([charsets_provided/2]).
 -optional_callbacks([charsets_provided/2]).
 
 
 -callback content_types_accepted(Req, State)
 -callback content_types_accepted(Req, State)
-	-> {[{binary() | {binary(), binary(), '*' | [{binary(), binary()}]}, atom()}], Req, State}
+	-> {[{'*' | binary() | {binary(), binary(), '*' | [{binary(), binary()}]}, atom()}], Req, State}
 	| {stop, Req, State}
 	| {stop, Req, State}
 	| {switch_handler(), Req, State}
 	| {switch_handler(), Req, State}
 	when Req::cowboy_req:req(), State::any().
 	when Req::cowboy_req:req(), State::any().

+ 2 - 0
test/handlers/content_types_accepted_h.erl

@@ -21,6 +21,8 @@ content_types_accepted(Req=#{qs := <<"multipart">>}, State) ->
 	], Req, State};
 	], Req, State};
 content_types_accepted(Req=#{qs := <<"param">>}, State) ->
 content_types_accepted(Req=#{qs := <<"param">>}, State) ->
 	{[{{<<"text">>, <<"plain">>, [{<<"charset">>, <<"utf-8">>}]}, put_text_plain}], Req, State};
 	{[{{<<"text">>, <<"plain">>, [{<<"charset">>, <<"utf-8">>}]}, put_text_plain}], Req, State};
+content_types_accepted(Req=#{qs := <<"wildcard">>}, State) ->
+	{[{'*', put_text_plain}], Req, State};
 content_types_accepted(Req=#{qs := <<"wildcard-param">>}, State) ->
 content_types_accepted(Req=#{qs := <<"wildcard-param">>}, State) ->
 	{[{{<<"text">>, <<"plain">>, '*'}, put_text_plain}], Req, State}.
 	{[{{<<"text">>, <<"plain">>, '*'}, put_text_plain}], Req, State}.
 
 

+ 18 - 0
test/rest_handler_SUITE.erl

@@ -359,6 +359,24 @@ content_types_accepted_param(Config) ->
 	{response, fin, 204, _} = gun:await(ConnPid, Ref),
 	{response, fin, 204, _} = gun:await(ConnPid, Ref),
 	ok.
 	ok.
 
 
+content_types_accepted_wildcard(Config) ->
+	doc("When a wildcard is returned from the content_types_accepted "
+		"callback, any content-type must be accepted."),
+	ConnPid = gun_open(Config),
+	Ref1 = gun:put(ConnPid, "/content_types_accepted?wildcard", [
+		{<<"accept-encoding">>, <<"gzip">>},
+		{<<"content-type">>, <<"text/plain">>}
+	]),
+	gun:data(ConnPid, Ref1, fin, "Hello world!"),
+	{response, fin, 204, _} = gun:await(ConnPid, Ref1),
+	Ref2 = gun:put(ConnPid, "/content_types_accepted?wildcard", [
+		{<<"accept-encoding">>, <<"gzip">>},
+		{<<"content-type">>, <<"application/vnd.plain;charset=UTF-8">>}
+	]),
+	gun:data(ConnPid, Ref2, fin, "Hello world!"),
+	{response, fin, 204, _} = gun:await(ConnPid, Ref2),
+	ok.
+
 content_types_accepted_wildcard_param_no_content_type_param(Config) ->
 content_types_accepted_wildcard_param_no_content_type_param(Config) ->
 	doc("When a wildcard is returned for parameters from the "
 	doc("When a wildcard is returned for parameters from the "
 		"content_types_accepted callback, a content-type header "
 		"content_types_accepted callback, a content-type header "