summaryrefslogtreecommitdiff
path: root/src/mochiweb/mochiweb_request.erl
diff options
context:
space:
mode:
authorFilipe David Borba Manana <fdmanana@apache.org>2010-11-12 20:15:25 +0000
committerFilipe David Borba Manana <fdmanana@apache.org>2010-11-12 20:15:25 +0000
commit0264c51de7f281bc3b01d51e43831da2bcc741df (patch)
tree7ee5b7831007a1abe59071d71e868c4e26901f1d /src/mochiweb/mochiweb_request.erl
parentf3329af215151bc949214fda9d44f7b9995da367 (diff)
Backporting issue 21 from the official Mochiweb repository:
correctly determining (as specified by RFC2616) if a request accepts a specific media type for the Content-Type of the response. https://github.com/mochi/mochiweb/issues/closed#issue/21 git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@1034553 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/mochiweb/mochiweb_request.erl')
-rw-r--r--src/mochiweb/mochiweb_request.erl53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/mochiweb/mochiweb_request.erl b/src/mochiweb/mochiweb_request.erl
index 1cf96160..ffe4e9eb 100644
--- a/src/mochiweb/mochiweb_request.erl
+++ b/src/mochiweb/mochiweb_request.erl
@@ -21,6 +21,7 @@
-export([parse_cookie/0, get_cookie_value/1]).
-export([serve_file/2, serve_file/3]).
-export([accepted_encodings/1]).
+-export([accepts_content_type/1]).
-define(SAVE_QS, mochiweb_request_qs).
-define(SAVE_PATH, mochiweb_request_path).
@@ -707,6 +708,58 @@ accepted_encodings(SupportedEncodings) ->
)
end.
+%% @spec accepts_content_type(string() | binary()) -> boolean() | bad_accept_header
+%%
+%% @doc Determines whether a request accepts a given media type by analyzing its
+%% "Accept" header.
+%%
+%% Examples
+%%
+%% 1) For a missing "Accept" header:
+%% accepts_content_type("application/json") -> true
+%%
+%% 2) For an "Accept" header with value "text/plain, application/*":
+%% accepts_content_type("application/json") -> true
+%%
+%% 3) For an "Accept" header with value "text/plain, */*; q=0.0":
+%% accepts_content_type("application/json") -> false
+%%
+%% 4) For an "Accept" header with value "text/plain; q=0.5, */*; q=0.1":
+%% accepts_content_type("application/json") -> true
+%%
+%% 5) For an "Accept" header with value "text/*; q=0.0, */*":
+%% accepts_content_type("text/plain") -> false
+%%
+accepts_content_type(ContentType) when is_binary(ContentType) ->
+ accepts_content_type(binary_to_list(ContentType));
+accepts_content_type(ContentType1) ->
+ ContentType = re:replace(ContentType1, "\\s", "", [global, {return, list}]),
+ AcceptHeader = case get_header_value("Accept") of
+ undefined ->
+ "*/*";
+ Value ->
+ Value
+ end,
+ case mochiweb_util:parse_qvalues(AcceptHeader) of
+ invalid_qvalue_string ->
+ bad_accept_header;
+ QList ->
+ [MainType, _SubType] = string:tokens(ContentType, "/"),
+ SuperType = MainType ++ "/*",
+ lists:any(
+ fun({"*/*", Q}) when Q > 0.0 ->
+ true;
+ ({Type, Q}) when Q > 0.0 ->
+ Type =:= ContentType orelse Type =:= SuperType;
+ (_) ->
+ false
+ end,
+ QList
+ ) andalso
+ (not lists:member({ContentType, 0.0}, QList)) andalso
+ (not lists:member({SuperType, 0.0}, QList))
+ end.
+
%%
%% Tests
%%