SlideShare ist ein Scribd-Unternehmen logo
1 von 69
Rack Middleware
     David Dollar
What is Rack?
A Rack application is a Ruby object that responds to call.

       It takes exactly one argument, the environment.

         It returns an Array of exactly three values:
            The status, the headers, and the body.

The headers should respond to each and yield key/value pairs.

 The body should respond to each and yield String objects.
lambda do |environment|
  [ 200, { 'Content-Type' => 'text/plain' }, [ 'OK' ] ]
end


      A Rack application is a Ruby object that responds to call.

          It takes exactly one argument, the environment.

             It returns an Array of exactly three values:
                The status, the headers, and the body.

   The headers should respond to each and yield key/value pairs.

     The body should respond to each and yield String objects.
lambda do |environment|
  [ 200, { 'Content-Type' => 'text/plain' }, [ 'OK' ] ]
end


      A Rack application is a Ruby object that responds to call.

          It takes exactly one argument, the environment.

             It returns an Array of exactly three values:
                The status, the headers, and the body.

   The headers should respond to each and yield key/value pairs.

     The body should respond to each and yield String objects.
lambda do |environment|
  [ 200, { 'Content-Type' => 'text/plain' }, [ 'OK' ] ]
end


      A Rack application is a Ruby object that responds to call.

          It takes exactly one argument, the environment.

             It returns an Array of exactly three values:
                The status, the headers, and the body.

   The headers should respond to each and yield key/value pairs.

     The body should respond to each and yield String objects.
lambda do |environment|
  [ 200, { 'Content-Type' => 'text/plain' }, [ 'OK' ] ]
end


      A Rack application is a Ruby object that responds to call.

          It takes exactly one argument, the environment.

             It returns an Array of exactly three values:
                The status, the headers, and the body.

   The headers should respond to each and yield key/value pairs.

     The body should respond to each and yield String objects.
lambda do |environment|
  [ 200, { 'Content-Type' => 'text/plain' }, [ 'OK' ] ]
end


      A Rack application is a Ruby object that responds to call.

          It takes exactly one argument, the environment.

             It returns an Array of exactly three values:
                The status, the headers, and the body.

   The headers should respond to each and yield key/value pairs.

     The body should respond to each and yield String objects.
lambda do |environment|
  [ 200, { 'Content-Type' => 'text/plain' }, [ 'OK' ] ]
end


      A Rack application is a Ruby object that responds to call.

          It takes exactly one argument, the environment.

             It returns an Array of exactly three values:
                The status, the headers, and the body.

   The headers should respond to each and yield key/value pairs.

     The body should respond to each and yield String objects.
lambda do |environment|
  [ 200, { 'Content-Type' => 'text/plain' }, [ 'OK' ] ]
end


      A Rack application is a Ruby object that responds to call.

          It takes exactly one argument, the environment.

             It returns an Array of exactly three values:
                The status, the headers, and the body.

   The headers should respond to each and yield key/value pairs.

     The body should respond to each and yield String objects.
lambda do |environment|
  [ 200, { 'Content-Type' => 'text/plain' }, [ 'OK' ] ]
end


      A Rack application is a Ruby object that responds to call.

          It takes exactly one argument, the environment.

             It returns an Array of exactly three values:
                The status, the headers, and the body.

   The headers should respond to each and yield key/value pairs.

     The body should respond to each and yield String objects.
Rack and Rails
Before Rails 2.3
Before Rails 2.3

Apache
Before Rails 2.3

Apache     Passenger
Before Rails 2.3

Apache     Passenger        Rails
Before Rails 2.3

Apache     Passenger        Rails




         After Rails 2.3
Before Rails 2.3

Apache     Passenger        Rails




         After Rails 2.3

Apache
Before Rails 2.3

Apache     Passenger        Rails




         After Rails 2.3

Apache     Passenger
Before Rails 2.3

Apache     Passenger        Rails




         After Rails 2.3

Apache     Passenger        Rails
Before Rails 2.3

Apache     Passenger        Rails




         After Rails 2.3

Apache     Passenger        Rails
Passenger   ActionController::Base#call(env)   Rails
What is Rack
Middleware?
Passenger   ActionController::Base#call(env)   Rails
Passenger   Middleware   Rails
Passenger              Middleware                     Rails


 class ExampleMiddleware

   def initialize(next_in_chain)
     @next_in_chain = next_in_chain
   end

   def call(env)
     if env['PATH_INFO'] =~ Regexp.new('^/api')
       [ 200, { 'Content-Type' => 'text/xml' }, do_api_call(env) ]
     else
       env['mydata'] = 'test'
       @next_in_chain.call(env)
     end
   end

 end
Passenger              Middleware                     Rails

  class ExampleMiddleware

    def initialize(next_in_chain)
      @next_in_chain = next_in_chain
    end

    def call(env)
      if env['PATH_INFO'] =~ Regexp.new('^/api')
        [ 200, { 'Content-Type' => 'text/xml' }, do_api_call(env) ]
      else
        env['mydata'] = 'test'
        @next_in_chain.call(env)
      end
    end

  end
Passenger              Middleware                     Rails

  class ExampleMiddleware

    def initialize(next_in_chain)
      @next_in_chain = next_in_chain
    end

    def call(env)
      if env['PATH_INFO'] =~ Regexp.new('^/api')
        [ 200, { 'Content-Type' => 'text/xml' }, do_api_call(env) ]
      else
        env['mydata'] = 'test'
        @next_in_chain.call(env)
      end
    end

  end
Passenger              Middleware                     Rails

  class ExampleMiddleware

    def initialize(next_in_chain)
      @next_in_chain = next_in_chain
    end

    def call(env)
      if env['PATH_INFO'] =~ Regexp.new('^/api')
        [ 200, { 'Content-Type' => 'text/xml' }, do_api_call(env) ]
      else
        env['mydata'] = 'test'
        @next_in_chain.call(env)
      end
    end

  end
