Skip to content

Tags: pengjia/tornado

Tags

v3.2.1

Toggle v3.2.1's commit message
What's new in Tornado 3.2.1

===========================

May 5, 2014
-----------

Security fixes
~~~~~~~~~~~~~~

* The signed-value format used by `.RequestHandler.set_secure_cookie`
  and `.RequestHandler.get_secure_cookie` has changed to be more secure.
  **This is a disruptive change**.  The ``secure_cookie`` functions
  take new ``version`` parameters to support transitions between cookie
  formats.
* The new cookie format fixes a vulnerability that may be present in
  applications that use multiple cookies where the name of one cookie
  is a prefix of the name of another.
* To minimize disruption, cookies in the older format will be accepted
  by default until they expire.  Applications that may be vulnerable
  can reject all cookies in the older format by passing ``min_version=2``
  to `.RequestHandler.get_secure_cookie`.

Backwards-compatibility notes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* Signed cookies issued by `.RequestHandler.set_secure_cookie` in Tornado
  3.2.1 cannot be read by older releases.  If you need to run 3.2.1
  in parallel with older releases, you can pass ``version=1`` to
  `.RequestHandler.set_secure_cookie` to issue cookies that are
  backwards-compatible (but have a known weakness, so this option
  should only be used for a transitional period).

Other changes
~~~~~~~~~~~~~

* The C extension used to speed up the websocket module now compiles
  correctly on Windows with MSVC and 64-bit mode.  The fallback to
  the pure-Python alternative now works correctly on Mac OS X machines
  with no C compiler installed.

v3.2.0

Toggle v3.2.0's commit message
What's new in Tornado 3.2

=========================

Jan 14, 2014
------------

Installation
~~~~~~~~~~~~
* Tornado now depends on the `backports.ssl_match_hostname
  <https://pypi.python.org/pypi/backports.ssl_match_hostname>`_ when
  running on Python 2.  This will be installed automatically when using ``pip``
  or ``easy_install``
* Tornado now includes an optional C extension module, which greatly improves
  performance of websockets.  This extension will be built automatically
  if a C compiler is found at install time.

New modules
~~~~~~~~~~~

* The `tornado.platform.asyncio` module provides integration with the
  ``asyncio`` module introduced in Python 3.4 (also available for Python
  3.3 with ``pip install asyncio``).

`tornado.auth`
~~~~~~~~~~~~~~

* Added `.GoogleOAuth2Mixin` support authentication to Google services
  with OAuth 2 instead of OpenID and OAuth 1.
* `.FacebookGraphMixin` has been updated to use the current Facebook login
  URL, which saves a redirect.

`tornado.concurrent`
~~~~~~~~~~~~~~~~~~~~

* `.TracebackFuture` now accepts a ``timeout`` keyword argument (although
  it is still incorrect to use a non-zero timeout in non-blocking code).

``tornado.curl_httpclient``
~~~~~~~~~~~~~~~~~~~~~~~~~~~

* ``tornado.curl_httpclient`` now works on Python 3 with the
  soon-to-be-released pycurl 7.19.3, which will officially support
  Python 3 for the first time.  Note that there are some unofficial
  Python 3 ports of pycurl (Ubuntu has included one for its past
  several releases); these are not supported for use with Tornado.

`tornado.escape`
~~~~~~~~~~~~~~~~

* `.xhtml_escape` now escapes apostrophes as well.
* `tornado.escape.utf8`, `.to_unicode`, and `.native_str` now raise
  `TypeError` instead of `AssertionError` when given an invalid value.

`tornado.gen`
~~~~~~~~~~~~~

* Coroutines may now yield dicts in addition to lists to wait for
  multiple tasks in parallel.
* Improved performance of `tornado.gen` when yielding a `.Future` that is
  already done.

`tornado.httpclient`
~~~~~~~~~~~~~~~~~~~~

* `tornado.httpclient.HTTPRequest` now uses property setters so that
  setting attributes after construction applies the same conversions
  as ``__init__`` (e.g. converting the body attribute to bytes).

`tornado.httpserver`
~~~~~~~~~~~~~~~~~~~~

