SlideShare uma empresa Scribd logo
1 de 38
Using and scaling
  Rack and Rack-based
               middleware
Alona Mekhovova
Ruby/Rails developer & co-founder @ RubyGarage

Organizer & coach @ RailsGirls

Ruby on Rails courses leading

Involved in growing Ruby Community in Dnipro

Monthly Rails MeetUps organizer


                                          skype: alony_
                                  alony@rubygarage.org
Overview
Why do we need Rack?

Simple Rack app & own middleware

Available middleware overview

Plugging middleware into Rails

What’s next?
Lots of Web-servers
...and frameworks
the http protocol
request => response

stateless
request:               response:
Request method, URI,   Protocol version,
protocol version       status code, its desc

Request headers        Response headers

Request body           Response body
http
from a bird’s eye view

REQUEST         RESPONSE
Request structure
{"HTTP_USER_AGENT"=>"curl/7.12.2 ..."      Classically, a
 "REMOTE_HOST"=>"127.0.0.1",               CGI
 "PATH_INFO"=>"/",
 "HTTP_HOST"=>"ruby-lang.org",             environment
 "SERVER_PROTOCOL"=>"HTTP/1.1",
 "SCRIPT_NAME"=>"",
 "REQUEST_PATH"=>"/",
                                           Most
 "REMOTE_ADDR"=>"127.0.0.1",               frameworks
 "HTTP_VERSION"=>"HTTP/1.1",
 "REQUEST_URI"=>"http://ruby-lang.org/",
                                           already use
 "SERVER_PORT"=>"80",                      smth like that,
 "HTTP_PRAGMA"=>"no-cache",                most developers
 "QUERY_STRING"=>"",
 "GATEWAY_INTERFACE"=>"CGI/1.1",           know the fields
 "HTTP_ACCEPT"=>"*/*",
 "REQUEST_METHOD"=>"GET"}
                                           Let’s keep it
Response structure
 Status   HTTP/1.1 302 Found
          Date: Sat, 27 Oct 2007 10:07:53 GMT
          Server: Apache/2.0.54 (Debian GNU/Linux)
          mod_ssl/2.0.54 OpenSSL0.9.7e

Headers   Location: http://www.ruby-lang.org/
          Content-Length: 209
          Content-Type: text/html; charset=iso-8859-1

  Body    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
          <html><head>
          <title>302 Found</title>
          </head><body>
          <h1>Found</h1>
          <p>The document has moved <a
          href="http://www.ruby-lang.org/">here</a>
          </p>
          </body></html>
Response in Ruby
  Status   HTTP/1.1 302 Found
Integer    Date: Sat, 27 Oct 2007 10:07:53 GMT
           Server: Apache/2.0.54 (Debian GNU/Linux)
           mod_ssl/2.0.54 OpenSSL0.9.7e

Headers    Location: http://www.ruby-lang.org/
           Content-Length: 209
  Hash     Content-Type: text/html; charset=iso-8859-1

  Body     <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
 Array     <html><head>
           <title>302 Found</title>
           </head><body>
           <h1>Found</h1>
           <p>The document has moved <a
           href="http://www.ruby-lang.org/">here</a>
           </p>
           </body></html>
Response in Ruby
                   Environment
                                    Status
lambda { |env|
         [
           200,
           {"Content-Type"=>"text/plain"},
           ["Hello, Rack!"]
         ]
       }                                 Headers


                        Body
Summarizing

The Rack app gets called with the CGI
environment...

...and returns an Array of status, header & body
...and again


 HTTP SERVER   YOUR FANCY APP
Simplest Rack app
run Proc.new { |env|
         [
           200,
           {"Content-Type"=>"text/plain"},
           ["Hello, Rack!"]
         ]
       }
rackup
# config.ru

class Awesome
 def call(env)
   [200, {'Content-Type' => 'text/plain'}, 'AWESOME.']
 end
end

run Awesome.new


# console

rackup config.ru
Rack::Builder
app = Rack::Builder.app do
  map '/awesome' do
    run Awesome
  end
  
  map '/' do
    run Proc{ 404,
        {"Content-Type" => "text/html"},
        ['awesome requests only'] }
  end