Passenger              Middleware                     Rails

  class ExampleMiddleware

    def initialize(next_in_chain)
      @next_in_chain = next_in_chain
    end

    def call(env)
      if env['PATH_INFO'] =~ Regexp.new('^/api')
        [ 200, { 'Content-Type' => 'text/xml' }, do_api_call(env) ]
      else
        env['mydata'] = 'test'
        @next_in_chain.call(env)
      end
    end

  end
Passenger              Middleware                     Rails

  class ExampleMiddleware

    def initialize(next_in_chain)
      @next_in_chain = next_in_chain
    end

    def call(env)
      if env['PATH_INFO'] =~ Regexp.new('^/api')
        [ 200, { 'Content-Type' => 'text/xml' }, do_api_call(env) ]
      else
        env['mydata'] = 'test'
        @next_in_chain.call(env)
      end
    end

  end
Passenger              Middleware                     Rails

  class ExampleMiddleware

    def initialize(next_in_chain)
      @next_in_chain = next_in_chain
    end

    def call(env)
      if env['PATH_INFO'] =~ Regexp.new('^/api')
        [ 200, { 'Content-Type' => 'text/xml' }, do_api_call(env) ]
      else
        env['mydata'] = 'test'
        @next_in_chain.call(env)
      end
    end

  end
Passenger              Middleware                     Rails

  class ExampleMiddleware

    def initialize(next_in_chain)
      @next_in_chain = next_in_chain
    end

    def call(env)
      if env['PATH_INFO'] =~ Regexp.new('^/api')
        [ 200, { 'Content-Type' => 'text/xml' }, do_api_call(env) ]
      else
        env['mydata'] = 'test'
        @next_in_chain.call(env)
      end
    end

  end
Passenger              Middleware                     Rails

  class ExampleMiddleware

    def initialize(next_in_chain)
      @next_in_chain = next_in_chain
    end

    def call(env)
      if env['PATH_INFO'] =~ Regexp.new('^/api')
        [ 200, { 'Content-Type' => 'text/xml' }, do_api_call(env) ]
      else
        env['mydata'] = 'test'
        @next_in_chain.call(env)
      end
    end

  end
Example
Existing Middleware
Rack::Cache
http://github.com/rtomayko/rack-cache
App Server   Rack::Cache   Rails



               Storage
App Server   Rack::Cache   Rails



               Storage
Rack::Bug
http://github.com/brynary/rack-bug
Rack::OpenID
http://github.com/josh/rack-openid
class SessionsController

  def new
    render :new   # contains a textbox called quot;identityquot;
  end

  def create
    if openid = request.env['rack.openid.response']
      case openid.status
         when :success # ...
         when :failure # ...
      end
    else
      response.headers['WWW-Authenticate'] = Rack::OpenID.build_header(
         :identifier => params[:identity]
      )
      render :text => '', :status => 401
    end
  end

end
class SessionsController

  def new
    render :new   # contains a textbox called quot;identityquot;
  end

  def create
    if openid = request.env['rack.openid.response']
      case openid.status
         when :success # ...
         when :failure # ...
      end
    else
      response.headers['WWW-Authenticate'] = Rack::OpenID.build_header(
         :identifier => params[:identity]
      )
      render :text => '', :status => 401
    end
  end

end
class SessionsController

  def new
    render :new   # contains a textbox called quot;identityquot;
  end

  def create
    if openid = request.env['rack.openid.response']
      case openid.status
         when :success # ...
         when :failure # ...
      end
    else
      response.headers['WWW-Authenticate'] = Rack::OpenID.build_header(
         :identifier => params[:identity]
      )
      render :text => '', :status => 401
    end
  end

end
class SessionsController

  def new
    render :new   # contains a textbox called quot;identityquot;
  end

  def create
    if openid = request.env['rack.openid.response']
      case openid.status
         when :success # ...
         when :failure # ...
      end
    else
      response.headers['WWW-Authenticate'] = Rack::OpenID.build_header(
         :identifier => params[:identity]
      )
      render :text => '', :status => 401
    end
  end

end
class SessionsController

  def new
    render :new   # contains a textbox called quot;identityquot;
  end

  def create
    if openid = request.env['rack.openid.response']
      case openid.status
         when :success # ...
         when :failure # ...
      end
    else
      response.headers['WWW-Authenticate'] = Rack::OpenID.build_header(
         :identifier => params[:identity]
      )
      render :text => '', :status => 401
    end
  end

end
class SessionsController

  def new
    render :new   # contains a textbox called quot;identityquot;
  end

  def create
    if openid = request.env['rack.openid.response']
      case openid.status
         when :success # ...
         when :failure # ...
      end
    else
      response.headers['WWW-Authenticate'] = Rack::OpenID.build_header(
         :identifier => params[:identity]
      )
      render :text => '', :status => 401
    end
  end

end
class SessionsController

  def new
    render :new   # contains a textbox called quot;identityquot;
  end

  def create
    if openid = request.env['rack.openid.response']
      case openid.status
         when :success # ...
         when :failure # ...
      end
    else
      response.headers['WWW-Authenticate'] = Rack::OpenID.build_header(
         :identifier => params[:identity]
      )
      render :text => '', :status => 401
    end
  end

end
class SessionsController

  def new
    render :new   # contains a textbox called quot;identityquot;
  end

  def create
    if openid = request.env['rack.openid.response']
      case openid.status
         when :success # ...
         when :failure # ...
      end
    else
      response.headers['WWW-Authenticate'] = Rack::OpenID.build_header(
         :identifier => params[:identity]
      )
      render :text => '', :status => 401
    end
  end

