mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 12:20:24 +00:00
Add cowboy_http:x_www_form_urlencoded/2
This was initially an internal function, it has been made public due to popular demand as it can sometimes be needed.
This commit is contained in:
parent
db382d4d39
commit
a7264a1af3
2 changed files with 33 additions and 37 deletions
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
%% Interpretation.
|
%% Interpretation.
|
||||||
-export([connection_to_atom/1, urldecode/1, urldecode/2, urlencode/1,
|
-export([connection_to_atom/1, urldecode/1, urldecode/2, urlencode/1,
|
||||||
urlencode/2]).
|
urlencode/2, x_www_form_urlencoded/2]).
|
||||||
|
|
||||||
-type method() :: 'OPTIONS' | 'GET' | 'HEAD'
|
-type method() :: 'OPTIONS' | 'GET' | 'HEAD'
|
||||||
| 'POST' | 'PUT' | 'DELETE' | 'TRACE' | binary().
|
| 'POST' | 'PUT' | 'DELETE' | 'TRACE' | binary().
|
||||||
|
@ -800,6 +800,16 @@ tohexu(C) when C < 17 -> $A + C - 10.
|
||||||
tohexl(C) when C < 10 -> $0 + C;
|
tohexl(C) when C < 10 -> $0 + C;
|
||||||
tohexl(C) when C < 17 -> $a + C - 10.
|
tohexl(C) when C < 17 -> $a + C - 10.
|
||||||
|
|
||||||
|
-spec x_www_form_urlencoded(binary(), fun((binary()) -> binary())) ->
|
||||||
|
list({binary(), binary() | true}).
|
||||||
|
x_www_form_urlencoded(<<>>, _URLDecode) ->
|
||||||
|
[];
|
||||||
|
x_www_form_urlencoded(Qs, URLDecode) ->
|
||||||
|
Tokens = binary:split(Qs, <<"&">>, [global, trim]),
|
||||||
|
[case binary:split(Token, <<"=">>) of
|
||||||
|
[Token] -> {URLDecode(Token), true};
|
||||||
|
[Name, Value] -> {URLDecode(Name), URLDecode(Value)}
|
||||||
|
end || Token <- Tokens].
|
||||||
|
|
||||||
%% Tests.
|
%% Tests.
|
||||||
|
|
||||||
|
@ -967,6 +977,22 @@ digits_test_() ->
|
||||||
],
|
],
|
||||||
[{V, fun() -> R = digits(V) end} || {V, R} <- Tests].
|
[{V, fun() -> R = digits(V) end} || {V, R} <- Tests].
|
||||||
|
|
||||||
|
x_www_form_urlencoded_test_() ->
|
||||||
|
%% {Qs, Result}
|
||||||
|
Tests = [
|
||||||
|
{<<"">>, []},
|
||||||
|
{<<"a=b">>, [{<<"a">>, <<"b">>}]},
|
||||||
|
{<<"aaa=bbb">>, [{<<"aaa">>, <<"bbb">>}]},
|
||||||
|
{<<"a&b">>, [{<<"a">>, true}, {<<"b">>, true}]},
|
||||||
|
{<<"a=b&c&d=e">>, [{<<"a">>, <<"b">>},
|
||||||
|
{<<"c">>, true}, {<<"d">>, <<"e">>}]},
|
||||||
|
{<<"a=b=c=d=e&f=g">>, [{<<"a">>, <<"b=c=d=e">>}, {<<"f">>, <<"g">>}]},
|
||||||
|
{<<"a+b=c+d">>, [{<<"a b">>, <<"c d">>}]}
|
||||||
|
],
|
||||||
|
URLDecode = fun urldecode/1,
|
||||||
|
[{Qs, fun() -> R = x_www_form_urlencoded(
|
||||||
|
Qs, URLDecode) end} || {Qs, R} <- Tests].
|
||||||
|
|
||||||
urldecode_test_() ->
|
urldecode_test_() ->
|
||||||
U = fun urldecode/2,
|
U = fun urldecode/2,
|
||||||
[?_assertEqual(<<" ">>, U(<<"%20">>, crash)),
|
[?_assertEqual(<<" ">>, U(<<"%20">>, crash)),
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
]). %% Misc API.
|
]). %% Misc API.
|
||||||
|
|
||||||
-include("include/http.hrl").
|
-include("include/http.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
|
||||||
|
|
||||||
%% Request API.
|
%% Request API.
|
||||||
|
|
||||||
|
@ -151,7 +150,8 @@ qs_val(Name, Req) when is_binary(Name) ->
|
||||||
-> {binary() | true | Default, #http_req{}} when Default::any().
|
-> {binary() | true | Default, #http_req{}} when Default::any().
|
||||||
qs_val(Name, Req=#http_req{raw_qs=RawQs, qs_vals=undefined,
|
qs_val(Name, Req=#http_req{raw_qs=RawQs, qs_vals=undefined,
|
||||||
urldecode={URLDecFun, URLDecArg}}, Default) when is_binary(Name) ->
|
urldecode={URLDecFun, URLDecArg}}, Default) when is_binary(Name) ->
|
||||||
QsVals = parse_qs(RawQs, fun(Bin) -> URLDecFun(Bin, URLDecArg) end),
|
QsVals = cowboy_http:x_www_form_urlencoded(
|
||||||
|
RawQs, fun(Bin) -> URLDecFun(Bin, URLDecArg) end),
|
||||||
qs_val(Name, Req#http_req{qs_vals=QsVals}, Default);
|
qs_val(Name, Req#http_req{qs_vals=QsVals}, Default);
|
||||||
qs_val(Name, Req, Default) ->
|
qs_val(Name, Req, Default) ->
|
||||||
case lists:keyfind(Name, 1, Req#http_req.qs_vals) of
|
case lists:keyfind(Name, 1, Req#http_req.qs_vals) of
|
||||||
|
@ -163,7 +163,8 @@ qs_val(Name, Req, Default) ->
|
||||||
-spec qs_vals(#http_req{}) -> {list({binary(), binary() | true}), #http_req{}}.
|
-spec qs_vals(#http_req{}) -> {list({binary(), binary() | true}), #http_req{}}.
|
||||||
qs_vals(Req=#http_req{raw_qs=RawQs, qs_vals=undefined,
|
qs_vals(Req=#http_req{raw_qs=RawQs, qs_vals=undefined,
|
||||||
urldecode={URLDecFun, URLDecArg}}) ->
|
urldecode={URLDecFun, URLDecArg}}) ->
|
||||||
QsVals = parse_qs(RawQs, fun(Bin) -> URLDecFun(Bin, URLDecArg) end),
|
QsVals = cowboy_http:x_www_form_urlencoded(
|
||||||
|
RawQs, fun(Bin) -> URLDecFun(Bin, URLDecArg) end),
|
||||||
qs_vals(Req#http_req{qs_vals=QsVals});
|
qs_vals(Req#http_req{qs_vals=QsVals});
|
||||||
qs_vals(Req=#http_req{qs_vals=QsVals}) ->
|
qs_vals(Req=#http_req{qs_vals=QsVals}) ->
|
||||||
{QsVals, Req}.
|
{QsVals, Req}.
|
||||||
|
@ -405,7 +406,8 @@ body(Length, Req=#http_req{socket=Socket, transport=Transport,
|
||||||
-spec body_qs(#http_req{}) -> {list({binary(), binary() | true}), #http_req{}}.
|
-spec body_qs(#http_req{}) -> {list({binary(), binary() | true}), #http_req{}}.
|
||||||
body_qs(Req=#http_req{urldecode={URLDecFun, URLDecArg}}) ->
|
body_qs(Req=#http_req{urldecode={URLDecFun, URLDecArg}}) ->
|
||||||
{ok, Body, Req2} = body(Req),
|
{ok, Body, Req2} = body(Req),
|
||||||
{parse_qs(Body, fun(Bin) -> URLDecFun(Bin, URLDecArg) end), Req2}.
|
{cowboy_http:x_www_form_urlencoded(
|
||||||
|
Body, fun(Bin) -> URLDecFun(Bin, URLDecArg) end), Req2}.
|
||||||
|
|
||||||
%% Multipart Request API.
|
%% Multipart Request API.
|
||||||
|
|
||||||
|
@ -641,17 +643,6 @@ transport(#http_req{transport=Transport, socket=Socket}) ->
|
||||||
|
|
||||||
%% Internal.
|
%% Internal.
|
||||||
|
|
||||||
-spec parse_qs(binary(), fun((binary()) -> binary())) ->
|
|
||||||
list({binary(), binary() | true}).
|
|
||||||
parse_qs(<<>>, _URLDecode) ->
|
|
||||||
[];
|
|
||||||
parse_qs(Qs, URLDecode) ->
|
|
||||||
Tokens = binary:split(Qs, <<"&">>, [global, trim]),
|
|
||||||
[case binary:split(Token, <<"=">>) of
|
|
||||||
[Token] -> {URLDecode(Token), true};
|
|
||||||
[Name, Value] -> {URLDecode(Name), URLDecode(Value)}
|
|
||||||
end || Token <- Tokens].
|
|
||||||
|
|
||||||
-spec response_connection(cowboy_http:headers(), keepalive | close)
|
-spec response_connection(cowboy_http:headers(), keepalive | close)
|
||||||
-> keepalive | close.
|
-> keepalive | close.
|
||||||
response_connection([], Connection) ->
|
response_connection([], Connection) ->
|
||||||
|
@ -813,24 +804,3 @@ header_to_binary('Cookie') -> <<"Cookie">>;
|
||||||
header_to_binary('Keep-Alive') -> <<"Keep-Alive">>;
|
header_to_binary('Keep-Alive') -> <<"Keep-Alive">>;
|
||||||
header_to_binary('Proxy-Connection') -> <<"Proxy-Connection">>;
|
header_to_binary('Proxy-Connection') -> <<"Proxy-Connection">>;
|
||||||
header_to_binary(B) when is_binary(B) -> B.
|
header_to_binary(B) when is_binary(B) -> B.
|
||||||
|
|
||||||
%% Tests.
|
|
||||||
|
|
||||||
-ifdef(TEST).
|
|
||||||
|
|
||||||
parse_qs_test_() ->
|
|
||||||
%% {Qs, Result}
|
|
||||||
Tests = [
|
|
||||||
{<<"">>, []},
|
|
||||||
{<<"a=b">>, [{<<"a">>, <<"b">>}]},
|
|
||||||
{<<"aaa=bbb">>, [{<<"aaa">>, <<"bbb">>}]},
|
|
||||||
{<<"a&b">>, [{<<"a">>, true}, {<<"b">>, true}]},
|
|
||||||
{<<"a=b&c&d=e">>, [{<<"a">>, <<"b">>},
|
|
||||||
{<<"c">>, true}, {<<"d">>, <<"e">>}]},
|
|
||||||
{<<"a=b=c=d=e&f=g">>, [{<<"a">>, <<"b=c=d=e">>}, {<<"f">>, <<"g">>}]},
|
|
||||||
{<<"a+b=c+d">>, [{<<"a b">>, <<"c d">>}]}
|
|
||||||
],
|
|
||||||
URLDecode = fun cowboy_http:urldecode/1,
|
|
||||||
[{Qs, fun() -> R = parse_qs(Qs, URLDecode) end} || {Qs, R} <- Tests].
|
|
||||||
|
|
||||||
-endif.
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue