Monday, 13 June 2011

Rack on Rails and Custom webserver

Rails on Rack

What would be interesting
  • Where does  Rack fit in web framework
  • How to install
  • Build our own framework
  • Use our middle ware in Rails.
Rack is an interface for Ruby webserver. It provides a minimal interface between webservers supporting Ruby and Ruby frameworks.

Rack provides an interface between different web servers and your application, Making it very simple for your application to be compatible with any web server that supports Rack - Passenger, Litespeed, Mongrel, Thin, Ebb, Webrick etc ...

It is also possible to use multiple frameworks in a single application. Rails and Sinatra integration is a good example.

Think of Middle ware as a Rails before_filter/after_filter that are reusable across different rack supported frameworks. Ex: We can use the same 'anti_spamming' middle ware for our Rails app, Sinatra app etc ..

Rack handlers

Rack in our web frame work

  • gem install rack
  • Require 'rack' for further usage
  • "rake middle ware" gives you the list of classes/modules usable as middle ware in our application
Rack specification

A Rack application is a Ruby object(not a class) that responds to call. It takes exactly one argument, the environment, and returns an Array of exactly three values: The status, the headers and the body.

 class HelloWorld

     def call(env)
         [200, {"Content-Type" => "text/html" }, "Hello Rack !"]


sample Rack environment is pasted here

sample Rack environment

We will have another syntax to bring a Rack server up and running, Using various handlers.

require 'rubygems'
require 'rack' proc{|env| [200, {"Content-Type" => "text/html"}, "Hello Rack"]}, :Port => 9292
INFO  WEBrick::HTTPServer#start: pid=4557 port=19292

Now the server is running on 19292 port and 'http://localhost:19292/' gives "Hello Rack"

Some of the other Rack handlers are listed below,
  • Rack::Handler::CGI
  • Rack::Handler::EventedMongrel
  • Rack::Handler::FastCGI
  • Rack::Handler::LSWS
  • Rack::Handler::Mongrel
  • Rack::Handler::SCGI
  • Rack::Handler::WEBrick
  • Rack::Handler::Thin

Custom middle ware for Rails

Use an existing rails application or create a new one.
$ rackup   #will bring up the rack server. This depends on the values in file in RAILS_ROOT.

rub {|env|  [200, {"Content-Type" => ""text/html"},  "Hello Rack!"]}

config.middleware.use(new_middleware, args) # adds a new middle ware at the end of middle ware stack.

Example :
 Adding a middle ware to an existing Rails application. This filter redirects page to 'google' if the requested resource is not present with in rails app.

require 'rubygems'
require 'rack'

class MyRackMiddleWare
    def initialize(app)
        @app = app

    def call(env)
        #executes the request using Rails app
        status, headers, body =
        if status == 404
            [301, {"Location" => ''}, 'redirecting to google as the requested resource is not available']
            [status, headers, body]
Add middle ware details in the 'environment.rb'
  config.middleware.use(MyRackMiddleWare) # Make sure to require the file.

 Run the application and try for an invalid page in the URL, the page should get redirected to google.

Friday, 3 June 2011

rails - bundle exec

"It’s worth noting that typing in rake foo (or anyexecutable foo) in the presence of aGemfile.lock, and expecting it to execute in the bundler sandbox doesn’t make any sense" - Yahuda

Ex: "rake middleware" should be replaced as "bundle exec rake middleware"