Hello World rack middleware with rails 3: how to process body of all requests

孤者浪人 提交于 2019-12-04 23:52:44

问题


i want to try out a simple rack middleware "hello world", but i seem to get stuck. it looks like the main sytax changed, since some examples use this code:

require 'rack/utils'

class FooBar

  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, body = @app.call(env)
         body.body << "\nHi from #{self.class}"
         [status, headers, body]
  end
end

produces an error:

undefined method `<<' for #<ActionDispatch::Response:0x103f07c48>

even when i look at other codes out there, i cannot seem to get them running with rails 3.0.3.

here are my concrete questions:

  • how can i get a simple rack middleware to run and modify the body of any output from a rails app?
  • where should i put the Rails.application.config.middleware.use declaration? (i created an own initializer in config/initializers for that)

thanks a lot in advance!


回答1:


This should do what you want it to:

# in config/application.rb
config.middleware.use 'FooBar'

# in config/initializers/foo_bar.rb
class FooBar
  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, response = @app.call(env)
    [status, headers, response.body << "\nHi from #{self.class}"]
  end
end

Be advised, that on just about every other request (at least on Rails 3.0.3), this will fail due to another middleware (Rack::Head) because it sends an empty request when content is unchanged. We are in this example depending on being able to call response.body, but in fact, the last member of the array can be anything that responds to .each.

Ryan Bates goes over Rack pretty well here:

http://asciicasts.com/episodes/151-rack-middleware

http://railscasts.com/episodes/151-rack-middleware

And the official Rails guide is pretty good too:

http://guides.rubyonrails.org/rails_on_rack.html

And of course the official Rack spec:

http://rack.rubyforge.org/doc/SPEC.html




回答2:


Rails 3.2.12+:

previous answer does not work for Rails 3.2.12+

This one does:

# in config/application.rb
config.middleware.use 'FooBar'

# in config/initializers/foo_bar.rb
class FooBar
  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, response = @app.call(env)
    response.body += "\nHi from #{self.class}"
    # response.body << "..." WILL NOT WORK
    [status, headers, response]
  end
end


来源:https://stackoverflow.com/questions/4823170/hello-world-rack-middleware-with-rails-3-how-to-process-body-of-all-requests

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!