end
class SessionsController

  def new
    render :new   # contains a textbox called quot;identityquot;
  end

  def create
    if openid = request.env['rack.openid.response']
      case openid.status
         when :success # ...
         when :failure # ...
      end
    else
      response.headers['WWW-Authenticate'] = Rack::OpenID.build_header(
         :identifier => params[:identity]
      )
      render :text => '', :status => 401
    end
  end

end
Rack::Debug
http://github.com/ddollar/rack-debug
# app/controllers/users_controller.rb
@user = User.find(params[:id])
debugger
render :show



# run the rake task,
$ rake debug
Connected.



# refresh a page in your browser, your app will break at debugger statements
(rdb:1) p @user
<User id: 1, name: quot;David Dollarquot;, email: quot;ddollar@gmail.comquot;>
# app/controllers/users_controller.rb
@user = User.find(params[:id])
debugger
render :show



# run the rake task
$ rake debug
Connected.
(rdb:1) p @user
<User id: 1, name: quot;David Dollarquot;, email: quot;ddollar@gmail.comquot;>
# app/controllers/users_controller.rb
@user = User.find(params[:id])
debugger
render :show



# run the rake task
$ rake debug
Connected.
(rdb:1) p @user
<User id: 1, name: quot;David Dollarquot;, email: quot;ddollar@gmail.comquot;>
# app/controllers/users_controller.rb
@user = User.find(params[:id])
debugger
render :show



# run the rake task
$ rake debug
Connected.
(rdb:1) p @user
<User id: 1, name: quot;David Dollarquot;, email: quot;ddollar@gmail.comquot;>
Using Middleware
Passenger              Middleware                     Rails

  class ExampleMiddleware

    def initialize(next_in_chain)
      @next_in_chain = next_in_chain
    end

    def call(env)
      if env['PATH_INFO'] =~ Regexp.new('^/api')
        [ 200, { 'Content-Type' => 'text/xml' }, '<?xml?>' ]
      else
        @next_in_chain.call(env)
      end
    end

  end
Passenger            Middleware                     Rails



        class ExampleMiddleware
          # ...
        end



        # config/environment.rb
        config.middleware.use 'ExampleMiddleware'
Passenger            Middleware                     Rails



        class ExampleMiddleware
          # ...
        end



        # config/environment.rb
        config.middleware.use 'ExampleMiddleware'
Passenger            Middleware      Sinatra



        class ExampleMiddleware
          # ...
        end



        app = Rack::Builder.new do
          use ExampleMiddleware
          run MySinatraApp.new
        end
Passenger            Middleware      Sinatra



        class ExampleMiddleware
          # ...
        end



        app = Rack::Builder.new do
          use ExampleMiddleware
          run MySinatraApp.new
        end
Passenger            Middleware      Sinatra



        class ExampleMiddleware
          # ...
        end



        app = Rack::Builder.new do
          use ExampleMiddleware
          run MySinatraApp.new
        end
class ExampleMiddleware
  # ...
end



# Rails
config.middleware.use 'ExampleMiddleware'



# Rack::Builder
app = Rack::Builder.new do
  use ExampleMiddleware
  run MySinatraApp.new
end
class ExampleMiddleware
  # ...
end



# Rails
config.middleware.use 'ExampleMiddleware'
config.middleware.use 'ExampleMiddlewareTwo'



# Rack::Builder
app = Rack::Builder.new do
  use ExampleMiddleware
  use ExampleMiddlewareTwo
  run MySinatraApp.new
end
class ExampleMiddleware
  # ...
end



# Rails
config.middleware.use 'ExampleMiddleware'
config.middleware.use 'ExampleMiddlewareTwo'
config.middleware.use 'ExampleMiddlewareThree'



# Rack::Builder
app = Rack::Builder.new do
  use ExampleMiddleware
  use ExampleMiddlewareTwo
  use ExampleMiddlewareThree
  run MySinatraApp.new
end
Questions?

Weitere ähnliche Inhalte

Was ist angesagt?

Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl TechniquesDave Cross
 
Introduction to Perl - Day 2
Introduction to Perl - Day 2Introduction to Perl - Day 2
Introduction to Perl - Day 2Dave Cross
 
Bioinformatics p1-perl-introduction v2013
Bioinformatics p1-perl-introduction v2013Bioinformatics p1-perl-introduction v2013
Bioinformatics p1-perl-introduction v2013Prof. Wim Van Criekinge
 
Perl programming language
Perl programming languagePerl programming language
Perl programming languageElie Obeid
 
LPW: Beginners Perl
LPW: Beginners PerlLPW: Beginners Perl
LPW: Beginners PerlDave Cross
 
Actor Clustering with Docker Containers and Akka.Net in F#
Actor Clustering with Docker Containers and Akka.Net in F#Actor Clustering with Docker Containers and Akka.Net in F#
Actor Clustering with Docker Containers and Akka.Net in F#Riccardo Terrell
 
Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...
Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...
Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...Puppet
 
Above the clouds: introducing Akka
Above the clouds: introducing AkkaAbove the clouds: introducing Akka
Above the clouds: introducing Akkanartamonov
 
Demystifying Oak Search
Demystifying Oak SearchDemystifying Oak Search
Demystifying Oak SearchJustin Edelson
 
Introduction to Perl - Day 1
Introduction to Perl - Day 1Introduction to Perl - Day 1
Introduction to Perl - Day 1Dave Cross
 
Puppet Camp Berlin 2015: Martin Alfke | The Power of Puppet 4
Puppet Camp Berlin 2015: Martin Alfke | The Power of Puppet 4Puppet Camp Berlin 2015: Martin Alfke | The Power of Puppet 4
Puppet Camp Berlin 2015: Martin Alfke | The Power of Puppet 4NETWAYS
 

Was ist angesagt? (20)

Rack
RackRack
Rack
 
Intro to Perl and Bioperl
Intro to Perl and BioperlIntro to Perl and Bioperl
Intro to Perl and Bioperl
 
Concurrecny inf sharp
Concurrecny inf sharpConcurrecny inf sharp
Concurrecny inf sharp
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
 
