Ruby 1.9.3将不安全的字符添加到URI.escape

时间:2013-02-20 20:45:11

标签: ruby escaping sinatra uri ruby-1.9.3

我正在使用Sinatra并使用get '/foo/:bar' {}方法从网址获取参数。遗憾的是,:bar中的值可能包含/等令人讨厌的内容,导致404,因为没有路由匹配/foo/:bar/baz /。我使用URI.escape来转义URL参数,但它认为/有效的有效字符。正如提到的那样here这是因为要检查的默认Regexp不区分不安全字符和保留字符。我想改变这个并做到这一点:

URI.escape("foo_<_>_&_3_#_/_+_%_bar", Regexp.union(URI::REGEXP::UNSAFE, '/'))

只是为了测试它。

URI::REGEXP::UNSAFE是根据Ruby 1.9.3 Documentaton匹配的默认正则表达式:

escape(*arg)
Synopsis
    URI.escape(str [, unsafe])

Args
    str
        String to replaces in.
    unsafe
        Regexp that matches all symbols that must be replaced with
        codes. By default uses REGEXP::UNSAFE. When this argument is
        a String, it represents a character set.
Description
    Escapes the string, replacing all unsafe characters with codes.

不幸的是我收到了这个错误:

uninitialized constant URI::REGEXP::UNSAFE

正如this GitHub Issue所暗示的那样,这个Regexp已经从Ruby中删除了1.9.3。不幸的是,URI模块文档通常有点糟糕,但我真的无法解决这个问题。任何提示?

提前致谢!

2 个答案:

答案 0 :(得分:9)

URI#escape不是你想要的。你想要CGI#escape

require 'cgi'
CGI.escape("foo_<_>_&_3_#_/_+_%_bar")
# => "foo_%3C_%3E_%26_3_%23_%2F_%2B_%25_bar"

这将对其进行正确编码,以允许Sinatra检索它。

答案 1 :(得分:2)

也许你会更幸运CGI.escape

>> require 'uri'; URI.escape("foo_<_>_&_3_#_/_+_%_bar")
=> "foo_%3C_%3E_&_3_%23_/_+_%25_bar"
>> require 'cgi'; CGI.escape("foo_<_>_&_3_#_/_+_%_bar")
=> "foo_%3C_%3E_%26_3_%23_%2F_%2B_%25_bar"