Skip to content

Commit b3cc527

Browse files
committed
Introduce URI.decode_www_form/1 function
1 parent 6b45855 commit b3cc527

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

lib/elixir/lib/uri.ex

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,10 @@ defmodule URI do
126126

127127
current =
128128
case :binary.split(first, "=") do
129-
[ key, value ] -> {decode(key), decode(value)}
130-
[ key ] -> {decode(key), nil}
129+
[key, value] ->
130+
{decode_www_form(key), decode_www_form(value)}
131+
[key] ->
132+
{decode_www_form(key), nil}
131133
end
132134

133135
{current, next}
@@ -236,6 +238,22 @@ defmodule URI do
236238
raise ArgumentError, "malformed URI #{inspect uri}"
237239
end
238240

241+
@doc """
242+
Decode a string as "x-www-urlencoded".
243+
244+
## Examples
245+
246+
iex> URI.decode_www_form("%3Call+in%2F")
247+
"<all in/"
248+
249+
"""
250+
def decode_www_form(str) do
251+
String.split(str, "+") |> Enum.map_join(" ", &unpercent/1)
252+
catch
253+
:malformed_uri ->
254+
raise ArgumentError, "malformed URI #{inspect str}"
255+
end
256+
239257
defp unpercent(<<?%, hex_1, hex_2, tail :: binary>>) do
240258
<<bsl(hex_to_dec(hex_1), 4) + hex_to_dec(hex_2)>> <> unpercent(tail)
241259
end

lib/elixir/test/elixir/uri_test.exs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ defmodule URITest do
2929
assert URI.decode_query("", []) == []
3030
assert URI.decode_query("", %{}) == %{}
3131

32-
assert URI.decode_query("q=search%20query&cookie=ab%26cd&block%20buster=") ==
32+
assert URI.decode_query("q=search%20query&cookie=ab%26cd&block+buster=") ==
3333
%{"block buster" => "", "cookie" => "ab&cd", "q" => "search query"}
3434

3535
assert URI.decode_query("something=weird%3Dhappening") ==
@@ -46,7 +46,7 @@ defmodule URITest do
4646
test :decoder do
4747
decoder = URI.query_decoder("q=search%20query&cookie=ab%26cd&block%20buster=")
4848
expected = [{"q", "search query"}, {"cookie", "ab&cd"}, {"block buster", ""}]
49-
assert Enum.map(decoder, fn(x) -> x end) == expected
49+
assert Enum.map(decoder, &(&1)) == expected
5050
end
5151

5252
test :decode do
@@ -62,6 +62,11 @@ defmodule URITest do
6262
end
6363
end
6464

65+
test :decode_www_form do
66+
assert URI.decode_www_form("%3Eval+ue%2B") == ">val ue+"
67+
assert URI.decode_www_form("%E3%82%86+") == "ゆ "
68+
end
69+
6570
test :parse_http do
6671
assert %URI{scheme: "http", host: "foo.com", path: "/path/to/something",
6772
query: "foo=bar&bar=foo", fragment: "fragment", port: 80,

0 commit comments

Comments
 (0)