Introduction to Perl - Day 2
Introduction to Perl - Day 2Introduction to Perl - Day 2
Introduction to Perl - Day 2
 
Evolving Tests
Evolving TestsEvolving Tests
Evolving Tests
 
Bioinformatics p1-perl-introduction v2013
Bioinformatics p1-perl-introduction v2013Bioinformatics p1-perl-introduction v2013
Bioinformatics p1-perl-introduction v2013
 
Perl tutorial
Perl tutorialPerl tutorial
Perl tutorial
 
Perl programming language
Perl programming languagePerl programming language
Perl programming language
 
Introduction to Perl and BioPerl
Introduction to Perl and BioPerlIntroduction to Perl and BioPerl
Introduction to Perl and BioPerl
 
LPW: Beginners Perl
LPW: Beginners PerlLPW: Beginners Perl
LPW: Beginners Perl
 
Perl Introduction
Perl IntroductionPerl Introduction
Perl Introduction
 
Actor Clustering with Docker Containers and Akka.Net in F#
Actor Clustering with Docker Containers and Akka.Net in F#Actor Clustering with Docker Containers and Akka.Net in F#
Actor Clustering with Docker Containers and Akka.Net in F#
 
Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...
Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...
Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...
 
Above the clouds: introducing Akka
Above the clouds: introducing AkkaAbove the clouds: introducing Akka
Above the clouds: introducing Akka
 
Demystifying Oak Search
Demystifying Oak SearchDemystifying Oak Search
Demystifying Oak Search
 
Perl Basics with Examples
Perl Basics with ExamplesPerl Basics with Examples
Perl Basics with Examples
 
Introduction to Perl - Day 1
Introduction to Perl - Day 1Introduction to Perl - Day 1
Introduction to Perl - Day 1
 
Puppet Camp Berlin 2015: Martin Alfke | The Power of Puppet 4
Puppet Camp Berlin 2015: Martin Alfke | The Power of Puppet 4Puppet Camp Berlin 2015: Martin Alfke | The Power of Puppet 4
Puppet Camp Berlin 2015: Martin Alfke | The Power of Puppet 4
 
Perl Scripting
Perl ScriptingPerl Scripting
Perl Scripting
 

Andere mochten auch

Why the hardness test can not determine yield strength and the asme guide
Why the hardness test can not determine yield strength and the asme guideWhy the hardness test can not determine yield strength and the asme guide
Why the hardness test can not determine yield strength and the asme guideFahmy Haggag
 
Crew, FOIA,Documents 017782- 017823
Crew, FOIA,Documents 017782- 017823Crew, FOIA,Documents 017782- 017823
Crew, FOIA,Documents 017782- 017823Obama White House
 
Post-It Girl
Post-It GirlPost-It Girl
Post-It GirlLitWorld
 
Hollow - Recovering from Eating Disorders
Hollow - Recovering from Eating DisordersHollow - Recovering from Eating Disorders
Hollow - Recovering from Eating Disorderspyromarketing
 
PresentacióN.Ppt
PresentacióN.PptPresentacióN.Ppt
PresentacióN.Pptguest772b1f
 
Chase Oaks VBX - Monday - Greatness of the Journey
Chase Oaks VBX - Monday - Greatness of the JourneyChase Oaks VBX - Monday - Greatness of the Journey
Chase Oaks VBX - Monday - Greatness of the JourneyJason Loveless
 
What Is Literary Criticism[1]2
What Is Literary Criticism[1]2What Is Literary Criticism[1]2
What Is Literary Criticism[1]2makeefer
 
Chase Oaks VBX - Wednesday - The Sacrifice Of The Journey
Chase Oaks VBX - Wednesday - The  Sacrifice Of The  JourneyChase Oaks VBX - Wednesday - The  Sacrifice Of The  Journey
Chase Oaks VBX - Wednesday - The Sacrifice Of The JourneyJason Loveless
 
Annual Report: What's happening @ the Wadleigh 2009-2010
Annual Report: What's happening @ the Wadleigh 2009-2010Annual Report: What's happening @ the Wadleigh 2009-2010
Annual Report: What's happening @ the Wadleigh 2009-2010librarygrl3
 
P R I D I N A K A V I C O!!!
P R I D I  N A  K A V I C O!!!P R I D I  N A  K A V I C O!!!
P R I D I N A K A V I C O!!!Stelarosa .
 
Top lista najboljih poza u krevetu
Top lista najboljih poza u krevetuTop lista najboljih poza u krevetu
Top lista najboljih poza u krevetuStelarosa .
 
Power Point 802.3
Power Point 802.3Power Point 802.3
Power Point 802.3roby90f
 
AGUILAS 2009
AGUILAS 2009AGUILAS 2009
AGUILAS 2009paobazzi
 
New Media Presentation
New Media PresentationNew Media Presentation
New Media Presentationgaskinjo
 
D6D Portfolio
D6D PortfolioD6D Portfolio
D6D Portfoliobethleo
 
The ABC's of Dad and Me
The ABC's of Dad and MeThe ABC's of Dad and Me
The ABC's of Dad and Mesunnymel20
 

Andere mochten auch (20)

Why the hardness test can not determine yield strength and the asme guide
Why the hardness test can not determine yield strength and the asme guideWhy the hardness test can not determine yield strength and the asme guide
Why the hardness test can not determine yield strength and the asme guide
 
Orm
OrmOrm
Orm
 
Crew, FOIA,Documents 017782- 017823
Crew, FOIA,Documents 017782- 017823Crew, FOIA,Documents 017782- 017823
Crew, FOIA,Documents 017782- 017823
 
Visita Uv
Visita UvVisita Uv
Visita Uv
 
Post-It Girl
Post-It GirlPost-It Girl
Post-It Girl
 
