Rack
-
Upload
sarah-allen -
Category
Technology
-
view
789 -
download
1
description
Transcript of Rack
![Page 1: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/1.jpg)
8 minutes on
Rackbased on a presentation byDan Webb ([email protected])@danwronghttp://slidesha.re/dan_on_rack
![Page 2: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/2.jpg)
![Page 3: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/3.jpg)
![Page 4: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/4.jpg)
![Page 5: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/5.jpg)
A Convention
![Page 6: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/6.jpg)
If you have a Ruby object...
![Page 7: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/7.jpg)
that has a call method which takes one argument...
app.call(env)
![Page 8: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/8.jpg)
and that method returns an array with 3 elements...
[200, { 'Content-Type' => 'text/plain' }, 'Hello World!']
![Page 9: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/9.jpg)
then you can connect it to any web server that supports Rack
require 'thin' Rack::Handler::Thin.run(app, :Port => 4000)
![Page 10: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/10.jpg)
and you've got yourself a web application
![Page 11: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/11.jpg)
That's it.
![Page 12: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/12.jpg)
For Example...
![Page 13: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/13.jpg)
app = Proc.new do |env| [200, { 'Content-Type' => 'text/plain' }, 'Hello World!'] end
require 'rubygems' require 'thin'Rack::Handler::Thin.run(app, :Port => 4000)
![Page 14: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/14.jpg)
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)
![Page 15: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/15.jpg)
def call(env)
![Page 16: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/16.jpg)
{ "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"}
![Page 17: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/17.jpg)
[200, { 'Content-Type' => 'text/plain' }, "Hello #{@name}!"]
Status Code
![Page 18: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/18.jpg)
[200, { 'Content-Type' => 'text/plain' }, "Hello #{@name}!"]
HTTP Headers
![Page 19: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/19.jpg)
[200, { 'Content-Type' => 'text/plain' }, "Hello #{@name}!"]
Response Body
![Page 20: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/20.jpg)
Response body can be any object that respond_to?(:each)
file = File.new('myfile.xml') [200, { 'Content-Type' => 'application/xml' }, file]
![Page 21: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/21.jpg)
For Example...
![Page 22: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/22.jpg)
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
![Page 23: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/23.jpg)
[200, { 'Content-Type' => 'audio/mp3', 'Content-Length' => file.length.to_s}, file]
![Page 24: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/24.jpg)
Duck Typing!
• Streaming
• Clean up after response sent
• Complex responses
• Loads more...
![Page 25: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/25.jpg)
Why?
![Page 26: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/26.jpg)
Common interface
![Page 27: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/27.jpg)
• Passenger
• Mongrel
• CGI
• SCGI
• FastCGI
• Thin
• Ebb
• Fuzed
• Webrick
• Litespeed
![Page 28: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/28.jpg)
Write once, serve however...
![Page 29: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/29.jpg)
Convienient way to write
micro apps
![Page 30: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/30.jpg)
There's More...
• The Rack Gem
• Middleware
• Rack and Passenger
• rackup
![Page 31: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/31.jpg)
rack.rubyforge.org
![Page 32: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/32.jpg)
What about Rails?
![Page 33: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/33.jpg)
Rails is a Rack Application
![Page 34: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/34.jpg)
config.ru
# This file is used by Rack-based servers to start the application.
require ::File.expand_path('../config/environment', __FILE__)run MyApp::Application
![Page 35: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/35.jpg)
routes.rb
# You can call any Rack app from a route
match "/foo" => MySinatraApp
match "/bar" => MyMiddleware.new(OtherApp)
![Page 36: Rack](https://reader035.fdocuments.in/reader035/viewer/2022081403/555686aad8b42a182f8b493f/html5/thumbnails/36.jpg)
Questions?
Original Presentation by Dan Webb, @danwrongModified with Rails examples by Sarah Allen
@ultrasaurus, Blazing Cloud