如何让Sinatra使用HTTPClient?

时间:2013-06-27 04:46:59

标签: ruby sinatra

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

在我的"你好世界"脚本我有:

#!/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,但不确定它是否重要。

1 个答案:

答案 0 :(得分:13)

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

由于已经定义了HTTP命名空间,因此Sinatra实际上认为它是一个Rack处理程序。我认为这是Sinatra的一个错误。它应该在使用之前检查处理程序是否响应run

无论如何,修复是使用Thin,或者如果你想使用WEBrick,那么明确告诉Sinatra跳过自动机架检测:

set :server, 'webrick'

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