【问题标题】:How do I get Sinatra to work with HTTPClient?如何让 Sinatra 使用 HTTPClient?
【发布时间】:2013-06-27 04:46:58
【问题描述】:

我正在尝试创建一个外观 API,它通过 Sinatra 接收请求,然后在后端的 Github API 上启动 HTTP 请求。

在我的“hello world”脚本中:

#!/usr/bin/ruby

require 'httpclient'
require 'sinatra'

get '/foo' do
    "hello world"
end

但是,它会遇到如下错误:

$ ./api.rb 
/usr/local/share/gems/gems/sinatra-1.4.3/lib/sinatra/base.rb:1408:in `run!': undefined method `run' for HTTP:Module (NoMethodError)
from /usr/local/share/gems/gems/sinatra-1.4.3/lib/sinatra/main.rb:25:in `block in <module:Sinatra>'

我不明白为什么会这样。如果我注释掉 require 'httpclient' 行,它就可以正常工作:

#!/usr/bin/ruby

#require 'httpclient'
require 'sinatra'

get '/foo' do
  "hello world"
end

$ ./api.rb 
[2013-06-26 21:43:12] INFO  WEBrick 1.3.1
[2013-06-26 21:43:12] INFO  ruby 1.9.3 (2013-05-15) [x86_64-linux]
[2013-06-26 21:43:12] WARN  TCPServer Error: Cannot assign requested address - bind(2)
== Sinatra/1.4.3 has taken the stage on 4567 for development with backup from WEBrick
[2013-06-26 21:43:12] INFO  WEBrick::HTTPServer#start: pid=31272 port=4567

我的猜测是 Sinatra 自己使用 HTTPClient 并且正在发生某种命名空间冲突。有没有办法同时使用 HTTPClient 和 Sinatra?

好的,这里是请求的信息:

$ gem list sinatra httpclient

*** LOCAL GEMS ***

sinatra (1.4.3)

$ gem out sinatra httpclient
bigdecimal (1.1.0 < 1.2.0)
io-console (0.3 < 0.4.2)
json (1.6.8 < 1.8.0)
rdoc (3.12 < 4.0.1)

我是这样计算httpclient版本的:

$ locate httpclient.rb
/usr/local/share/gems/gems/httpclient-2.3.3/lib/httpclient.rb
/usr/local/share/gems/gems/httpclient-2.3.3/test/test_httpclient.rb

我的操作系统是 Fedora 17,但不确定是否重要。

【问题讨论】:

  • Sinatra 不使用 HTTPClient。如果是这样,您就不必单独要求它们,并且当您告诉 gems 安装 Sinatra 时,它会自动安装 HTTPClient。
  • 我刚刚在带有 Sinatra 1.4.3 和 httpclient 2.3.3 的 Ruby 1.9.3 上尝试了这段代码。我无法复制这个问题。你遗漏了什么吗?
  • 无法用 sinatra (1.4.1) 和 httpclient (2.3.3) 重现。我的看法是因为你使用全局 ruby​​,它可能有旧版本的 httpclient
  • 它与“全局”Ruby 无关。它会在某处的源代码中。
  • 感谢您的回复。我没有遗漏任何东西;如您所见,我所做的只是注释掉 require 'httpclient' 行。据我所知,我的 httpclient 版本是 2.3.3。我将在不同的操作系统 (RHEL6) 上对其进行测试,看看会发生什么。

标签: ruby sinatra


【解决方案1】:

我找到了原因。 HTTPClient 定义了一个名为HTTP 的模块。默认情况下,Sinatra 会按照命名空间名称为 HTTPWEBrick 的顺序查找 Rack 处理程序。

自从定义了HTTP 命名空间后,Sinatra 实际上认为它是一个机架处理程序。我认为这是 Sinatra 中的一个错误。它应该在使用它之前检查处理程序是否响应run

无论如何,解决方法是使用 Thin,或者如果您想使用 WEBrick,则明确告诉 Sinatra 跳过自动机架检测:

set :server, 'webrick'

这将阻止 Sinatra 认为 HTTPClient HTTP 模块是 Rack 处理程序。

【讨论】:

  • +1 对他们来说,将responds_to(:run) 作为健全性检查听起来很合理。使用 Thin 也有优势。好收获!
  • 你们真是不可思议。非常感谢您的帮助!我会在今天晚些时候测试它并报告结果。
  • 是的,刚刚用thin测试过,效果很好。无论如何,看起来瘦是一个更好的网络服务器,所以我可以坚持下去。我还学习了如何配置 Rack 应用程序并使用增加的超时值启动精简。再次感谢大家!
  • 我也遇到了这个问题——当我设置一个新的环境时。我没有意识到我没有安装瘦。由于默认情况下 sinatra 会首先尝试使用瘦,所以我所要做的就是“sudo gem install thin”——然后再次启动应用程序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-12
  • 2018-01-30
  • 1970-01-01
  • 2011-04-11
  • 1970-01-01
  • 2014-10-12
  • 1970-01-01
相关资源
最近更新 更多