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.


  • OAuthMixin always sends oauth_version=1.0 in its request as required by the spec.

  • FacebookGraphMixin now uses self._FACEBOOK_BASE_URL in 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.



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


  • 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.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).


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


  • 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.


  • 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.



  • The default Resolver implementation now works on Solaris.

  • Resolver now has a 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.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 has been rewritten and is now much faster.

  • New function run_with_stack_context facilitates the use of stack contexts with coroutines.



  • Some internal names used by the template system have been changed; now all “reserved” names in templates start with _tt_.


  • 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.



  • The handlers list passed to the tornado.web.Application constructor and add_handlers methods can now contain lists in addition to tuples and 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.



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