feat(uri): support decoding uri in string
This commit is contained in:
parent
5009ec0c34
commit
bd1051d1e6
|
@ -31,22 +31,40 @@
|
|||
fragment => unicode:chardata(),
|
||||
userinfo => unicode:chardata()}.
|
||||
|
||||
-type hex_uri() :: string() | binary().
|
||||
-type maybe_hex_uri() :: string() | binary(). %% A possibly hexadecimal encoded URI.
|
||||
-type uri() :: string() | binary().
|
||||
|
||||
%% @doc Decode percent-encoded URI.
|
||||
%% This is copied from http_uri.erl which has been deprecated since OTP-23
|
||||
%% The recommended replacement uri_string function is not quite equivalent
|
||||
%% and not backward compatible.
|
||||
-spec uri_decode(binary()) -> binary().
|
||||
uri_decode(<<$%, Hex:2/binary, Rest/bits>>) ->
|
||||
<<(binary_to_integer(Hex, 16)), (uri_decode(Rest))/binary>>;
|
||||
uri_decode(<<First:1/binary, Rest/bits>>) ->
|
||||
<<First/binary, (uri_decode(Rest))/binary>>;
|
||||
uri_decode(<<>>) ->
|
||||
-spec uri_decode(maybe_hex_uri()) -> uri().
|
||||
uri_decode(String) when is_list(String) ->
|
||||
do_uri_decode(String);
|
||||
uri_decode(String) when is_binary(String) ->
|
||||
do_uri_decode_binary(String).
|
||||
|
||||
do_uri_decode([$%,Hex1,Hex2|Rest]) ->
|
||||
[hex2dec(Hex1)*16+hex2dec(Hex2)|do_uri_decode(Rest)];
|
||||
do_uri_decode([First|Rest]) ->
|
||||
[First|do_uri_decode(Rest)];
|
||||
do_uri_decode([]) ->
|
||||
[].
|
||||
|
||||
do_uri_decode_binary(<<$%, Hex:2/binary, Rest/bits>>) ->
|
||||
<<(binary_to_integer(Hex, 16)), (do_uri_decode_binary(Rest))/binary>>;
|
||||
do_uri_decode_binary(<<First:1/binary, Rest/bits>>) ->
|
||||
<<First/binary, (do_uri_decode_binary(Rest))/binary>>;
|
||||
do_uri_decode_binary(<<>>) ->
|
||||
<<>>.
|
||||
|
||||
%% @doc Encode URI.
|
||||
-spec uri_encode(binary()) -> binary().
|
||||
-spec uri_encode(uri()) -> hex_uri().
|
||||
uri_encode(URI) when is_list(URI) ->
|
||||
lists:append([do_uri_encode(Char) || Char <- URI]);
|
||||
uri_encode(URI) when is_binary(URI) ->
|
||||
<< <<(uri_encode_binary(Char))/binary>> || <<Char>> <= URI >>.
|
||||
<< <<(do_uri_encode_binary(Char))/binary>> || <<Char>> <= URI >>.
|
||||
|
||||
%% @doc Parse URI into a map as uri_string:uri_map(), but with two fields
|
||||
%% normalised: (1): port number is never 'undefined', default ports are used
|
||||
|
@ -93,7 +111,15 @@ atom_scheme(<<"https">>) -> https;
|
|||
atom_scheme(<<"http">>) -> http;
|
||||
atom_scheme(Other) -> throw({unsupported_scheme, Other}).
|
||||
|
||||
uri_encode_binary(Char) ->
|
||||
do_uri_encode(Char) ->
|
||||
case reserved(Char) of
|
||||
true ->
|
||||
[ $% | http_util:integer_to_hexlist(Char)];
|
||||
false ->
|
||||
[Char]
|
||||
end.
|
||||
|
||||
do_uri_encode_binary(Char) ->
|
||||
case reserved(Char) of
|
||||
true ->
|
||||
<< $%, (integer_to_binary(Char, 16))/binary >>;
|
||||
|
|
Loading…
Reference in New Issue