Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to designate a Rack handler

Rackup is successfully running any Rack app via Rack's default handler. e.g.:

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

But rackup is giving "NoMethodError at / undefined method `call' for nil:NilClass" when the last line is changed to instead use Rack's built-in CGI handler:

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

The same objection is raised for Rack's other built-in handlers. e.g. Rack::Handler::Thin, Rack::Handler::FastCGI, even Rack::Handler::WEBrick (which is the handler Rack selects above in default mode).

What's the correct syntax here?

like image 311
cczona Avatar asked Sep 27 '11 22:09

cczona


People also ask

What is a Rack handler?

The Rack Handler is an attachable handling system ergonomically designed for manually moving racks over long distances and in tight areas. It allows operators to quickly attach handles onto any rack within seconds.

How does Rack work in Ruby?

Rack provides a minimal, modular, and adaptable interface for developing web applications in Ruby. By wrapping HTTP requests and responses in the simplest way possible, it unifies and distills the API for web servers, web frameworks, and software in between (the so-called middleware) into a single method call.

What is Rack middleware?

Rack middleware is a way to filter a request and response coming into your application. A middleware component sits between the client and the server, processing inbound requests and outbound responses, but it's more than interface that can be used to talk to web server.

What is Rack request?

Rack::Request provides a convenient interface to a Rack environment. It is stateless, the environment env passed to the constructor will be directly modified. req = Rack::Request. new(env) req.


1 Answers

The rackup command reads the config file and starts a server. The Rack::Handler::XXX.run methods also start a server, independently of the rackup command (CGI is slightly different as it isn't actually a server as such).

What happens when you change the line

run RackApp.new

to

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

and run rackup is as follows. The server starts and parses the config file. When the Rack::Handler::CGI.run RackApp.new line is reached it is executed as any other Ruby code would be. In the case of the CGI handler this calls the app and writes the output to the standard output as it would if running as a CGI script (have a look at your terminal when you run rackup). Afterwards the 'rackup' server is started as normal, but without an app to run. When you try to access the page you'll get the NoMethodError, since the app is nil.

Using Rack::Handler::Thin is similar, but in this case, as Thin actually is a web server, it is started and will serve RackApp, but listens on Thin's default port of 8080 (not the rack default of 9292). After stopping Thin (e.g. with Ctrl-C) the default rackup server (Mongrel or Webrick) will start listening on port 9292, again with no app specified so you'll get the NoMethodError.

If you run your modified 'config.ru' as a plain Ruby script rather than using rackup you'll see the same behaviour, but without the rackup server being started. (You'll need to require rack first, so use ruby -rrack config.ru). In the CGI case the output of a single call to your app will be printed to the console, in the Thin case Thin will be started serving your app.

In order to specify the server to use with rackup, you can use the -s option, e.g. rackup -s thin will start the app using Thin (this time on the rackup default port of 9292). You can also do rackup -s cgi but this won't really work in any useful way - it just prints out the html of an error page to the console.

CGI

If you're trying to run your app as a CGI there are a couple of options. You need to create a CGI script that calls your app using the CGI handler. This could itself be a ruby script that calls Rack::Handler::CGI.run directly, in fact you could use your modified config.ru directly (you might want to rename it first and add an explicit require 'rack' line).

Alternatively you can use a shell script which then calls rackup config.ru. In this situation rackup detects that it's running as CGI and automatically uses the correct handler

like image 51
matt Avatar answered Oct 22 '22 14:10

matt