@@ -126,8 +126,10 @@ defmodule URI do
126
126
127
127
current =
128
128
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 }
131
133
end
132
134
133
135
{ current , next }
@@ -142,7 +144,8 @@ defmodule URI do
142
144
end
143
145
144
146
defp pair ( { k , v } ) do
145
- encode ( to_string ( k ) ) <> "=" <> encode ( to_string ( v ) )
147
+ encode_www_form ( to_string ( k ) ) <>
148
+ "=" <> encode_www_form ( to_string ( v ) )
146
149
end
147
150
148
151
@ doc """
@@ -154,7 +157,6 @@ defmodule URI do
154
157
c in ':/?#[]@!$&\' ()*+,;='
155
158
end
156
159
157
- #
158
160
@ doc """
159
161
Checks if the character is a "unreserved" character in a URI.
160
162
@@ -191,6 +193,24 @@ defmodule URI do
191
193
for << c <- str >> , into: "" , do: percent ( c , predicate )
192
194
end
193
195
196
+ @ doc """
197
+ Encode a string as "x-www-urlencoded".
198
+
199
+ ## Example
200
+
201
+ iex> URI.encode_www_form("put: it+й")
202
+ "put%3A+it%2B%D0%B9"
203
+
204
+ """
205
+ def encode_www_form ( str ) do
206
+ for << c <- str >> , into: "" do
207
+ case percent ( c , & char_unreserved? / 1 ) do
208
+ "%20" -> "+"
209
+ pct -> pct
210
+ end
211
+ end
212
+ end
213
+
194
214
defp percent ( c , predicate ) do
195
215
if predicate . ( c ) do
196
216
<< c >>
@@ -212,26 +232,45 @@ defmodule URI do
212
232
213
233
"""
214
234
def decode ( uri ) do
215
- decode ( uri , uri )
235
+ unpercent ( uri )
236
+ catch
237
+ :malformed_uri ->
238
+ raise ArgumentError , "malformed URI #{ inspect uri } "
216
239
end
217
240
218
- def decode ( << ?% , hex1 , hex2 , tail :: binary >> , uri ) do
219
- << bsl ( hex_to_dec ( hex1 , uri ) , 4 ) + hex_to_dec ( hex2 , uri ) >> <> decode ( tail , uri )
220
- end
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/"
221
248
222
- def decode ( << head , tail :: binary >> , uri ) do
223
- << head >> <> decode ( tail , uri )
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 } "
224
255
end
225
256
226
- def decode ( << >> , _uri ) , do: << >>
257
+ defp unpercent ( << ?% , hex_1 , hex_2 , tail :: binary >> ) do
258
+ << bsl ( hex_to_dec ( hex_1 ) , 4 ) + hex_to_dec ( hex_2 ) >> <> unpercent ( tail )
259
+ end
260
+ defp unpercent ( << ?% , _ >> ) , do: throw ( :malformed_uri )
261
+ defp unpercent ( << ?% >> ) , do: throw ( :malformed_uri )
227
262
228
- defp hex_to_dec ( n , _uri ) when n in ?A .. ?F , do: n - ?A + 10
229
- defp hex_to_dec ( n , _uri ) when n in ?a .. ?f , do: n - ?a + 10
230
- defp hex_to_dec ( n , _uri ) when n in ?0 .. ?9 , do: n - ?0
231
- defp hex_to_dec ( _n , uri ) do
232
- raise ArgumentError , "malformed URI #{ inspect uri } "
263
+ defp unpercent ( << head , tail :: binary >> ) do
264
+ << head >> <> unpercent ( tail )
233
265
end
234
266
267
+ defp unpercent ( << >> ) , do: << >>
268
+
269
+ defp hex_to_dec ( n ) when n in ?A .. ?F , do: n - ?A + 10
270
+ defp hex_to_dec ( n ) when n in ?a .. ?f , do: n - ?a + 10
271
+ defp hex_to_dec ( n ) when n in ?0 .. ?9 , do: n - ?0
272
+ defp hex_to_dec ( _n ) , do: throw ( :malformed_uri )
273
+
235
274
@ doc """
236
275
Parses a URI into components.
237
276
0 commit comments