* Malformed ``x-www-form-urlencoded`` request bodies will now log a warning
  and continue instead of causing the request to fail (similar to the existing
  handling of malformed ``multipart/form-data`` bodies.  This is done mainly
  because some libraries send this content type by default even when the data
  is not form-encoded.
* Fix some error messages for unix sockets (and other non-IP sockets)

`tornado.ioloop`
~~~~~~~~~~~~~~~~

* `.IOLoop` now uses `~.IOLoop.handle_callback_exception` consistently for
  error logging.
* `.IOLoop` now frees callback objects earlier, reducing memory usage
  while idle.
* `.IOLoop` will no longer call `logging.basicConfig` if there is a handler
  defined for the root logger or for the ``tornado`` or ``tornado.application``
  loggers (previously it only looked at the root logger).

`tornado.iostream`
~~~~~~~~~~~~~~~~~~

* `.IOStream` now recognizes ``ECONNABORTED`` error codes in more places
  (which was mainly an issue on Windows).
* `.IOStream` now frees memory earlier if a connection is closed while
  there is data in the write buffer.
* `.PipeIOStream` now handles ``EAGAIN`` error codes correctly.
* `.SSLIOStream` now initiates the SSL handshake automatically without
  waiting for the application to try and read or write to the connection.
* Swallow a spurious exception from ``set_nodelay`` when a connection
  has been reset.

`tornado.locale`
~~~~~~~~~~~~~~~~

* `.Locale.format_date` no longer forces the use of absolute
  dates in Russian.

`tornado.log`
~~~~~~~~~~~~~

* Fix an error from `tornado.log.enable_pretty_logging` when
  `sys.stderr` does not have an ``isatty`` method.
* `tornado.log.LogFormatter` now accepts keyword arguments ``fmt``
  and ``datefmt``.

`tornado.netutil`
~~~~~~~~~~~~~~~~~

* `.is_valid_ip` (and therefore ``HTTPRequest.remote_ip``) now rejects
  empty strings.
* Synchronously using `.ThreadedResolver` at import time to resolve
  a unicode hostname no longer deadlocks.

`tornado.platform.twisted`
~~~~~~~~~~~~~~~~~~~~~~~~~~

* `.TwistedResolver` now has better error handling.

`tornado.process`
~~~~~~~~~~~~~~~~~

* `.Subprocess` no longer leaks file descriptors if `subprocess.Popen` fails.

``tornado.simple_httpclient``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* ``simple_httpclient`` now applies the ``connect_timeout`` to requests
  that are queued and have not yet started.
* On Python 2.6, ``simple_httpclient`` now uses TLSv1 instead of SSLv3.
* ``simple_httpclient`` now enforces the connect timeout during DNS resolution.
* The embedded ``ca-certificates.crt`` file has been updated with the current
  Mozilla CA list.

`tornado.web`
~~~~~~~~~~~~~

* `.StaticFileHandler` no longer fails if the client requests a ``Range`` that
  is larger than the entire file (Facebook has a crawler that does this).
* `.RequestHandler.on_connection_close` now works correctly on subsequent
  requests of a keep-alive connection.
* New application setting ``default_handler_class`` can be used to easily
  set up custom 404 pages.
* New application settings ``autoreload``, ``compiled_template_cache``,
  ``static_hash_cache``, and ``serve_traceback`` can be used to control
  individual aspects of debug mode.
* New methods `.RequestHandler.get_query_argument` and
  `.RequestHandler.get_body_argument` and new attributes
  `.HTTPRequest.query_arguments` and `.HTTPRequest.body_arguments` allow access
  to arguments without intermingling those from the query string with those
  from the request body.
* `.RequestHandler.decode_argument` and related methods now raise
  an ``HTTPError(400)`` instead of `UnicodeDecodeError` when the
  argument could not be decoded.
* `.RequestHandler.clear_all_cookies` now accepts ``domain`` and ``path``
  arguments, just like `~.RequestHandler.clear_cookie`.
* It is now possible to specify handlers by name when using the `.URLSpec`
  class.
* `.Application` now accepts 4-tuples to specify the ``name`` parameter
  (which previously required constructing a `.URLSpec` object instead of
  a tuple).
* Fixed an incorrect error message when handler methods return a value
  other than None or a Future.
* Exceptions will no longer be logged twice when using both ``@asynchronous``
  and ``@gen.coroutine``

`tornado.websocket`
~~~~~~~~~~~~~~~~~~~

* `.WebSocketHandler.write_message` now raises `.WebSocketClosedError` instead
  of `AttributeError` when the connection has been closed.
* `.websocket_connect` now accepts preconstructed ``HTTPRequest`` objects.
* Fix a bug with `.WebSocketHandler` when used with some proxies that
  unconditionally modify the ``Connection`` header.
* `.websocket_connect` now returns an error immediately for refused connections
  instead of waiting for the timeout.
* `.WebSocketClientConnection` now has a ``close`` method.

`tornado.wsgi`
~~~~~~~~~~~~~~

* `.WSGIContainer` now calls the iterable's ``close()`` method even if
  an error is raised, in compliance with the spec.

v3.2.0b2

Toggle v3.2.0b2's commit message
Set version number to 3.2b2

v3.2.0b1

Toggle v3.2.0b1's commit message
Set version number to 3.2b1.

v3.1.1

Toggle v3.1.1's commit message
What's new in Tornado 3.1.1

===========================

Sep 1, 2013
-----------

* `.StaticFileHandler` no longer fails if the client requests a ``Range`` that
  is larger than the entire file (Facebook has a crawler that does this).
* `.RequestHandler.on_connection_close` now works correctly on subsequent
  requests of a keep-alive connection.

v3.1.0

Toggle v3.1.0's commit message
What's new in Tornado 3.1

=========================

Jun 15, 2013
------------

Multiple modules
~~~~~~~~~~~~~~~~

* Many reference cycles have been broken up throughout the package,
  allowing for more efficient garbage collection on CPython.
* Silenced some log messages when connections are opened and immediately
  closed (i.e. port scans), or other situations related to closed
  connections.
* Various small speedups: `.HTTPHeaders` case normalization, `.UIModule`
  proxy objects, precompile some regexes.

`tornado.auth`
~~~~~~~~~~~~~~

* `~tornado.auth.OAuthMixin` always sends ``oauth_version=1.0`` in its
  request as required by the spec.
* `~tornado.auth.FacebookGraphMixin` now uses ``self._FACEBOOK_BASE_URL``
  in `~.FacebookGraphMixin.facebook_request` to allow the base url to be
  overridden.
* The ``authenticate_redirect`` and ``authorize_redirect`` methods in the
  `tornado.auth` mixin classes all now return Futures.  These methods
  are asynchronous in `.OAuthMixin` and derived classes, although they
  do not take a callback.  The `.Future` these methods return must be
  yielded if they are called from a function decorated with `.gen.coroutine`
  (but not `.gen.engine`).
* `.TwitterMixin` now uses ``/account/verify_credentials`` to get information
  about the logged-in user, which is more robust against changing screen
  names.
* The ``demos`` directory (in the source distribution) has a new
  ``twitter`` demo using `.TwitterMixin`.

`tornado.escape`
~~~~~~~~~~~~~~~~

* `.url_escape` and `.url_unescape` have a new ``plus`` argument (defaulting
  to True for consistency with the previous behavior) which specifies
  whether they work like `urllib.parse.unquote` or `urllib.parse.unquote_plus`.

`tornado.gen`
~~~~~~~~~~~~~

* Fixed a potential memory leak with long chains of `tornado.gen` coroutines.

`tornado.httpclient`
~~~~~~~~~~~~~~~~~~~~

* `tornado.httpclient.HTTPRequest` takes a new argument ``auth_mode``,
  which can be either ``basic`` or ``digest``.  Digest authentication
  is only supported with ``tornado.curl_httpclient``.
* ``tornado.curl_httpclient`` no longer goes into an infinite loop when
  pycurl returns a negative timeout.
* ``curl_httpclient`` now supports the ``PATCH`` and ``OPTIONS`` methods
  without the use of ``allow_nonstandard_methods=True``.
* 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``.
* ``simple_httpclient`` no longer logs exceptions, since those exceptions
  are made available to the caller as ``HTTPResponse.error``.

`tornado.httpserver`
~~~~~~~~~~~~~~~~~~~~

* `tornado.httpserver.HTTPServer` handles malformed HTTP headers more
  gracefully.
* `.HTTPServer` now supports lists of IPs in ``X-Forwarded-For``
  (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`.
* 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
  case-insensitive.
* The `str` and `repr` of `tornado.httpserver.HTTPRequest` no longer
  include the request body, reducing log spam on errors (and potential
  exposure/retention of private data).

`tornado.httputil`
~~~~~~~~~~~~~~~~~~

* The cache used in `.HTTPHeaders` will no longer grow without bound.

`tornado.ioloop`
~~~~~~~~~~~~~~~~

* Some `.IOLoop` implementations (such as ``pyzmq``) accept objects
  other than integer file descriptors; these objects will now have
  their ``.close()`` method called when the ``IOLoop` is closed with
  ``all_fds=True``.
* The stub handles left behind by `.IOLoop.remove_timeout` will now get
  cleaned up instead of waiting to expire.

`tornado.iostream`
~~~~~~~~~~~~~~~~~~

* Fixed a bug in `.BaseIOStream.read_until_close` that would sometimes
  cause data to be passed to the final callback instead of the streaming
  callback.
* The `.IOStream` close callback is now run more reliably if there is
  an exception in ``_try_inline_read``.
* 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.

`tornado.locale`
~~~~~~~~~~~~~~~~

* `.Locale.format_date` now works on Python 3.

`tornado.netutil`
~~~~~~~~~~~~~~~~~

* The default `.Resolver` implementation now works on Solaris.
* `.Resolver` now has a `~.Resolver.close` method.
* Fixed a potential CPU DoS when ``tornado.netutil.ssl_match_hostname``
  is used on certificates with an abusive wildcard pattern.
* All instances of `.ThreadedResolver` now share a single thread pool,
  whose size is set by the first one to be created (or the static
  ``Resolver.configure`` method).
* `.ExecutorResolver` is now documented for public use.
* `.bind_sockets` now works in configurations with incomplete IPv6 support.

`tornado.options`
~~~~~~~~~~~~~~~~~

* `tornado.options.define` with ``multiple=True`` now works on Python 3.
* `tornado.options.options` and other `.OptionParser` instances support some
  new dict-like methods: `~.OptionParser.items()`, iteration over keys,
  and (read-only) access to options with square braket syntax.
  `.OptionParser.group_dict` returns all options with a given group
  name, and `.OptionParser.as_dict` returns all options.

`tornado.process`
~~~~~~~~~~~~~~~~~

* `tornado.process.Subprocess` no longer leaks file descriptors into
  the child process, which fixes a problem in which the child could not
  detect that the parent process had closed its stdin pipe.
* `.Subprocess.set_exit_callback` now works for subprocesses created
  without an explicit ``io_loop`` parameter.

`tornado.stack_context`
~~~~~~~~~~~~~~~~~~~~~~~

* `tornado.stack_context` has been rewritten and is now much faster.
* New function `.run_with_stack_context` facilitates the use of stack
  contexts with coroutines.

`tornado.tcpserver`
~~~~~~~~~~~~~~~~~~~

* The constructors of `.TCPServer` and `.HTTPServer` now take a
  ``max_buffer_size`` keyword argument.

`tornado.template`
~~~~~~~~~~~~~~~~~~

* Some internal names used by the template system have been changed;
  now all "reserved" names in templates start with ``_tt_``.

`tornado.testing`
~~~~~~~~~~~~~~~~~

* `tornado.testing.AsyncTestCase.wait` now raises the correct exception
  when it has been modified by `tornado.stack_context`.
* `tornado.testing.gen_test` can now be called as ``@gen_test(timeout=60)``
  to give some tests a longer timeout than others.
* The environment variable ``ASYNC_TEST_TIMEOUT`` can now be set to
  override the default timeout for `.AsyncTestCase.wait` and `.gen_test`.
* `.bind_unused_port` now passes ``None`` instead of ``0`` as the port
  to ``getaddrinfo``, which works better with some unusual network
  configurations.

`tornado.util`
~~~~~~~~~~~~~~

* `tornado.util.import_object` now works with top-level module names that
  do not contain a dot.
* `tornado.util.import_object` now consistently raises `ImportError`
  instead of `AttributeError` when it fails.

`tornado.web`
~~~~~~~~~~~~~

* The ``handlers`` list passed to the `tornado.web.Application` constructor
  and `~tornado.web.Application.add_handlers` methods can now contain
  lists in addition to tuples and `~tornado.web.URLSpec` objects.
* `tornado.web.StaticFileHandler` now works on Windows when the client
  passes an ``If-Modified-Since`` timestamp before 1970.
* New method `.RequestHandler.log_exception` can be overridden to
  customize the logging behavior when an exception is uncaught.  Most
  apps that currently override ``_handle_request_exception`` can now
  use a combination of `.RequestHandler.log_exception` and
  `.write_error`.
* `.RequestHandler.get_argument` now raises `.MissingArgumentError`
  (a subclass of `tornado.web.HTTPError`, which is what it raised previously)
  if the argument cannot be found.
* `.Application.reverse_url` now uses `.url_escape` with ``plus=False``,
  i.e. spaces are encoded as ``%20`` instead of ``+``.
* Arguments extracted from the url path are now decoded with
  `.url_unescape` with ``plus=False``, so plus signs are left as-is
  instead of being turned into spaces.
* `.RequestHandler.send_error` will now only be called once per request,
  even if multiple exceptions are caught by the stack context.
* The `tornado.web.asynchronous` decorator is no longer necessary for
  methods that return a `.Future` (i.e. those that use the `.gen.coroutine`
  or `.return_future` decorators)
* `.RequestHandler.prepare` may now be asynchronous if it returns a
  `.Future`.  The `~tornado.web.asynchronous` decorator is not used with
  ``prepare``; one of the `.Future`-related decorators should be used instead.
* ``RequestHandler.current_user`` may now be assigned to normally.
* `.RequestHandler.redirect` no longer silently strips control characters
  and whitespace.  It is now an error to pass control characters, newlines
  or tabs.
* `.StaticFileHandler` has been reorganized internally and now has additional
  extension points that can be overridden in subclasses.
* `.StaticFileHandler` now supports HTTP ``Range`` requests.
  `.StaticFileHandler` is still not suitable for files too large to
  comfortably fit in memory, but ``Range`` support is necessary in some
  browsers to enable seeking of HTML5 audio and video.
* `.StaticFileHandler` now uses longer hashes by default, and uses the same
  hashes for ``Etag`` as it does for versioned urls.
* `.StaticFileHandler.make_static_url` and `.RequestHandler.static_url`
  now have an additional keyword argument ``include_version`` to suppress
  the url versioning.
* `.StaticFileHandler` now reads its file in chunks, which will reduce
  memory fragmentation.
* Fixed a problem with the ``Date`` header and cookie expiration dates
  when the system locale is set to a non-english configuration.

`tornado.websocket`
~~~~~~~~~~~~~~~~~~~

* `.WebSocketHandler` now catches `.StreamClosedError` and runs
  `~.WebSocketHandler.on_close` immediately instead of logging a
  stack trace.
* New method `.WebSocketHandler.set_nodelay` can be used to set the
  ``TCP_NODELAY`` flag.

`tornado.wsgi`
~~~~~~~~~~~~~~

* Fixed an exception in `.WSGIContainer` when the connection is closed
  while output is being written.

v3.0.2

Toggle v3.0.2's commit message
What's new in Tornado 3.0.2

===========================

Jun 2, 2013
-----------

* `tornado.auth.TwitterMixin` now defaults to version 1.1 of the
  Twitter API, instead of version 1.0 which is being `discontinued on
  June 11 <https://dev.twitter.com/calendar>`_.  It also now uses HTTPS
  when talking to Twitter.
* Fixed a potential memory leak with a long chain of `.gen.coroutine`
  or `.gen.engine` functions.

v3.0.1

Toggle v3.0.1's commit message
What's new in Tornado 3.0.1

===========================

Apr 8, 2013
-----------

* The interface of `tornado.auth.FacebookGraphMixin` is now consistent
  with its documentation and the rest of the module.  The
  ``get_authenticated_user`` and ``facebook_request`` methods return a
  ``Future`` and the ``callback`` argument is optional.
* The `tornado.testing.gen_test` decorator will no longer be recognized
  as a (broken) test by ``nose``.
* Work around a bug in Ubuntu 13.04 betas involving an incomplete backport
  of the `ssl.match_hostname` function.
* `tornado.websocket.websocket_connect` now fails cleanly when it attempts
  to connect to a non-websocket url.
* `tornado.testing.LogTrapTestCase` once again works with byte strings
  on Python 2.
* The ``request`` attribute of `tornado.httpclient.HTTPResponse` is
  now always an `~tornado.httpclient.HTTPRequest`, never a ``_RequestProxy``.
* Exceptions raised by the `tornado.gen` module now have better messages
  when tuples are used as callback keys.

v3.0.0

Toggle v3.0.0's commit message
What's new in Tornado 3.0

=========================

Mar 29, 2013
------------

Highlights
^^^^^^^^^^

* The ``callback`` argument to many asynchronous methods is now
  optional, and these methods return a `.Future`.  The `tornado.gen`
  module now understands ``Futures``, and these methods can be used
  directly without a `.gen.Task` wrapper.
* New function `.IOLoop.current` returns the `.IOLoop` that is running
  on the current thread (as opposed to `.IOLoop.instance`, which
  returns a specific thread's (usually the main thread's) IOLoop.
* New class `tornado.netutil.Resolver` provides an asynchronous
  interface to DNS resolution.  The default implementation is still
  blocking, but non-blocking implementations are available using one
  of three optional dependencies: `~tornado.netutil.ThreadedResolver`
  using the `concurrent.futures` thread pool,
  ``tornado.platform.caresresolver.CaresResolver`` using the ``pycares``
  library, or ``tornado.platform.twisted.TwistedResolver`` using ``twisted``
* Tornado's logging is now less noisy, and it no longer goes directly
  to the root logger, allowing for finer-grained configuration.
* New class `tornado.process.Subprocess` wraps `subprocess.Popen` with
  `.PipeIOStream` access to the child's file descriptors.
* `.IOLoop` now has a static `configure <.Configurable.configure>`
  method like the one on `.AsyncHTTPClient`, which can be used to
  select an `.IOLoop` implementation other than the default.
* `.IOLoop` can now optionally use a monotonic clock if available
  (see below for more details).

Backwards-incompatible changes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

* Python 2.5 is no longer supported.  Python 3 is now supported in a single
  codebase instead of using ``2to3``
* The ``tornado.database`` module has been removed.  It is now available
  as a separate package, `torndb <https://github.com/bdarnell/torndb>`_
* Functions that take an ``io_loop`` parameter now default to
  `.IOLoop.current()` instead of `.IOLoop.instance()`.
* Empty HTTP request arguments are no longer ignored.  This applies to
  ``HTTPRequest.arguments`` and ``RequestHandler.get_argument[s]``
  in WSGI and non-WSGI modes.
* On Python 3, `tornado.escape.json_encode` no longer accepts byte strings.
* On Python 3, the ``get_authenticated_user`` methods in `tornado.auth`
  now return character strings instead of byte strings.
* ``tornado.netutil.TCPServer`` has moved to its own module,
  `tornado.tcpserver`.
* The Tornado test suite now requires ``unittest2`` when run on Python 2.6.

Detailed changes by module
^^^^^^^^^^^^^^^^^^^^^^^^^^

Multiple modules
~~~~~~~~~~~~~~~~

* Tornado no longer logs to the root logger.  Details on the new logging
  scheme can be found under the `tornado.log` module.  Note that in some
  cases this will require that you add an explicit logging configuration
  in order to see any output (perhaps just calling ``logging.basicConfig()``),
  although both `.IOLoop.start()` and `tornado.options.parse_command_line`
  will do this for you.
* On python 3.2+, methods that take an ``ssl_options`` argument (on
  `.SSLIOStream`, `.TCPServer`, and `.HTTPServer`) now accept either a
  dictionary of options or an `ssl.SSLContext` object.
* New optional dependency on `concurrent.futures` to provide better support
  for working with threads.  `concurrent.futures` is in the standard library
  for Python 3.2+, and can be installed on older versions with
  ``pip install futures``.

`tornado.autoreload`
~~~~~~~~~~~~~~~~~~~~

* `tornado.autoreload` is now more reliable when there are errors at import
  time.
* Calling `tornado.autoreload.start` (or creating an `.Application` with
  ``debug=True``) twice on the same `.IOLoop` now does nothing (instead of
  creating multiple periodic callbacks).  Starting autoreload on
  more than one `.IOLoop` in the same process now logs a warning.
* Scripts run by autoreload no longer inherit ``__future__`` imports
  used by Tornado.

`tornado.auth`
~~~~~~~~~~~~~~

* On Python 3, the ``get_authenticated_user`` method family now returns
  character strings instead of byte strings.
* Asynchronous methods defined in `tornado.auth` now return a
  `.Future`, and their ``callback`` argument is optional.  The
  ``Future`` interface is preferred as it offers better error handling
  (the previous interface just logged a warning and returned None).
* The `tornado.auth` mixin classes now define a method
  ``get_auth_http_client``, which can be overridden to use a non-default
  `.AsyncHTTPClient` instance (e.g. to use a different `.IOLoop`)
* Subclasses of `.OAuthMixin` are encouraged to override
  `.OAuthMixin._oauth_get_user_future` instead of ``_oauth_get_user``,
  although both methods are still supported.

`tornado.concurrent`
~~~~~~~~~~~~~~~~~~~~

* New module `tornado.concurrent` contains code to support working with
  `concurrent.futures`, or to emulate future-based interface when that module
  is not available.

``tornado.curl_httpclient``
~~~~~~~~~~~~~~~~~~~~~~~~~~~

* Preliminary support for ``tornado.curl_httpclient`` on Python 3.  The latest
  official release of pycurl only supports Python 2, but Ubuntu has a
  port available in 12.10 (``apt-get install python3-pycurl``).  This port
  currently has bugs that prevent it from handling arbitrary binary data
  but it should work for textual (utf8) resources.
* Fix a crash with libcurl 7.29.0 if a curl object is created and closed
  without being used.

`tornado.escape`
~~~~~~~~~~~~~~~~

* On Python 3, `~tornado.escape.json_encode` no longer accepts byte strings.
  This mirrors the behavior of the underlying json module.  Python 2 behavior
  is unchanged but should be faster.

`tornado.gen`
~~~~~~~~~~~~~

* New decorator ``@gen.coroutine`` is available as an alternative to
  ``@gen.engine``.  It automatically returns a
  `.Future`, and within the function instead of
  calling a callback you return a value with ``raise
  gen.Return(value)`` (or simply ``return value`` in Python 3.3).
* Generators may now yield `.Future` objects.
* Callbacks produced by `.gen.Callback` and `.gen.Task` are now automatically
  stack-context-wrapped, to minimize the risk of context leaks when used
  with asynchronous functions that don't do their own wrapping.
* Fixed a memory leak involving generators, `.RequestHandler.flush`,
  and clients closing connections while output is being written.
* Yielding a large list no longer has quadratic performance.

`tornado.httpclient`
~~~~~~~~~~~~~~~~~~~~

* `.AsyncHTTPClient.fetch` now returns a `.Future` and its callback argument
  is optional.  When the future interface is used, any error will be raised
  automatically, as if `.HTTPResponse.rethrow` was called.
* `.AsyncHTTPClient.configure` and all `.AsyncHTTPClient` constructors
  now take a ``defaults`` keyword argument.  This argument should be a
  dictionary, and its values will be used in place of corresponding
  attributes of `~tornado.httpclient.HTTPRequest` that are not set.
* All unset attributes of `tornado.httpclient.HTTPRequest` are now
  ``None``.  The default values of some attributes
  (``connect_timeout``, ``request_timeout``, ``follow_redirects``,
  ``max_redirects``, ``use_gzip``, ``proxy_password``,
  ``allow_nonstandard_methods``, and ``validate_cert`` have been moved
  from `~tornado.httpclient.HTTPRequest` to the client
  implementations.
* The ``max_clients`` argument to `.AsyncHTTPClient` is now a keyword-only
  argument.
* Keyword arguments to `.AsyncHTTPClient.configure` are no longer used
  when instantiating an implementation subclass directly.
* Secondary `.AsyncHTTPClient` callbacks (``streaming_callback``,
  ``header_callback``, and ``prepare_curl_callback``) now respect
  `.StackContext`.

`tornado.httpserver`
~~~~~~~~~~~~~~~~~~~~

* `.HTTPServer` no longer logs an error when it is unable to read a second
  request from an HTTP 1.1 keep-alive connection.
* `.HTTPServer` now takes a ``protocol`` keyword argument which can be set
  to ``https`` if the server is behind an SSL-decoding proxy that does not
  set any supported X-headers.
* `tornado.httpserver.HTTPConnection` now has a ``set_close_callback``
  method that should be used instead of reaching into its ``stream``
  attribute.
* Empty HTTP request arguments are no longer ignored.  This applies to
  ``HTTPRequest.arguments`` and ``RequestHandler.get_argument[s]``
  in WSGI and non-WSGI modes.

`tornado.ioloop`
~~~~~~~~~~~~~~~~

* New function `.IOLoop.current` returns the ``IOLoop`` that is running
  on the current thread (as opposed to `.IOLoop.instance`, which returns a
  specific thread's (usually the main thread's) IOLoop).
* New method `.IOLoop.add_future` to run a callback on the IOLoop when
  an asynchronous `.Future` finishes.
* `.IOLoop` now has a static `configure <.Configurable.configure>`
  method like the one on `.AsyncHTTPClient`, which can be used to
  select an `.IOLoop` implementation other than the default.
* The `.IOLoop` poller implementations (``select``, ``epoll``, ``kqueue``)
  are now available as distinct subclasses of `.IOLoop`.  Instantiating
  `.IOLoop` will continue to automatically choose the best available
  implementation.
* The `.IOLoop` constructor has a new keyword argument ``time_func``,
  which can be used to set the time function used when scheduling callbacks.
  This is most useful with the `time.monotonic` function, introduced
  in Python 3.3 and backported to older versions via the ``monotime``
  module.  Using a monotonic clock here avoids problems when the system
  clock is changed.
* New function `.IOLoop.time` returns the current time according to the
  IOLoop.  To use the new monotonic clock functionality, all calls to
  `.IOLoop.add_timeout` must be either pass a `datetime.timedelta` or
  a time relative to `.IOLoop.time`, not `time.time`.  (`time.time` will
  continue to work only as long as the IOLoop's ``time_func`` argument
  is not used).
* New convenience method `.IOLoop.run_sync` can be used to start an IOLoop
  just long enough to run a single coroutine.
* New method `.IOLoop.add_callback_from_signal` is safe to use in a signal
  handler (the regular `.add_callback` method may deadlock).
* `.IOLoop` now uses `signal.set_wakeup_fd` where available (Python 2.6+
  on Unix) to avoid a race condition that could result in Python signal
  handlers being delayed.
* Method ``IOLoop.running()`` has been removed.
* `.IOLoop` has been refactored to better support subclassing.
* `.IOLoop.add_callback` and `.add_callback_from_signal` now take
  ``*args, **kwargs`` to pass along to the callback.

`tornado.iostream`
~~~~~~~~~~~~~~~~~~

* `.IOStream.connect` now has an optional ``server_hostname`` argument
  which will be used for SSL certificate validation when applicable.
  Additionally, when supported (on Python 3.2+), this hostname
  will be sent via SNI (and this is supported by ``tornado.simple_httpclient``)
* Much of `.IOStream` has been refactored into a separate class
  `.BaseIOStream`.
* New class `tornado.iostream.PipeIOStream` provides the IOStream
  interface on pipe file descriptors.
* `.IOStream` now raises a new exception
  ``tornado.iostream.StreamClosedError`` when you attempt to read or
  write after the stream has been closed (by either side).
* `.IOStream` now simply closes the connection when it gets an
  ``ECONNRESET`` error, rather than logging it as an error.
* ``IOStream.error`` no longer picks up unrelated exceptions.
* `.BaseIOStream.close` now has an ``exc_info`` argument (similar to the
  one used in the `logging` module) that can be used to set the stream's
  ``error`` attribute when closing it.
* `.BaseIOStream.read_until_close` now works correctly when it is called
  while there is buffered data.
* Fixed a major performance regression when run on PyPy (introduced in
  Tornado 2.3).

`tornado.log`
~~~~~~~~~~~~~

* New module containing `.enable_pretty_logging` and `.LogFormatter`,
  moved from the options module.
* `.LogFormatter` now handles non-ascii data in messages and tracebacks better.

`tornado.netutil`
~~~~~~~~~~~~~~~~~

* New class `tornado.netutil.Resolver` provides an asynchronous
  interface to DNS resolution.  The default implementation is still
  blocking, but non-blocking implementations are available using one
  of three optional dependencies: `~tornado.netutil.ThreadedResolver`
  using the `concurrent.futures` thread pool,
  `tornado.platform.caresresolver.CaresResolver` using the ``pycares``
  library, or `tornado.platform.twisted.TwistedResolver` using ``twisted``
* New function `tornado.netutil.is_valid_ip` returns true if a given string
  is a valid IP (v4 or v6) address.
* `tornado.netutil.bind_sockets` has a new ``flags`` argument that can
  be used to pass additional flags to ``getaddrinfo``.
* `tornado.netutil.bind_sockets` no longer sets ``AI_ADDRCONFIG``; this will
  cause it to bind to both ipv4 and ipv6 more often than before.
* `tornado.netutil.bind_sockets` now works when Python was compiled
  with ``--disable-ipv6`` but IPv6 DNS resolution is available on the
  system.
* ``tornado.netutil.TCPServer`` has moved to its own module, `tornado.tcpserver`.

`tornado.options`
~~~~~~~~~~~~~~~~~

* The class underlying the functions in `tornado.options` is now public
  (`tornado.options.OptionParser`).  This can be used to create multiple
  independent option sets, such as for subcommands.
* `tornado.options.parse_config_file` now configures logging automatically
  by default, in the same way that `~tornado.options.parse_command_line` does.
* New function `tornado.options.add_parse_callback` schedules a callback
  to be run after the command line or config file has been parsed.  The
  keyword argument ``final=False`` can be used on either parsing function
  to supress these callbacks.
* `tornado.options.define` now takes a ``callback`` argument.  This callback
  will be run with the new value whenever the option is changed.  This is
  especially useful for options that set other options, such as by reading
  from a config file.
* `tornado.options.parse_command_line` ``--help`` output now goes to ``stderr``
  rather than ``stdout``.
* `tornado.options.options` is no longer a subclass of `dict`; attribute-style
  access is now required.
* `tornado.options.options` (and `.OptionParser` instances generally) now
  have a `.mockable()` method that returns a wrapper object compatible with
  `mock.patch <unittest.mock.patch>`.
* Function ``tornado.options.enable_pretty_logging`` has been moved to the
  `tornado.log` module.

`tornado.platform.caresresolver`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* New module containing an asynchronous implementation of the `.Resolver`
  interface, using the ``pycares`` library.

`tornado.platform.twisted`
~~~~~~~~~~~~~~~~~~~~~~~~~~

* New class `tornado.platform.twisted.TwistedIOLoop` allows Tornado
  code to be run on the Twisted reactor (as opposed to the existing
  `.TornadoReactor`, which bridges the gap in the other direction).
* New class `tornado.platform.twisted.TwistedResolver` is an asynchronous
  implementation of the `.Resolver` interface.

`tornado.process`
~~~~~~~~~~~~~~~~~

* New class `tornado.process.Subprocess` wraps `subprocess.Popen` with
  `.PipeIOStream` access to the child's file descriptors.

``tornado.simple_httpclient``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* ``SimpleAsyncHTTPClient`` now takes a ``resolver`` keyword argument
  (which may be passed to either the constructor or `configure
  <.Configurable.configure>`), to allow it to use the new non-blocking
  `tornado.netutil.Resolver`.
* When following redirects, ``SimpleAsyncHTTPClient`` now treats a 302
  response code the same as a 303.  This is contrary to the HTTP spec
  but consistent with all browsers and other major HTTP clients
  (including ``CurlAsyncHTTPClient``).
* The behavior of ``header_callback`` with ``SimpleAsyncHTTPClient`` has
  changed and is now the same as that of ``CurlAsyncHTTPClient``.  The
  header callback now receives the first line of the response (e.g.
  ``HTTP/1.0 200 OK``) and the final empty line.
* ``tornado.simple_httpclient`` now accepts responses with a 304
  status code that include a ``Content-Length`` header.
* Fixed a bug in which ``SimpleAsyncHTTPClient`` callbacks were being run in the
  client's ``stack_context``.

`tornado.stack_context`
~~~~~~~~~~~~~~~~~~~~~~~

* `.stack_context.wrap` now runs the wrapped callback in a more consistent
  environment by recreating contexts even if they already exist on the
  stack.
* Fixed a bug in which stack contexts could leak from one callback
  chain to another.
* Yield statements inside a ``with`` statement can cause stack
  contexts to become inconsistent; an exception will now be raised
  when this case is detected.

`tornado.template`
~~~~~~~~~~~~~~~~~~

* Errors while rendering templates no longer log the generated code,
  since the enhanced stack traces (from version 2.1) should make this
  unnecessary.
* The ``{% apply %}`` directive now works properly with functions that return
  both unicode strings and byte strings (previously only byte strings were
  supported).
* Code in templates is no longer affected by Tornado's ``__future__`` imports
  (which previously included ``absolute_import`` and ``division``).

`tornado.testing`
~~~~~~~~~~~~~~~~~

* New function `tornado.testing.bind_unused_port` both chooses a port
  and binds a socket to it, so there is no risk of another process
  using the same port.  ``get_unused_port`` is now deprecated.
* New decorator `tornado.testing.gen_test` can be used to allow for
  yielding `tornado.gen` objects in tests, as an alternative to the
  ``stop`` and ``wait`` methods of `.AsyncTestCase`.
* `tornado.testing.AsyncTestCase` and friends now extend ``unittest2.TestCase``
  when it is available (and continue to use the standard ``unittest`` module
  when ``unittest2`` is not available)
* `tornado.testing.ExpectLog` can be used as a finer-grained alternative
  to `tornado.testing.LogTrapTestCase`
* The command-line interface to `tornado.testing.main` now supports
  additional arguments from the underlying `unittest` module:
  ``verbose``, ``quiet``, ``failfast``, ``catch``, ``buffer``.
* The deprecated ``--autoreload`` option of `tornado.testing.main` has
  been removed.  Use ``python -m tornado.autoreload`` as a prefix command
  instead.
* The ``--httpclient`` option of `tornado.testing.main` has been moved
  to ``tornado.test.runtests`` so as not to pollute the application
  option namespace.  The `tornado.options` module's new callback
  support now makes it easy to add options from a wrapper script
  instead of putting all possible options in `tornado.testing.main`.
* `.AsyncHTTPTestCase` no longer calls `.AsyncHTTPClient.close` for tests
  that use the singleton `.IOLoop.instance`.
* `.LogTrapTestCase` no longer fails when run in unknown logging
  configurations.  This allows tests to be run under nose, which does its
  own log buffering (`.LogTrapTestCase` doesn't do anything useful in this
  case, but at least it doesn't break things any more).

``tornado.util``
~~~~~~~~~~~~~~~~

* ``tornado.util.b`` (which was only intended for internal use) is gone.

`tornado.web`
~~~~~~~~~~~~~

* `.RequestHandler.set_header` now overwrites previous header values
  case-insensitively.
* `tornado.web.RequestHandler` has new attributes ``path_args`` and
  ``path_kwargs``, which contain the positional and keyword arguments
  that are passed to the ``get``/``post``/etc method.  These attributes
  are set before those methods are called, so they are available during
  ``prepare()``
* `tornado.web.ErrorHandler` no longer requires XSRF tokens on ``POST``
  requests, so posts to an unknown url will always return 404 instead of
  complaining about XSRF tokens.
* Several methods related to HTTP status codes now take a ``reason`` keyword
  argument to specify an alternate "reason" string (i.e. the "Not Found" in
  "HTTP/1.1 404 Not Found").  It is now possible to set status codes other
  than those defined in the spec, as long as a reason string is given.
* The ``Date`` HTTP header is now set by default on all responses.
* ``Etag``/``If-None-Match`` requests now work with `.StaticFileHandler`.
* `.StaticFileHandler` no longer sets ``Cache-Control: public`` unnecessarily.
* When gzip is enabled in a `tornado.web.Application`, appropriate
  ``Vary: Accept-Encoding`` headers are now sent.
* It is no longer necessary to pass all handlers for a host in a single
  `.Application.add_handlers` call.  Now the request will be matched
  against the handlers for any ``host_pattern`` that includes the request's
  ``Host`` header.

`tornado.websocket`
~~~~~~~~~~~~~~~~~~~

* Client-side WebSocket support is now available:
  `tornado.websocket.websocket_connect`
* `.WebSocketHandler` has new methods `~.WebSocketHandler.ping` and
  `~.WebSocketHandler.on_pong` to send pings to the browser (not
  supported on the ``draft76`` protocol)

v2.4.1

Toggle v2.4.1's commit message
What's new in Tornado 2.4.1

===========================

Nov 24, 2012
------------

Bug fixes
~~~~~~~~~

* Fixed a memory leak in `tornado.stack_context` that was especially likely
  with long-running ``@gen.engine`` functions.
* `tornado.auth.TwitterMixin` now works on Python 3.
* Fixed a bug in which `IOStream.read_until_close` with a streaming callback
  would sometimes pass the last chunk of data to the final callback instead
  of the streaming callback.