end

run app
Rack::Builder

Rack::Builder.new do
  use Rack::CommonLogger
  use Rack::ShowExceptions
  use Rack::ShowStatus
  use Rack::Lint
  run MyRackApp.new
end
Middleware
    HTTP                    HTTP

 Middleware1             Middleware

 Middleware2
                     Rack          Rack
                   application   application
Rack application
Home-made middleware
class JSMinifier
    
  def initialize(app, path)
    @app, @root = app, File.expand_path(path)
  end

  def call(env)
    path = File.join(@root, Utils.unescape(env["PATH_INFO"]))
    return @app.call(env) unless path.match(/.*/(w+.js)$/)
 
    if !File.readable?(path) or env["PATH_INFO"].include?("..")
      return [403, {"Content-Type" => "text/plain"}, ["Forbiddenn"]]
    end

    return [ 200,
             { "Content-Type" => "text/javascript" },
             [JSMin.minify( File.new( path, "r" ) )]
           ]
  end
end
Home-made middleware
class JSMinifier
    
  def initialize(app, path)
    @app, @root = app, File.expand_path(path)
  end

  def call(env)
    path = File.join(@root, Utils.unescape(env["PATH_INFO"]))
    return @app.call(env) unless path.match(/.*/(w+.js)$/)
 
    if !File.readable?(path) or env["PATH_INFO"].include?("..")
      return [403, {"Content-Type" => "text/plain"}, ["Forbiddenn"]]
    end

    return [ 200,
             { "Content-Type" => "text/javascript" },
             [JSMin.minify( File.new( path, "r" ) )]
           ]
  end
end
Home-made middleware
class JSMinifier
    
  def initialize(app, path)
    @app, @root = app, File.expand_path(path)
  end

  def call(env)
    path = File.join(@root, Utils.unescape(env["PATH_INFO"]))
    return @app.call(env) unless path.match(/.*/(w+.js)$/)
 
    if !File.readable?(path) or env["PATH_INFO"].include?("..")
      return [403, {"Content-Type" => "text/plain"}, ["Forbiddenn"]]
    end

    return [ 200,
             { "Content-Type" => "text/javascript" },
             [JSMin.minify( File.new( path, "r" ) )]
           ]
  end
end
What we already have
Rack::Bug
Rack::Cascade
Rack::Cache
Rack::GeoIP
Rack::Callback
Rack::MailExceptions
Rack::Honeypot
env['warden'].authenticated?
     env['warden'].authenticate!(:password)
     env['warden'].user


     Warden::Strategies.add(:password) do

       def valid?
         params[:username] || params[:password]
       end

       def authenticate!
         u = User.authenticate(params[:username],
     params[:password])
         u.nil? ? fail!("Could not log in") : success!
     (u)
       end
     end



Warden
... and lots of others
 Rack::Static             Rack::CSSHTTPRequest

     Rack::noIE                 Rack::GoogleAnalytics

          Rack::Profiler              Rack::Maintenance

Rack::Lock        Rack::Spellcheck          Rack::Log

             Rack::Pack              Rack::Validate

   https://github.com/rack/rack/wiki/List-of-Middleware
              http://coderack.org/middlewares
Plug it into Rails stack
$ rake middleware

use   ActionDispatch::Static
use   Rack::Lock
use   ActiveSupport::Cache::Strategy::LocalCache
use   Rack::Runtime
use   Rails::Rack::Logger
use   ActionDispatch::ShowExceptions
use   ActionDispatch::DebugExceptions
use   ActionDispatch::RemoteIp
use   Rack::Sendfile
use   ActionDispatch::Callbacks
use   ActiveRecord::ConnectionAdapters::ConnectionManagement
use   ActiveRecord::QueryCache
      ...
