SlideShare ist ein Scribd-Unternehmen logo
Werde ein Rackstar
       mit
 Rack Middleware
            Hussein Morsy

              24.11.2009
 Heinrich-Heine-Universität Düsseldorf
     Rails User Group Düsseldorf
SalesLentz::DevTeam
Über uns

• internes Entwicklerteam von Sales-Lentz
• IBEs für Reisen, Bustickets, Eventtickets
• seit 2006 entwickeln wir mit Ruby on Rails
• Buch Ruby on Rails 2 Galileo Press
  http://www.railsbuch.de
Wer hat schon mal eine
     Rack-Middleware
              erstellt ?
Was ist Rack ?
Billy !
Das Fundament von
  Ruby basierten
 Webapplikationen
Ruby-Webframeworks

           Rails



  Ramaze   Rack    Sinatra




           Merb
Webbapp       Webbapp   Webbapp
Webapps           mit          mit        mit
             Ruby On Rails    Merb      Sinatra

  Rack          CGI/FCGI LiteSpeed     Mongrel


Webserver




                    HTTP       HTTP    HTTP

Webclients
Rack ist ...

• eine Spezifikation
• Standardisierung von Ruby-Webapps
  (HTTP)
• ein Gem
• Grundlage von Ruby-Webframeworks
Rack-Hello World
•   require 'rubygems'
    require 'rack'

    class HelloWorld
      def call(env)
        [200, {"Content-Type" => "text/html"}, "Hallo Welt"]
      end
    end

    Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292
Rack-Applikation
                        env
                            Request



                   Rack-Applikation

                            Response


[200, {"Content-Type" => "text/html"}, "Hallo Welt"]

    [ HTTP-Status-Code, R-Header, R-Body]
require 'rubygems'
require 'rack'

