Upload
hussein-morsy
View
2.266
Download
0
Embed Size (px)
DESCRIPTION
Einführung in Rack und Rack-MiddlewareVortrag wurde am 24.11.2009 an der Heinrich-Heine-Universität Düsseldorf im Rahmen der Rails User Group Düsseldorf von Hussein Morsy gehalten
Citation preview
Werde ein Rackstarmit
Rack MiddlewareHussein Morsy
24.11.2009Heinrich-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 eineRack-Middleware
erstellt ?
Was ist Rack ?
Billy !
Das Fundament von Ruby basierten
Webapplikationen
Ruby-Webframeworks
Rails
Merb
SinatraRamaze Rack
HTTP HTTP
CGI/FCGI LiteSpeed Mongrel
Webclients
HTTP
Webserver
WebappsWebbapp
mitRuby On Rails
Webbappmit
Merb
Webbappmit
Sinatra
Rack
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"] endend
Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292
Rack-Applikation
Rack-Applikation
env
[200, {"Content-Type" => "text/html"}, "Hallo Welt"]
[ HTTP-Status-Code, R-Header, R-Body]
Request
Response
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 endend
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 endend
Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292
Herzlich Willkommen Geh weg
Geh weg
• 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)
• ...
env
Rack-Request Objekt
request = Rack::Request.new(env)request.path_inforequest.request_methodrequest.query_stringrequest.http_user_agent
env['PATH_INFO']env['REQUEST_METHOD']env['QUERY_STRING']env['HTTP_USER_AGENT']
• Rails
• Merb
• Sinatra
• Ramaze
• ....
Rack basiert
Warum sich mit Rack beschäftigen ?
Um einen eigenen Webframeworkzu entwickeln ?
Verwendung und Programmierung
vonRack-Middleware
PlugIns fürRack-Applikationen
• 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.
Rack-Middleware
Rack-Middleware A
envRequest
Response
Rack-Middleware B
[ HTTP-Status-Code, R-Header, R-Body]
Rack-Middleware C
Rack-Applikation (z.B. Rails)
Response
Middleware
Middleware
Middleware
Middleware
Middleware
Middleware
Rack Middleware Bsp 1
class Downcase def initialize(app) @app = app end def call(env) status, headers, response = @app.call(env) [status, headers, response.body.downcase] endend
Alles in Kleinbuchstaben
Rack Middleware Bsp 2
class ResponseTimer def initialize(app) @app = app end def call(env) status, headers, response = @app.call(env) [status, headers, "<!-- Programmiert von ... !>" + response.body] endend
Kommentar am Anfang setzen
Rack Middleware Bsp 3
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)] endend
Ersetzung von Zeichenketten
Rack Middleware Bsp 3
# http://coderack.org/users/techiferous/entries/84-racklockdownclass 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
Deaktivierung von POST, PUT, DELETE
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 Rails1. Rack-Middlewares (z.B.) ins lib-Verzeichnis
2. Middleware in environment.rb aktivieren# lib/downcase.rbclass Downcase def initialize(app) @app = app end def call(env) status, headers, response = @app.call(env) [status, headers, response.body.downcase] endend
# config/environment.rb Rails::Initializer.run do |config| config.middleware.use "Downcase" # ... end
rack middlewarerake middleware
use Rack::Lockuse ActionController::Failsafeuse ActionController::Session::CookieStore, #<Proc:0x000000010212e348@(eval):8>use ActionController::ParamsParseruse Rack::MethodOverrideuse Rack::Headuse Commentuse Downcaseuse NewPhoneuse ActiveRecord::ConnectionAdapters::ConnectionManagementuse ActiveRecord::QueryCacherun ActionController::Dispatcher.new
twitter.com/husseinmorsy