use   Rack::MethodOverride
use   ActionDispatch::Head
use   ActionDispatch::BestStandardsSupport
run   MyApp::Application.routes
Configure middleware stack
Rails::Initializer.run do |config|
  config.middleware.use Rack::MailExceptions
  config.middleware.delete Rack::Lock
  config.middleware.insert_after Rack::Sendfile, Rack::Static
  config.middleware.insert_before Rack::Head, Ben::Asplode
  config.middleware.swap ActionDispatch::Callbacks,
ActiveRecord::QueryCache
end




        config.middleware.is_a? Array   # => true
...or replace it
# config/initializers/stack.rb
ActionController::Dispatcher.middleware =
       ActionController::MiddlewareStack.new do |m|
         m.use ActionController::Failsafe
         m.use ActiveRecord::QueryCache
         m.use Rack::Head
end


        # console
        $ rake middleware

        use   ActionController::Failsafe
        use   ActiveRecord::QueryCache
        use   Rack::Head
        run   ActionController::Dispatcher.new
The future
Rails 4 will have an API only middleware stack
configuration

RocketPants is an interesting alternative right now
(github.com/filtersquad/rocket_pants)
Many thanks!

Mais conteúdo relacionado

Mais procurados

Mais procurados (20)

Rack
RackRack
Rack
 
Rails 4.0
Rails 4.0Rails 4.0
Rails 4.0
 
Construindo APIs Usando Rails
Construindo APIs Usando RailsConstruindo APIs Usando Rails
Construindo APIs Usando Rails
 
Apache Hive Hook
Apache Hive HookApache Hive Hook
Apache Hive Hook
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Rack
 
Refactoring terraform
Refactoring terraformRefactoring terraform
Refactoring terraform
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
HTTP Caching and PHP
HTTP Caching and PHPHTTP Caching and PHP
HTTP Caching and PHP
 
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
 
5-WebServers.ppt
5-WebServers.ppt5-WebServers.ppt
5-WebServers.ppt
 
Frontend Servers and NGINX: What, Where and How
Frontend Servers and NGINX: What, Where and HowFrontend Servers and NGINX: What, Where and How
Frontend Servers and NGINX: What, Where and How
 
Rails 2.0 Presentation
Rails 2.0 PresentationRails 2.0 Presentation
Rails 2.0 Presentation
 
Hashiconf EU 2019 - A Tour of Terraform 0.12
Hashiconf EU 2019 - A Tour of Terraform 0.12Hashiconf EU 2019 - A Tour of Terraform 0.12
Hashiconf EU 2019 - A Tour of Terraform 0.12
 
HBaseConEast2016: HBase on Docker with Clusterdock
HBaseConEast2016: HBase on Docker with ClusterdockHBaseConEast2016: HBase on Docker with Clusterdock
HBaseConEast2016: HBase on Docker with Clusterdock
 
Real time server
Real time serverReal time server
Real time server
 
Failsafe Mechanism for Yahoo Homepage
Failsafe Mechanism for Yahoo HomepageFailsafe Mechanism for Yahoo Homepage
Failsafe Mechanism for Yahoo Homepage
 
REST APIs in Laravel 101
REST APIs in Laravel 101REST APIs in Laravel 101
REST APIs in Laravel 101
 
Server Side? Swift
Server Side? SwiftServer Side? Swift
Server Side? Swift
 
Deploy Rails Application by Capistrano
Deploy Rails Application by CapistranoDeploy Rails Application by Capistrano
Deploy Rails Application by Capistrano
 
Replacing Squid with ATS
Replacing Squid with ATSReplacing Squid with ATS
Replacing Squid with ATS
 

Destaque

4th yr images
4th yr images4th yr images
4th yr images
kaziomer
 
Hubspot Charts Graphs April2010
Hubspot Charts Graphs April2010Hubspot Charts Graphs April2010
Hubspot Charts Graphs April2010
SocialOnline
 
The archived Canadian Competitive Intelligence (CI) by Patent Mapping, August...
The archived Canadian Competitive Intelligence (CI) by Patent Mapping, August...The archived Canadian Competitive Intelligence (CI) by Patent Mapping, August...
The archived Canadian Competitive Intelligence (CI) by Patent Mapping, August...
Muchiu (Henry) Chang, PhD. Cantab
 

