【问题标题】:How to designate a Rack handler如何指定机架处理程序
【发布时间】:2011-09-27 22:13:40
【问题描述】:

Rackup 正在通过 Rack 的默认处理程序成功运行任何 Rack 应用程序。例如:

class RackApp  
  def call(environment)    
  [
    '200', 
    {'Content-Type' => 'text/html'}, 
    ["Hello world"]
  ]
  end 
end
run RackApp.new

但是当最后一行更改为使用 Rack 的内置 CGI 处理程序时,rackup 给出“NoMethodError at / undefined method `call' for nil:NilClass”:

Rack::Handler::CGI.run RackApp.new

同样的反对意见也针对 Rack 的其他内置处理程序。例如Rack::Handler::Thin、Rack::Handler::FastCGI,甚至是 Rack::Handler::WEBrick(这是 Rack 在上面默认模式下选择的处理程序)。

这里的正确语法是什么?

【问题讨论】:

  • 我很惊讶样本运行,因为没有方法运行,所以run RackApp.new 将返回一个未定义的方法错误。另一方面,CGI 处理程序可以正常工作。
  • 由 rackup 执行,即$ rackup rackapp.ru。所以 run 确实存在;并且,正如我所指出的,按预期运行。似乎缺少的是 Rack::Handler::foo.run 方法。 'rack'、'rack/handler' 和 'rack/handler/foo' 的显式要求似乎也没有让 rackup 识别它们。

标签: ruby cgi webserver rack


【解决方案1】:

rackup 命令读取配置文件并启动服务器。 Rack::Handler::XXX.run 方法启动一个服务器,独立于 rackup 命令(CGI 略有不同,因为它实际上并不是一个服务器)。

换行会发生什么

run RackApp.new

Rack::Handler::CGI.run RackApp.new

运行rackup如下。服务器启动并解析配置文件。当到达Rack::Handler::CGI.run RackApp.new 行时,它将像任何其他Ruby 代码一样执行。对于 CGI 处理程序,它会调用应用程序并将输出写入标准输出,就像作为 CGI 脚本运行时一样(运行 rackup 时查看终端)。之后“rackup”服务器正常启动,但没有应用程序运行。当您尝试访问该页面时,您将收到 NoMethodError,因为该应用程序为 nil。

使用Rack::Handler::Thin 是类似的,但在这种情况下,由于 Thin 实际上是一个 Web 服务器,它会启动并服务于RackApp,但会侦听 Thin 的默认端口 8080(不是机架默认端口 9292)。停止 Thin(例如使用 Ctrl-C)后,默认机架服务器(Mongrel 或 Webrick)将开始在端口 9292 上侦听,再次没有指定应用程序,因此您将收到 NoMethodError。

如果您将修改后的“config.ru”作为纯 Ruby 脚本运行,而不是使用 rackup,您将看到相同的行为,但没有启动 rackup 服务器。 (您需要先使用机架,因此请使用ruby -rrack config.ru)。在 CGI 情况下,对您的应用的单个调用的输出将打印到控制台,在 Thin 情况下,Thin 将开始为您的应用提供服务。

为了指定要与 rackup 一起使用的服务器,您可以使用 -s 选项,例如rackup -s thin 将使用 Thin 启动应用程序(这次在机架默认端口 9292 上)。您也可以使用rackup -s cgi,但这不会以任何有用的方式真正起作用 - 它只是将错误页面的 html 打印到控制台。

CGI

如果您尝试将应用作为 CGI 运行,则有多种选择。您需要创建一个使用 CGI 处理程序调用您的应用程序的 CGI 脚本。这本身可能是一个直接调用Rack::Handler::CGI.run 的ruby 脚本,实际上您可以直接使用修改后的config.ru(您可能需要先重命名它并添加一个显式的require 'rack' 行)。

或者,您可以使用一个 shell 脚本,然后调用 rackup config.ru。在这种情况下,rackup 检测到它作为 CGI 运行并自动使用正确的处理程序

【讨论】:

    【解决方案2】:

    【讨论】:

    • 这不是 Rails 问题,我不打算创建自定义处理程序、自定义调度程序或进行路由。您能否详细说明其中任何一个如何回答如何从 Rack 的内置处理程序中进行选择的问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多