`
rshua
  • 浏览: 23644 次
  • 性别: Icon_minigender_1
  • 来自: jx
文章分类
社区版块
存档分类
最新评论

rails3 rack middleware

阅读更多

 

今天在研究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
分享到:
评论

相关推荐

    weixin_rails_middleware, 微信集成 ruby weixin_rails_middleware for integration weixin..zip

    `weixin_rails_middleware` 是基于 Ruby 的 Rack 技术构建的,它能够插入到 Rails 应用的请求处理流程中。当收到微信服务器发来的请求时,中间件会自动处理这些请求,如验证签名、解析XML数据,并提供相应的响应。 ...

    Ruby on Rails中Rack中间件的基础学习教程

    ### Ruby on Rails中Rack中间件的基础学习教程 #### 一、Rack简介 Rack是一种轻量级的Web服务器接口规范,它定义了Web服务器和Web应用之间的接口,使得不同的Web应用能够运行在同一服务器上。Rack的重要性在于它...

    rails-auth:RailsRack的基于资源的模块化身份验证和授权

    Rails :: Auth是一个灵活的库,旨在使用Rack Middleware进行身份验证(AuthN)和授权(AuthZ)。 它将,使用AuthN中间件首先验证凭据(例如X.509证书或cookie),然后通过使用这些凭据(例如(ACL))的单独AuthZ...

    rack-bearer_auth:在机架应用程序中使用RFC 6750承载身份验证的中间件

    机架:: BearerAuth Rack :: BearerAuth是在Rack应用中使用承载身份验证的中间件。... use Rack :: BearerAuth :: Middleware do match path : "/foo" do | token | # validate token # AccessToken.where

    rails-beginner-s-guide

    Rails中的Middleware(中间件)机制是构建在Rack之上的。Rack为Ruby Web应用提供了一个简单的接口,允许应用处理HTTP请求和响应。Rails中间件负责应用中各个层次的请求处理逻辑。书中介绍了如何查看和定制中间件,...

    Ruby-RailsFootnotes在每一个Rails页脚展示应用程序的相关信息方便调试

    config.middleware.use Rails::Rack::Debugger config.middleware.use RailsFootnotes ``` 4. 重启Rails服务器以使更改生效。 5. 访问任何Rails应用页面,你将在页脚看到Footnotes链接,点击它们即可查看相关...

    Rack::UTF8Sanitizer.zip

    Rack::UTF8Sanitizer 是一个 Rack 中间件用来清理 URI 和 HTTP 请求头部中包含的无效 UTF-8 字符。Rails 的使用方法:config.middleware.insert 0, Rack::UTF8SanitizerRack 的使用方法:use Rack::UTF8Sanitizer

    ROR绿色最新环境(2013/3/10)

    Rails::Rack::Logger ActionDispatch::ShowExceptions ActionDispatch::DebugExceptions ActionDispatch::RemoteIp ActionDispatch::Reloader ActionDispatch::Callbacks ActiveRecord::ConnectionAdapters::...

    Rails API文档

    7. **Middleware**:Rails使用中间件栈来处理HTTP请求,每个中间件都像一个洋葱层,依次处理请求并传递给下一层。常见的中间件包括Rack(Ruby接口)、Session管理、缓存处理等。 8. **Gemfile和Gemfile.lock**:...

    rack-host-redirect:机架中间件以重定向旧域

    下面的配置适用于Rails,但是该中间件也可以与Sinatra和裸Rack应用配合使用。 滑轨配置 在Gemfile中: gem 'rack-host-redirect' 在config / environments / production.rb中: config . middleware . use Rack ...

    Rails认证系统OmniAuth.zip

    Rails.application.config.middleware.use OmniAuth::Builder do provider :developer unless Rails.env.production? provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET'] end 标签:安全相关...

    ionic-rails-app:与Rails通信的示例Ionic应用程序

    离子+滑轨 这是一段代码,伴随着有关如何使Rails和Ionic完美配合播放的屏幕录像。 入门 创建一个文件夹来容纳应用程序的两面 ...config.middleware.insert_before 0, "Rack::Cors" do allow do origins '*' reso

    rails2.3.2 ExceptionNotifier 配置

    config.middleware.use ExceptionNotifier::Rack ``` 这将插入一个中间件,当有未处理的异常发生时,该中间件会触发邮件通知。 此外,如果你的应用使用的是Rails 2.x版本,可能需要处理ActionMailer的配置,确保它...

    scrolls-rails

    滚动导轨 用法 在config/production.rb : Scrolls::Rails.setup(Rails.application) config.middleware.delete Rails::Rack::Logger config.middleware.use Scrolls::Rails::Rack::QuietLogger

    用于检查应用程序健康状况的简单Rack中间件 -Ruby-Shell-下载

    它可能会使用`Rack::Builder`来构建中间件堆栈,或者直接定义一个类来继承`Rack::Middleware`。健康检查的实现可能包括调用`system`或`spawn`函数来执行Shell命令,或者使用特定的Ruby库来检查特定的服务状态,如`pg...

    rails_warden:在Warden上的瘦导轨插件,用于身份验证

    该应用程序在基本的 Rack层的顶部添加了一些不错的帮助程序。 它的目的是使Warden更易于在基于Rails的环境中使用,而无需像设计中那样繁重。 安装 将此行添加到您的应用程序的Gemfile中: gem 'rails_warden' ...

    Ruby-warden普通的Rack身份认证框架

    1. **Middleware**: Warden 是一个基于Rack的中间件,意味着它可以插入到任何Rack兼容的应用程序中。当请求到达时,Warden可以处理身份验证过程,并在必要时触发会话的创建或终止。 2. **Strategies**: Warden支持...

    Ruby-ApartmentRack和Rails应用的数据库多租户

    Apartment是Ruby社区中广泛使用的库,它为Rack(包括Rails)应用提供了简单的多租户支持。 Apartment gem允许你在单个数据库中为每个租户创建独立的数据空间,从而避免了维护多个独立数据库的复杂性和成本。这种...

    prerender_rails_embedded

    预渲染 Rails 嵌入式 一个 rails gem 使用中间件来渲染 JavaScript Web 应用程序,无需安装其他服务即可动态调用 phantomjs。 概述 使用Prerender Rails Embedded可以避免在 ... use Rack :: Prerender before_render

    akita-rails-har-logger:秋田的Rails中间件

    有两种方法可以检测您的Rack / Rails应用程序。 第一种是将HAR记录器用作Rack中间件。 第二种是将其用作Rails ActionController过滤器。 根据您使用的框架,一个或两个选项可能可供您使用。 如果您对记录RSpec测试...

Global site tag (gtag.js) - Google Analytics