Destaque (20)

Rapid-ruby-api-on-grape
Rapid-ruby-api-on-grapeRapid-ruby-api-on-grape
Rapid-ruby-api-on-grape
 
The archived Canadian US Patent Competitive Intelligence Database (2016/6/28)
The archived Canadian US Patent Competitive Intelligence Database (2016/6/28) The archived Canadian US Patent Competitive Intelligence Database (2016/6/28)
The archived Canadian US Patent Competitive Intelligence Database (2016/6/28)
 
Ti
TiTi
Ti
 
The Archived Canadian Patent Competitive Intelligence (January 11, 2011)
The Archived Canadian Patent Competitive Intelligence (January 11, 2011)The Archived Canadian Patent Competitive Intelligence (January 11, 2011)
The Archived Canadian Patent Competitive Intelligence (January 11, 2011)
 
Search Engine Optimisation - Have you been crawled over?
Search Engine Optimisation - Have you been crawled over?Search Engine Optimisation - Have you been crawled over?
Search Engine Optimisation - Have you been crawled over?
 
The archived Canadian US Patent Competitive Intelligence Database (2014/7/22)
The archived Canadian US Patent Competitive Intelligence Database (2014/7/22) The archived Canadian US Patent Competitive Intelligence Database (2014/7/22)
The archived Canadian US Patent Competitive Intelligence Database (2014/7/22)
 
The archived Canadian US Patent Competitive Intelligence Database (2015/8/25)
The archived Canadian US Patent Competitive Intelligence Database (2015/8/25) The archived Canadian US Patent Competitive Intelligence Database (2015/8/25)
The archived Canadian US Patent Competitive Intelligence Database (2015/8/25)
 
A Feast for Your Eyes
A Feast for Your EyesA Feast for Your Eyes
A Feast for Your Eyes
 
4th yr images
4th yr images4th yr images
4th yr images
 
Hubspot Charts Graphs April2010
Hubspot Charts Graphs April2010Hubspot Charts Graphs April2010
Hubspot Charts Graphs April2010
 
Verrex E Portfolio 2011
Verrex E Portfolio 2011Verrex E Portfolio 2011
Verrex E Portfolio 2011
 
The archived Canadian US Patent Competitive Intelligence Database (2016/3/8)
The archived Canadian US Patent Competitive Intelligence Database (2016/3/8) The archived Canadian US Patent Competitive Intelligence Database (2016/3/8)
The archived Canadian US Patent Competitive Intelligence Database (2016/3/8)
 
The Archived Canadian Patent Competitive Intelligence (May 3, 2011)
The Archived Canadian Patent Competitive Intelligence (May 3, 2011)The Archived Canadian Patent Competitive Intelligence (May 3, 2011)
The Archived Canadian Patent Competitive Intelligence (May 3, 2011)
 
Timing-pulse measurement and detector calibration for the OsteoQuant®.
Timing-pulse measurement and detector calibration for the OsteoQuant®.Timing-pulse measurement and detector calibration for the OsteoQuant®.
Timing-pulse measurement and detector calibration for the OsteoQuant®.
 
Ado Net
Ado NetAdo Net
Ado Net
 
The Archived Canadian Patent Competitive Intelligence (2013/10/8)
The Archived Canadian Patent Competitive Intelligence (2013/10/8) The Archived Canadian Patent Competitive Intelligence (2013/10/8)
The Archived Canadian Patent Competitive Intelligence (2013/10/8)
 
The archived Canadian Competitive Intelligence (CI) by Patent Mapping, August...
The archived Canadian Competitive Intelligence (CI) by Patent Mapping, August...The archived Canadian Competitive Intelligence (CI) by Patent Mapping, August...
The archived Canadian Competitive Intelligence (CI) by Patent Mapping, August...
 
The archived Canadian US Patent Competitive Intelligence Database (2015/7/28)
The archived Canadian US Patent Competitive Intelligence Database (2015/7/28) The archived Canadian US Patent Competitive Intelligence Database (2015/7/28)
The archived Canadian US Patent Competitive Intelligence Database (2015/7/28)
 
