rack in rails 3
play

Rack in Rails 3 <http://twitter.com/rtomayko> Ryan Tomayko - PowerPoint PPT Presentation

Rack in Rails 3 <http://twitter.com/rtomayko> Ryan Tomayko GitHub Rack (Core Team) Rack::Contrib (Maintainer) Sinatra (Committer) Rack::Cache (Maintainer) Shotgun (Maintainer) "Get a better logo, guys." -- Tim


  1. Rack in Rails 3

  2. <http://twitter.com/rtomayko> Ryan Tomayko GitHub • Rack (Core Team) • Rack::Contrib (Maintainer) • Sinatra (Committer) • Rack::Cache (Maintainer) • Shotgun (Maintainer)

  3. "Get a better logo, guys." -- Tim Bray

  4. The Rack SPEC <http://rack.rubyforge.org/doc/SPEC.html> • "Just" a document. • Conventions for expressing HTTP in Ruby. • Interface, Contract, Agreement, Protocol. • Based on Python's WSGI. • Fits on a single slide.

  5. Expressing HTTP in Ruby

  6. HTTP Request GET
/hello
HTTP/1.1 Host: 
localhost:9292 Connection: 
keep‐alive User‐Agent: 
Mozilla/5.0
(Macinto... Accept: 
application/xml,applicati... Accept‐Encoding: 
gzip,deflate,sdch Accept‐Language: 
en‐US,en;q=0.8 Accept‐Charset: 
UTF‐8,*;q=0.5 Cache‐Control: 
max‐age=0 Cookie: 
foo=bar

  7. HTTP Request Rack "env" Hash { " REQUEST_METHOD "=>"GET", GET
/hello
HTTP/1.1 
" PATH_INFO "=>"/hello", Host: 
localhost:9292 
" SCRIPT_NAME "=>"", Connection: 
keep‐alive 
" SERVER_NAME "=>"localhost", User‐Agent: 
Mozilla/5.0
(Macinto... 
" SERVER_PORT "=>"9292", Accept: 
application/xml,applicati... 
" REMOTE_ADDR "=>"127.0.0.1", Accept‐Encoding: 
gzip,deflate,sdch 
" QUERY_STRING "=>"", Accept‐Language: 
en‐US,en;q=0.8 
" HTTP_HOST "=>"localhost:9292", Accept‐Charset: 
UTF‐8,*;q=0.5 
" HTTP_CONNECTION "=>"keep‐alive", Cache‐Control: 
max‐age=0 
" HTTP_USER_AGENT "=>"Mozilla/5.0
(...", Cookie: 
foo=bar 
" HTTP_ACCEPT "=>"application/xml,a...", 
" HTTP_ACCEPT_ENCODING "=>"gzip,def...", 
" HTTP_ACCEPT_LANGUAGE "=>"en‐US,en...", 
" HTTP_ACCEPT_CHARSET "=>"UTF‐8,*;q=0.5", 
" HTTP_CACHE_CONTROL "=>"max‐age=0", 
" HTTP_COOKIE "=>"foo=bar", 
" rack.url_scheme "=>"http", 
" rack.input "=>#<StringIO:0x10841ec>, 
" rack.errors "=>#<IO:0x3a8d4c>, 
" rack.version "=>[1,
1], 
" rack.run_once "=>false, 
" rack.multithread "=>true, 
" rack.multiprocess "=>false }

  8. HTTP Response HTTP/1.1
200
OK Connection: 
close Date: 
Tue,
16
Feb
2010
23:49:18
GMT Content‐Type: 
text/plain Content‐Length: 
11 Cache‐Control: 
max‐age=60 Hello
World

  9. HTTP Response Rack Response HTTP/1.1
200
OK [ Connection: 
close 

 200 , Date: 
Tue,
16
Feb
2010
23:49:18
GMT 

{' Content‐Type '


=>
'text/plain', Content‐Type: 
text/plain 


' Content‐Length '
=>
'11', Content‐Length: 
11 


' Cache‐Control '

=>
'max‐age=60'}, Cache‐Control: 
max‐age=60 

[" Hello
World "] ] Hello
World

  10. HTTP Response Rack Response HTTP/1.1
200
OK [ Connection: 
close 

 200 , Date: 
Tue,
16
Feb
2010
23:49:18
GMT 

{' Content‐Type '


=>
'text/plain', Content‐Type: 
text/plain 


' Content‐Length '
=>
'11', Content‐Length: 
11 


' Cache‐Control '

=>
'max‐age=60'}, Cache‐Control: 
max‐age=60 

[" Hello
World "] ] Hello
World OR [ 

 200 , 

{' Content‐Type '


=>
'text/plain', 


' Content‐Length '
=>
 File.size('hello.txt').to_s , 


' Cache‐Control '

=>
'max‐age=60'}, 

 File.open('hello.txt',
'rb') ]

  11. A Rack application is an 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 .

  12. class 
 HelloWorldApp 

 def 
 call (env) 



 [ 200, 




{'Content‐Type'
 => 
'text/plain'}, 




 [ "Hello
World" ]] 

 end end 
 app
 = 
HelloWorldApp . new

  13. class 
 HelloWorldApp 

 def 
 call (env) 



 [ 200, 




{'Content‐Type'
 => 
'text/plain'}, 




 [ "Hello
World" ]] 

 end end 
 app
 = 
HelloWorldApp . new OR app
 = 
lambda
{
 | env | 

 [ 200,
{'Content‐Type' => 'text/plain'},
 [ "Hello
World" ]] 
}

  14. We haven't used any Rack APIs yet.

  15. Interoperability Servers Frameworks WEBrick Rails CGI Sinatra FastCGI Merb Mongrel Ramaze Rack Thin SPEC Camping Passenger Coset Unicorn Rango Heroku Just Rack

  16. Interoperability Servers Frameworks WEBrick Rails CGI Sinatra FastCGI Merb Mongrel Ramaze Rack Thin SPEC Camping Passenger Coset Unicorn Rango Heroku Just Rack

  17. Architecture of Intermediaries

  18. HTTP Intermediaries HTTP Alice HTTP Company HTTP HTTP Regional Proxy App 1 Proxy Auth + Logging Load Balancing HTTP HTTP HTTP Compression Bob HTTP HTTP App 2 HTTP HTTP Carol separate process inside example.com firewall

  19. HTTP Intermediaries HTTP Alice HTTP Company HTTP HTTP Regional Proxy App 1 Proxy Auth + Logging Load Balancing HTTP HTTP HTTP Compression Bob HTTP HTTP App 2 HTTP HTTP Carol separate process inside example.com firewall

  20. Middleware class 
 ShoutMiddleware 

 def 
 initialize (app) 



@app
 = 
app 

 end 
 

 def 
 call (env) 



status,
headers,
body
 = 
@app . call(env) 



parts
 = 
 [] 



body . each
{
 | part | 
parts
 << 
part . upcase
} 



 [ status,
headers,
parts ] 

 end end

  21. Middleware class 
 ShoutMiddleware 

 def 
 initialize (app) 



@app
 = 
app 

 end 
 

 def 
 call (env) 



status,
headers,
body
 = 
@app . call(env) 



parts
 = 
 [] 



body . each
{
 | part | 
parts
 << 
part . upcase
} 



 [ status,
headers,
parts ] 

 end end app
 = 
lambda
{
 | env | 

 [ 200,
{'Content‐Type' => 'text/plain'},
 [ "hello
world" ]] 
} stream
 = 
ShoutMiddleware . new(app) Rack :: Handler :: Mongrel . run(stream,
:Port
 => 
8080)

  22. Rack::ETag require
'digest/md5' module 
Rack 

 class 
 ETag 



 def 
 initialize (app) 





@app
 = 
app 



 end 
 



 def 
 call (env) 





status,
headers,
body
 = 
@app . call(env) 





 if 
 ! headers . has_key?('ETag') 







parts
 = 
 [] 







body . each
{
 | part | 
parts
 << 
part . to_s
} 







headers [ 'ETag' ] 
 = 
%("#{Digest :: MD5 . hexdigest(parts . join(""))}") 







 [ status,
headers,
parts ] 





 else 







 [ status,
headers,
body ] 





 end 



 end 

 end end

  23. Rack Middleware <http://github.com/rack/rack/tree/master/lib/rack> Content Modifying Behavioral Rack::Chunked Rack::CommonLogger Rack::ContentLength Rack::Lint Rack::ConditionalGet Rack::Lock Rack::ContentType Rack::Reloader Rack::Deflater Rack::ETag Routing Rack::Head Rack::MethodOverride Rack::Cascade Rack::Runtime Rack::Recursive Rack::Sendfile Rack::Static Rack::ShowStatus Rack::URLMap

  24. Rack::Contrib <http://github.com/rack/rack‐contrib> Rack::AcceptFormat Rack::MailExceptions Rack::Access Rack::NestedParams Rack::Backstage Rack::NotFound Rack::Callbacks Rack::ProcTitle Rack::Config Rack::Profiler Rack::Cookies Rack::ResponseCache Rack::CSSHTTPRequest Rack::ResponseHeaders Rack::Deflect Rack::RelativeRedirect Rack::Evil Rack::Signals Rack::HostMeta Rack::StaticCache Rack::JSONP Rack::SimpleEndpoint Rack::LighttpdScriptNameFix Rack::TimeZone Rack::Locale

  25. <http://coderack.org>

  26. <http://coderack.org> 99 Pieces of Middleware

  27. ActionDispatch <http://github.com/rails/rails/tree/master/actionpack/lib/action_dispatch > • Middleware extracted from ActionController • ActionDispatch::MiddlewareStack • Request/Response objects • Routing • Integration Testing Support

  28. Default Middleware $
rake
middleware use
ActionDispatch::Static use
Rack::Lock use
Rack::Runtime use
Rails::Rack::Logger use
ActionDispatch::ShowExceptions use
ActionDispatch::Callbacks use
ActionDispatch::Cookies use
ActionDispatch::Session::CookieStore use
ActionDispatch::Flash use
ActionDispatch::ParamsParser use
Rack::MethodOverride use
ActionDispatch::Head use
ActiveRecord::ConnectionAdapters::ConnectionManagement use
ActiveRecord::QueryCache run
Helloworld::Application.routes

Recommend


More recommend