SlideShare une entreprise Scribd logo
1  sur  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!

Contenu connexe

Tendances

Tendances (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
 

En vedette

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
 

En vedette (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)
 

Similaire à 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
 

Similaire à 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
 

Dernier

Dernier (20)

2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
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...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
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?
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 

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)

Notes de l'éditeur

  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