The archived Canadian US Patent Competitive Intelligence Database (2015/6/9)
The archived Canadian US Patent Competitive Intelligence Database (2015/6/9) The archived Canadian US Patent Competitive Intelligence Database (2015/6/9)
The archived Canadian US Patent Competitive Intelligence Database (2015/6/9)
 
The archived Canadian US Patent Competitive Intelligence Database (2015/8/11)
The archived Canadian US Patent Competitive Intelligence Database (2015/8/11) The archived Canadian US Patent Competitive Intelligence Database (2015/8/11)
The archived Canadian US Patent Competitive Intelligence Database (2015/8/11)
 

Semelhante a Using and scaling Rack and Rack-based middleware

An Introduction to Tornado
An Introduction to TornadoAn Introduction to Tornado
An Introduction to Tornado
Gavin Roy
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Tatsuhiko Miyagawa
 
Scalable network applications, event-driven - Node JS
Scalable network applications, event-driven - Node JSScalable network applications, event-driven - Node JS
Scalable network applications, event-driven - Node JS
Cosmin Mereuta
 
nodejs_at_a_glance.ppt
nodejs_at_a_glance.pptnodejs_at_a_glance.ppt
nodejs_at_a_glance.ppt
WalaSidhom1
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
Yehuda Katz
 
Scalalable Language for a Scalable Web
Scalalable Language for a Scalable WebScalalable Language for a Scalable Web
Scalalable Language for a Scalable Web
Timothy Perrett
 

Semelhante a Using and scaling Rack and Rack-based middleware (20)

Intro to Rack
Intro to RackIntro to Rack
Intro to Rack
 
Ruby MVC from scratch with Rack
Ruby MVC from scratch with RackRuby MVC from scratch with Rack
Ruby MVC from scratch with Rack
 
An Introduction to Tornado
An Introduction to TornadoAn Introduction to Tornado
An Introduction to Tornado
 
Play!ng with scala
Play!ng with scalaPlay!ng with scala
Play!ng with scala
 
Apache and PHP: Why httpd.conf is your new BFF!
Apache and PHP: Why httpd.conf is your new BFF!Apache and PHP: Why httpd.conf is your new BFF!
Apache and PHP: Why httpd.conf is your new BFF!
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Adriano Di Luzio - Davvy - PyconSEI Talk
Adriano Di Luzio - Davvy - PyconSEI TalkAdriano Di Luzio - Davvy - PyconSEI Talk
Adriano Di Luzio - Davvy - PyconSEI Talk
 
Plack at YAPC::NA 2010
Plack at YAPC::NA 2010Plack at YAPC::NA 2010
Plack at YAPC::NA 2010
 
Rich Portlet Development in uPortal
Rich Portlet Development in uPortalRich Portlet Development in uPortal
Rich Portlet Development in uPortal
 
Scalable network applications, event-driven - Node JS
Scalable network applications, event-driven - Node JSScalable network applications, event-driven - Node JS
Scalable network applications, event-driven - Node JS
 
nodejs_at_a_glance.ppt
nodejs_at_a_glance.pptnodejs_at_a_glance.ppt
nodejs_at_a_glance.ppt
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Play Framework: async I/O with Java and Scala
Play Framework: async I/O with Java and ScalaPlay Framework: async I/O with Java and Scala
Play Framework: async I/O with Java and Scala
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
 
Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014
 
Express Presentation
Express PresentationExpress Presentation
Express Presentation
 
Scalalable Language for a Scalable Web
Scalalable Language for a Scalable WebScalalable Language for a Scalable Web
Scalalable Language for a Scalable Web
 
Supercharging WordPress Development in 2018
Supercharging WordPress Development in 2018Supercharging WordPress Development in 2018
Supercharging WordPress Development in 2018
 
Universal JavaScript
Universal JavaScriptUniversal JavaScript
Universal JavaScript
 

Último

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 

Último (20)

The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 

Using and scaling Rack and Rack-based middleware

  • 1. Using and scaling Rack and Rack-based middleware
  • 2. Alona Mekhovova Ruby/Rails developer & co-founder @ RubyGarage Organizer & coach @ RailsGirls Ruby on Rails courses leading Involved in growing Ruby Community in Dnipro Monthly Rails MeetUps organizer skype: alony_ alony@rubygarage.org
  • 3. Overview Why do we need Rack? Simple Rack app & own middleware Available middleware overview Plugging middleware into Rails What’s next?
  • 4.
  • 7. the http protocol request => response stateless
  • 8. request: response: Request method, URI, Protocol version, protocol version status code, its desc Request headers Response headers Request body Response body
  • 9. http from a bird’s eye view REQUEST RESPONSE
  • 10. Request structure {"HTTP_USER_AGENT"=>"curl/7.12.2 ..." Classically, a "REMOTE_HOST"=>"127.0.0.1", CGI "PATH_INFO"=>"/", "HTTP_HOST"=>"ruby-lang.org", environment "SERVER_PROTOCOL"=>"HTTP/1.1", "SCRIPT_NAME"=>"", "REQUEST_PATH"=>"/", Most "REMOTE_ADDR"=>"127.0.0.1", frameworks "HTTP_VERSION"=>"HTTP/1.1", "REQUEST_URI"=>"http://ruby-lang.org/", already use "SERVER_PORT"=>"80", smth like that, "HTTP_PRAGMA"=>"no-cache", most developers "QUERY_STRING"=>"", "GATEWAY_INTERFACE"=>"CGI/1.1", know the fields "HTTP_ACCEPT"=>"*/*", "REQUEST_METHOD"=>"GET"} Let’s keep it
  • 11. Response structure Status HTTP/1.1 302 Found Date: Sat, 27 Oct 2007 10:07:53 GMT Server: Apache/2.0.54 (Debian GNU/Linux) mod_ssl/2.0.54 OpenSSL0.9.7e Headers Location: http://www.ruby-lang.org/ Content-Length: 209 Content-Type: text/html; charset=iso-8859-1 Body <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>302 Found</title> </head><body> <h1>Found</h1> <p>The document has moved <a href="http://www.ruby-lang.org/">here</a> </p> </body></html>
  • 12. Response in Ruby Status HTTP/1.1 302 Found Integer Date: Sat, 27 Oct 2007 10:07:53 GMT Server: Apache/2.0.54 (Debian GNU/Linux) mod_ssl/2.0.54 OpenSSL0.9.7e Headers Location: http://www.ruby-lang.org/ Content-Length: 209 Hash Content-Type: text/html; charset=iso-8859-1 Body <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> Array <html><head> <title>302 Found</title> </head><body> <h1>Found</h1> <p>The document has moved <a href="http://www.ruby-lang.org/">here</a> </p> </body></html>
  • 13. Response in Ruby Environment Status lambda { |env|     [        200,        {"Content-Type"=>"text/plain"},        ["Hello, Rack!"]      ]    } Headers Body
  • 14. Summarizing The Rack app gets called with the CGI environment... ...and returns an Array of status, header & body
  • 15. ...and again HTTP SERVER YOUR FANCY APP
  • 16. Simplest Rack app run Proc.new { |env|     [        200,        {"Content-Type"=>"text/plain"},        ["Hello, Rack!"]      ]    }
  • 17. rackup # config.ru class Awesome def call(env) [200, {'Content-Type' => 'text/plain'}, 'AWESOME.'] end end run Awesome.new # console rackup config.ru
  • 18. Rack::Builder app = Rack::Builder.app do   map '/awesome' do     run Awesome   end      map '/' do     run Proc{ 404, {"Content-Type" => "text/html"}, ['awesome requests only'] }   end end run app
  • 19. Rack::Builder Rack::Builder.new do   use Rack::CommonLogger   use Rack::ShowExceptions   use Rack::ShowStatus   use Rack::Lint   run MyRackApp.new end
  • 20. Middleware HTTP HTTP Middleware1 Middleware Middleware2 Rack Rack application application Rack application
  • 21. Home-made middleware class JSMinifier      def initialize(app, path)     @app, @root = app, File.expand_path(path)   end   def call(env)     path = File.join(@root, Utils.unescape(env["PATH_INFO"]))     return @app.call(env) unless path.match(/.*/(w+.js)$/)       if !File.readable?(path) or env["PATH_INFO"].include?("..")       return [403, {"Content-Type" => "text/plain"}, ["Forbiddenn"]]     end     return [ 200,        { "Content-Type" => "text/javascript" },        [JSMin.minify( File.new( path, "r" ) )]      ]   end end
  • 22. Home-made middleware class JSMinifier      def initialize(app, path)     @app, @root = app, File.expand_path(path)   end   def call(env)     path = File.join(@root, Utils.unescape(env["PATH_INFO"]))     return @app.call(env) unless path.match(/.*/(w+.js)$/)       if !File.readable?(path) or env["PATH_INFO"].include?("..")       return [403, {"Content-Type" => "text/plain"}, ["Forbiddenn"]]     end     return [ 200,        { "Content-Type" => "text/javascript" },        [JSMin.minify( File.new( path, "r" ) )]      ]   end end
  • 23. Home-made middleware class JSMinifier      def initialize(app, path)     @app, @root = app, File.expand_path(path)   end   def call(env)     path = File.join(@root, Utils.unescape(env["PATH_INFO"]))     return @app.call(env) unless path.match(/.*/(w+.js)$/)       if !File.readable?(path) or env["PATH_INFO"].include?("..")       return [403, {"Content-Type" => "text/plain"}, ["Forbiddenn"]]     end     return [ 200,        { "Content-Type" => "text/javascript" },        [JSMin.minify( File.new( path, "r" ) )]      ]   end end
  • 32. env['warden'].authenticated? env['warden'].authenticate!(:password) env['warden'].user Warden::Strategies.add(:password) do   def valid?     params[:username] || params[:password]   end   def authenticate!     u = User.authenticate(params[:username], params[:password])     u.nil? ? fail!("Could not log in") : success! (u)   end end Warden
  • 33. ... and lots of others Rack::Static Rack::CSSHTTPRequest Rack::noIE Rack::GoogleAnalytics Rack::Profiler Rack::Maintenance Rack::Lock Rack::Spellcheck Rack::Log Rack::Pack Rack::Validate https://github.com/rack/rack/wiki/List-of-Middleware http://coderack.org/middlewares
  • 34. Plug it into Rails stack $ rake middleware use ActionDispatch::Static use Rack::Lock use ActiveSupport::Cache::Strategy::LocalCache use Rack::Runtime use Rails::Rack::Logger use ActionDispatch::ShowExceptions use ActionDispatch::DebugExceptions use ActionDispatch::RemoteIp use Rack::Sendfile use ActionDispatch::Callbacks use ActiveRecord::ConnectionAdapters::ConnectionManagement use ActiveRecord::QueryCache ... use Rack::MethodOverride use ActionDispatch::Head use ActionDispatch::BestStandardsSupport run MyApp::Application.routes
  • 35. Configure middleware stack Rails::Initializer.run do |config|   config.middleware.use Rack::MailExceptions   config.middleware.delete Rack::Lock   config.middleware.insert_after Rack::Sendfile, Rack::Static   config.middleware.insert_before Rack::Head, Ben::Asplode   config.middleware.swap ActionDispatch::Callbacks, ActiveRecord::QueryCache end config.middleware.is_a? Array # => true
  • 36. ...or replace it # config/initializers/stack.rb ActionController::Dispatcher.middleware = ActionController::MiddlewareStack.new do |m|    m.use ActionController::Failsafe    m.use ActiveRecord::QueryCache    m.use Rack::Head end # console $ rake middleware use ActionController::Failsafe use ActiveRecord::QueryCache use Rack::Head run ActionController::Dispatcher.new
  • 37. The future Rails 4 will have an API only middleware stack configuration RocketPants is an interesting alternative right now (github.com/filtersquad/rocket_pants)

Notas do Editor

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n