|
@@ -31,22 +31,40 @@
|
|
|
fragment => unicode:chardata(),
|
|
fragment => unicode:chardata(),
|
|
|
userinfo => 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.
|
|
%% @doc Decode percent-encoded URI.
|
|
|
%% This is copied from http_uri.erl which has been deprecated since OTP-23
|
|
%% This is copied from http_uri.erl which has been deprecated since OTP-23
|
|
|
%% The recommended replacement uri_string function is not quite equivalent
|
|
%% The recommended replacement uri_string function is not quite equivalent
|
|
|
%% and not backward compatible.
|
|
%% 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.
|
|
%% @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(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
|
|
%% @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
|
|
%% 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(<<"http">>) -> http;
|
|
|
atom_scheme(Other) -> throw({unsupported_scheme, Other}).
|
|
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
|
|
case reserved(Char) of
|
|
|
true ->
|
|
true ->
|
|
|
<< $%, (integer_to_binary(Char, 16))/binary >>;
|
|
<< $%, (integer_to_binary(Char, 16))/binary >>;
|