Reputation: 4370
On a rails app, I need to parse uris
a = 'some file name.txt'
URI(URI.encode(a)) # works
b = 'some filename with :colon in it.txt'
URI(URI.encode(b)) # fails URI::InvalidURIError: bad URI(is not URI?):
How can I safely pass a file name to URI that contains special characters? Why doesn't encode work on colon?
Upvotes: 5
Views: 4819
Reputation: 114138
URI.escape
(or encode
) takes an optional second parameter. It's a Regexp matching all symbols that should be escaped. To escape all non-word characters you could use:
URI.encode('some filename with :colon in it.txt', /\W/)
#=> "some%20filename%20with%20%3Acolon%20in%20it%2Etxt"
There are two predefined regular expressions for encode
:
URI::PATTERN::UNRESERVED #=> "\\-_.!~*'()a-zA-Z\\d"
URI::PATTERN::RESERVED #=> ";/?:@&=+$,\\[\\]"
Upvotes: 12
Reputation: 48599
require 'uri'
url = "file1:abc.txt"
p URI.encode_www_form_component url
--output:--
"file1%3Aabc.txt"
p URI(URI.encode_www_form_component url)
--output:--
#<URI::Generic:0x000001008abf28 URL:file1%3Aabc.txt>
p URI(URI.encode url, ":")
--output:--
#<URI::Generic:0x000001008abcd0 URL:file1%3Aabc.txt>
Why doesn't encode work on colon?
Because encode/escape is broken.
Upvotes: 2
Reputation: 118261
require "addressable/uri"
a = 'some file name.txt'
Addressable::URI.encode(Addressable::URI.encode(a))
# => "some%2520file%2520name.txt"
b = 'some filename with :colon in it.txt'
Addressable::URI.encode(Addressable::URI.encode(b))
# => "some%2520filename%2520with%2520:colon%2520in%2520it.txt"
Upvotes: 1
Reputation: 1440
If you want to escape special character from the given string. It is best to use
esc_uri=URI.escape("String with special character")
The result string is URI escaped string and safe to pass it to URI. Refer URI::Escape for how to use URI escape. Hope this helps.
Upvotes: -1
Reputation: 15089
The problem seems to be the empty space preceding the colon, 'lol :lol.txt'
don't work, but 'lol:lol.txt'
works.
Maybe you could replace the spaces for something else.
Upvotes: 0