Tuesday, October 13, 2009

Ruby: Escaping URL Parameters

If you are trying to escape some URL parameters completely separate of Rails' routing infrastructure, URI.escape (AKA URI.encode) is not what you're looking for. In fact, I can't even figure out what problem URI.escape is trying to solve. Consider:
irb(main):003:0> require "uri"
=> true
irb(main):004:0> url = "http://foo.com?a=" + URI.escape("a&b+c")
=> "http://foo.com?a=a&b+c"
What you're looking for is CGI::escape:
irb(main):005:0> require "cgi"
=> true
irb(main):006:0> url = "http://foo.com?a=" + CGI::escape("a&b+c")
=> "http://foo.com?a=a%26b%2Bc"
The same thing goes for URI.decode vs. CGI::unescape.

However, if you're trying parse the query string from a complete URL, try this:
irb(main):008:0> require "uri"
=> false
irb(main):009:0> require "cgi"
=> false
irb(main):010:0> url = "http://foo.com?a=b+c&d=a&d=b"
=> "http://foo.com?a=b+c&d=a&d=b"
irb(main):011:0> uri = URI.parse(url)
=> #<URI::HTTP:0xb7bab258 URL:http://foo.com?a=b+c&d=a&d=b>
irb(main):012:0> uri.query
=> "a=b+c&d=a&d=b"
irb(main):013:0> params = CGI.parse(uri.query)
=> {"a"=>["b c"], "d"=>["a", "b"]}

No comments: