Skip to content

Commit 3de7391

Browse files
committed
fix parsing query parameters on url without path
fix #512
1 parent 13dd2f4 commit 3de7391

File tree

2 files changed

+37
-13
lines changed

2 files changed

+37
-13
lines changed

src/hackney_url.erl

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,7 @@ parse_url(URL, S) ->
5050
case binary:split(URL, <<"/">>) of
5151
[Addr] ->
5252
Path = <<"/">>,
53-
parse_addr(Addr, S#hackney_url{raw_path = Path,
54-
path = Path });
53+
parse_addr1(Addr, S#hackney_url{raw_path = Path, path = Path });
5554
[Addr, Path] ->
5655
RawPath = <<"/", Path/binary>>,
5756
{Path1, Query, Fragment} = parse_path(RawPath),
@@ -82,7 +81,7 @@ normalize(#hackney_url{}=Url, Fun) when is_function(Fun, 1) ->
8281
port = Port,
8382
netloc = Netloc0,
8483
path = Path} = Url,
85-
84+
8685
{Host, Netloc} = case inet_parse:address(Host0) of
8786
{ok, {_, _, _, _}} ->
8887
{Host0, Netloc0};
@@ -91,7 +90,7 @@ normalize(#hackney_url{}=Url, Fun) when is_function(Fun, 1) ->
9190
_ ->
9291
Host1 = unicode:characters_to_list(
9392
urldecode(unicode:characters_to_binary(Host0))),
94-
93+
9594
%% encode domain if needed
9695
Host2 = idna:to_ascii(Host1),
9796
Netloc1 = case {Scheme, Port} of
@@ -121,13 +120,13 @@ unparse_url(#hackney_url{}=Url) ->
121120
fragment = Fragment,
122121
user = User,
123122
password = Password} = Url,
124-
123+
125124
Scheme1 = case Scheme of
126125
http -> <<"http://">>;
127126
https -> <<"https://">>;
128127
http_unix -> <<"http+unix://">>
129128
end,
130-
129+
131130
Netloc1 = case User of
132131
<<>> ->
133132
Netloc;
@@ -136,27 +135,39 @@ unparse_url(#hackney_url{}=Url) ->
136135
_ ->
137136
<< User/binary, "@", Netloc/binary >>
138137
end,
139-
138+
140139
Qs1 = case Qs of
141140
<<>> -> <<>>;
142141
_ -> << "?", Qs/binary >>
143142
end,
144-
143+
145144
Fragment1 = case Fragment of
146145
<<>> -> <<>>;
147146
_ -> << "#", Fragment/binary >>
148147
end,
149-
148+
150149
Path1 = case Path of
151150
nil -> <<>>;
152151
undefined -> <<>>;
153152
<<>> -> <<"/">>;
154153
_ -> Path
155154
end,
156-
155+
157156
<< Scheme1/binary, Netloc1/binary, Path1/binary, Qs1/binary, Fragment1/binary >>.
158157

159158
%% @private
159+
parse_addr1(Addr, S) ->
160+
case binary:split(Addr, <<"?">>) of
161+
[_Addr] ->
162+
{Addr1, Fragment} = parse_fragment(Addr),
163+
parse_addr(Addr1, S#hackney_url{fragment = Fragment});
164+
[Addr1, Query] ->
165+
{Query1, Fragment} = parse_fragment(Query),
166+
#hackney_url{raw_path = RawPath0 } = S,
167+
RawPath1 = << RawPath0/binary, "?", Query1/binary >>,
168+
parse_addr(Addr1, S#hackney_url{raw_path=RawPath1, qs=Query1, fragment=Fragment})
169+
end.
170+
160171
parse_addr(Addr, S) ->
161172
case binary:split(Addr, <<"@">>) of
162173
[Addr] ->
@@ -172,7 +183,7 @@ parse_addr(Addr, S) ->
172183
user = User,
173184
password = <<>> })
174185
end
175-
186+
176187
end.
177188

178189
parse_netloc(<<"[", Rest/binary>>, #hackney_url{transport=Transport}=S) ->
@@ -355,13 +366,13 @@ make_url(Url, PathParts, Query) when is_binary(Query) ->
355366
%% create path
356367
PathParts1 = [fix_path(P) || P <- PathParts, P /= "", P /= "/" orelse P /= <<"/">>],
357368
Path = hackney_bstr:join([<<>> | PathParts1], <<"/">>),
358-
369+
359370
%% initialise the query
360371
Query1 = case Query of
361372
<<>> -> <<>>;
362373
_ -> << "?", Query/binary >>
363374
end,
364-
375+
365376
%% make the final uri
366377
iolist_to_binary([fix_path(Url), Path, Query1]).
367378

test/hackney_url_tests.erl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,19 @@ parse_url_test_() ->
181181
port = 80,
182182
user = <<"">>,
183183
password = <<"">>}
184+
},
185+
{<<"http://www.example.com?q=123">>,
186+
#hackney_url{transport =hackney_tcp,
187+
scheme = http,
188+
netloc = <<"www.example.com">>,
189+
raw_path = <<"/?q=123">>,
190+
path = <<"/">>,
191+
qs = <<"q=123">>,
192+
fragment = <<"">>,
193+
host = "www.example.com",
194+
port = 80,
195+
user = <<"">>,
196+
password = <<"">>}
184197
}
185198
],
186199
[{V, fun() -> R = hackney_url:parse_url(V) end} || {V, R} <- Tests].

0 commit comments

Comments
 (0)