class HelloWorld
  def call(env)
    if env['PATH_INFO'] == '/'
      [200, {"Content-Type" => "text/html"}, "Hallo Homepage"]
    elsif env['PATH_INFO'] == '/impressum'
      [200, {"Content-Type" => "text/html"}, "© by Hussein
Morsy"]
    else
      [404, {"Content-Type" => "text/html"}, "Seite nicht gefunden"]
    end
  end
end

Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292
require 'rubygems'
require 'rack'

class HelloWorld
  def call(env)
    if env['HTTP_USER_AGENT'] =~ /Mac OS X/
      [200, {"Content-Type" => "text/html"}, "Herzlich Willkommen"]
    else
      [500, {"Content-Type" => "text/html"}, "Geh weg"]
    end
  end
end

Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292




  Herzlich Willkommen                    Geh weg
                                   Geh weg
env
• PATH_INFO ( /impressum)
• REQUEST_METHOD (get, post, put,...)
• QUERY_STRING (id=5)
• HTTP_*
 • HTTP_USER_AGENT (Mozilla/5.0 ...)
 • HTTP_REMOTE_IP (192.198.1.54)
 • ...
Rack-Request Objekt

env['PATH_INFO']
env['REQUEST_METHOD']
env['QUERY_STRING']
env['HTTP_USER_AGENT']




request = Rack::Request.new(env)
request.path_info
request.request_method
request.query_string
request.http_user_agent
Rack basiert

• Rails
• Merb
• Sinatra
• Ramaze
• ....
Warum sich mit Rack
  beschäftigen ?
Um einen eigenen
 Webframework
 zu entwickeln ?
Verwendung und
Programmierung
      von
Rack-Middleware
PlugIns für
Rack-Applikationen
Rack-Middleware
• Rack-Middleware ist eine Rack-Applikation
  mit besonderen anforderungen
• Eine Rack-Middleware ist eine Filter, mit
  der Request und der Response verändert
  werden kann
• Mehrere Rack-Middleware können
  hintereinander geschaltet werden.
env
                     Request


    Rack-Middleware A
  [ HTTP-Status-Code, R-Header, R-Body]

                     Response



    Rack-Middleware B

                     Response


    Rack-Middleware C



Rack-Applikation (z.B. Rails)
Middleware

Middleware

Middleware

Middleware

Middleware

Middleware
Rack Middleware Bsp 1
                  Alles in Kleinbuchstaben
class Downcase
  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, response = @app.call(env)
    [status, headers, response.body.downcase]
  end
end
Rack Middleware Bsp 2
             Kommentar am Anfang setzen
class ResponseTimer
  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, response = @app.call(env)
    [status, headers, "<!-- Programmiert von ... !>" + response.body]
  end
end
Rack Middleware Bsp 3
              Ersetzung von Zeichenketten
class NewPhone
  def initialize(app)
    @app = app
  end

  def call(env)
    old = "0211 456"
    new = "0211 789"
    status, headers, response = @app.call(env)
    [status, headers, response.body.gsub(old,new)]
  end
end
Rack Middleware Bsp 3
       Deaktivierung von POST, PUT, DELETE
# http://coderack.org/users/techiferous/entries/84-racklockdown
class Lockdown

 def initialize(app)
   @app = app
 end

 def call(env)
   request = Rack::Request.new(env)
   if ["GET", "HEAD"].include?(request.request_method)
     @app.call(env)
   else
     message = "That action is currently not supported."
     message << " We apologize for any inconvenience."
     [405, {"Content-Type" => "text/html"}, message]
   end
 end

end
Nützliche Middlewares
• Refraction:
   mod_rewrite
• rack-bug
   Debugging Toolbar
• api-throttling: Anzahl
  Zugriffe beschränken
• siehe auch coderack.org,   github
coderack.org
Wie kann man die
Middlewares zusammen
       setzen ?
Rack::Builder
oder einfach in Rails
Middleware in Rails
    1. Rack-Middlewares (z.B.) ins lib-Verzeichnis
    2. Middleware in environment.rb aktivieren
# lib/downcase.rb
class Downcase
  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, response = @app.call(env)
    [status, headers, response.body.downcase]
  end
end

# config/environment.rb
Rails::Initializer.run do |config|
  config.middleware.use "Downcase"
   # ...
end
rack middleware
rake middleware

use Rack::Lock
use ActionController::Failsafe
use ActionController::Session::CookieStore, #<Proc:
0x000000010212e348@(eval):8>
use ActionController::ParamsParser
use Rack::MethodOverride
use Rack::Head
use Comment
use Downcase
use NewPhone
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
run ActionController::Dispatcher.new
Twitter


twitter.com/husseinmorsy

Weitere ähnliche Inhalte

Andere mochten auch

Agile Softwareentwicklung mit Rails
Agile Softwareentwicklung mit RailsAgile Softwareentwicklung mit Rails
Agile Softwareentwicklung mit Rails
Hussein Morsy
 
Homebrew
HomebrewHomebrew
Homebrew
Hussein Morsy
 
Rubymotion trip to inspect 2013
Rubymotion trip to inspect 2013Rubymotion trip to inspect 2013
Rubymotion trip to inspect 2013
Hussein Morsy
 
Unobtrusive JavaScript in Rails 3
Unobtrusive JavaScript in Rails 3Unobtrusive JavaScript in Rails 3
Unobtrusive JavaScript in Rails 3
Hussein Morsy
 
Einführung in Cucumber mit Rails
Einführung in Cucumber mit RailsEinführung in Cucumber mit Rails
Einführung in Cucumber mit Rails
Hussein Morsy
 
Datamapper Railskonferenz 2009
Datamapper Railskonferenz 2009Datamapper Railskonferenz 2009
Datamapper Railskonferenz 2009
Hussein Morsy
 
How to Battle Bad Reviews
How to Battle Bad ReviewsHow to Battle Bad Reviews
How to Battle Bad Reviews
Glassdoor
 
Test Video
Test VideoTest Video
Test Video
jivanoff
 
Activism x Technology
Activism x TechnologyActivism x Technology
Activism x Technology
WebVisions
 

Andere mochten auch (9)

Agile Softwareentwicklung mit Rails
Agile Softwareentwicklung mit RailsAgile Softwareentwicklung mit Rails
Agile Softwareentwicklung mit Rails
 
Homebrew
HomebrewHomebrew
Homebrew
 
Rubymotion trip to inspect 2013
Rubymotion trip to inspect 2013Rubymotion trip to inspect 2013
Rubymotion trip to inspect 2013
 
Unobtrusive JavaScript in Rails 3
Unobtrusive JavaScript in Rails 3Unobtrusive JavaScript in Rails 3
Unobtrusive JavaScript in Rails 3
 
Einführung in Cucumber mit Rails
Einführung in Cucumber mit RailsEinführung in Cucumber mit Rails
Einführung in Cucumber mit Rails
 
Datamapper Railskonferenz 2009
Datamapper Railskonferenz 2009Datamapper Railskonferenz 2009
Datamapper Railskonferenz 2009
 
How to Battle Bad Reviews
How to Battle Bad ReviewsHow to Battle Bad Reviews
How to Battle Bad Reviews
 
Test Video
Test VideoTest Video
Test Video
 
Activism x Technology
Activism x TechnologyActivism x Technology
Activism x Technology
 

Ähnlich wie Rack-Middleware

Microservices mit Rust
Microservices mit RustMicroservices mit Rust
Microservices mit Rust
Jens Siebert
 
Backend-Services mit Rust
Backend-Services mit RustBackend-Services mit Rust
Backend-Services mit Rust
Jens Siebert
 
Javascript auf Client und Server mit node.js - webtech 2010
Javascript auf Client und Server mit node.js - webtech 2010Javascript auf Client und Server mit node.js - webtech 2010
Javascript auf Client und Server mit node.js - webtech 2010
Dirk Ginader
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-Patterns
Josef Adersberger
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-Patterns
QAware GmbH
 
Ruby On Rails Einführung
Ruby On Rails EinführungRuby On Rails Einführung
Ruby On Rails Einführung
Reinhold Weber
 
HTML5 und node.js Grundlagen
HTML5 und node.js GrundlagenHTML5 und node.js Grundlagen
HTML5 und node.js Grundlagen
Mayflower GmbH
 
Node.js
Node.jsNode.js
Ist GraphQL das bessere REST
Ist GraphQL das bessere RESTIst GraphQL das bessere REST
Ist GraphQL das bessere REST
Martin Abraham
 
OSDC 2013 | Enterprise open source virtualization with oVirt and RHEV by René...
OSDC 2013 | Enterprise open source virtualization with oVirt and RHEV by René...OSDC 2013 | Enterprise open source virtualization with oVirt and RHEV by René...
OSDC 2013 | Enterprise open source virtualization with oVirt and RHEV by René...
NETWAYS
 
Webapplikationen mit Node.js
Webapplikationen mit Node.jsWebapplikationen mit Node.js
Webapplikationen mit Node.js
Sebastian Springer
 
Rails in Production - telewebber Architektur
Rails in Production - telewebber ArchitekturRails in Production - telewebber Architektur
Rails in Production - telewebber Architektur
Heiko Seebach
 
Rhomobile
RhomobileRhomobile
Rhomobile
Jan Ow
 
Fanstatic pycon.de 2012
Fanstatic pycon.de 2012Fanstatic pycon.de 2012
Fanstatic pycon.de 2012
Daniel Havlik
 
Helm introduction
Helm introductionHelm introduction
Helm introduction
Marc Müller
 
Einführung in Helm - der Paket-Manger für Kubernetes
Einführung in Helm - der Paket-Manger für KubernetesEinführung in Helm - der Paket-Manger für Kubernetes
Einführung in Helm - der Paket-Manger für Kubernetes
Marc Müller
 
Automatisierte Linux Administration mit (R)?ex
Automatisierte Linux Administration mit (R)?ex Automatisierte Linux Administration mit (R)?ex
Automatisierte Linux Administration mit (R)?ex
Jan Gehring
 

Ähnlich wie Rack-Middleware (20)

Microservices mit Rust
Microservices mit RustMicroservices mit Rust
Microservices mit Rust
 
Backend-Services mit Rust
Backend-Services mit RustBackend-Services mit Rust
Backend-Services mit Rust
 
Javascript auf Client und Server mit node.js - webtech 2010
Javascript auf Client und Server mit node.js - webtech 2010Javascript auf Client und Server mit node.js - webtech 2010
Javascript auf Client und Server mit node.js - webtech 2010
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-Patterns
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-Patterns
 
Ruby On Rails Einführung
Ruby On Rails EinführungRuby On Rails Einführung
Ruby On Rails Einführung
 
HTML5 und node.js Grundlagen
HTML5 und node.js GrundlagenHTML5 und node.js Grundlagen
HTML5 und node.js Grundlagen
 
Node.js
Node.jsNode.js
Node.js
 
Hdc2012 cordova-präsi
Hdc2012 cordova-präsiHdc2012 cordova-präsi
Hdc2012 cordova-präsi
 
PHP Sucks?!
PHP Sucks?!PHP Sucks?!
PHP Sucks?!
 
Ist GraphQL das bessere REST
Ist GraphQL das bessere RESTIst GraphQL das bessere REST
Ist GraphQL das bessere REST
 
Ruby on Rails SS09 04
Ruby on Rails SS09 04Ruby on Rails SS09 04
Ruby on Rails SS09 04
 
OSDC 2013 | Enterprise open source virtualization with oVirt and RHEV by René...
OSDC 2013 | Enterprise open source virtualization with oVirt and RHEV by René...OSDC 2013 | Enterprise open source virtualization with oVirt and RHEV by René...
OSDC 2013 | Enterprise open source virtualization with oVirt and RHEV by René...
 
Webapplikationen mit Node.js
Webapplikationen mit Node.jsWebapplikationen mit Node.js
Webapplikationen mit Node.js
 
Rails in Production - telewebber Architektur
Rails in Production - telewebber ArchitekturRails in Production - telewebber Architektur
Rails in Production - telewebber Architektur
 
Rhomobile
RhomobileRhomobile
Rhomobile
 
Fanstatic pycon.de 2012
Fanstatic pycon.de 2012Fanstatic pycon.de 2012
Fanstatic pycon.de 2012
 
Helm introduction
Helm introductionHelm introduction
Helm introduction
 
Einführung in Helm - der Paket-Manger für Kubernetes
Einführung in Helm - der Paket-Manger für KubernetesEinführung in Helm - der Paket-Manger für Kubernetes
Einführung in Helm - der Paket-Manger für Kubernetes
 
Automatisierte Linux Administration mit (R)?ex
Automatisierte Linux Administration mit (R)?ex Automatisierte Linux Administration mit (R)?ex
Automatisierte Linux Administration mit (R)?ex
 

Rack-Middleware

  • 1. Werde ein Rackstar mit Rack Middleware Hussein Morsy 24.11.2009 Heinrich-Heine-Universität Düsseldorf Rails User Group Düsseldorf
  • 3. Über uns • internes Entwicklerteam von Sales-Lentz • IBEs für Reisen, Bustickets, Eventtickets • seit 2006 entwickeln wir mit Ruby on Rails • Buch Ruby on Rails 2 Galileo Press http://www.railsbuch.de
  • 4. Wer hat schon mal eine Rack-Middleware erstellt ?
  • 7. Das Fundament von Ruby basierten Webapplikationen
  • 8. Ruby-Webframeworks Rails Ramaze Rack Sinatra Merb
  • 9. Webbapp Webbapp Webbapp Webapps mit mit mit Ruby On Rails Merb Sinatra Rack CGI/FCGI LiteSpeed Mongrel Webserver HTTP HTTP HTTP Webclients
  • 10. Rack ist ... • eine Spezifikation • Standardisierung von Ruby-Webapps (HTTP) • ein Gem • Grundlage von Ruby-Webframeworks
  • 11. Rack-Hello World • require 'rubygems' require 'rack' class HelloWorld def call(env) [200, {"Content-Type" => "text/html"}, "Hallo Welt"] end end Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292
  • 12. Rack-Applikation env Request Rack-Applikation Response [200, {"Content-Type" => "text/html"}, "Hallo Welt"] [ HTTP-Status-Code, R-Header, R-Body]
  • 13. require 'rubygems' require 'rack' class HelloWorld def call(env) if env['PATH_INFO'] == '/' [200, {"Content-Type" => "text/html"}, "Hallo Homepage"] elsif env['PATH_INFO'] == '/impressum' [200, {"Content-Type" => "text/html"}, "&copy; by Hussein Morsy"] else [404, {"Content-Type" => "text/html"}, "Seite nicht gefunden"] end end end Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292
  • 14. require 'rubygems' require 'rack' class HelloWorld def call(env) if env['HTTP_USER_AGENT'] =~ /Mac OS X/ [200, {"Content-Type" => "text/html"}, "Herzlich Willkommen"] else [500, {"Content-Type" => "text/html"}, "Geh weg"] end end end Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292 Herzlich Willkommen Geh weg Geh weg
  • 15. env • PATH_INFO ( /impressum) • REQUEST_METHOD (get, post, put,...) • QUERY_STRING (id=5) • HTTP_* • HTTP_USER_AGENT (Mozilla/5.0 ...) • HTTP_REMOTE_IP (192.198.1.54) • ...
  • 16. Rack-Request Objekt env['PATH_INFO'] env['REQUEST_METHOD'] env['QUERY_STRING'] env['HTTP_USER_AGENT'] request = Rack::Request.new(env) request.path_info request.request_method request.query_string request.http_user_agent
  • 17. Rack basiert • Rails • Merb • Sinatra • Ramaze • ....
  • 18. Warum sich mit Rack beschäftigen ?
  • 19. Um einen eigenen Webframework zu entwickeln ?
  • 20. Verwendung und Programmierung von Rack-Middleware
  • 22. Rack-Middleware • Rack-Middleware ist eine Rack-Applikation mit besonderen anforderungen • Eine Rack-Middleware ist eine Filter, mit der Request und der Response verändert werden kann • Mehrere Rack-Middleware können hintereinander geschaltet werden.
  • 23. env Request Rack-Middleware A [ HTTP-Status-Code, R-Header, R-Body] Response Rack-Middleware B Response Rack-Middleware C Rack-Applikation (z.B. Rails)
  • 25. Rack Middleware Bsp 1 Alles in Kleinbuchstaben class Downcase def initialize(app) @app = app end def call(env) status, headers, response = @app.call(env) [status, headers, response.body.downcase] end end
  • 26. Rack Middleware Bsp 2 Kommentar am Anfang setzen class ResponseTimer def initialize(app) @app = app end def call(env) status, headers, response = @app.call(env) [status, headers, "<!-- Programmiert von ... !>" + response.body] end end
  • 27. Rack Middleware Bsp 3 Ersetzung von Zeichenketten class NewPhone def initialize(app) @app = app end def call(env) old = "0211 456" new = "0211 789" status, headers, response = @app.call(env) [status, headers, response.body.gsub(old,new)] end end
  • 28. Rack Middleware Bsp 3 Deaktivierung von POST, PUT, DELETE # http://coderack.org/users/techiferous/entries/84-racklockdown class Lockdown def initialize(app) @app = app end def call(env) request = Rack::Request.new(env) if ["GET", "HEAD"].include?(request.request_method) @app.call(env) else message = "That action is currently not supported." message << " We apologize for any inconvenience." [405, {"Content-Type" => "text/html"}, message] end end end
  • 29. Nützliche Middlewares • Refraction: mod_rewrite • rack-bug Debugging Toolbar • api-throttling: Anzahl Zugriffe beschränken • siehe auch coderack.org, github
  • 31. Wie kann man die Middlewares zusammen setzen ?
  • 34. Middleware in Rails 1. Rack-Middlewares (z.B.) ins lib-Verzeichnis 2. Middleware in environment.rb aktivieren # lib/downcase.rb class Downcase def initialize(app) @app = app end def call(env) status, headers, response = @app.call(env) [status, headers, response.body.downcase] end end # config/environment.rb Rails::Initializer.run do |config| config.middleware.use "Downcase" # ... end
  • 35. rack middleware rake middleware use Rack::Lock use ActionController::Failsafe use ActionController::Session::CookieStore, #<Proc: 0x000000010212e348@(eval):8> use ActionController::ParamsParser use Rack::MethodOverride use Rack::Head use Comment use Downcase use NewPhone use ActiveRecord::ConnectionAdapters::ConnectionManagement use ActiveRecord::QueryCache run ActionController::Dispatcher.new