在 Rails 项目中要求 'open-uri' 安全吗?

Is it safe to require 'open-uri' in a Rails project?

我看过很多 open-uri 的例子,对于简单的事情来说它似乎非常棒。不过,要求它在全局范围内定义一个名为 open 的方法确实让我很困扰。

这尤其令人不安,因为在 Rails 5 控制台中四处寻找之后,似乎已经定义了一个名为 open 的方法:

irb(main):001:0> open
ArgumentError: wrong number of arguments (given 0, expected 1..3)
        from (irb):1:in `initialize'
        from (irb):1:in `open'
        from (irb):1
        from /Users/ahamon/.gem/ruby/2.3.0/gems/railties-5.0.0.beta3/lib/rails/commands/console.rb:65:in `start'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/railties-5.0.0.beta3/lib/rails/commands/console_helper.rb:9:in `start'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/railties-5.0.0.beta3/lib/rails/commands/commands_tasks.rb:78:in `console'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/railties-5.0.0.beta3/lib/rails/commands/commands_tasks.rb:49:in `run_command!'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/railties-5.0.0.beta3/lib/rails/command.rb:20:in `run'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/railties-5.0.0.beta3/lib/rails/commands.rb:18:in `<top (required)>'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:302:in `require'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:302:in `block in require'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:268:in `load_dependency'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:302:in `require'
        from /Users/ahamon/code/signist/bin/rails:9:in `<top (required)>'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:296:in `load'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:296:in `block in load'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:268:in `load_dependency'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:296:in `load'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/spring-1.6.4/lib/spring/commands/rails.rb:6:in `call'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/spring-1.6.4/lib/spring/command_wrapper.rb:38:in `call'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/spring-1.6.4/lib/spring/application.rb:185:in `block in serve'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/spring-1.6.4/lib/spring/application.rb:156:in `fork'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/spring-1.6.4/lib/spring/application.rb:156:in `serve'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/spring-1.6.4/lib/spring/application.rb:131:in `block in run'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/spring-1.6.4/lib/spring/application.rb:125:in `loop'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/spring-1.6.4/lib/spring/application.rb:125:in `run'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/spring-1.6.4/lib/spring/application/boot.rb:18:in `<top (required)>'
        from /Users/ahamon/.rubies/ruby-2.3.0/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from /Users/ahamon/.rubies/ruby-2.3.0/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from -e:1:in `<main>'irb(main):002:0>

如果我继续 require 'open-uri',return 的值为 true,我现在已经删除了之前的 open,不管它是什么:

irb(main):002:0> require 'open-uri'
=> true
irb(main):003:0> open
ArgumentError: wrong number of arguments (given 0, expected 1+)
        from /Users/ahamon/.rubies/ruby-2.3.0/lib/ruby/2.3.0/open-uri.rb:29:in `open'
        from (irb):3
        from /Users/ahamon/.gem/ruby/2.3.0/gems/railties-5.0.0.beta3/lib/rails/commands/console.rb:65:in `start'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/railties-5.0.0.beta3/lib/rails/commands/console_helper.rb:9:in `start'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/railties-5.0.0.beta3/lib/rails/commands/commands_tasks.rb:78:in `console'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/railties-5.0.0.beta3/lib/rails/commands/commands_tasks.rb:49:in `run_command!'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/railties-5.0.0.beta3/lib/rails/command.rb:20:in `run'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/railties-5.0.0.beta3/lib/rails/commands.rb:18:in `<top (required)>'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:302:in `require'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:302:in `block in require'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:268:in `load_dependency'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:302:in `require'
        from /Users/ahamon/code/signist/bin/rails:9:in `<top (required)>'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:296:in `load'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:296:in `block in load'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:268:in `load_dependency'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:296:in `load'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/spring-1.6.4/lib/spring/commands/rails.rb:6:in `call'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/spring-1.6.4/lib/spring/command_wrapper.rb:38:in `call'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/spring-1.6.4/lib/spring/application.rb:185:in `block in serve'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/spring-1.6.4/lib/spring/application.rb:156:in `fork'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/spring-1.6.4/lib/spring/application.rb:156:in `serve'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/spring-1.6.4/lib/spring/application.rb:131:in `block in run'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/spring-1.6.4/lib/spring/application.rb:125:in `loop'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/spring-1.6.4/lib/spring/application.rb:125:in `run'
        from /Users/ahamon/.gem/ruby/2.3.0/gems/spring-1.6.4/lib/spring/application/boot.rb:18:in `<top (required)>'
        from /Users/ahamon/.rubies/ruby-2.3.0/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from /Users/ahamon/.rubies/ruby-2.3.0/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from -e:1:in `<main>'irb(main):004:0>

注意每个堆栈跟踪中指定的不同数量。

那么之前定义的open是什么?抹杀安全吗?有没有办法在不定义全局方法的情况下使用 open-uri?

openKernel#open, not Rails. open-uri 包装 Kernel#open:它检查目标是否是 URL 或知道 #open,如果是则处理它,通过一切都是真实的 Kernel#open 如果不是的话。

因此,如果没有 open-uri,URLs 将不起作用,openables 将不起作用,其他一切都起作用。使用 open-uri、URLs 工作,openables 工作,其他一切都是一样的。要求它应该没有危险,除了在 open-uri 检查您的参数是 URL 或响应 #open.

时非常非常轻微的性能影响之外