diff -Nru python-tornado-4.5.2/debian/changelog python-tornado-4.5.3/debian/changelog --- python-tornado-4.5.2/debian/changelog 2017-10-31 20:26:31.000000000 +0000 +++ python-tornado-4.5.3/debian/changelog 2018-01-15 13:02:11.000000000 +0000 @@ -1,3 +1,14 @@ +python-tornado (4.5.3-1) unstable; urgency=medium + + * New upstream release + * Bump std-ver to 4.1.3 (no changes needed) + * Push dh compat to 11 + * d/copyright: Bump my copyright year + * Move docs and examples into /usr/share/python-tornado + * Override wrong-section-according-to-package-name for python3-tornado too + + -- Ondřej Nový Mon, 15 Jan 2018 14:02:11 +0100 + python-tornado (4.5.2-1) unstable; urgency=medium [ Julien Puydt ] diff -Nru python-tornado-4.5.2/debian/compat python-tornado-4.5.3/debian/compat --- python-tornado-4.5.2/debian/compat 2017-10-31 20:26:31.000000000 +0000 +++ python-tornado-4.5.3/debian/compat 2018-01-15 11:58:28.000000000 +0000 @@ -1 +1 @@ -10 +11 diff -Nru python-tornado-4.5.2/debian/control python-tornado-4.5.3/debian/control --- python-tornado-4.5.2/debian/control 2017-10-31 20:26:31.000000000 +0000 +++ python-tornado-4.5.3/debian/control 2018-01-15 11:58:32.000000000 +0000 @@ -10,7 +10,7 @@ Julien Puydt , Ondřej Nový , Build-Depends: ca-certificates, - debhelper (>= 10), + debhelper (>= 11), dh-python, python-all-dev, python-backports-abc, @@ -30,7 +30,7 @@ python3-sphinx, python3-sphinx-rtd-theme, python3-twisted, -Standards-Version: 4.1.1 +Standards-Version: 4.1.3 Homepage: http://www.tornadoweb.org/ Vcs-Git: https://anonscm.debian.org/git/python-modules/packages/python-tornado.git Vcs-Browser: https://anonscm.debian.org/cgit/python-modules/packages/python-tornado.git diff -Nru python-tornado-4.5.2/debian/copyright python-tornado-4.5.3/debian/copyright --- python-tornado-4.5.2/debian/copyright 2017-10-31 20:26:31.000000000 +0000 +++ python-tornado-4.5.3/debian/copyright 2018-01-15 11:59:32.000000000 +0000 @@ -33,7 +33,7 @@ 2012 Thomas Kluyver 2012 Julian Taylor 2015 Julien Puydt - 2016-2017 Ondřej Nový + 2016-2018 Ondřej Nový License: Apache-2.0 License: Apache-2.0 diff -Nru python-tornado-4.5.2/debian/.git-dpm python-tornado-4.5.3/debian/.git-dpm --- python-tornado-4.5.2/debian/.git-dpm 2017-10-31 20:26:31.000000000 +0000 +++ python-tornado-4.5.3/debian/.git-dpm 2018-01-15 11:57:06.000000000 +0000 @@ -1,11 +1,11 @@ # see git-dpm(1) from git-dpm package -ae886c3d0c8290e2b5092b2bd6616cf49ce7743c -ae886c3d0c8290e2b5092b2bd6616cf49ce7743c -e889a879916c589d031215316fdabded28f62a9d -e889a879916c589d031215316fdabded28f62a9d -python-tornado_4.5.2.orig.tar.gz -27a7690aae925c6ec6450830befccc11fe3dfecf -506334 +cc6316374c95737dbd2233796aec410306c93d03 +cc6316374c95737dbd2233796aec410306c93d03 +fc4b473db4e6d6591c63f1b03ebee1fd3f4eeea1 +fc4b473db4e6d6591c63f1b03ebee1fd3f4eeea1 +python-tornado_4.5.3.orig.tar.gz +068448750104012deed1186e25cb2513356d1cca +507307 debianTag="debian/%e%v" patchedTag="patched/%e%v" upstreamTag="upstream/%e%u" diff -Nru python-tornado-4.5.2/debian/patches/0007-Use-local-objects.inv-for-intersphinx-mapping.patch python-tornado-4.5.3/debian/patches/0007-Use-local-objects.inv-for-intersphinx-mapping.patch --- python-tornado-4.5.2/debian/patches/0007-Use-local-objects.inv-for-intersphinx-mapping.patch 2017-10-31 20:26:31.000000000 +0000 +++ python-tornado-4.5.3/debian/patches/0007-Use-local-objects.inv-for-intersphinx-mapping.patch 2018-01-15 11:57:06.000000000 +0000 @@ -1,4 +1,4 @@ -From ae886c3d0c8290e2b5092b2bd6616cf49ce7743c Mon Sep 17 00:00:00 2001 +From cc6316374c95737dbd2233796aec410306c93d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Nov=C3=BD?= Date: Wed, 3 Aug 2016 19:02:48 +0200 Subject: Use local objects.inv for intersphinx mapping diff -Nru python-tornado-4.5.2/debian/patches/disable-domain-tests.patch python-tornado-4.5.3/debian/patches/disable-domain-tests.patch --- python-tornado-4.5.2/debian/patches/disable-domain-tests.patch 2017-10-31 20:26:31.000000000 +0000 +++ python-tornado-4.5.3/debian/patches/disable-domain-tests.patch 2018-01-15 11:57:06.000000000 +0000 @@ -1,4 +1,4 @@ -From 580709c89ead6ee26ee602d3f7eb33af579f0387 Mon Sep 17 00:00:00 2001 +From 31b5f00e4189ec7e619992eca1770398a2e4dbaf Mon Sep 17 00:00:00 2001 From: SVN-Git Migration Date: Thu, 8 Oct 2015 13:13:30 -0700 Subject: Disable domain tests to prevent internet access during build diff -Nru python-tornado-4.5.2/debian/patches/fix-ftbfs-on-hurd.patch python-tornado-4.5.3/debian/patches/fix-ftbfs-on-hurd.patch --- python-tornado-4.5.2/debian/patches/fix-ftbfs-on-hurd.patch 2017-10-31 20:26:31.000000000 +0000 +++ python-tornado-4.5.3/debian/patches/fix-ftbfs-on-hurd.patch 2018-01-15 11:57:06.000000000 +0000 @@ -1,4 +1,4 @@ -From 2e6b95748a85d9110f1cc76cfe8b83ebf0d2a76b Mon Sep 17 00:00:00 2001 +From d2f9e204430b258a05de0d81776a41b654809788 Mon Sep 17 00:00:00 2001 From: Mattia Rizzolo Date: Sat, 21 May 2016 21:55:27 +0000 Subject: skip UnixSocketTest on hurd, as unix sockets with SO_REUSEADDR are @@ -14,7 +14,7 @@ 1 file changed, 2 insertions(+) diff --git a/tornado/test/httpserver_test.py b/tornado/test/httpserver_test.py -index 11cb723..3535c56 100644 +index 59eb6fd..5da7271 100644 --- a/tornado/test/httpserver_test.py +++ b/tornado/test/httpserver_test.py @@ -581,6 +581,8 @@ class ManualProtocolTest(HandlerBaseTestCase): diff -Nru python-tornado-4.5.2/debian/patches/ignoreuserwarning.patch python-tornado-4.5.3/debian/patches/ignoreuserwarning.patch --- python-tornado-4.5.2/debian/patches/ignoreuserwarning.patch 2017-10-31 20:26:31.000000000 +0000 +++ python-tornado-4.5.3/debian/patches/ignoreuserwarning.patch 2018-01-15 11:57:06.000000000 +0000 @@ -1,4 +1,4 @@ -From 42aee5633b7c0dba08177b8089e0bd92fdd3fc6d Mon Sep 17 00:00:00 2001 +From 605566d38eed104b9e5ece9870ff228488e0d269 Mon Sep 17 00:00:00 2001 From: SVN-Git Migration Date: Thu, 8 Oct 2015 13:13:31 -0700 Subject: ignore userwarning in tests diff -Nru python-tornado-4.5.2/debian/patches/skip-timing-tests.patch python-tornado-4.5.3/debian/patches/skip-timing-tests.patch --- python-tornado-4.5.2/debian/patches/skip-timing-tests.patch 2017-10-31 20:26:31.000000000 +0000 +++ python-tornado-4.5.3/debian/patches/skip-timing-tests.patch 2018-01-15 11:57:06.000000000 +0000 @@ -1,4 +1,4 @@ -From 1209b9b0d8883e9a141385b5e47bdf4f66853321 Mon Sep 17 00:00:00 2001 +From 2bc847616d56623a3038419d84f5c09e93c6c290 Mon Sep 17 00:00:00 2001 From: SVN-Git Migration Date: Thu, 8 Oct 2015 13:13:32 -0700 Subject: like travis buildd are often slow so skip the same tests @@ -9,10 +9,10 @@ 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tornado/test/util.py b/tornado/test/util.py -index 6c032da..e819771 100644 +index 90a9c7b..126d426 100644 --- a/tornado/test/util.py +++ b/tornado/test/util.py -@@ -23,7 +23,7 @@ skipIfNonUnix = unittest.skipIf(os.name != 'posix' or sys.platform == 'cygwin', +@@ -24,7 +24,7 @@ skipIfNonUnix = unittest.skipIf(os.name != 'posix' or sys.platform == 'cygwin', # travis-ci.org runs our tests in an overworked virtual machine, which makes # timing-related tests unreliable. diff -Nru python-tornado-4.5.2/debian/patches/sockopt.patch python-tornado-4.5.3/debian/patches/sockopt.patch --- python-tornado-4.5.2/debian/patches/sockopt.patch 2017-10-31 20:26:31.000000000 +0000 +++ python-tornado-4.5.3/debian/patches/sockopt.patch 2018-01-15 11:57:06.000000000 +0000 @@ -1,4 +1,4 @@ -From 372e881ad0340313dce63bbce2bbc1ef55110cb5 Mon Sep 17 00:00:00 2001 +From 7d1cb0dd05fedcdb13740ce24b798b7adf673f31 Mon Sep 17 00:00:00 2001 From: SVN-Git Migration Date: Thu, 8 Oct 2015 13:13:33 -0700 Subject: Ignore ENOPROTOOPT errors from SO_REUSEADDR or SO_ERROR on AF_UNIX @@ -12,10 +12,10 @@ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/tornado/iostream.py b/tornado/iostream.py -index a1619c4..1b64723 100644 +index 639ed50..279e558 100644 --- a/tornado/iostream.py +++ b/tornado/iostream.py -@@ -1214,7 +1214,12 @@ class IOStream(BaseIOStream): +@@ -1219,7 +1219,12 @@ class IOStream(BaseIOStream): return future def _handle_connect(self): diff -Nru python-tornado-4.5.2/debian/patches/without-certifi.patch python-tornado-4.5.3/debian/patches/without-certifi.patch --- python-tornado-4.5.2/debian/patches/without-certifi.patch 2017-10-31 20:26:31.000000000 +0000 +++ python-tornado-4.5.3/debian/patches/without-certifi.patch 2018-01-15 11:57:06.000000000 +0000 @@ -1,4 +1,4 @@ -From a5406c8674f27e9800fe8e17f7cc95d4b4db168d Mon Sep 17 00:00:00 2001 +From 072a0c3c557ff1da84c2a2b641edf57db20147df Mon Sep 17 00:00:00 2001 From: Julien Puydt Date: Thu, 8 Oct 2015 13:13:34 -0700 Subject: remove dependance on certifi @@ -15,7 +15,7 @@ 3 files changed, 4 insertions(+), 23 deletions(-) diff --git a/setup.py b/setup.py -index 66d846b..026775f 100644 +index a1feea6..a475920 100644 --- a/setup.py +++ b/setup.py @@ -136,7 +136,7 @@ if setuptools is not None: diff -Nru python-tornado-4.5.2/debian/python3-tornado.lintian-overrides python-tornado-4.5.3/debian/python3-tornado.lintian-overrides --- python-tornado-4.5.2/debian/python3-tornado.lintian-overrides 2017-10-31 20:26:31.000000000 +0000 +++ python-tornado-4.5.3/debian/python3-tornado.lintian-overrides 2018-01-15 12:56:48.000000000 +0000 @@ -1,3 +1,5 @@ +# webserver belongs to web (#665854) +python3-tornado binary: wrong-section-according-to-package-name # test sample, so duplication shouldn't be a problem python3-tornado: duplicated-compressed-file usr/lib/python3/dist-packages/tornado/test/static/sample.xml.bz2 python3-tornado: duplicated-compressed-file usr/lib/python3/dist-packages/tornado/test/static/sample.xml.gz diff -Nru python-tornado-4.5.2/debian/python-tornado-doc.doc-base python-tornado-4.5.3/debian/python-tornado-doc.doc-base --- python-tornado-4.5.2/debian/python-tornado-doc.doc-base 2017-10-31 20:26:31.000000000 +0000 +++ python-tornado-4.5.3/debian/python-tornado-doc.doc-base 2018-01-15 12:55:42.000000000 +0000 @@ -5,5 +5,5 @@ Section: Programming/Python Format: HTML -Index: /usr/share/doc/python-tornado-doc/html/index.html -Files: /usr/share/doc/python-tornado-doc/html/*.html +Index: /usr/share/doc/python-tornado/html/index.html +Files: /usr/share/doc/python-tornado/html/*.html diff -Nru python-tornado-4.5.2/debian/python-tornado-doc.links python-tornado-4.5.3/debian/python-tornado-doc.links --- python-tornado-4.5.2/debian/python-tornado-doc.links 2017-10-31 20:26:31.000000000 +0000 +++ python-tornado-4.5.3/debian/python-tornado-doc.links 2018-01-15 12:50:39.000000000 +0000 @@ -1 +1 @@ -usr/share/doc/python-tornado-doc/html/_sources usr/share/doc/python-tornado-doc/rst +usr/share/doc/python-tornado/html/_sources usr/share/doc/python-tornado/rst diff -Nru python-tornado-4.5.2/debian/python-tornado-doc.lintian-overrides python-tornado-4.5.3/debian/python-tornado-doc.lintian-overrides --- python-tornado-4.5.2/debian/python-tornado-doc.lintian-overrides 2017-10-31 20:26:31.000000000 +0000 +++ python-tornado-4.5.3/debian/python-tornado-doc.lintian-overrides 2018-01-15 12:51:31.000000000 +0000 @@ -2,11 +2,11 @@ python-tornado-doc binary: privacy-breach-uses-embedded-file python-tornado-doc binary: privacy-breach-generic # examples on how to connect to facebook are expected to connect to the web -python-tornado-doc: privacy-breach-facebook usr/share/doc/python-tornado-doc/examples/facebook/templates/modules/post.html (//graph.facebook.com/{{ escape(post[) +python-tornado-doc: privacy-breach-facebook usr/share/doc/python-tornado/examples/facebook/templates/modules/post.html (//graph.facebook.com/{{ escape(post[) # examples, so duplication shouldn't be a problem -python-tornado-doc: duplicate-files usr/share/doc/python-tornado-doc/examples/appengine/templates/archive.html usr/share/doc/python-tornado-doc/examples/blog/templates/archive.html -python-tornado-doc: duplicate-files usr/share/doc/python-tornado-doc/examples/appengine/templates/entry.html usr/share/doc/python-tornado-doc/examples/blog/templates/entry.html -python-tornado-doc: duplicate-files usr/share/doc/python-tornado-doc/examples/appengine/templates/feed.xml usr/share/doc/python-tornado-doc/examples/blog/templates/feed.xml -python-tornado-doc: duplicate-files usr/share/doc/python-tornado-doc/examples/appengine/templates/home.html usr/share/doc/python-tornado-doc/examples/blog/templates/home.html -python-tornado-doc: duplicate-files usr/share/doc/python-tornado-doc/examples/chat/static/chat.css usr/share/doc/python-tornado-doc/examples/websocket/static/chat.css -python-tornado-doc: duplicate-files usr/share/doc/python-tornado-doc/examples/chat/templates/message.html usr/share/doc/python-tornado-doc/examples/websocket/templates/message.html +python-tornado-doc: duplicate-files usr/share/doc/python-tornado/examples/appengine/templates/archive.html usr/share/doc/python-tornado/examples/blog/templates/archive.html +python-tornado-doc: duplicate-files usr/share/doc/python-tornado/examples/appengine/templates/entry.html usr/share/doc/python-tornado/examples/blog/templates/entry.html +python-tornado-doc: duplicate-files usr/share/doc/python-tornado/examples/appengine/templates/feed.xml usr/share/doc/python-tornado/examples/blog/templates/feed.xml +python-tornado-doc: duplicate-files usr/share/doc/python-tornado/examples/appengine/templates/home.html usr/share/doc/python-tornado/examples/blog/templates/home.html +python-tornado-doc: duplicate-files usr/share/doc/python-tornado/examples/chat/static/chat.css usr/share/doc/python-tornado/examples/websocket/static/chat.css +python-tornado-doc: duplicate-files usr/share/doc/python-tornado/examples/chat/templates/message.html usr/share/doc/python-tornado/examples/websocket/templates/message.html diff -Nru python-tornado-4.5.2/debian/rules python-tornado-4.5.3/debian/rules --- python-tornado-4.5.2/debian/rules 2017-10-31 20:26:31.000000000 +0000 +++ python-tornado-4.5.3/debian/rules 2018-01-15 12:50:53.000000000 +0000 @@ -18,7 +18,7 @@ override_dh_sphinxdoc: ifeq (,$(findstring nodocs, $(DEB_BUILD_OPTIONS))) - sphinx-build -b html docs $(CURDIR)/debian/python-tornado-doc/usr/share/doc/python-tornado-doc/html + sphinx-build -b html docs $(CURDIR)/debian/python-tornado-doc/usr/share/doc/python-tornado/html dh_sphinxdoc endif diff -Nru python-tornado-4.5.2/docs/releases/v4.5.3.rst python-tornado-4.5.3/docs/releases/v4.5.3.rst --- python-tornado-4.5.2/docs/releases/v4.5.3.rst 1970-01-01 00:00:00.000000000 +0000 +++ python-tornado-4.5.3/docs/releases/v4.5.3.rst 2018-01-06 17:48:56.000000000 +0000 @@ -0,0 +1,49 @@ +What's new in Tornado 4.5.3 +=========================== + +Jan 6, 2018 +------------ + +`tornado.curl_httpclient` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Improved debug logging on Python 3. + +`tornado.httpserver` +~~~~~~~~~~~~~~~~~~~~ + +- ``Content-Length`` and ``Transfer-Encoding`` headers are no longer + sent with 1xx or 204 responses (this was already true of 304 + responses). +- Reading chunked requests no longer leaves the connection in a broken + state. + +`tornado.iostream` +~~~~~~~~~~~~~~~~~~ + +- Writing a `memoryview` can no longer result in "BufferError: + Existing exports of data: object cannot be re-sized". + +`tornado.options` +~~~~~~~~~~~~~~~~~ + +- Duplicate option names are now detected properly whether they use + hyphens or underscores. + +`tornado.testing` +~~~~~~~~~~~~~~~~~ + +- `.AsyncHTTPTestCase.fetch` now uses ``127.0.0.1`` instead of + ``localhost``, improving compatibility with systems that have + partially-working ipv6 stacks. + +`tornado.web` +~~~~~~~~~~~~~ + +- It is no longer allowed to send a body with 1xx or 204 responses. + +`tornado.websocket` +~~~~~~~~~~~~~~~~~~~ + +- Requests with invalid websocket headers now get a response with + status code 400 instead of a closed connection. diff -Nru python-tornado-4.5.2/docs/releases.rst python-tornado-4.5.3/docs/releases.rst --- python-tornado-4.5.2/docs/releases.rst 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/docs/releases.rst 2018-01-06 17:48:56.000000000 +0000 @@ -4,6 +4,7 @@ .. toctree:: :maxdepth: 2 + releases/v4.5.3 releases/v4.5.2 releases/v4.5.1 releases/v4.5.0 diff -Nru python-tornado-4.5.2/maint/test/appengine/py27/tornado/curl_httpclient.py python-tornado-4.5.3/maint/test/appengine/py27/tornado/curl_httpclient.py --- python-tornado-4.5.2/maint/test/appengine/py27/tornado/curl_httpclient.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/maint/test/appengine/py27/tornado/curl_httpclient.py 2018-01-06 17:48:56.000000000 +0000 @@ -493,6 +493,7 @@ def _curl_debug(self, debug_type, debug_msg): debug_types = ('I', '<', '>', '<', '>') + debug_msg = native_str(debug_msg) if debug_type == 0: curl_log.debug('%s', debug_msg.strip()) elif debug_type in (1, 2): diff -Nru python-tornado-4.5.2/maint/test/appengine/py27/tornado/http1connection.py python-tornado-4.5.3/maint/test/appengine/py27/tornado/http1connection.py --- python-tornado-4.5.2/maint/test/appengine/py27/tornado/http1connection.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/maint/test/appengine/py27/tornado/http1connection.py 2018-01-06 17:48:56.000000000 +0000 @@ -349,10 +349,11 @@ # self._request_start_line.version or # start_line.version? self._request_start_line.version == 'HTTP/1.1' and - # 304 responses have no body (not even a zero-length body), and so - # should not have either Content-Length or Transfer-Encoding. - # headers. + # 1xx, 204 and 304 responses have no body (not even a zero-length + # body), and so should not have either Content-Length or + # Transfer-Encoding headers. start_line.code not in (204, 304) and + (start_line.code < 100 or start_line.code >= 200) and # No need to chunk the output if a Content-Length is specified. 'Content-Length' not in headers and # Applications are discouraged from touching Transfer-Encoding, @@ -592,6 +593,9 @@ chunk_len = yield self.stream.read_until(b"\r\n", max_bytes=64) chunk_len = int(chunk_len.strip(), 16) if chunk_len == 0: + crlf = yield self.stream.read_bytes(2) + if crlf != b'\r\n': + raise httputil.HTTPInputError("improperly terminated chunked request") return total_size += chunk_len if total_size > self._max_body_size: diff -Nru python-tornado-4.5.2/maint/test/appengine/py27/tornado/__init__.py python-tornado-4.5.3/maint/test/appengine/py27/tornado/__init__.py --- python-tornado-4.5.2/maint/test/appengine/py27/tornado/__init__.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/maint/test/appengine/py27/tornado/__init__.py 2018-01-06 17:48:56.000000000 +0000 @@ -25,5 +25,5 @@ # is zero for an official release, positive for a development branch, # or negative for a release candidate or beta (after the base version # number has been incremented) -version = "4.5.2" -version_info = (4, 5, 2, 0) +version = "4.5.3" +version_info = (4, 5, 3, 0) diff -Nru python-tornado-4.5.2/maint/test/appengine/py27/tornado/iostream.py python-tornado-4.5.3/maint/test/appengine/py27/tornado/iostream.py --- python-tornado-4.5.2/maint/test/appengine/py27/tornado/iostream.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/maint/test/appengine/py27/tornado/iostream.py 2018-01-06 17:48:56.000000000 +0000 @@ -1061,7 +1061,12 @@ return chunk def write_to_fd(self, data): - return self.socket.send(data) + try: + return self.socket.send(data) + finally: + # Avoid keeping to data, which can be a memoryview. + # See https://github.com/tornadoweb/tornado/pull/2008 + del data def connect(self, address, callback=None, server_hostname=None): """Connects the socket to a remote address without blocking. @@ -1471,6 +1476,10 @@ # simply return 0 bytes written. return 0 raise + finally: + # Avoid keeping to data, which can be a memoryview. + # See https://github.com/tornadoweb/tornado/pull/2008 + del data def read_from_fd(self): if self._ssl_accepting: @@ -1528,7 +1537,12 @@ os.close(self.fd) def write_to_fd(self, data): - return os.write(self.fd, data) + try: + return os.write(self.fd, data) + finally: + # Avoid keeping to data, which can be a memoryview. + # See https://github.com/tornadoweb/tornado/pull/2008 + del data def read_from_fd(self): try: diff -Nru python-tornado-4.5.2/maint/test/appengine/py27/tornado/options.py python-tornado-4.5.3/maint/test/appengine/py27/tornado/options.py --- python-tornado-4.5.2/maint/test/appengine/py27/tornado/options.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/maint/test/appengine/py27/tornado/options.py 2018-01-06 17:48:56.000000000 +0000 @@ -223,9 +223,10 @@ override options set earlier on the command line, but can be overridden by later flags. """ - if name in self._options: + normalized = self._normalize_name(name) + if normalized in self._options: raise Error("Option %r already defined in %s" % - (name, self._options[name].file_name)) + (normalized, self._options[normalized].file_name)) frame = sys._getframe(0) options_file = frame.f_code.co_filename @@ -247,7 +248,6 @@ group_name = group else: group_name = file_name - normalized = self._normalize_name(name) option = _Option(name, file_name=file_name, default=default, type=type, help=help, metavar=metavar, multiple=multiple, diff -Nru python-tornado-4.5.2/maint/test/appengine/py27/tornado/test/httpserver_test.py python-tornado-4.5.3/maint/test/appengine/py27/tornado/test/httpserver_test.py --- python-tornado-4.5.2/maint/test/appengine/py27/tornado/test/httpserver_test.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/maint/test/appengine/py27/tornado/test/httpserver_test.py 2018-01-06 17:48:56.000000000 +0000 @@ -786,9 +786,12 @@ def test_keepalive_chunked(self): self.http_version = b'HTTP/1.0' self.connect() - self.stream.write(b'POST / HTTP/1.0\r\nConnection: keep-alive\r\n' + self.stream.write(b'POST / HTTP/1.0\r\n' + b'Connection: keep-alive\r\n' b'Transfer-Encoding: chunked\r\n' - b'\r\n0\r\n') + b'\r\n' + b'0\r\n' + b'\r\n') self.read_response() self.assertEqual(self.headers['Connection'], 'Keep-Alive') self.stream.write(b'GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n') diff -Nru python-tornado-4.5.2/maint/test/appengine/py27/tornado/test/iostream_test.py python-tornado-4.5.3/maint/test/appengine/py27/tornado/test/iostream_test.py --- python-tornado-4.5.2/maint/test/appengine/py27/tornado/test/iostream_test.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/maint/test/appengine/py27/tornado/test/iostream_test.py 2018-01-06 17:48:56.000000000 +0000 @@ -9,7 +9,7 @@ from tornado.stack_context import NullContext from tornado.tcpserver import TCPServer from tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, bind_unused_port, ExpectLog, gen_test -from tornado.test.util import unittest, skipIfNonUnix, refusing_port +from tornado.test.util import unittest, skipIfNonUnix, refusing_port, skipPypy3V58 from tornado.web import RequestHandler, Application import errno import logging @@ -539,6 +539,7 @@ client.close() @skipIfNonUnix + @skipPypy3V58 def test_inline_read_error(self): # An error on an inline read is raised without logging (on the # assumption that it will eventually be noticed or logged further @@ -557,6 +558,7 @@ server.close() client.close() + @skipPypy3V58 def test_async_read_error_logging(self): # Socket errors on asynchronous reads should be logged (but only # once). @@ -993,7 +995,7 @@ server_future = self.server_start_tls(_server_ssl_options()) client_future = self.client_start_tls( ssl.create_default_context(), - server_hostname=b'127.0.0.1') + server_hostname='127.0.0.1') with ExpectLog(gen_log, "SSL Error"): with self.assertRaises(ssl.SSLError): # The client fails to connect with an SSL error. diff -Nru python-tornado-4.5.2/maint/test/appengine/py27/tornado/test/options_test.py python-tornado-4.5.3/maint/test/appengine/py27/tornado/test/options_test.py --- python-tornado-4.5.2/maint/test/appengine/py27/tornado/test/options_test.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/maint/test/appengine/py27/tornado/test/options_test.py 2018-01-06 17:48:56.000000000 +0000 @@ -7,7 +7,7 @@ from tornado.options import OptionParser, Error from tornado.util import basestring_type, PY3 -from tornado.test.util import unittest +from tornado.test.util import unittest, subTest if PY3: from io import StringIO @@ -232,6 +232,24 @@ self.assertRegexpMatches(str(cm.exception), 'Option.*foo.*already defined') + def test_error_redefine_underscore(self): + # Ensure that the dash/underscore normalization doesn't + # interfere with the redefinition error. + tests = [ + ('foo-bar', 'foo-bar'), + ('foo_bar', 'foo_bar'), + ('foo-bar', 'foo_bar'), + ('foo_bar', 'foo-bar'), + ] + for a, b in tests: + with subTest(self, a=a, b=b): + options = OptionParser() + options.define(a) + with self.assertRaises(Error) as cm: + options.define(b) + self.assertRegexpMatches(str(cm.exception), + 'Option.*foo.bar.*already defined') + def test_dash_underscore_cli(self): # Dashes and underscores should be interchangeable. for defined_name in ['foo-bar', 'foo_bar']: diff -Nru python-tornado-4.5.2/maint/test/appengine/py27/tornado/test/simple_httpclient_test.py python-tornado-4.5.3/maint/test/appengine/py27/tornado/test/simple_httpclient_test.py --- python-tornado-4.5.2/maint/test/appengine/py27/tornado/test/simple_httpclient_test.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/maint/test/appengine/py27/tornado/test/simple_httpclient_test.py 2018-01-06 17:48:56.000000000 +0000 @@ -272,16 +272,9 @@ @skipIfNoIPv6 def test_ipv6(self): - try: - [sock] = bind_sockets(None, '::1', family=socket.AF_INET6) - port = sock.getsockname()[1] - self.http_server.add_socket(sock) - except socket.gaierror as e: - if e.args[0] == socket.EAI_ADDRFAMILY: - # python supports ipv6, but it's not configured on the network - # interface, so skip this test. - return - raise + [sock] = bind_sockets(None, '::1', family=socket.AF_INET6) + port = sock.getsockname()[1] + self.http_server.add_socket(sock) url = '%s://[::1]:%d/hello' % (self.get_protocol(), port) # ipv6 is currently enabled by default but can be disabled @@ -327,7 +320,7 @@ self.assertNotIn("Content-Length", response.headers) def test_host_header(self): - host_re = re.compile(b"^localhost:[0-9]+$") + host_re = re.compile(b"^127.0.0.1:[0-9]+$") response = self.fetch("/host_echo") self.assertTrue(host_re.match(response.body)) diff -Nru python-tornado-4.5.2/maint/test/appengine/py27/tornado/test/util.py python-tornado-4.5.3/maint/test/appengine/py27/tornado/test/util.py --- python-tornado-4.5.2/maint/test/appengine/py27/tornado/test/util.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/maint/test/appengine/py27/tornado/test/util.py 2018-01-06 17:48:56.000000000 +0000 @@ -1,5 +1,6 @@ from __future__ import absolute_import, division, print_function +import contextlib import os import platform import socket @@ -34,14 +35,39 @@ skipIfNoNetwork = unittest.skipIf('NO_NETWORK' in os.environ, 'network access disabled') -skipIfNoIPv6 = unittest.skipIf(not socket.has_ipv6, 'ipv6 support not present') - - skipBefore33 = unittest.skipIf(sys.version_info < (3, 3), 'PEP 380 (yield from) not available') skipBefore35 = unittest.skipIf(sys.version_info < (3, 5), 'PEP 492 (async/await) not available') skipNotCPython = unittest.skipIf(platform.python_implementation() != 'CPython', 'Not CPython implementation') +# Used for tests affected by +# https://bitbucket.org/pypy/pypy/issues/2616/incomplete-error-handling-in +# TODO: remove this after pypy3 5.8 is obsolete. +skipPypy3V58 = unittest.skipIf(platform.python_implementation() == 'PyPy' and + sys.version_info > (3,) and + sys.pypy_version_info < (5, 9), + 'pypy3 5.8 has buggy ssl module') + + +def _detect_ipv6(): + if not socket.has_ipv6: + # socket.has_ipv6 check reports whether ipv6 was present at compile + # time. It's usually true even when ipv6 doesn't work for other reasons. + return False + sock = None + try: + sock = socket.socket(socket.AF_INET6) + sock.bind(('::1', 0)) + except socket.error: + return False + finally: + if sock is not None: + sock.close() + return True + + +skipIfNoIPv6 = unittest.skipIf(not _detect_ipv6(), 'ipv6 support not present') + def refusing_port(): """Returns a local port number that will refuse all connections. @@ -94,3 +120,15 @@ except AttributeError: return False return mod.startswith('coverage') + + +def subTest(test, *args, **kwargs): + """Compatibility shim for unittest.TestCase.subTest. + + Usage: ``with tornado.test.util.subTest(self, x=x):`` + """ + try: + subTest = test.subTest # py34+ + except AttributeError: + subTest = contextlib.contextmanager(lambda *a, **kw: (yield)) + return subTest(*args, **kwargs) diff -Nru python-tornado-4.5.2/maint/test/appengine/py27/tornado/test/websocket_test.py python-tornado-4.5.3/maint/test/appengine/py27/tornado/test/websocket_test.py --- python-tornado-4.5.2/maint/test/appengine/py27/tornado/test/websocket_test.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/maint/test/appengine/py27/tornado/test/websocket_test.py 2018-01-06 17:48:56.000000000 +0000 @@ -189,6 +189,13 @@ response = self.fetch('/echo') self.assertEqual(response.code, 400) + def test_missing_websocket_key(self): + response = self.fetch('/echo', + headers={'Connection': 'Upgrade', + 'Upgrade': 'WebSocket', + 'Sec-WebSocket-Version': '13'}) + self.assertEqual(response.code, 400) + def test_bad_websocket_version(self): response = self.fetch('/echo', headers={'Connection': 'Upgrade', diff -Nru python-tornado-4.5.2/maint/test/appengine/py27/tornado/test/web_test.py python-tornado-4.5.3/maint/test/appengine/py27/tornado/test/web_test.py --- python-tornado-4.5.2/maint/test/appengine/py27/tornado/test/web_test.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/maint/test/appengine/py27/tornado/test/web_test.py 2018-01-06 17:48:56.000000000 +0000 @@ -356,7 +356,7 @@ response = self.wait() self.assertEqual(response.code, 302) self.assertTrue(re.match( - 'http://example.com/login\?next=http%3A%2F%2Flocalhost%3A[0-9]+%2Fabsolute', + 'http://example.com/login\?next=http%3A%2F%2F127.0.0.1%3A[0-9]+%2Fabsolute', response.headers['Location']), response.headers['Location']) @@ -2134,7 +2134,7 @@ stream.write(b"4\r\nqwer\r\n") data = yield self.data self.assertEquals(data, b"qwer") - stream.write(b"0\r\n") + stream.write(b"0\r\n\r\n") yield self.finished data = yield gen.Task(stream.read_until_close) # This would ideally use an HTTP1Connection to read the response. diff -Nru python-tornado-4.5.2/maint/test/appengine/py27/tornado/testing.py python-tornado-4.5.3/maint/test/appengine/py27/tornado/testing.py --- python-tornado-4.5.2/maint/test/appengine/py27/tornado/testing.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/maint/test/appengine/py27/tornado/testing.py 2018-01-06 17:48:56.000000000 +0000 @@ -423,7 +423,7 @@ def get_url(self, path): """Returns an absolute url for the given path on the test server.""" - return '%s://localhost:%s%s' % (self.get_protocol(), + return '%s://127.0.0.1:%s%s' % (self.get_protocol(), self.get_http_port(), path) def tearDown(self): diff -Nru python-tornado-4.5.2/maint/test/appengine/py27/tornado/web.py python-tornado-4.5.3/maint/test/appengine/py27/tornado/web.py --- python-tornado-4.5.2/maint/test/appengine/py27/tornado/web.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/maint/test/appengine/py27/tornado/web.py 2018-01-06 17:48:56.000000000 +0000 @@ -974,7 +974,8 @@ if self.check_etag_header(): self._write_buffer = [] self.set_status(304) - if self._status_code in (204, 304): + if (self._status_code in (204, 304) or + (self._status_code >= 100 and self._status_code < 200)): assert not self._write_buffer, "Cannot send body with %s" % self._status_code self._clear_headers_for_304() elif "Content-Length" not in self._headers: diff -Nru python-tornado-4.5.2/maint/test/appengine/py27/tornado/websocket.py python-tornado-4.5.3/maint/test/appengine/py27/tornado/websocket.py --- python-tornado-4.5.2/maint/test/appengine/py27/tornado/websocket.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/maint/test/appengine/py27/tornado/websocket.py 2018-01-06 17:48:56.000000000 +0000 @@ -616,6 +616,14 @@ def accept_connection(self): try: self._handle_websocket_headers() + except ValueError: + self.handler.set_status(400) + log_msg = "Missing/Invalid WebSocket headers" + self.handler.finish(log_msg) + gen_log.debug(log_msg) + return + + try: self._accept_connection() except ValueError: gen_log.debug("Malformed WebSocket request received", diff -Nru python-tornado-4.5.2/setup.py python-tornado-4.5.3/setup.py --- python-tornado-4.5.2/setup.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/setup.py 2018-01-06 17:48:56.000000000 +0000 @@ -103,7 +103,7 @@ kwargs = {} -version = "4.5.2" +version = "4.5.3" with open('README.rst') as f: kwargs['long_description'] = f.read() diff -Nru python-tornado-4.5.2/tornado/curl_httpclient.py python-tornado-4.5.3/tornado/curl_httpclient.py --- python-tornado-4.5.2/tornado/curl_httpclient.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/tornado/curl_httpclient.py 2018-01-06 17:48:56.000000000 +0000 @@ -493,6 +493,7 @@ def _curl_debug(self, debug_type, debug_msg): debug_types = ('I', '<', '>', '<', '>') + debug_msg = native_str(debug_msg) if debug_type == 0: curl_log.debug('%s', debug_msg.strip()) elif debug_type in (1, 2): diff -Nru python-tornado-4.5.2/tornado/http1connection.py python-tornado-4.5.3/tornado/http1connection.py --- python-tornado-4.5.2/tornado/http1connection.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/tornado/http1connection.py 2018-01-06 17:48:56.000000000 +0000 @@ -349,10 +349,11 @@ # self._request_start_line.version or # start_line.version? self._request_start_line.version == 'HTTP/1.1' and - # 304 responses have no body (not even a zero-length body), and so - # should not have either Content-Length or Transfer-Encoding. - # headers. + # 1xx, 204 and 304 responses have no body (not even a zero-length + # body), and so should not have either Content-Length or + # Transfer-Encoding headers. start_line.code not in (204, 304) and + (start_line.code < 100 or start_line.code >= 200) and # No need to chunk the output if a Content-Length is specified. 'Content-Length' not in headers and # Applications are discouraged from touching Transfer-Encoding, @@ -592,6 +593,9 @@ chunk_len = yield self.stream.read_until(b"\r\n", max_bytes=64) chunk_len = int(chunk_len.strip(), 16) if chunk_len == 0: + crlf = yield self.stream.read_bytes(2) + if crlf != b'\r\n': + raise httputil.HTTPInputError("improperly terminated chunked request") return total_size += chunk_len if total_size > self._max_body_size: diff -Nru python-tornado-4.5.2/tornado/__init__.py python-tornado-4.5.3/tornado/__init__.py --- python-tornado-4.5.2/tornado/__init__.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/tornado/__init__.py 2018-01-06 17:48:56.000000000 +0000 @@ -25,5 +25,5 @@ # is zero for an official release, positive for a development branch, # or negative for a release candidate or beta (after the base version # number has been incremented) -version = "4.5.2" -version_info = (4, 5, 2, 0) +version = "4.5.3" +version_info = (4, 5, 3, 0) diff -Nru python-tornado-4.5.2/tornado/iostream.py python-tornado-4.5.3/tornado/iostream.py --- python-tornado-4.5.2/tornado/iostream.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/tornado/iostream.py 2018-01-06 17:48:56.000000000 +0000 @@ -1061,7 +1061,12 @@ return chunk def write_to_fd(self, data): - return self.socket.send(data) + try: + return self.socket.send(data) + finally: + # Avoid keeping to data, which can be a memoryview. + # See https://github.com/tornadoweb/tornado/pull/2008 + del data def connect(self, address, callback=None, server_hostname=None): """Connects the socket to a remote address without blocking. @@ -1471,6 +1476,10 @@ # simply return 0 bytes written. return 0 raise + finally: + # Avoid keeping to data, which can be a memoryview. + # See https://github.com/tornadoweb/tornado/pull/2008 + del data def read_from_fd(self): if self._ssl_accepting: @@ -1528,7 +1537,12 @@ os.close(self.fd) def write_to_fd(self, data): - return os.write(self.fd, data) + try: + return os.write(self.fd, data) + finally: + # Avoid keeping to data, which can be a memoryview. + # See https://github.com/tornadoweb/tornado/pull/2008 + del data def read_from_fd(self): try: diff -Nru python-tornado-4.5.2/tornado/options.py python-tornado-4.5.3/tornado/options.py --- python-tornado-4.5.2/tornado/options.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/tornado/options.py 2018-01-06 17:48:56.000000000 +0000 @@ -223,9 +223,10 @@ override options set earlier on the command line, but can be overridden by later flags. """ - if name in self._options: + normalized = self._normalize_name(name) + if normalized in self._options: raise Error("Option %r already defined in %s" % - (name, self._options[name].file_name)) + (normalized, self._options[normalized].file_name)) frame = sys._getframe(0) options_file = frame.f_code.co_filename @@ -247,7 +248,6 @@ group_name = group else: group_name = file_name - normalized = self._normalize_name(name) option = _Option(name, file_name=file_name, default=default, type=type, help=help, metavar=metavar, multiple=multiple, diff -Nru python-tornado-4.5.2/tornado/test/httpserver_test.py python-tornado-4.5.3/tornado/test/httpserver_test.py --- python-tornado-4.5.2/tornado/test/httpserver_test.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/tornado/test/httpserver_test.py 2018-01-06 17:48:56.000000000 +0000 @@ -786,9 +786,12 @@ def test_keepalive_chunked(self): self.http_version = b'HTTP/1.0' self.connect() - self.stream.write(b'POST / HTTP/1.0\r\nConnection: keep-alive\r\n' + self.stream.write(b'POST / HTTP/1.0\r\n' + b'Connection: keep-alive\r\n' b'Transfer-Encoding: chunked\r\n' - b'\r\n0\r\n') + b'\r\n' + b'0\r\n' + b'\r\n') self.read_response() self.assertEqual(self.headers['Connection'], 'Keep-Alive') self.stream.write(b'GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n') diff -Nru python-tornado-4.5.2/tornado/test/iostream_test.py python-tornado-4.5.3/tornado/test/iostream_test.py --- python-tornado-4.5.2/tornado/test/iostream_test.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/tornado/test/iostream_test.py 2018-01-06 17:48:56.000000000 +0000 @@ -9,7 +9,7 @@ from tornado.stack_context import NullContext from tornado.tcpserver import TCPServer from tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, bind_unused_port, ExpectLog, gen_test -from tornado.test.util import unittest, skipIfNonUnix, refusing_port +from tornado.test.util import unittest, skipIfNonUnix, refusing_port, skipPypy3V58 from tornado.web import RequestHandler, Application import errno import logging @@ -539,6 +539,7 @@ client.close() @skipIfNonUnix + @skipPypy3V58 def test_inline_read_error(self): # An error on an inline read is raised without logging (on the # assumption that it will eventually be noticed or logged further @@ -557,6 +558,7 @@ server.close() client.close() + @skipPypy3V58 def test_async_read_error_logging(self): # Socket errors on asynchronous reads should be logged (but only # once). @@ -993,7 +995,7 @@ server_future = self.server_start_tls(_server_ssl_options()) client_future = self.client_start_tls( ssl.create_default_context(), - server_hostname=b'127.0.0.1') + server_hostname='127.0.0.1') with ExpectLog(gen_log, "SSL Error"): with self.assertRaises(ssl.SSLError): # The client fails to connect with an SSL error. diff -Nru python-tornado-4.5.2/tornado/test/options_test.py python-tornado-4.5.3/tornado/test/options_test.py --- python-tornado-4.5.2/tornado/test/options_test.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/tornado/test/options_test.py 2018-01-06 17:48:56.000000000 +0000 @@ -7,7 +7,7 @@ from tornado.options import OptionParser, Error from tornado.util import basestring_type, PY3 -from tornado.test.util import unittest +from tornado.test.util import unittest, subTest if PY3: from io import StringIO @@ -232,6 +232,24 @@ self.assertRegexpMatches(str(cm.exception), 'Option.*foo.*already defined') + def test_error_redefine_underscore(self): + # Ensure that the dash/underscore normalization doesn't + # interfere with the redefinition error. + tests = [ + ('foo-bar', 'foo-bar'), + ('foo_bar', 'foo_bar'), + ('foo-bar', 'foo_bar'), + ('foo_bar', 'foo-bar'), + ] + for a, b in tests: + with subTest(self, a=a, b=b): + options = OptionParser() + options.define(a) + with self.assertRaises(Error) as cm: + options.define(b) + self.assertRegexpMatches(str(cm.exception), + 'Option.*foo.bar.*already defined') + def test_dash_underscore_cli(self): # Dashes and underscores should be interchangeable. for defined_name in ['foo-bar', 'foo_bar']: diff -Nru python-tornado-4.5.2/tornado/test/simple_httpclient_test.py python-tornado-4.5.3/tornado/test/simple_httpclient_test.py --- python-tornado-4.5.2/tornado/test/simple_httpclient_test.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/tornado/test/simple_httpclient_test.py 2018-01-06 17:48:56.000000000 +0000 @@ -272,16 +272,9 @@ @skipIfNoIPv6 def test_ipv6(self): - try: - [sock] = bind_sockets(None, '::1', family=socket.AF_INET6) - port = sock.getsockname()[1] - self.http_server.add_socket(sock) - except socket.gaierror as e: - if e.args[0] == socket.EAI_ADDRFAMILY: - # python supports ipv6, but it's not configured on the network - # interface, so skip this test. - return - raise + [sock] = bind_sockets(None, '::1', family=socket.AF_INET6) + port = sock.getsockname()[1] + self.http_server.add_socket(sock) url = '%s://[::1]:%d/hello' % (self.get_protocol(), port) # ipv6 is currently enabled by default but can be disabled @@ -327,7 +320,7 @@ self.assertNotIn("Content-Length", response.headers) def test_host_header(self): - host_re = re.compile(b"^localhost:[0-9]+$") + host_re = re.compile(b"^127.0.0.1:[0-9]+$") response = self.fetch("/host_echo") self.assertTrue(host_re.match(response.body)) diff -Nru python-tornado-4.5.2/tornado/test/util.py python-tornado-4.5.3/tornado/test/util.py --- python-tornado-4.5.2/tornado/test/util.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/tornado/test/util.py 2018-01-06 17:48:56.000000000 +0000 @@ -1,5 +1,6 @@ from __future__ import absolute_import, division, print_function +import contextlib import os import platform import socket @@ -34,14 +35,39 @@ skipIfNoNetwork = unittest.skipIf('NO_NETWORK' in os.environ, 'network access disabled') -skipIfNoIPv6 = unittest.skipIf(not socket.has_ipv6, 'ipv6 support not present') - - skipBefore33 = unittest.skipIf(sys.version_info < (3, 3), 'PEP 380 (yield from) not available') skipBefore35 = unittest.skipIf(sys.version_info < (3, 5), 'PEP 492 (async/await) not available') skipNotCPython = unittest.skipIf(platform.python_implementation() != 'CPython', 'Not CPython implementation') +# Used for tests affected by +# https://bitbucket.org/pypy/pypy/issues/2616/incomplete-error-handling-in +# TODO: remove this after pypy3 5.8 is obsolete. +skipPypy3V58 = unittest.skipIf(platform.python_implementation() == 'PyPy' and + sys.version_info > (3,) and + sys.pypy_version_info < (5, 9), + 'pypy3 5.8 has buggy ssl module') + + +def _detect_ipv6(): + if not socket.has_ipv6: + # socket.has_ipv6 check reports whether ipv6 was present at compile + # time. It's usually true even when ipv6 doesn't work for other reasons. + return False + sock = None + try: + sock = socket.socket(socket.AF_INET6) + sock.bind(('::1', 0)) + except socket.error: + return False + finally: + if sock is not None: + sock.close() + return True + + +skipIfNoIPv6 = unittest.skipIf(not _detect_ipv6(), 'ipv6 support not present') + def refusing_port(): """Returns a local port number that will refuse all connections. @@ -94,3 +120,15 @@ except AttributeError: return False return mod.startswith('coverage') + + +def subTest(test, *args, **kwargs): + """Compatibility shim for unittest.TestCase.subTest. + + Usage: ``with tornado.test.util.subTest(self, x=x):`` + """ + try: + subTest = test.subTest # py34+ + except AttributeError: + subTest = contextlib.contextmanager(lambda *a, **kw: (yield)) + return subTest(*args, **kwargs) diff -Nru python-tornado-4.5.2/tornado/test/websocket_test.py python-tornado-4.5.3/tornado/test/websocket_test.py --- python-tornado-4.5.2/tornado/test/websocket_test.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/tornado/test/websocket_test.py 2018-01-06 17:48:56.000000000 +0000 @@ -189,6 +189,13 @@ response = self.fetch('/echo') self.assertEqual(response.code, 400) + def test_missing_websocket_key(self): + response = self.fetch('/echo', + headers={'Connection': 'Upgrade', + 'Upgrade': 'WebSocket', + 'Sec-WebSocket-Version': '13'}) + self.assertEqual(response.code, 400) + def test_bad_websocket_version(self): response = self.fetch('/echo', headers={'Connection': 'Upgrade', diff -Nru python-tornado-4.5.2/tornado/test/web_test.py python-tornado-4.5.3/tornado/test/web_test.py --- python-tornado-4.5.2/tornado/test/web_test.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/tornado/test/web_test.py 2018-01-06 17:48:56.000000000 +0000 @@ -356,7 +356,7 @@ response = self.wait() self.assertEqual(response.code, 302) self.assertTrue(re.match( - 'http://example.com/login\?next=http%3A%2F%2Flocalhost%3A[0-9]+%2Fabsolute', + 'http://example.com/login\?next=http%3A%2F%2F127.0.0.1%3A[0-9]+%2Fabsolute', response.headers['Location']), response.headers['Location']) @@ -2134,7 +2134,7 @@ stream.write(b"4\r\nqwer\r\n") data = yield self.data self.assertEquals(data, b"qwer") - stream.write(b"0\r\n") + stream.write(b"0\r\n\r\n") yield self.finished data = yield gen.Task(stream.read_until_close) # This would ideally use an HTTP1Connection to read the response. diff -Nru python-tornado-4.5.2/tornado/testing.py python-tornado-4.5.3/tornado/testing.py --- python-tornado-4.5.2/tornado/testing.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/tornado/testing.py 2018-01-06 17:48:56.000000000 +0000 @@ -423,7 +423,7 @@ def get_url(self, path): """Returns an absolute url for the given path on the test server.""" - return '%s://localhost:%s%s' % (self.get_protocol(), + return '%s://127.0.0.1:%s%s' % (self.get_protocol(), self.get_http_port(), path) def tearDown(self): diff -Nru python-tornado-4.5.2/tornado/web.py python-tornado-4.5.3/tornado/web.py --- python-tornado-4.5.2/tornado/web.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/tornado/web.py 2018-01-06 17:48:56.000000000 +0000 @@ -974,7 +974,8 @@ if self.check_etag_header(): self._write_buffer = [] self.set_status(304) - if self._status_code in (204, 304): + if (self._status_code in (204, 304) or + (self._status_code >= 100 and self._status_code < 200)): assert not self._write_buffer, "Cannot send body with %s" % self._status_code self._clear_headers_for_304() elif "Content-Length" not in self._headers: diff -Nru python-tornado-4.5.2/tornado/websocket.py python-tornado-4.5.3/tornado/websocket.py --- python-tornado-4.5.2/tornado/websocket.py 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/tornado/websocket.py 2018-01-06 17:48:56.000000000 +0000 @@ -616,6 +616,14 @@ def accept_connection(self): try: self._handle_websocket_headers() + except ValueError: + self.handler.set_status(400) + log_msg = "Missing/Invalid WebSocket headers" + self.handler.finish(log_msg) + gen_log.debug(log_msg) + return + + try: self._accept_connection() except ValueError: gen_log.debug("Malformed WebSocket request received", diff -Nru python-tornado-4.5.2/.travis.yml python-tornado-4.5.3/.travis.yml --- python-tornado-4.5.2/.travis.yml 2017-08-27 18:50:20.000000000 +0000 +++ python-tornado-4.5.3/.travis.yml 2018-01-06 17:48:56.000000000 +0000 @@ -1,7 +1,6 @@ # https://travis-ci.org/tornadoweb/tornado language: python python: - - 2.7.8 - 2.7 - pypy - 3.3 @@ -9,7 +8,7 @@ - 3.5 - 3.6 - nightly - - pypy3 + - pypy3.5-5.8.0 install: - if [[ $TRAVIS_PYTHON_VERSION == 2* ]]; then travis_retry pip install futures mock monotonic trollius; fi