Hollow - Recovering from Eating Disorders
Hollow - Recovering from Eating DisordersHollow - Recovering from Eating Disorders
Hollow - Recovering from Eating Disorders
 
PresentacióN.Ppt
PresentacióN.PptPresentacióN.Ppt
PresentacióN.Ppt
 
Chase Oaks VBX - Monday - Greatness of the Journey
Chase Oaks VBX - Monday - Greatness of the JourneyChase Oaks VBX - Monday - Greatness of the Journey
Chase Oaks VBX - Monday - Greatness of the Journey
 
Hr2all offer to AIMS
Hr2all offer to AIMSHr2all offer to AIMS
Hr2all offer to AIMS
 
What Is Literary Criticism[1]2
What Is Literary Criticism[1]2What Is Literary Criticism[1]2
What Is Literary Criticism[1]2
 
Chase Oaks VBX - Wednesday - The Sacrifice Of The Journey
Chase Oaks VBX - Wednesday - The  Sacrifice Of The  JourneyChase Oaks VBX - Wednesday - The  Sacrifice Of The  Journey
Chase Oaks VBX - Wednesday - The Sacrifice Of The Journey
 
Annual Report: What's happening @ the Wadleigh 2009-2010
Annual Report: What's happening @ the Wadleigh 2009-2010Annual Report: What's happening @ the Wadleigh 2009-2010
Annual Report: What's happening @ the Wadleigh 2009-2010
 
P R I D I N A K A V I C O!!!
P R I D I  N A  K A V I C O!!!P R I D I  N A  K A V I C O!!!
P R I D I N A K A V I C O!!!
 
Top lista najboljih poza u krevetu
Top lista najboljih poza u krevetuTop lista najboljih poza u krevetu
Top lista najboljih poza u krevetu
 
Power Point 802.3
Power Point 802.3Power Point 802.3
Power Point 802.3
 
AGUILAS 2009
AGUILAS 2009AGUILAS 2009
AGUILAS 2009
 
Client Samples
Client SamplesClient Samples
Client Samples
 
New Media Presentation
New Media PresentationNew Media Presentation
New Media Presentation
 
D6D Portfolio
D6D PortfolioD6D Portfolio
D6D Portfolio
 
The ABC's of Dad and Me
The ABC's of Dad and MeThe ABC's of Dad and Me
The ABC's of Dad and Me
 

Ähnlich wie Rack Middleware

Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record.toster
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everythingnoelrap
 
TDC 2012 - Patterns e Anti-Patterns em Ruby
TDC 2012 - Patterns e Anti-Patterns em RubyTDC 2012 - Patterns e Anti-Patterns em Ruby
TDC 2012 - Patterns e Anti-Patterns em RubyFabio Akita
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteLeonardo Proietti
 
Php my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.netPhp my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.netProgrammer Blog
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl TechniquesDave Cross
 
Rails 3 Beautiful Code
Rails 3 Beautiful CodeRails 3 Beautiful Code
Rails 3 Beautiful CodeGreggPollack
 
Ruby conf 2011, Create your own rails framework
Ruby conf 2011, Create your own rails frameworkRuby conf 2011, Create your own rails framework
Ruby conf 2011, Create your own rails frameworkPankaj Bhageria
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkBen Scofield
 
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 jQueryTatsuhiko Miyagawa
 
Aura Project for PHP
Aura Project for PHPAura Project for PHP
Aura Project for PHPHari K T
 
Introduction to Rails - presented by Arman Ortega
Introduction to Rails - presented by Arman OrtegaIntroduction to Rails - presented by Arman Ortega
Introduction to Rails - presented by Arman Ortegaarman o
 
8 Minutes On Rack
8 Minutes On Rack8 Minutes On Rack
8 Minutes On Rackdanwrong
 
And the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack SupportAnd the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack SupportBen Scofield
 
Does your configuration code smell?
Does your configuration code smell?Does your configuration code smell?
Does your configuration code smell?Tushar Sharma
 

Ähnlich wie Rack Middleware (20)

Intro to Rack
Intro to RackIntro to Rack
Intro to Rack
 
Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record
 
Rack
RackRack
Rack
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everything
 
Rack Middleware
Rack MiddlewareRack Middleware
Rack Middleware
 
TDC 2012 - Patterns e Anti-Patterns em Ruby
TDC 2012 - Patterns e Anti-Patterns em RubyTDC 2012 - Patterns e Anti-Patterns em Ruby
TDC 2012 - Patterns e Anti-Patterns em Ruby
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
 
Php my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.netPhp my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.net
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
 
Rails 3 Beautiful Code
Rails 3 Beautiful CodeRails 3 Beautiful Code
Rails 3 Beautiful Code
 
Ruby conf 2011, Create your own rails framework
Ruby conf 2011, Create your own rails frameworkRuby conf 2011, Create your own rails framework
Ruby conf 2011, Create your own rails framework
 
Arrays in php
Arrays in phpArrays in php
Arrays in php
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web Framework
 
Scala in Places API
Scala in Places APIScala in Places API
Scala in Places API
 
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
 
Aura Project for PHP
Aura Project for PHPAura Project for PHP
Aura Project for PHP
 
Introduction to Rails - presented by Arman Ortega
Introduction to Rails - presented by Arman OrtegaIntroduction to Rails - presented by Arman Ortega
Introduction to Rails - presented by Arman Ortega
 
8 Minutes On Rack
8 Minutes On Rack8 Minutes On Rack
8 Minutes On Rack
 
And the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack SupportAnd the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack Support
 
Does your configuration code smell?
Does your configuration code smell?Does your configuration code smell?
Does your configuration code smell?
 

Kürzlich hochgeladen

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 CVKhem
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
 
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)wesley chun
 
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...Drew Madelung
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbuapidays
 
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, Adobeapidays
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
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 2024The Digital Insurer
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 

Kürzlich hochgeladen (20)

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
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 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)
 
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...
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
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
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
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
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 

