36
Werde ein Rackstar mit Rack Middleware Hussein Morsy 24.11.2009 Heinrich-Heine-Universität Düsseldorf Rails User Group Düsseldorf

Rack-Middleware

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

Page 1: Rack-Middleware

Werde ein Rackstarmit

Rack MiddlewareHussein Morsy

24.11.2009Heinrich-Heine-Universität Düsseldorf

Rails User Group Düsseldorf

Page 2: Rack-Middleware

SalesLentz::DevTeam

Page 3: Rack-Middleware

Ü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

Page 4: Rack-Middleware

Wer hat schon mal eineRack-Middleware

erstellt ?

Page 5: Rack-Middleware

Was ist Rack ?

Page 6: Rack-Middleware

Billy !

Page 7: Rack-Middleware

Das Fundament von Ruby basierten

Webapplikationen

Page 8: Rack-Middleware

Ruby-Webframeworks

Rails

Merb

SinatraRamaze Rack

Page 9: Rack-Middleware

HTTP HTTP

CGI/FCGI LiteSpeed Mongrel

Webclients

HTTP

Webserver

WebappsWebbapp

mitRuby On Rails

Webbappmit

Merb

Webbappmit

Sinatra

Rack

Page 10: Rack-Middleware

Rack ist ...

• eine Spezifikation

• Standardisierung von Ruby-Webapps (HTTP)

• ein Gem

• Grundlage von Ruby-Webframeworks

Page 11: Rack-Middleware

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

Page 12: Rack-Middleware

Rack-Applikation

Rack-Applikation

env

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

[ HTTP-Status-Code, R-Header, R-Body]

Request

Response

Page 13: Rack-Middleware

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

Page 14: Rack-Middleware

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

Page 15: Rack-Middleware

• 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

Page 16: Rack-Middleware

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']

Page 17: Rack-Middleware

• Rails

• Merb

• Sinatra

• Ramaze

• ....

Rack basiert

Page 18: Rack-Middleware

Warum sich mit Rack beschäftigen ?

Page 19: Rack-Middleware

Um einen eigenen Webframeworkzu entwickeln ?

Page 20: Rack-Middleware

Verwendung und Programmierung

vonRack-Middleware

Page 21: Rack-Middleware

PlugIns fürRack-Applikationen

Page 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.

Rack-Middleware

Page 23: 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

Page 24: Rack-Middleware

Middleware

Middleware

Middleware

Middleware

Middleware

Middleware

Page 25: Rack-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

Page 26: Rack-Middleware

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

Page 27: Rack-Middleware

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

Page 28: Rack-Middleware

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

Page 29: Rack-Middleware

Nützliche Middlewares

• Refraction:

mod_rewrite

• rack-bug

Debugging Toolbar

• api-throttling: Anzahl

Zugriffe beschränken

• siehe auch coderack.org, github

Page 30: Rack-Middleware

coderack.org

Page 31: Rack-Middleware

Wie kann man die Middlewares zusammen

setzen ?

Page 32: Rack-Middleware

Rack::Builder

Page 33: Rack-Middleware

oder einfach in Rails

Page 34: Rack-Middleware

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

Page 35: Rack-Middleware

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

Page 36: Rack-Middleware

Twitter

twitter.com/husseinmorsy