rack
Post on 16-May-2015
789 Views
Preview:
DESCRIPTION
TRANSCRIPT
8 minutes on
Rackbased on a presentation byDan Webb (dan@danwebb.net)@danwronghttp://slidesha.re/dan_on_rack
A Convention
If you have a Ruby object...
that has a call method which takes one argument...
app.call(env)
and that method returns an array with 3 elements...
[200, { 'Content-Type' => 'text/plain' }, 'Hello World!']
then you can connect it to any web server that supports Rack
require 'thin' Rack::Handler::Thin.run(app, :Port => 4000)
and you've got yourself a web application
That's it.
For Example...
app = Proc.new do |env| [200, { 'Content-Type' => 'text/plain' }, 'Hello World!'] end
require 'rubygems' require 'thin'Rack::Handler::Thin.run(app, :Port => 4000)
class HelloWorld def initialize(name) @name = name end
def call(env) [200, { 'Content-Type' => 'text/plain' }, "Hello #{@name}!"] end end
require 'rubygems' require 'rack'Rack::Handler::Mongrel.run(HelloWorld.new("Dan"), :Port => 4000)
def call(env)
{ "SERVER_NAME"=>"localhost", "HTTP_ACCEPT_ENCODING"=>"gzip,deflate", "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en- GB; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4", "PATH_INFO"=>"/", "SCRIPT_NAME"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "HTTP_ACCEPT_LANGUAGE"=>"en-gb,en;q=0.5", "HTTP_HOST"=>"localhost:4000", "REMOTE_ADDR"=>"127.0.0.1", "HTTP_KEEP_ALIVE"=>"300", "REQUEST_PATH"=>"/", "SERVER_SOFTWARE"=>"thin 0.8.2 codename Double Margarita", "HTTP_ACCEPT_CHARSET"=>"ISO-8859-1,utf-8;q=0.7,*;q=0.7", "HTTP_VERSION"=>"HTTP/1.1", "REQUEST_URI"=>"/", "SERVER_PORT"=>"4000", "QUERY_STRING"=>"", "GATEWAY_INTERFACE"=>"CGI/1.2", "HTTP_ACCEPT"=>"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "HTTP_CONNECTION"=>"keep-alive", "REQUEST_METHOD"=>"GET"}
[200, { 'Content-Type' => 'text/plain' }, "Hello #{@name}!"]
Status Code
[200, { 'Content-Type' => 'text/plain' }, "Hello #{@name}!"]
HTTP Headers
[200, { 'Content-Type' => 'text/plain' }, "Hello #{@name}!"]
Response Body
Response body can be any object that respond_to?(:each)
file = File.new('myfile.xml') [200, { 'Content-Type' => 'application/xml' }, file]
For Example...
class StreamingFile def initialize(file) @file = file end
def length File.size(@file) end
def last_modified File.mtime(@file).rfc822 end
def each File.open(@file, "rb") do |file| while part = file.read(8192) yield part end File.delete(@file) end end
[200, { 'Content-Type' => 'audio/mp3', 'Content-Length' => file.length.to_s}, file]
Duck Typing!
• Streaming
• Clean up after response sent
• Complex responses
• Loads more...
Why?
Common interface
• Passenger
• Mongrel
• CGI
• SCGI
• FastCGI
• Thin
• Ebb
• Fuzed
• Webrick
• Litespeed
Write once, serve however...
Convienient way to write
micro apps
There's More...
• The Rack Gem
• Middleware
• Rack and Passenger
• rackup
rack.rubyforge.org
What about Rails?
Rails is a Rack Application
config.ru
# This file is used by Rack-based servers to start the application.
require ::File.expand_path('../config/environment', __FILE__)run MyApp::Application
routes.rb
# You can call any Rack app from a route
match "/foo" => MySinatraApp
match "/bar" => MyMiddleware.new(OtherApp)
Questions?
Original Presentation by Dan Webb, @danwrongModified with Rails examples by Sarah Allen
@ultrasaurus, Blazing Cloud
top related