Rack Middleware

  • 1. Rack Middleware David Dollar
  • 3. A Rack application is a Ruby object that responds to call. It takes exactly one argument, the environment. It returns an Array of exactly three values: The status, the headers, and the body. The headers should respond to each and yield key/value pairs. The body should respond to each and yield String objects.
  • 4. lambda do |environment| [ 200, { 'Content-Type' => 'text/plain' }, [ 'OK' ] ] end A Rack application is a Ruby object that responds to call. It takes exactly one argument, the environment. It returns an Array of exactly three values: The status, the headers, and the body. The headers should respond to each and yield key/value pairs. The body should respond to each and yield String objects.
  • 5. lambda do |environment| [ 200, { 'Content-Type' => 'text/plain' }, [ 'OK' ] ] end A Rack application is a Ruby object that responds to call. It takes exactly one argument, the environment. It returns an Array of exactly three values: The status, the headers, and the body. The headers should respond to each and yield key/value pairs. The body should respond to each and yield String objects.
  • 6. lambda do |environment| [ 200, { 'Content-Type' => 'text/plain' }, [ 'OK' ] ] end A Rack application is a Ruby object that responds to call. It takes exactly one argument, the environment. It returns an Array of exactly three values: The status, the headers, and the body. The headers should respond to each and yield key/value pairs. The body should respond to each and yield String objects.
  • 7. lambda do |environment| [ 200, { 'Content-Type' => 'text/plain' }, [ 'OK' ] ] end A Rack application is a Ruby object that responds to call. It takes exactly one argument, the environment. It returns an Array of exactly three values: The status, the headers, and the body. The headers should respond to each and yield key/value pairs. The body should respond to each and yield String objects.
  • 8. lambda do |environment| [ 200, { 'Content-Type' => 'text/plain' }, [ 'OK' ] ] end A Rack application is a Ruby object that responds to call. It takes exactly one argument, the environment. It returns an Array of exactly three values: The status, the headers, and the body. The headers should respond to each and yield key/value pairs. The body should respond to each and yield String objects.
  • 9. lambda do |environment| [ 200, { 'Content-Type' => 'text/plain' }, [ 'OK' ] ] end A Rack application is a Ruby object that responds to call. It takes exactly one argument, the environment. It returns an Array of exactly three values: The status, the headers, and the body. The headers should respond to each and yield key/value pairs. The body should respond to each and yield String objects.
  • 10. lambda do |environment| [ 200, { 'Content-Type' => 'text/plain' }, [ 'OK' ] ] end A Rack application is a Ruby object that responds to call. It takes exactly one argument, the environment. It returns an Array of exactly three values: The status, the headers, and the body. The headers should respond to each and yield key/value pairs. The body should respond to each and yield String objects.
  • 11. lambda do |environment| [ 200, { 'Content-Type' => 'text/plain' }, [ 'OK' ] ] end A Rack application is a Ruby object that responds to call. It takes exactly one argument, the environment. It returns an Array of exactly three values: The status, the headers, and the body. The headers should respond to each and yield key/value pairs. The body should respond to each and yield String objects.
  • 16. Before Rails 2.3 Apache Passenger Rails
  • 17. Before Rails 2.3 Apache Passenger Rails After Rails 2.3
  • 18. Before Rails 2.3 Apache Passenger Rails After Rails 2.3 Apache
  • 19. Before Rails 2.3 Apache Passenger Rails After Rails 2.3 Apache Passenger
  • 20. Before Rails 2.3 Apache Passenger Rails After Rails 2.3 Apache Passenger Rails
  • 21. Before Rails 2.3 Apache Passenger Rails After Rails 2.3 Apache Passenger Rails
  • 22. Passenger ActionController::Base#call(env) Rails
  • 24. Passenger ActionController::Base#call(env) Rails
  • 25. Passenger Middleware Rails
  • 26. Passenger Middleware Rails class ExampleMiddleware def initialize(next_in_chain) @next_in_chain = next_in_chain end def call(env) if env['PATH_INFO'] =~ Regexp.new('^/api') [ 200, { 'Content-Type' => 'text/xml' }, do_api_call(env) ] else env['mydata'] = 'test' @next_in_chain.call(env) end end end
  • 27. Passenger Middleware Rails class ExampleMiddleware def initialize(next_in_chain) @next_in_chain = next_in_chain end def call(env) if env['PATH_INFO'] =~ Regexp.new('^/api') [ 200, { 'Content-Type' => 'text/xml' }, do_api_call(env) ] else env['mydata'] = 'test' @next_in_chain.call(env) end end end
  • 28. Passenger Middleware Rails class ExampleMiddleware def initialize(next_in_chain) @next_in_chain = next_in_chain end def call(env) if env['PATH_INFO'] =~ Regexp.new('^/api') [ 200, { 'Content-Type' => 'text/xml' }, do_api_call(env) ] else env['mydata'] = 'test' @next_in_chain.call(env) end end end
  • 29. Passenger Middleware Rails class ExampleMiddleware def initialize(next_in_chain) @next_in_chain = next_in_chain end def call(env) if env['PATH_INFO'] =~ Regexp.new('^/api') [ 200, { 'Content-Type' => 'text/xml' }, do_api_call(env) ] else env['mydata'] = 'test' @next_in_chain.call(env) end end end
  • 30. Passenger Middleware Rails class ExampleMiddleware def initialize(next_in_chain) @next_in_chain = next_in_chain end def call(env) if env['PATH_INFO'] =~ Regexp.new('^/api') [ 200, { 'Content-Type' => 'text/xml' }, do_api_call(env) ] else env['mydata'] = 'test' @next_in_chain.call(env) end end end
  • 31. Passenger Middleware Rails class ExampleMiddleware def initialize(next_in_chain) @next_in_chain = next_in_chain end def call(env) if env['PATH_INFO'] =~ Regexp.new('^/api') [ 200, { 'Content-Type' => 'text/xml' }, do_api_call(env) ] else env['mydata'] = 'test' @next_in_chain.call(env) end end end
  • 32. Passenger Middleware Rails class ExampleMiddleware def initialize(next_in_chain) @next_in_chain = next_in_chain end def call(env) if env['PATH_INFO'] =~ Regexp.new('^/api') [ 200, { 'Content-Type' => 'text/xml' }, do_api_call(env) ] else env['mydata'] = 'test' @next_in_chain.call(env) end end end
  • 33. Passenger Middleware Rails class ExampleMiddleware def initialize(next_in_chain) @next_in_chain = next_in_chain end def call(env) if env['PATH_INFO'] =~ Regexp.new('^/api') [ 200, { 'Content-Type' => 'text/xml' }, do_api_call(env) ] else env['mydata'] = 'test' @next_in_chain.call(env) end end end
  • 34. Passenger Middleware Rails class ExampleMiddleware def initialize(next_in_chain) @next_in_chain = next_in_chain end def call(env) if env['PATH_INFO'] =~ Regexp.new('^/api') [ 200, { 'Content-Type' => 'text/xml' }, do_api_call(env) ] else env['mydata'] = 'test' @next_in_chain.call(env) end end end
  • 38. App Server Rack::Cache Rails Storage
  • 39. App Server Rack::Cache Rails Storage
  • 41.
  • 42.
  • 43.
  • 45. class SessionsController def new render :new # contains a textbox called quot;identityquot; end def create if openid = request.env['rack.openid.response'] case openid.status when :success # ... when :failure # ... end else response.headers['WWW-Authenticate'] = Rack::OpenID.build_header( :identifier => params[:identity] ) render :text => '', :status => 401 end end end
  • 46. class SessionsController def new render :new # contains a textbox called quot;identityquot; end def create if openid = request.env['rack.openid.response'] case openid.status when :success # ... when :failure # ... end else response.headers['WWW-Authenticate'] = Rack::OpenID.build_header( :identifier => params[:identity] ) render :text => '', :status => 401 end end end
  • 47. class SessionsController def new render :new # contains a textbox called quot;identityquot; end def create if openid = request.env['rack.openid.response'] case openid.status when :success # ... when :failure # ... end else response.headers['WWW-Authenticate'] = Rack::OpenID.build_header( :identifier => params[:identity] ) render :text => '', :status => 401 end end end
  • 48. class SessionsController def new render :new # contains a textbox called quot;identityquot; end def create if openid = request.env['rack.openid.response'] case openid.status when :success # ... when :failure # ... end else response.headers['WWW-Authenticate'] = Rack::OpenID.build_header( :identifier => params[:identity] ) render :text => '', :status => 401 end end end
  • 49. class SessionsController def new render :new # contains a textbox called quot;identityquot; end def create if openid = request.env['rack.openid.response'] case openid.status when :success # ... when :failure # ... end else response.headers['WWW-Authenticate'] = Rack::OpenID.build_header( :identifier => params[:identity] ) render :text => '', :status => 401 end end end
  • 50. class SessionsController def new render :new # contains a textbox called quot;identityquot; end def create if openid = request.env['rack.openid.response'] case openid.status when :success # ... when :failure # ... end else response.headers['WWW-Authenticate'] = Rack::OpenID.build_header( :identifier => params[:identity] ) render :text => '', :status => 401 end end end
  • 51. class SessionsController def new render :new # contains a textbox called quot;identityquot; end def create if openid = request.env['rack.openid.response'] case openid.status when :success # ... when :failure # ... end else response.headers['WWW-Authenticate'] = Rack::OpenID.build_header( :identifier => params[:identity] ) render :text => '', :status => 401 end end end
  • 52. class SessionsController def new render :new # contains a textbox called quot;identityquot; end def create if openid = request.env['rack.openid.response'] case openid.status when :success # ... when :failure # ... end else response.headers['WWW-Authenticate'] = Rack::OpenID.build_header( :identifier => params[:identity] ) render :text => '', :status => 401 end end end
  • 53. class SessionsController def new render :new # contains a textbox called quot;identityquot; end def create if openid = request.env['rack.openid.response'] case openid.status when :success # ... when :failure # ... end else response.headers['WWW-Authenticate'] = Rack::OpenID.build_header( :identifier => params[:identity] ) render :text => '', :status => 401 end end end
  • 55. # app/controllers/users_controller.rb @user = User.find(params[:id]) debugger render :show # run the rake task, $ rake debug Connected. # refresh a page in your browser, your app will break at debugger statements (rdb:1) p @user <User id: 1, name: quot;David Dollarquot;, email: quot;ddollar@gmail.comquot;>
  • 56. # app/controllers/users_controller.rb @user = User.find(params[:id]) debugger render :show # run the rake task $ rake debug Connected. (rdb:1) p @user <User id: 1, name: quot;David Dollarquot;, email: quot;ddollar@gmail.comquot;>
  • 57. # app/controllers/users_controller.rb @user = User.find(params[:id]) debugger render :show # run the rake task $ rake debug Connected. (rdb:1) p @user <User id: 1, name: quot;David Dollarquot;, email: quot;ddollar@gmail.comquot;>
  • 58. # app/controllers/users_controller.rb @user = User.find(params[:id]) debugger render :show # run the rake task $ rake debug Connected. (rdb:1) p @user <User id: 1, name: quot;David Dollarquot;, email: quot;ddollar@gmail.comquot;>
  • 60. Passenger Middleware Rails class ExampleMiddleware def initialize(next_in_chain) @next_in_chain = next_in_chain end def call(env) if env['PATH_INFO'] =~ Regexp.new('^/api') [ 200, { 'Content-Type' => 'text/xml' }, '<?xml?>' ] else @next_in_chain.call(env) end end end
  • 61. Passenger Middleware Rails class ExampleMiddleware # ... end # config/environment.rb config.middleware.use 'ExampleMiddleware'
  • 62. Passenger Middleware Rails class ExampleMiddleware # ... end # config/environment.rb config.middleware.use 'ExampleMiddleware'
  • 63. Passenger Middleware Sinatra class ExampleMiddleware # ... end app = Rack::Builder.new do use ExampleMiddleware run MySinatraApp.new end
  • 64. Passenger Middleware Sinatra class ExampleMiddleware # ... end app = Rack::Builder.new do use ExampleMiddleware run MySinatraApp.new end
  • 65. Passenger Middleware Sinatra class ExampleMiddleware # ... end app = Rack::Builder.new do use ExampleMiddleware run MySinatraApp.new end
  • 66. class ExampleMiddleware # ... end # Rails config.middleware.use 'ExampleMiddleware' # Rack::Builder app = Rack::Builder.new do use ExampleMiddleware run MySinatraApp.new end
  • 67. class ExampleMiddleware # ... end # Rails config.middleware.use 'ExampleMiddleware' config.middleware.use 'ExampleMiddlewareTwo' # Rack::Builder app = Rack::Builder.new do use ExampleMiddleware use ExampleMiddlewareTwo run MySinatraApp.new end
  • 68. class ExampleMiddleware # ... end # Rails config.middleware.use 'ExampleMiddleware' config.middleware.use 'ExampleMiddlewareTwo' config.middleware.use 'ExampleMiddlewareThree' # Rack::Builder app = Rack::Builder.new do use ExampleMiddleware use ExampleMiddlewareTwo use ExampleMiddlewareThree run MySinatraApp.new end

