@@ -145,30 +145,53 @@ defmodule URI do
145
145
encode ( to_string ( k ) ) <> "=" <> encode ( to_string ( v ) )
146
146
end
147
147
148
+ # RFC3986, section 2.2
149
+ @ doc """
150
+ Returns true if the character is a "reserved" character in a URI.
151
+ """
152
+ def char_reserved? ( c ) do
153
+ c in ':/?#[]@!$&\' ()*+,;='
154
+ end
155
+
156
+ # RFC3986, section 2.3
157
+ @ doc """
158
+ Returns true if the character is a "unreserved" character in a URI.
159
+ """
160
+ def char_unreserved? ( c ) do
161
+ c in ?0 .. ?9 or
162
+ c in ?a .. ?z or
163
+ c in ?A .. ?Z or
164
+ c in '~_-.'
165
+ end
166
+
167
+ @ doc """
168
+ Returns true if the character is allowed unescaped in a URI.
169
+ """
170
+ def char_unescaped? ( c ) do
171
+ char_reserved? ( c ) or char_unreserved? ( c )
172
+ end
173
+
148
174
@ doc """
149
175
Percent-escape a URI.
176
+ Accepts `predicate` function as an argument to specify if char can be left as is.
150
177
151
178
## Example
152
179
153
- iex> URI.encode("http ://elixir-lang.org/getting_started/2.html ")
154
- "http%3A%2F%2Felixir-lang.org%2Fgetting_started%2F2.html "
180
+ iex> URI.encode("ftp ://s-ite.tld/?value=put it+й ")
181
+ "ftp://s-ite.tld/?value=put%20it+%D0%B9 "
155
182
156
183
"""
157
- def encode ( s ) , do: for ( << c <- s >> , into: "" , do: percent ( c ) )
158
-
159
- defp percent ( ?~ ) , do: << ?~ >>
160
- defp percent ( ?- ) , do: << ?- >>
161
- defp percent ( ?_ ) , do: << ?_ >>
162
- defp percent ( ?. ) , do: << ?. >>
163
-
164
- defp percent ( c )
165
- when c in ?0 .. ?9
166
- when c in ?a .. ?z
167
- when c in ?A .. ?Z do
168
- << c >>
184
+ def encode ( str , predicate \\ & char_unescaped? / 1 ) do
185
+ for << c <- str >> , into: "" , do: percent ( c , predicate )
169
186
end
170
187
171
- defp percent ( c ) , do: "%" <> hex ( bsr ( c , 4 ) ) <> hex ( band ( c , 15 ) )
188
+ defp percent ( c , predicate ) do
189
+ if predicate . ( c ) do
190
+ << c >>
191
+ else
192
+ "%" <> hex ( bsr ( c , 4 ) ) <> hex ( band ( c , 15 ) )
193
+ end
194
+ end
172
195
173
196
defp hex ( n ) when n <= 9 , do: << n + ?0 >>
174
197
defp hex ( n ) , do: << n + ?A - 10 >>
0 commit comments