Differences between revisions 16 and 17
Revision 16 as of 2006-08-24 04:56:24
Size: 6676
Editor: ZoomQuiet
Comment:
Revision 17 as of 2006-08-24 04:57:45
Size: 856
Editor: ZoomQuiet
Comment:
Deletions are marked like this. Additions are marked like this.
Line 23: Line 23:
[[Include(/MidWSGI)]]
Line 24: Line 25:
注意一个对象可以在一些应用程序面前是服务器, 而从一些服务器看来却是应用程序. 这样的 "中间件" 可以实现以下一些功能:

Note that a single object may play the role of a server with respect
to some application(s), while also acting as an application with
respect to some server(s). Such "middleware" components can perform
such functions as:

 * 可以根据目的 URL 将一个请求分发 (routing) 给不同的应用程序对象, 并对 {{{environ}}} 做相应修改.

 * Routing a request to different application objects based on the
  target URL, after rewriting the ``environ`` accordingly.

 * 允许多个应用程序或框架在同一个进程中一起运行.

 * Allowing multiple applications or frameworks to run side-by-side
  in the same process

 * 通过在网络上转发请求和响应, 进行负载均衡和远程处理.

 * Load balancing and remote processing, by forwarding requests and
  responses over a network

 * 对内容进行后加工, 比如应用 XSL 样式.

 * Perform content postprocessing, such as applying XSL stylesheets

通常中间件的存在对 服务器 和 应用程序 两边的接口都是透明的, 并且应该不需要提供什么特殊的支持. 用户如果想在应用程序中组合一个中间件, 只需简单地把中间件当个应用程序提供给服务器, 并配置该中间件, 让它以服务器的身份来调用应用程序. 当然中间件包装的这个应用程序实际上可能是一个包装着另一个应用程序的中间件, 如此反复, (以至无穷), 最终形成了传说中的 "中间件栈" .

The presence of middleware in general is transparent to both the
"server/gateway" and the "application/framework" sides of the
interface, and should require no special support. A user who
desires to incorporate middleware into an application simply
provides the middleware component to the server, as if it were
an application, and configures the middleware component to
invoke the application, as if the middleware component were a
server. Of course, the "application" that the middleware wraps
may in fact be another middleware component wrapping another
application, and so on, creating what is referred to as a
"middleware stack".

在多数情况下, 中间件必须同时遵守WSGI服务器和WSGI应用程序两边的限制和需要.
而且在某些情况下, 对中间件的要求比一个纯粹服务器或应用程序还要严格, 这几个方面在规范中还会涉及到.

For the most part, middleware must conform to the restrictions
and requirements of both the server and application sides of
WSGI. In some cases, however, requirements for middleware
are more stringent than for a "pure" server or application,
and these points will be noted in the specification.

这里有一个 (随手写的) 中间件的例子, 它将 {{{text/plain}}} 的响应转换成 pig latin, 用到 Joe Strout 的 {{{piglatin.py}}}.
(注意: 一个 "真实" 的中间件组件很可能会使用一种更成熟的方式来检查 content type, 而且还应该检查一下 content encoding.
另外, 这个简单的例子还忽略了一个单词可能会在数据块的边界处被分割.)

Here is a (tongue-in-cheek) example of a middleware component that
converts ``text/plain`` responses to pig latin, using Joe Strout's
``piglatin.py``. (Note: a "real" middleware component would
probably use a more robust way of checking the content type, and
should also check for a content encoding. Also, this simple
example ignores the possibility that a word might be split across
a block boundary.)

###[#head-229f9e55e6acb5e474a68f7293b978f55ff3beb5-2 示例]
=== 示例 ===
{{{#!python
from piglatin import piglatin

class LatinIter:

    """Transform iterated output to piglatin, if it's okay to do so

    Note that the "okayness" can change until the application yields
    its first non-empty string, so 'transform_ok' has to be a mutable
    truth value."""

    def __init__(self,result,transform_ok):
        if hasattr(result,'close'):
            self.close = result.close
        self._next = iter(result).next
        self.transform_ok = transform_ok

    def __iter__(self):
        return self

    def next(self):
        if self.transform_ok:
            return piglatin(self._next())
        else:
            return self._next()

class Latinator:

    # by default, don't transform output
    transform = False

    def __init__(self, application):
        self.application = application

    def __call__(self, environ, start_response):

        transform_ok = []

        def start_latin(status,response_headers,exc_info=None):

            # Reset ok flag, in case this is a repeat call
            transform_ok[:]=[]

            for name,value in response_headers:
                if name.lower()=='content-type' and value=='text/plain':
                    transform_ok.append(True)
                    # Strip content-length if present, else it'll be wrong
                    response_headers = [(name,value)
                        for name,value in response_headers
                            if name.lower()<>'content-length'
                    ]
                    break

            write = start_response(status,response_headers,exc_info)

            if transform_ok:
                def write_latin(data):
                    write(piglatin(data))
                return write_latin
            else:
                return write

        return LatinIter(self.application(environ,start_latin),transform_ok)


# Run foo_app under a Latinator's control, using the example CGI gateway
from foo_app import foo_app
run_with_cgi(Latinator(foo_app))
}}}

TableOfContents

简介

Include(/AbtWSGI)

相关页面

规范

WSGI应用程序

Include(/AppWSGI)

WSGI服务器

Include(/SrvWSGI)

WSGI中间件

Include(/MidWSGI)

规范细节

Include(/DetailsWSGI)

讨论

WSGI (last edited 2009-12-25 07:17:11 by localhost)