今天在研究rails3发错误电子信的时候无意中发现了强大的rack middleware,一开始还不知道,后来才发现了它强大的功能。先看看rack吧:(以下也是来自网络)
Rack:
Rack是什么?Rack提供了用ruby开发web应用的一个接口。比如Rails框架,就是由rack承担着跟web服务器之间的交互。简而言
之,Rack已经成为ruby开发web应用程序的一个规范,它统一了web服务器和web框架之间的交互接口。它所支持的web服务器和web框架已经
非常之多:http://rack.rubyforge.org/doc/
。
Rack的规范非常简单,就是一个call方法:http://rack.rubyforge.org/doc/SPEC.html
。接受一个environment,然后返回status,header和body。这不就是http的全部么?
Middleware
A Middleware is a simple class instance that has two methods (at least), initialize
and call
.
It is used to alter(改变) a HTTP request to and the response from your main
Rack-compliant(兼容
) web application. It is a form of proxy but with code
rather than separate software. A set of middleware and their respective
endpoints are known as a Stack.(一个
中间件及
各自
的端点
设置
被称为
堆栈。
)
What is an Endpoint?
An Endpoint is again a simple ruby class that only responds to call
.
Thus it is so similar to a middleware that in fact a class can be one
and the same thing, if it wants to return a response instead of letting
it cascade through to the main endpoint.
Almost the simplest middleware possible is the following:
class SimpleMiddleware
def initialize(app, options={})
@app = app
@options = options
end
def call(env)
# downward logic
status, headers, response = @app.call(env)
# upward logic
[status, headers, response]
end
end
Firstly, the initialize
method, which accepts two
arguments. The first is a rack endpoint, and the second is some options
that will be required later for some logic.
The other important feature is the call
method, which
accepts a hash of environment variables sent from the middleware further
out. It also returns an array consisting of three things: the status, a
hash of headers and a response body.
Middleware Stack是如何工作的?
As an example, here is a basic (imaginary) middleware stack:
# Top of the chain: the Listening Server
use SecondSimpleMiddleware # Inherits from SimpleMiddleware
use SimpleMiddleware
run ActionController::Routing::Routes
# Bottom of the chain: Your App
When a HTTP request comes in from a client, the server call
s SecondSimpleMiddleware, which executes its downward logic, then call
s SimpleMiddleware. SimpleMiddleware in turn executes it’s own downward logic, and call
s ActionController::Routing::Routes, which executes your applications logic.
Cleverly, ActionController::Routing::Routes returns an array containing 3
important elements. The first is the http status, as an integer. The
second is a hash of headers to send back in the response. The last is
the response body, which should respond to each
.
This array gets returned to SimpleMiddleware, which performs its upward
logic before returning an array in the exact same format to
SecondSimpleMiddleware. Then SecondSimpleMiddleware performs its upward
logic, before returning an array of the exact same format back to the
listening server, which formats it as a HTTP Response and sends it to
the client.
class EarlyResponderMiddleware
def initialize(app, options={})
@app = app
@options = options
end
def call(env)
if env['path'] == "/foo"
body = "Not Found"
[404, {"Content-Length"=> body.length}, body]
else
@app.call(env)
end
end
end
And the following is what would happen if the path matched “/foo”:
Implementation
The beauty of this implementation is that middlewares can be added,
moved and removed from this stack at will, without any other middlewares
giving a damn. The exact implementation has been made so simple yet
clever that an endpoint actually looks exactly the same as an endpoint
with a middleware in front of it.
The following is the build_app
method I mentioned earlier, which Rack calls to construct its app
object to hand to a server.
def build_app(app)
middleware[options[:environment]].reverse_each do |middleware|
middleware = middleware.call(self) if middleware.respond_to?(:call)
next unless middleware
klass = middleware.shift
app = klass.new(app, *middleware)
end
app
end
In Rails 3, the default middleware stack is:
use ActionDispatch::Static # only development # part two
use Rack::Lock
use ActiveSupport::Cache::Strategy::LocalCache
use Rack::Runtime
use Rails::Rack::Logger # part three
use ActionDispatch::ShowExceptions
use ActionDispatch::RemoteIp
use Rack::Sendfile
use ActionDispatch::Callbacks # part four
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore # part five
use ActionDispatch::Flash
use ActionDispatch::ParamsParser
use Rack::MethodOverride
use ActionDispatch::Head
run Test::Application.routes # part six
This stack is very easy to alter using the config.middleware methods.
They allow you to insert middleware anywhere in the stack. More
information can be found in the “Rails on Rack” Rails Guide
.
You’ll also find a lot more API centric information about middleware in
that article, whereas my articles are looking more at the
implementation.
Rack Middleware
为什么不可以在Rack和web framework之间做些事情呢?于是Rack
middleware发展起来了。Rack中间件其实就是一些遵循Rack规范的应用。为什么要发展出Rack
middleware?因为很多事情在这里做起来就非常方便,其实就是AOP的方式(你也可以把它理解成filter)。
看一下众多的middlewares:http://wiki.github.com/rack/rack/list-of-middleware
。或者在你的最新(2.3)rails应用下敲下命令行:rake middleware。
关联:http://andyhu1007.iteye.com/blog/537610
Configuring Middleware Stack
Rails provides a simple configuration interface config.middleware
for adding, removing and modifying the middlewares in the middleware stack via environment.rb
or the environment specific configuration file environments/<environment>.rb
.
Adding a Middleware
You can add a new middleware to the middleware stack using any of the following methods:
-
config.middleware.use(new_middleware, args)
– Adds the new middleware at the bottom of the middleware stack.
-
config.middleware.insert_before(existing_middleware, new_middleware, args)
– Adds the new middleware before the specified existing middleware in the middleware stack.
-
config.middleware.insert_after(existing_middleware, new_middleware, args)
– Adds the new middleware after the specified existing middleware in the middleware stack.
Example:
# config/environment.rb
# Push Rack::BounceFavicon at the bottom
config.middleware.use Rack::BounceFavicon
# Add Lifo::Cache after ActiveRecord::QueryCache.
# Pass { :page_cache => false } argument to Lifo::Cache.
config.middleware.insert_after ActiveRecord::QueryCache, Lifo::Cache, :page_cache => false
Swapping a Middleware
You can swap an existing middleware in the middleware stack using config.middleware.swap
.
Example:
# config/environment.rb
# Replace ActionController::Failsafe with Lifo::Failsafe
config.middleware.swap ActionController::Failsafe, Lifo::Failsafe
Middleware Stack is an Array
The middleware stack behaves just like a normal Array
. You can use any Array
methods to insert, reorder, or remove items from the stack. Methods
described in the section above are just convenience methods.
For example, the following removes the middleware matching the supplied class name:
config.middleware.delete(middleware)
Internal Middleware Stack
Much of Action Controller’s functionality is implemented as Middlewares.
The following table explains the purpose of each of them:
Middleware
Purpose
Rack::Lock
|
Sets env["rack.multithread"]
flag to true
and wraps the application within a Mutex. |
ActionController::Failsafe
|
Returns HTTP
Status 500
to the client if an exception gets raised while dispatching. |
ActiveRecord::QueryCache
|
Enable the Active Record query cache. |
ActionController::Session::CookieStore
|
Uses the cookie based session store. |
ActionController::Session::MemCacheStore
|
Uses the memcached based session store. |
ActiveRecord::SessionStore
|
Uses the database based session store. |
Rack::MethodOverride
|
Sets HTTP
method based on _method
parameter or env["HTTP_X_HTTP_METHOD_OVERRIDE"]
. |
Rack::Head
|
Discards the response body if the client sends a HEAD
request. |
- 大小: 595.1 KB
- 大小: 592.8 KB
- 大小: 593 KB
分享到:
相关推荐
Rails :: Auth是一个灵活的库,旨在使用Rack Middleware进行身份验证(AuthN)和授权(AuthZ)。 它将,使用AuthN中间件首先验证凭据(例如X.509证书或cookie),然后通过使用这些凭据(例如(ACL))的单独AuthZ...
机架:: BearerAuth Rack :: BearerAuth是在Rack应用中使用承载身份验证的中间件。... use Rack :: BearerAuth :: Middleware do match path : "/foo" do | token | # validate token # AccessToken.where
Rack::UTF8Sanitizer 是一个 Rack 中间件用来清理 URI 和 HTTP 请求头部中包含的无效 UTF-8 字符。Rails 的使用方法:config.middleware.insert 0, Rack::UTF8SanitizerRack 的使用方法:use Rack::UTF8Sanitizer
Rails::Rack::Logger ActionDispatch::ShowExceptions ActionDispatch::DebugExceptions ActionDispatch::RemoteIp ActionDispatch::Reloader ActionDispatch::Callbacks ActiveRecord::ConnectionAdapters::...
下面的配置适用于Rails,但是该中间件也可以与Sinatra和裸Rack应用配合使用。 滑轨配置 在Gemfile中: gem 'rack-host-redirect' 在config / environments / production.rb中: config . middleware . use Rack ...
Rails.application.config.middleware.use OmniAuth::Builder do provider :developer unless Rails.env.production? provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET'] end 标签:安全相关...
离子+滑轨 这是一段代码,伴随着有关如何使Rails和Ionic完美配合播放的屏幕录像。 入门 创建一个文件夹来容纳应用程序的两面 ...config.middleware.insert_before 0, "Rack::Cors" do allow do origins '*' reso
滚动导轨 用法 在config/production.rb : Scrolls::Rails.setup(Rails.application) config.middleware.delete Rails::Rack::Logger config.middleware.use Scrolls::Rails::Rack::QuietLogger
该应用程序在基本的 Rack层的顶部添加了一些不错的帮助程序。 它的目的是使Warden更易于在基于Rails的环境中使用,而无需像设计中那样繁重。 安装 将此行添加到您的应用程序的Gemfile中: gem 'rails_warden' ...
预渲染 Rails 嵌入式 一个 rails gem 使用中间件来渲染 JavaScript Web 应用程序,无需安装其他服务即可动态调用 phantomjs。 概述 使用Prerender Rails Embedded可以避免在 ... use Rack :: Prerender before_render
有两种方法可以检测您的Rack / Rails应用程序。 第一种是将HAR记录器用作Rack中间件。 第二种是将其用作Rails ActionController过滤器。 根据您使用的框架,一个或两个选项可能可供您使用。 如果您对记录RSpec测试...
保护您的Rails和Rack应用免受不良客户端的侵害。 使用Rack :: Attack,您可以根据请求的属性轻松决定何时允许,阻止和限制。 请参阅介绍Rack :: Attack的。 目录 入门 正在安装 将此行添加到您的应用程序的Gemfile...
微信公众平台开放消息接口机架中间件 使用“ weixin /中间件”验证微信请求 解析推消息与“ weixin / model...use Weixin :: Middleware , 'your api token' , '/your_app_root' configure do set :wx_id , 'your_wei
安装将此行添加到您的应用程序的Gemfile中: gem 'rack-utf8_sanitizer'然后执行: $ bundle或将其自己安装为: $ gem install rack-utf8_sanitizer对于Rails,将其添加到您的application.rb : config . middleware...
机架足够的 Json 机架中间件以减少 json 有效负载的大小 - 允许使用 json api 的客户端选择有效... Rails :: Application # Middleware options # root: the root key for the json payload , default: nil # target
机架式CSRF检测器仅当您使用GET和POST Rails才能保护您免受CSRF的侵害。 该中间件可帮助您确定GET请求何时导致应用程序状态更改。这个怎么运作rack-csrf-detector猴子修补ActiveRecord来标识导致数据库commit GET...
安装将rack-reducer添加到您的Gemfile中: gem 'rack-reducer' , require : 'rack/reducer' Rack :: Reducer除了Rack本身之外没有其他依赖项。利用如果您的应用需要呈现数据库记录列表,则可能希望这些记录可通过URL...
Rack :: Defense是Rack中间件,可以轻松地向基于Rack的应用程序(Ruby On Rails,Sintratra等)添加请求速率限制和请求过滤。 使用提供的时间段,请求条件和最大请求数,请求(也称为速率限制)在滑动窗口上...
安装将此行添加到应用程序的Gemfile中: gem 'rack-no_animations' 然后执行: $ bundle或将其自己安装为: $ gem install rack-no_animations用法在config/environments/test.rb将中间件添加到rails中,例如: ...
机架:: LiveReload 不推荐使用此fork:改为查看 。 嘿,您的有了! 不再需要浏览器扩展! 只需将其插入您的中间件堆栈中就... # Add Rack::LiveReload to the bottom of the middleware stack with the default opti