aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaweł Chmielowski <pchmielowski@process-one.net>2012-04-11 17:24:36 +0200
committerPaweł Chmielowski <pchmielowski@process-one.net>2012-04-11 17:28:18 +0200
commite2d6bc95a4ce5f5ea29fd369f376987ffc8b7e85 (patch)
tree3ab4ce2f5a93305b534a9f444080dc6344ef4095
parentreturn user affiliation for a specified node (thanks to Karim Gemayel) (EJAB-... (diff)
Parse and encode https header names like native http parser does
This code adds case normalization step to https headers parsing, making it correctly use atoms for some special header no matter how upper/lower case letters are used in input string
-rw-r--r--src/web/ejabberd_http.erl79
1 files changed, 48 insertions, 31 deletions
diff --git a/src/web/ejabberd_http.erl b/src/web/ejabberd_http.erl
index 067ed07d9..c20e267db 100644
--- a/src/web/ejabberd_http.erl
+++ b/src/web/ejabberd_http.erl
@@ -944,7 +944,7 @@ decode_packet(Type, Data) ->
http ->
parse_req(Line);
httph ->
- parse_line(Line)
+ parse_header_line(Line)
end,
case Result of
{ok, H} ->
@@ -1026,55 +1026,72 @@ parse_req(Line) ->
end.
-parse_line("Connection:" ++ Con) ->
+toupper(C) when C >= $a andalso C =< $z ->
+ C - 32;
+toupper(C) ->
+ C.
+
+tolower(C) when C >= $A andalso C =< $Z ->
+ C + 32;
+tolower(C) ->
+ C.
+
+
+parse_header_line(Line) ->
+ parse_header_line(Line, "", true).
+
+parse_header_line("", _, _) ->
+ bad_request;
+parse_header_line(":" ++ Rest, Name, _) ->
+ encode_header(lists:reverse(Name), Rest);
+parse_header_line("-" ++ Rest, Name, _) ->
+ parse_header_line(Rest, "-" ++ Name, true);
+parse_header_line([C | Rest], Name, true) ->
+ parse_header_line(Rest, [toupper(C) | Name], false);
+parse_header_line([C | Rest], Name, false) ->
+ parse_header_line(Rest, [tolower(C) | Name], false).
+
+
+encode_header("Connection", Con) ->
{ok, {http_header, undefined, 'Connection', undefined, strip_spaces(Con)}};
-parse_line("Host:" ++ Con) ->
+encode_header("Host", Con) ->
{ok, {http_header, undefined, 'Host', undefined, strip_spaces(Con)}};
-parse_line("Accept:" ++ Con) ->
+encode_header("Accept", Con) ->
{ok, {http_header, undefined, 'Accept', undefined, strip_spaces(Con)}};
-parse_line("If-Modified-Since:" ++ Con) ->
+encode_header("If-Modified-Since", Con) ->
{ok, {http_header, undefined, 'If-Modified-Since', undefined, strip_spaces(Con)}};
-parse_line("If-Match:" ++ Con) ->
+encode_header("If-Match", Con) ->
{ok, {http_header, undefined, 'If-Match', undefined, strip_spaces(Con)}};
-parse_line("If-None-Match:" ++ Con) ->
+encode_header("If-None-Match", Con) ->
{ok, {http_header, undefined, 'If-None-Match', undefined, strip_spaces(Con)}};
-parse_line("If-Range:" ++ Con) ->
+encode_header("If-Range", Con) ->
{ok, {http_header, undefined, 'If-Range', undefined, strip_spaces(Con)}};
-parse_line("If-Unmodified-Since:" ++ Con) ->
+encode_header("If-Unmodified-Since", Con) ->
{ok, {http_header, undefined, 'If-Unmodified-Since', undefined, strip_spaces(Con)}};
-parse_line("Range:" ++ Con) ->
+encode_header("Range", Con) ->
{ok, {http_header, undefined, 'Range', undefined, strip_spaces(Con)}};
-parse_line("User-Agent:" ++ Con) ->
+encode_header("User-Agent", Con) ->
{ok, {http_header, undefined, 'User-Agent', undefined, strip_spaces(Con)}};
-parse_line("Accept-Ranges:" ++ Con) ->
+encode_header("Accept-Ranges", Con) ->
{ok, {http_header, undefined, 'Accept-Ranges', undefined, strip_spaces(Con)}};
-parse_line("Authorization:" ++ Con) ->
+encode_header("Authorization", Con) ->
{ok, {http_header, undefined, 'Authorization', undefined, strip_spaces(Con)}};
-parse_line("Keep-Alive:" ++ Con) ->
+encode_header("Keep-Alive", Con) ->
{ok, {http_header, undefined, 'Keep-Alive', undefined, strip_spaces(Con)}};
-parse_line("Referer:" ++ Con) ->
+encode_header("Referer", Con) ->
{ok, {http_header, undefined, 'Referer', undefined, strip_spaces(Con)}};
-parse_line("Content-type:"++Con) ->
- {ok, {http_header, undefined, 'Content-Type', undefined, strip_spaces(Con)}};
-parse_line("Content-Type:"++Con) ->
+encode_header("Content-Type", Con) ->
{ok, {http_header, undefined, 'Content-Type', undefined, strip_spaces(Con)}};
-parse_line("Content-Length:"++Con) ->
- {ok, {http_header, undefined, 'Content-Length', undefined, strip_spaces(Con)}};
-parse_line("Content-length:"++Con) ->
+encode_header("Content-Length", Con) ->
{ok, {http_header, undefined, 'Content-Length', undefined, strip_spaces(Con)}};
-parse_line("Cookie:"++Con) ->
+encode_header("Cookie", Con) ->
{ok, {http_header, undefined, 'Cookie', undefined, strip_spaces(Con)}};
-parse_line("Accept-Language:"++Con) ->
+encode_header("Accept-Language", Con) ->
{ok, {http_header, undefined, 'Accept-Language', undefined, strip_spaces(Con)}};
-parse_line("Accept-Encoding:"++Con) ->
+encode_header("Accept-Encoding", Con) ->
{ok, {http_header, undefined, 'Accept-Encoding', undefined, strip_spaces(Con)}};
-parse_line(S) ->
- case lists:splitwith(fun(C)->C /= $: end, S) of
- {Name, [$:|Val]} ->
- {ok, {http_header, undefined, Name, undefined, strip_spaces(Val)}};
- _ ->
- bad_request
- end.
+encode_header(Name, Val) ->
+ {ok, {http_header, undefined, Name, undefined, strip_spaces(Val)}}.
is_space($\s) ->