* Worked around a class of bugs in libcurl that would result in
errors from `.IOLoop.update_handler` in various scenarios including
digest authentication and socks proxies.
+* The ``TCP_NODELAY`` flag is now set when appropriate in ``simple_httpclient``.
`tornado.httpserver`
~~~~~~~~~~~~~~~~~~~~
(it chooses the last, i.e. nearest one).
* Memory is now reclaimed promptly on CPython when an HTTP request
fails because it exceeded the maximum upload size.
-* The ``TCP_NODELAY`` flag is now set when appropriate in `.HTTPServer`
- and ``simple_httpclient``.
+* The ``TCP_NODELAY`` flag is now set when appropriate in `.HTTPServer`.
* The `.HTTPServer` ``no_keep_alive`` option is now respected with
HTTP 1.0 connections that explicitly pass ``Connection: keep-alive``.
* The ``Connection: keep-alive`` check for HTTP 1.0 connections is now
callback.
* The `.IOStream` close callback is now run more reliably if there is
an exception in ``_try_inline_read``.
-* New methods `.BaseIOStream.set_nodelay` and
- `.WebSocketHandler.set_nodelay` can be used to set the
+* New method `.BaseIOStream.set_nodelay` can be used to set the
``TCP_NODELAY`` flag.
* Fixed a case where errors in ``SSLIOStream.connect`` (and
``SimpleAsyncHTTPClient``) were not being reported correctly.
* Fixed a problem with the ``Date`` header and cookie expiration dates
when the system locale is set to a non-english configuration.
+`tornado.websocket`
+~~~~~~~~~~~~~~~~~~~
+
+* New method `.WebSocketHandler.set_nodelay` can be used to set the
+ ``TCP_NODELAY`` flag.
+
`tornado.wsgi`
~~~~~~~~~~~~~~
self.authorize_redirect()
return
self.finish("Posted a message!")
+
+ The given path is relative to ``self._FACEBOOK_BASE_URL``,
+ by default "https://graph.facebook.com".
+
+ .. versionchanged:: 3.1
+ Added the ability to override ``self._FACEBOOK_BASE_URL``.
"""
url = self._FACEBOOK_BASE_URL + path
all_args = {}
as "+" instead of "%20". This is appropriate for query strings
but not for the path component of a URL. Note that this default
is the reverse of Python's urllib module.
+
+ .. versionadded:: 3.1
+ The ``plus`` argument
"""
quote = urllib_parse.quote_plus if plus else urllib_parse.quote
return quote(utf8(value))
is appropriate for query strings and form-encoded values but not
for the path component of a URL. Note that this default is the
reverse of Python's urllib module.
+
+ .. versionadded:: 3.1
+ The ``plus`` argument
"""
unquote = (urllib_parse.unquote_plus if plus else urllib_parse.unquote)
if encoding is None:
is appropriate for query strings and form-encoded values but not
for the path component of a URL. Note that this default is the
reverse of Python's urllib module.
+
+ .. versionadded:: 3.1
+ The ``plus`` argument
"""
if encoding is None:
if plus:
``simple_httpclient`` and true in ``curl_httpclient``
:arg string client_key: Filename for client SSL key, if any
:arg string client_cert: Filename for client SSL certificate, if any
+
+ .. versionadded:: 3.1
+ The ``auth_mode`` argument.
"""
if headers is None:
headers = httputil.HTTPHeaders()
Client's IP address as a string. If ``HTTPServer.xheaders`` is set,
will pass along the real IP address provided by a load balancer
- in the ``X-Real-Ip`` header
+ in the ``X-Real-Ip`` or ``X-Forwarded-For`` header.
+
+ .. versionchanged:: 3.1
+ The list format of ``X-Forwarded-For`` is now supported.
.. attribute:: protocol
be allowed to return before attempting to call `IOLoop.close()`.
Therefore the call to `close` will usually appear just after
the call to `start` rather than near the call to `stop`.
+
+ .. versionchanged:: 3.1
+ If the `IOLoop` implementation supports non-integer objects
+ for "file descriptors", those objects will have their
+ ``close`` method when ``all_fds`` is true.
"""
raise NotImplementedError()
additional bandwidth.
This flag is currently defined only for TCP-based ``IOStreams``.
+
+ .. versionadded:: 3.1
"""
pass
raise NotImplementedError()
def close(self):
- """Closes the `Resolver`, freeing any resources used."""
+ """Closes the `Resolver`, freeing any resources used.
+
+ .. versionadded:: 3.1
+
+ """
pass
return self._options[item].value()
def items(self):
- """A sequence of (name, value) pairs."""
+ """A sequence of (name, value) pairs.
+
+ .. versionadded:: 3.1
+ """
return [(name, opt.value()) for name, opt in self._options.items()]
def groups(self):
- """The set of option-groups created by ``define``."""
+ """The set of option-groups created by ``define``.
+
+ .. versionadded:: 3.1
+ """
return set(opt.group_name for opt in self._options.values())
def group_dict(self, group):
application = Application(
handlers, **options.group_dict('application'))
+
+ .. versionadded:: 3.1
"""
return dict(
(name, opt.value()) for name, opt in self._options.items()
if not group or group == opt.group_name)
def as_dict(self):
- """The names and values of all options."""
+ """The names and values of all options.
+
+ .. versionadded:: 3.1
+ """
return dict(
(name, opt.value()) for name, opt in self._options.items())
@gen.coroutine
def correct():
yield run_with_stack_context(StackContext(ctx), other_coroutine)
+
+ .. versionadded:: 3.1
"""
with context:
return func()
also be used in single-process servers if you want to create
your listening sockets in some way other than
`~tornado.netutil.bind_sockets`.
+
+ .. versionadded:: 3.1
+ The ``max_buffer_size`` argument.
"""
def __init__(self, io_loop=None, ssl_options=None, max_buffer_size=None):
self.io_loop = io_loop
"""Get the global timeout setting for async tests.
Returns a float, the timeout in seconds.
+
+ .. versionadded:: 3.1
"""
try:
return float(os.environ.get('ASYNC_TEST_TIMEOUT'))
def wait(self, condition=None, timeout=None):
"""Runs the `.IOLoop` until stop is called or timeout has passed.
- In the event of a timeout, an exception will be thrown. The default
- timeout is 5 seconds; it may be overridden with a ``timeout`` keyword
- argument or globally with the ASYNC_TEST_TIMEOUT environment variable.
+ In the event of a timeout, an exception will be thrown. The
+ default timeout is 5 seconds; it may be overridden with a
+ ``timeout`` keyword argument or globally with the
+ ``ASYNC_TEST_TIMEOUT`` environment variable.
If ``condition`` is not None, the `.IOLoop` will be restarted
after `stop()` until ``condition()`` returns true.
+
+ .. versionchanged:: 3.1
+ Added the ``ASYNC_TEST_TIMEOUT`` environment variable.
"""
if timeout is None:
timeout = get_async_test_timeout()
response = yield gen.Task(self.fetch('/'))
By default, ``@gen_test`` times out after 5 seconds. The timeout may be
- overridden globally with the ASYNC_TEST_TIMEOUT environment variable,
+ overridden globally with the ``ASYNC_TEST_TIMEOUT`` environment variable,
or for each test with the ``timeout`` keyword argument::
class MyTest(AsyncHTTPTestCase):
def test_something_slow(self):
response = yield gen.Task(self.fetch('/'))
- If both the environment variable and the parameter are set, ``gen_test``
- uses the maximum of the two.
+ .. versionadded:: 3.1
+ The ``timeout`` argument and ``ASYNC_TEST_TIMEOUT`` environment
+ variable.
"""
if timeout is None:
timeout = get_async_test_timeout()
`asynchronous` decorator cannot be used on `prepare`).
If this method returns a `.Future` execution will not proceed
until the `.Future` is done.
+
+ .. versionadded:: 3.1
+ Asynchronous support.
"""
pass
stack traces (on the ``tornado.general`` logger), and all
other exceptions as errors with stack traces (on the
``tornado.application`` logger).
+
+ .. versionadded:: 3.1
"""
if isinstance(value, HTTPError):
if value.log_message:
self.write("Downloaded!")
self.finish()
+ .. versionadded:: 3.1
+ The ability to use ``@gen.coroutine`` without ``@asynchronous``.
"""
# Delay the IOLoop import because it's not available on app engine.
from tornado.ioloop import IOLoop
This is a subclass of `HTTPError`, so if it is uncaught a 400 response
code will be used instead of 500 (and a stack trace will not be logged).
+
+ .. versionadded:: 3.1
"""
def __init__(self, arg_name):
super(MissingArgumentError, self).__init__(
static content from a database), override `get_content`,
`get_content_size`, `get_modified_time`, `get_absolute_path`, and
`validate_absolute_path`.
+
+ .. versionchanged:: 3.1
+ Many of the methods for subclasses were added in Tornado 3.1.
"""
CACHE_MAX_AGE = 86400 * 365 * 10 # 10 years
This allows efficient ``If-None-Match`` checks against cached
versions, and sends the correct ``Etag`` for a partial response
(i.e. the same ``Etag`` as the full file).
+
+ .. versionadded:: 3.1
"""
version_hash = self._get_cached_version(self.absolute_path)
if not version_hash:
return '"%s"' % (version_hash, )
def set_headers(self):
- """Sets the content and caching headers on the response."""
+ """Sets the content and caching headers on the response.
+
+ .. versionadded:: 3.1
+ """
self.set_header("Accept-Ranges", "bytes")
self.set_etag_header()
self.set_extra_headers(self.path)
def should_return_304(self):
- """Returns True if the headers indicate that we should return 304."""
+ """Returns True if the headers indicate that we should return 304.
+
+ .. versionadded:: 3.1
+ """
if self.check_etag_header():
return True
it returns a filesystem path, but other strings may be used
as long as they are unique and understood by the subclass's
overridden `get_content`.
+
+ .. versionadded:: 3.1
"""
abspath = os.path.abspath(os.path.join(root, path))
return abspath
In instance methods, this method's result is available as
``self.absolute_path``.
+
+ .. versionadded:: 3.1
"""
root = os.path.abspath(root)
# os.path.abspath strips a trailing /
This method should either return a byte string or an iterator
of byte strings. The latter is preferred for large files
as it helps reduce memory fragmentation.
+
+ .. versionadded:: 3.1
"""
with open(abspath, "rb") as file:
if start is not None:
This class method may be overridden by subclasses. The
default implementation is a hash of the file's contents.
+
+ .. versionadded:: 3.1
"""
data = cls.get_content(abspath)
hasher = hashlib.md5()
This method may be overridden by subclasses. It will only
be called if a partial result is requested from `get_content`
+
+ .. versionadded:: 3.1
"""
stat_result = self._stat()
return stat_result[stat.ST_SIZE]
May be overridden in subclasses. Should return a `~datetime.datetime`
object or None.
+
+ .. versionadded:: 3.1
"""
stat_result = self._stat()
modified = datetime.datetime.utcfromtimestamp(stat_result[stat.ST_MTIME])
return modified
def get_content_type(self):
- """Returns the ``Content-Type`` header to be used for this request."""
+ """Returns the ``Content-Type`` header to be used for this request.
+
+ .. versionadded:: 3.1
+ """
mime_type, encoding = mimetypes.guess_type(self.absolute_path)
return mime_type
The returned value should be a string, or ``None`` if no version
could be determined.
- This method was previously recommended for subclasses to override;
- `get_content_version` is now preferred as it allows the base
- class to handle caching of the result.
+ .. versionchanged:: 3.1
+ This method was previously recommended for subclasses to override;
+ `get_content_version` is now preferred as it allows the base
+ class to handle caching of the result.
"""
abs_path = cls.get_absolute_path(settings['static_path'], path)
return cls._get_cached_version(abs_path)
connection is established.
See `.BaseIOStream.set_nodelay` for additional details.
+
+ .. versionadded:: 3.1
"""
self.stream.set_nodelay(value)