mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-15 04:30:25 +00:00
add cowboy_http:urlencode/2 and urlencode/1
This function complements the cowboy_http:urldecode/2 and urldecode/1 functions. We should have this encoding covered now. urldecode is only expected to be invoked by user code, no further changes needed to integrate this.
This commit is contained in:
parent
168405830d
commit
ef7b41c8ce
1 changed files with 69 additions and 8 deletions
|
@ -23,7 +23,8 @@
|
||||||
digits/1, token/2, token_ci/2, quoted_string/2]).
|
digits/1, token/2, token_ci/2, quoted_string/2]).
|
||||||
|
|
||||||
%% Interpretation.
|
%% Interpretation.
|
||||||
-export([connection_to_atom/1, urldecode/1, urldecode/2]).
|
-export([connection_to_atom/1, urldecode/1, urldecode/2, urlencode/1,
|
||||||
|
urlencode/2]).
|
||||||
|
|
||||||
-include("include/http.hrl").
|
-include("include/http.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
@ -710,6 +711,51 @@ unhex(C) when C >= $A, C =< $F -> C - $A + 10;
|
||||||
unhex(C) when C >= $a, C =< $f -> C - $a + 10;
|
unhex(C) when C >= $a, C =< $f -> C - $a + 10;
|
||||||
unhex(_) -> error.
|
unhex(_) -> error.
|
||||||
|
|
||||||
|
|
||||||
|
%% @doc URL encode a string binary.
|
||||||
|
%% @equiv urlencode(Bin, [])
|
||||||
|
-spec urlencode(binary()) -> binary().
|
||||||
|
urlencode(Bin) ->
|
||||||
|
urlencode(Bin, []).
|
||||||
|
|
||||||
|
%% @doc URL encode a string binary.
|
||||||
|
%% The `noplus' option disables the default behaviour of quoting space
|
||||||
|
%% characters, `\s', as `+'. The `upper' option overrides the default behaviour
|
||||||
|
%% of writing hex numbers using lowecase letters to using uppercase letters
|
||||||
|
%% instead.
|
||||||
|
-spec urlencode(binary(), [noplus|upper]) -> binary().
|
||||||
|
urlencode(Bin, Opts) ->
|
||||||
|
Plus = not proplists:get_value(noplus, Opts, false),
|
||||||
|
Upper = proplists:get_value(upper, Opts, false),
|
||||||
|
urlencode(Bin, <<>>, Plus, Upper).
|
||||||
|
|
||||||
|
-spec urlencode(binary(), binary(), boolean(), boolean()) -> binary().
|
||||||
|
urlencode(<<C, Rest/binary>>, Acc, P=Plus, U=Upper) ->
|
||||||
|
if C >= $0, C =< $9 -> urlencode(Rest, <<Acc/binary, C>>, P, U);
|
||||||
|
C >= $A, C =< $Z -> urlencode(Rest, <<Acc/binary, C>>, P, U);
|
||||||
|
C >= $a, C =< $z -> urlencode(Rest, <<Acc/binary, C>>, P, U);
|
||||||
|
C =:= $.; C =:= $-; C =:= $~; C =:= $_ ->
|
||||||
|
urlencode(Rest, <<Acc/binary, C>>, P, U);
|
||||||
|
C =:= $ , Plus ->
|
||||||
|
urlencode(Rest, <<Acc/binary, $+>>, P, U);
|
||||||
|
true ->
|
||||||
|
H = C band 16#F0 bsr 4, L = C band 16#0F,
|
||||||
|
H1 = if Upper -> tohexu(H); true -> tohexl(H) end,
|
||||||
|
L1 = if Upper -> tohexu(L); true -> tohexl(L) end,
|
||||||
|
urlencode(Rest, <<Acc/binary, $%, H1, L1>>, P, U)
|
||||||
|
end;
|
||||||
|
urlencode(<<>>, Acc, _Plus, _Upper) ->
|
||||||
|
Acc.
|
||||||
|
|
||||||
|
-spec tohexu(byte()) -> byte().
|
||||||
|
tohexu(C) when C < 10 -> $0 + C;
|
||||||
|
tohexu(C) when C < 17 -> $A + C - 10.
|
||||||
|
|
||||||
|
-spec tohexl(byte()) -> byte().
|
||||||
|
tohexl(C) when C < 10 -> $0 + C;
|
||||||
|
tohexl(C) when C < 17 -> $a + C - 10.
|
||||||
|
|
||||||
|
|
||||||
%% Tests.
|
%% Tests.
|
||||||
|
|
||||||
-ifdef(TEST).
|
-ifdef(TEST).
|
||||||
|
@ -877,12 +923,27 @@ digits_test_() ->
|
||||||
[{V, fun() -> R = digits(V) end} || {V, R} <- Tests].
|
[{V, fun() -> R = digits(V) end} || {V, R} <- Tests].
|
||||||
|
|
||||||
urldecode_test_() ->
|
urldecode_test_() ->
|
||||||
Tests = [
|
U = fun urldecode/2,
|
||||||
{<<" ">>, <<"%20">>},
|
[?_assertEqual(<<" ">>, U(<<"%20">>, crash)),
|
||||||
{<<" ">>, <<"+">>},
|
?_assertEqual(<<" ">>, U(<<"+">>, crash)),
|
||||||
{<<0>>, <<"%00">>},
|
?_assertEqual(<<0>>, U(<<"%00">>, crash)),
|
||||||
{<<255>>, <<"%fF">>}
|
?_assertEqual(<<255>>, U(<<"%fF">>, crash)),
|
||||||
],
|
?_assertEqual(<<"123">>, U(<<"123">>, crash)),
|
||||||
[{I, ?_assertEqual(E, urldecode(I))} || {E, I} <- Tests].
|
?_assertEqual(<<"%i5">>, U(<<"%i5">>, skip)),
|
||||||
|
?_assertEqual(<<"%5">>, U(<<"%5">>, skip)),
|
||||||
|
?_assertError(badarg, U(<<"%i5">>, crash)),
|
||||||
|
?_assertError(badarg, U(<<"%5">>, crash))
|
||||||
|
].
|
||||||
|
|
||||||
|
urlencode_test_() ->
|
||||||
|
U = fun urlencode/2,
|
||||||
|
[?_assertEqual(<<"%ff%00">>, U(<<255,0>>, [])),
|
||||||
|
?_assertEqual(<<"%FF%00">>, U(<<255,0>>, [upper])),
|
||||||
|
?_assertEqual(<<"+">>, U(<<" ">>, [])),
|
||||||
|
?_assertEqual(<<"%20">>, U(<<" ">>, [noplus])),
|
||||||
|
?_assertEqual(<<"aBc">>, U(<<"aBc">>, [])),
|
||||||
|
?_assertEqual(<<".-~_">>, U(<<".-~_">>, [])),
|
||||||
|
?_assertEqual(<<"%ff+">>, urlencode(<<255, " ">>))
|
||||||
|
].
|
||||||
|
|
||||||
-endif.
|
-endif.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue