3.5. These dependencies will be installed automatically when installing
with ``pip`` or ``setup.py install``. These dependencies will not
be required when running on Google App Engine.
+* Binary wheels are provided for Python 3.5 on Windows (32 and 64 bit).
`tornado.auth`
~~~~~~~~~~~~~~
* `tornado.httpclient.HTTPError` is now copyable with the `copy` module.
+`tornado.httpserver`
+~~~~~~~~~~~~~~~~~~~~
+
+* Requests containing both ``Content-Length`` and ``Transfer-Encoding``
+ will be treated as an error.
+
`tornado.httputil`
~~~~~~~~~~~~~~~~~~
* When following redirects, ``streaming_callback`` and
``header_callback`` will no longer be run on the redirect responses
(only the final non-redirect).
+* Responses containing both ``Content-Length`` and ``Transfer-Encoding``
+ will be treated as an error.
`tornado.template`
~~~~~~~~~~~~~~~~~~
* `tornado.web.HTTPError` is now copyable with the `copy` module.
* The exception `.Finish` now accepts an argument which will be passed to
the method `.RequestHandler.finish`.
+* New `.Application` setting ``xsrf_cookie_kwargs`` can be used to set
+ additional attributes such as ``secure`` or ``httponly`` on the
+ XSRF cookie.
+* `.Application.listen` now returns the `.HTTPServer` it created.
`tornado.websocket`
~~~~~~~~~~~~~~~~~~~
version), but may be set to a lower value temporarily
during version transitions. New in Tornado 3.2.2, which
introduced XSRF cookie version 2.
+ * ``xsrf_cookie_kwargs``: May be set to a dictionary of
+ additional arguments to be passed to `.RequestHandler.set_cookie`
+ for the XSRF cookie.
* ``twitter_consumer_key``, ``twitter_consumer_secret``,
``friendfeed_consumer_key``, ``friendfeed_consumer_secret``,
``google_consumer_key``, ``google_consumer_secret``,
from tornado.log import app_log, gen_log
from tornado.simple_httpclient import SimpleAsyncHTTPClient
from tornado.template import DictLoader
-from tornado.testing import AsyncHTTPTestCase, ExpectLog, gen_test
+from tornado.testing import AsyncHTTPTestCase, AsyncTestCase, ExpectLog, gen_test
from tornado.test.util import unittest, skipBefore35, exec_test
from tornado.util import u, ObjectDict, unicode_type, timedelta_to_seconds
from tornado.web import RequestHandler, authenticated, Application, asynchronous, url, HTTPError, StaticFileHandler, _create_signature_v1, create_signed_value, decode_signed_value, ErrorHandler, UIModule, MissingArgumentError, stream_request_body, Finish, removeslash, addslash, RedirectHandler as WebRedirectHandler, get_signature_key_version, GZipContentEncoding
self.assertEqual(response.code, 200)
+@wsgi_safe
+class XSRFCookieKwargsTest(SimpleHandlerTestCase):
+ class Handler(RequestHandler):
+ def get(self):
+ self.write(self.xsrf_token)
+
+ def get_app_kwargs(self):
+ return dict(xsrf_cookies=True,
+ xsrf_cookie_kwargs=dict(httponly=True))
+
+ def test_xsrf_httponly(self):
+ response = self.fetch("/")
+ self.assertIn('HttpOnly;', response.headers['Set-Cookie'])
+
+
@wsgi_safe
class FinishExceptionTest(SimpleHandlerTestCase):
class Handler(RequestHandler):
self.assertIsNot(e, e2)
self.assertEqual(e.status_code, e2.status_code)
self.assertEqual(e.reason, e2.reason)
+
+
+class ApplicationTest(AsyncTestCase):
+ def test_listen(self):
+ app = Application([])
+ server = app.listen(0)
+ server.stop()
cookies will be converted to version 2 when this method is called
unless the ``xsrf_cookie_version`` `Application` setting is
set to 1.
+
+ .. versionchanged:: 4.3
+ The ``xsrf_cookie_kwargs`` `Application` setting may be
+ used to supply additional cookie options (which will be
+ passed directly to `set_cookie`). For example,
+ ``xsrf_cookie_kwargs=dict(httponly=True, secure=True)``
+ will set the ``secure`` and ``httponly`` flags on the
+ ``_xsrf`` cookie.
"""
if not hasattr(self, "_xsrf_token"):
version, token, timestamp = self._get_raw_xsrf_token()
Note that after calling this method you still need to call
``IOLoop.current().start()`` to start the server.
+
+ Returns the `.HTTPServer` object.
+
+ .. versionchanged:: 4.3
+ Now returns the `.HTTPServer` object.
"""
# import is here rather than top level because HTTPServer
# is not importable on appengine