advertisement

8 Minutes On Rack

64 %
36 %
advertisement
Information about 8 Minutes On Rack
Technology

Published on November 23, 2008

Author: danwrong

Source: slideshare.net

Description

From Ruby Manor 2008
advertisement

8 minutes on Rack Dan Webb (dan@danwebb.net)

Web Framework

Web Server

Library

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

Fin

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' }, quot;Hello #{@name}!quot;] end end require 'rubygems' require 'rack' Rack::Handler::Mongrel.run(HelloWorld.new(quot;Danquot;), :Port => 4000)

// Courtesy of Pratik Naik! #include quot;ruby.hquot; VALUE method_call(VALUE self, VALUE env) { VALUE response = rb_ary_new(); VALUE headers = rb_hash_new(); rb_hash_aset(headers, rb_str_new2(quot;Content-Typequot;), rb_str_new2(quot;text/plainquot;)); rb_ary_push(response, INT2NUM(200)); rb_ary_push(response, headers); rb_ary_push(response, rb_str_new2(quot;Hello World!quot;)); return response; } void Init_rock() { VALUE Rock = rb_define_class(quot;Rockquot;, rb_cObject); rb_define_method(Rock, quot;callquot;, method_call, 1); } // run.rb require 'rock' require 'thin' Rack::Handler::Thin.run Rock.new, :Port => 4000

def call(env)

{ quot;SERVER_NAMEquot;=>quot;localhostquot;, quot;HTTP_ACCEPT_ENCODINGquot;=>quot;gzip,deflatequot;, quot;HTTP_USER_AGENTquot;=>quot;Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en- GB; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4quot;, quot;PATH_INFOquot;=>quot;/quot;, quot;SCRIPT_NAMEquot;=>quot;quot;, quot;SERVER_PROTOCOLquot;=>quot;HTTP/1.1quot;, quot;HTTP_ACCEPT_LANGUAGEquot;=>quot;en-gb,en;q=0.5quot;, quot;HTTP_HOSTquot;=>quot;localhost:4000quot;, quot;REMOTE_ADDRquot;=>quot;127.0.0.1quot;, quot;HTTP_KEEP_ALIVEquot;=>quot;300quot;, quot;REQUEST_PATHquot;=>quot;/quot;, quot;SERVER_SOFTWAREquot;=>quot;thin 0.8.2 codename Double Margaritaquot;, quot;HTTP_ACCEPT_CHARSETquot;=>quot;ISO-8859-1,utf-8;q=0.7,*;q=0.7quot;, quot;HTTP_VERSIONquot;=>quot;HTTP/1.1quot;, quot;REQUEST_URIquot;=>quot;/quot;, quot;SERVER_PORTquot;=>quot;4000quot;, quot;QUERY_STRINGquot;=>quot;quot;, quot;GATEWAY_INTERFACEquot;=>quot;CGI/1.2quot;, quot;HTTP_ACCEPTquot;=>quot;text/html,application/xhtml+xml,application/xml;q=0.9, */*;q=0.8quot;, quot;HTTP_CONNECTIONquot;=>quot;keep-alivequot;, quot;REQUEST_METHODquot;=>quot;GETquot; }

[200, { 'Content-Type' => 'text/plain' }, quot;Hello #{@name}!quot;] Status Code

[200, { 'Content-Type' => 'text/plain' }, quot;Hello #{@name}!quot;] HTTP Headers

[200, { 'Content-Type' => 'text/plain' }, quot;Hello #{@name}!quot;] Response Body

Response body can be any object that respond_to?(:each) file = File.new('myfile.xml') [200, { 'Content-Type' => 'application/xml' }, file]

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, quot;rbquot;) 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

Example: Development Server

class StaticOrRedirect def initialize(options={}) @redirect_base = options[:redirect_base] root = options[:root] || Dir.pwd @file_server = Rack::File.new(root) end def call(env) path = env[quot;PATH_INFOquot;] resp = @file_server.call(env) if resp.first == 404 [302, { 'Content-Type' => 'text/plain', 'Location' => quot;#{@redirect_base}#{env['PATH_INFO']}quot; }, 'Not here!'] else resp end end end Rack::Handler::Thin.run( StaticOrRedirect.new( :redirect_base => 'http://bbc.co.uk' ) )

There's more... • The Rack Gem • Middleware • Rack and Passenger • rackup

rack.rubyforge.org

danwebb.net

Questions?

Add a comment

Related presentations

Presentación que realice en el Evento Nacional de Gobierno Abierto, realizado los ...

In this presentation we will describe our experience developing with a highly dyna...

Presentation to the LITA Forum 7th November 2014 Albuquerque, NM

Un recorrido por los cambios que nos generará el wearabletech en el futuro

Um paralelo entre as novidades & mercado em Wearable Computing e Tecnologias Assis...

Microsoft finally joins the smartwatch and fitness tracker game by introducing the...