牧码人 2013-01-25
RequestHandler这个类有超过1000行,看似十一个庞然大物,其实大多是注释和空方法,总体读起来非常容易。
这个类也是blog项目中所有handler的父类,想必大多数tornado项目也是如此,当然顾名思义这个类以及它的派生类用来处理tornado web server收到的httprequest,目前为止还没有看到httpserver的代码,无责任随便猜测一下,一个httprequest处理的大概流程:
目前默认tornado支持如下几种方法:
SUPPORTED_METHODS = ("GET", "HEAD", "POST", "DELETE", "PATCH", "PUT",
"OPTIONS")貌似比几年前看得REST要多好几个啊。。。。head,patch,options是什么情况?
这个类因为是基础类,所以所以定义了一堆空方法,有几个方法值得拿出来单独列在这里的(虽然在基类中并没有任何实现)
def prepare(self):
"""Called at the beginning of a request before `get`/`post`/etc.
Override this method to perform common initialization regardless
of the request method.
"""
pass
def on_finish(self):
"""Called after the end of a request.
Override this method to perform cleanup, logging, etc.
This method is a counterpart to `prepare`. ``on_finish`` may
not produce any output, as it is called after the response
has been sent to the client.
"""
pass
def on_connection_close(self):
"""Called in async handlers if the client closed the connection.
Override this to clean up resources associated with
long-lived connections. Note that this method is called only if
the connection was closed during asynchronous processing; if you
need to do cleanup after every request override `on_finish`
instead.
Proxies may keep a connection open for a time (perhaps
indefinitely) after the client has gone away, so this method
may not be called promptly after the end user closes their
connection.
"""
pass基本上提供了某种程度上的callback,俺没有任何tornado经验,不知到有多少项目中真正用到了。
比较诡异的是,这个类里面定义了一些看起来重复的变量,比如下面两个
# UIModules are available as both `modules` and `_modules` in the
# template namespace. Historically only `modules` was available
# but could be clobbered by user additions to the namespace.
# The template {% module %} directive looks in `_modules` to avoid
# possible conflicts.
self.ui["_modules"] = ObjectDict((n, self._ui_module(n, m)) for n, m in
application.ui_modules.iteritems())
self.ui["modules"] = self.ui["_modules"]还有这两个方法中用到的两个成员变量。。。
def set_header(self, name, value):
"""Sets the given response header name and value.
If a datetime is given, we automatically format it according to the
HTTP specification. If the value is not a string, we convert it to
a string. All header values are then encoded as UTF-8.
"""
self._headers[name] = self._convert_header_value(value)
def add_header(self, name, value):
"""Adds the given response header and value.
Unlike `set_header`, `add_header` may be called multiple times
to return multiple values for the same header.
"""
self._list_headers.append((name, self._convert_header_value(value))) 尼嘛意义何在啊啊。。。还没看到后面,暂时还理解不了。
然后下面是一些已经实现的方法,其中比较重要的一个个拿出来说说
"""Writes the given chunk to the output buffer.
To write the output to the network, use the flush() method below.
If the given chunk is a dictionary, we write it as JSON and set
the Content-Type of the response to be application/json.
(if you want to send JSON as a different Content-Type, call
set_header *after* calling write()).
Note that lists are not converted to JSON because of a potential
cross-site security vulnerability. All JSON output should be
wrapped in a dictionary. More details at
http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx
"""namespace = dict(
handler=self,
request=self.request,
current_user=self.current_user,
locale=self.locale,
=self.locale.translate,
static_url=self.static_url,
xsrf_form_html=self.xsrf_form_html,
reverse_url=self.reverse_url)
namespace.update(self.ui)