Hinweis der Redaktion

  1. To start off, we should take a brief look at Rack itself.
  2. This is a valid Rack application.
  3. lambda takes a block and creates a Proc object. Proc objects are invoked using the call method.
  4. This proc object takes one argument, the environment.
  5. And returns three values, the status code...
  6. The response headers (here we&#x2019;re setting the Content Type to text/plain) ...
  7. and the response body (here the string &#x201C;OK&#x201D;)
  8. A Ruby Hash responds to each and returns key/value pairs
  9. This array responds to each and returns Strings
  10. Rack was introduced to Rails in version 2.3.
  11. Before Rack, a typical Rails stack in production would look like...
  12. A Web Server
  13. Some kind of application server (Mongrel, Thin, etc)..
  14. Your application.
  15. Now that we have Rack, this stack looks like...
  16. A web server...
  17. An application server...
  18. And your application. No difference. From a Rails developer&#x2019;s perspective, not much has changed at first glance.
  19. The magic happens here. Rails is now Rack compatible, and this interconnect now takes the form of the Rack API.
  20. The Rack API is encapsulated in Rails by ActionController::Base...
  21. Which has a call method...
  22. That takes the environment as a parameter...
  23. And returns a status code...
  24. The response headers...
  25. And the response body.
  26. There are many reasons this change is important, but the one I&#x2019;m going to talk about is Middleware. What is Rack Middleware?
  27. Because we know what the API between the app server and the Rails stack looks like now. And Because we know what inputs it is expecting. And because we know what the return will look like.
  28. We can now insert code in between the app server and the application, that can speak this Rack API. We call this code Middleware.
  29. A middleware application takes the form of a class...
  30. Its constructor...
  31. ...takes the next piece of the chain as a parameter, which allows you to keep the chain going.
  32. In this middleware, which has a call method...
  33. ...and takes the environment as a parameter...
  34. We&#x2019;re going to check a value in the environment, the requested path, and see if it starts with /api
  35. If it does, we&#x2019;re going to return an array of three values, A status code, the headers, and the body
  36. Otherwise, we&#x2019;re going to add some data to the environment. We can put any ruby objects we like in here for the benefit of applications further down the chain.
  37. And we&#x2019;re going to pass the call through to the next item in the chain.
  38. Rack::Cache sits in the middle of your application stack and monitors requests. It understands HTTP standards for both freshness (Expires, Cache-Control headers) and validation (Last-Modified, ETag headers)
  39. It can intercept requests and serve them from its own storage. (Disk, memcached, memory) Cache expiration and invalidation is handled automatically.
  40. Rack::Bug adds a toolbar to the top of your app to give you some insight into the internals.
  41. You can look at things like the Rails Environment
  42. You can look at which queries ran on the page and how long they took. You can run an EXPLAIN on them right from the page.
  43. Rack::OpenID takes care of OpenID authentication for you
  44. In your SessionsController which controls user authentication...
  45. ...you have a &#x201C;new&#x201D; method which renders a form that contains an identity textbox for the user to type their OpenID URL
  46. In the create action, which processes the form
  47. We check the environment to see if Rack::OpenID has injected credentials On the first pass through this will be missing, so...
  48. We build a header that Rack::OpenID will be able to process...
  49. ...that includes the OpenID identity provided by the user
  50. which in combination with a 401 status code lets Rack::OpenID know to take over
  51. After Rack::OpenID does its thing it injects &#x2018;rack.openid.response&#x2019; into the environment. So when we come back into the controller and the OpenID credentials are present in the environment...
  52. We can check the status of the OpenID response and take the appropriate action.
  53. Rack::Debug gives an easy interface to ruby-debug inside your application
  54. Add debugger statements to your code
  55. At the console, run the debug rake task
  56. The next time you refresh a page in your browser, your app stops at debugger statements and drops you into an interactive shell.
  57. How do I use Middleware in my applications.
  58. If I have a middleware called ExampleMiddleware
  59. In Rails, I&#x2019;m going to go to my config/environment.rb
  60. And add a line, config.middleware.use &#x2018;ExampleMiddleware&#x2019;
  61. Rack also gives us a class called Rack::Builder
  62. We tell it to use our Middleware