You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2021/06/07 17:26:01 UTC
[couchdb-ibrowse] 05/05: Unquote basic auth username and password
(#5)
This is an automated email from the ASF dual-hosted git repository.
vatamane pushed a commit to branch upstream-rebase
in repository https://gitbox.apache.org/repos/asf/couchdb-ibrowse.git
commit 16e73e0a9ad7b5fce1a73d322f7fed8b414dcfb6
Author: Jiahui Li <54...@users.noreply.github.com>
AuthorDate: Wed May 5 08:06:49 2021 -0500
Unquote basic auth username and password (#5)
Unquote username and password which were parsed by ibrowse_lib:parse_url/1 before inserting them in the basic auth header.
Previously if the user had characters like @ in their username or password, and they were percent-encoded, they were inserted encoded in the basic auth header which lead to authentication failure.
---
src/ibrowse_http_client.erl | 4 +++-
src/ibrowse_lib.erl | 43 +++++++++++++++++++++++++++++++++++++++++--
2 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/src/ibrowse_http_client.erl b/src/ibrowse_http_client.erl
index bee6a70..e3bc698 100644
--- a/src/ibrowse_http_client.erl
+++ b/src/ibrowse_http_client.erl
@@ -1066,7 +1066,9 @@ add_auth_headers(#url{username = User,
[{"Authorization", ["Basic ", http_auth_basic(U, P)]} | Headers]
end;
_ ->
- [{"Authorization", ["Basic ", http_auth_basic(User, UPw)]} | Headers]
+ User1 = ibrowse_lib:unquote(User),
+ UPw1 = ibrowse_lib:unquote(UPw),
+ [{"Authorization", ["Basic ", http_auth_basic(User1, UPw1)]} | Headers]
end,
add_proxy_auth_headers(State, Headers_1).
diff --git a/src/ibrowse_lib.erl b/src/ibrowse_lib.erl
index 6c1883d..581ebfd 100644
--- a/src/ibrowse_lib.erl
+++ b/src/ibrowse_lib.erl
@@ -30,9 +30,14 @@
get_value/3,
parse_url/1,
printable_date/0,
- printable_date/1
+ unquote/1
]).
+-define(PERCENT, 37). % $\%
+-define(IS_HEX(C), ((C >= $0 andalso C =< $9) orelse
+ (C >= $a andalso C =< $f) orelse
+ (C >= $A andalso C =< $F))).
+
get_trace_status(Host, Port) ->
ibrowse:get_config_value({trace, Host, Port}, false).
@@ -389,6 +394,29 @@ printable_date(Now) ->
$:,
integer_to_list(MicroSecs div 1000)].
+%% @spec unquote(string() | binary()) -> string()
+%% @doc Unquote a URL encoded string.
+unquote(Binary) when is_binary(Binary) ->
+ unquote(binary_to_list(Binary));
+unquote(String) ->
+ qs_revdecode(lists:reverse(String)).
+
+qs_revdecode(S) ->
+ qs_revdecode(S, []).
+
+qs_revdecode([], Acc) ->
+ Acc;
+qs_revdecode([$+ | Rest], Acc) ->
+ qs_revdecode(Rest, [$\s | Acc]);
+qs_revdecode([Lo, Hi, ?PERCENT | Rest], Acc) when ?IS_HEX(Lo), ?IS_HEX(Hi) ->
+ qs_revdecode(Rest, [(unhexdigit(Lo) bor (unhexdigit(Hi) bsl 4)) | Acc]);
+qs_revdecode([C | Rest], Acc) ->
+ qs_revdecode(Rest, [C | Acc]).
+
+unhexdigit(C) when C >= $0, C =< $9 -> C - $0;
+unhexdigit(C) when C >= $a, C =< $f -> C - $a + 10;
+unhexdigit(C) when C >= $A, C =< $F -> C - $A + 10.
+
do_trace(Fmt, Args) ->
do_trace(get(my_trace_flag), Fmt, Args).
@@ -462,4 +490,15 @@ parse_url_test() ->
?assertMatch(Expected_result, parse_url(Url))
end, Urls).
--endif.
+unquote_test() ->
+ ?assertEqual("foo bar",
+ unquote("foo+bar")),
+ ?assertEqual("foo bar",
+ unquote("foo%20bar")),
+ ?assertEqual("foo\r\n",
+ unquote("foo%0D%0A")),
+ ?assertEqual("foo\r\n",
+ unquote(<<"foo%0D%0A">>)),
+ ok.
+
+-endif.
\ No newline at end of file