Hello community, here is the log from the commit of package python-waitress for openSUSE:Factory checked in at 2013-09-13 14:46:21 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-waitress (Old) and /work/SRC/openSUSE:Factory/.python-waitress.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-waitress" Changes: -------- --- /work/SRC/openSUSE:Factory/python-waitress/python-waitress.changes 2013-08-15 12:30:23.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python-waitress.new/python-waitress.changes 2013-09-13 14:46:22.000000000 +0200 @@ -1,0 +2,9 @@ +Wed Sep 11 21:14:23 UTC 2013 - dmuel...@suse.com + +- update to 0.8.7: + - The HTTP version of the response returned by waitress when it catches an + exception will now match the HTTP request version. + - Fix: CONNECTION header will be HTTP_CONNECTION and not CONNECTION_TYPE + (see https://github.com/Pylons/waitress/issues/13) + +------------------------------------------------------------------- Old: ---- waitress-0.8.6.tar.gz New: ---- waitress-0.8.7.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-waitress.spec ++++++ --- /var/tmp/diff_new_pack.kdhbSo/_old 2013-09-13 14:46:23.000000000 +0200 +++ /var/tmp/diff_new_pack.kdhbSo/_new 2013-09-13 14:46:23.000000000 +0200 @@ -17,7 +17,7 @@ Name: python-waitress -Version: 0.8.6 +Version: 0.8.7 Release: 0 Summary: Waitress WSGI server License: ZPL-2.1 ++++++ waitress-0.8.6.tar.gz -> waitress-0.8.7.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.6/CHANGES.txt new/waitress-0.8.7/CHANGES.txt --- old/waitress-0.8.6/CHANGES.txt 2013-08-12 06:58:53.000000000 +0200 +++ new/waitress-0.8.7/CHANGES.txt 2013-08-29 17:54:01.000000000 +0200 @@ -1,3 +1,12 @@ +0.8.7 (2013-08-29) +------------------ + +- The HTTP version of the response returned by waitress when it catches an + exception will now match the HTTP request version. + +- Fix: CONNECTION header will be HTTP_CONNECTION and not CONNECTION_TYPE + (see https://github.com/Pylons/waitress/issues/13) + 0.8.6 (2013-08-12) ------------------ @@ -271,5 +280,3 @@ ---------------- - Initial release. - - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.6/CONTRIBUTORS.txt new/waitress-0.8.7/CONTRIBUTORS.txt --- old/waitress-0.8.6/CONTRIBUTORS.txt 2013-08-12 06:52:42.000000000 +0200 +++ new/waitress-0.8.7/CONTRIBUTORS.txt 2013-08-29 17:53:38.000000000 +0200 @@ -118,3 +118,5 @@ - Keith Gaughan, 2013/05/11 - Jamie Matthews, 2013/06/19 + +- Adam Groszer, 2013/08/15 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.6/PKG-INFO new/waitress-0.8.7/PKG-INFO --- old/waitress-0.8.6/PKG-INFO 2013-08-12 07:02:59.000000000 +0200 +++ new/waitress-0.8.7/PKG-INFO 2013-08-29 17:57:01.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: waitress -Version: 0.8.6 +Version: 0.8.7 Summary: Waitress WSGI server Home-page: https://github.com/Pylons/waitress Author: Chris McDonough @@ -16,6 +16,15 @@ http://docs.pylonsproject.org/projects/waitress/en/latest/ . + 0.8.7 (2013-08-29) + ------------------ + + - The HTTP version of the response returned by waitress when it catches an + exception will now match the HTTP request version. + + - Fix: CONNECTION header will be HTTP_CONNECTION and not CONNECTION_TYPE + (see https://github.com/Pylons/waitress/issues/13) + 0.8.6 (2013-08-12) ------------------ @@ -290,8 +299,6 @@ - Initial release. - - Keywords: waitress wsgi server http Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.6/docs/conf.py new/waitress-0.8.7/docs/conf.py --- old/waitress-0.8.6/docs/conf.py 2013-08-12 07:00:18.000000000 +0200 +++ new/waitress-0.8.7/docs/conf.py 2013-08-29 17:54:29.000000000 +0200 @@ -65,7 +65,7 @@ # other places throughout the built documents. # # The short X.Y version. -version = '0.8.6' +version = '0.8.7' # The full version, including alpha/beta/rc tags. release = version diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.6/setup.py new/waitress-0.8.7/setup.py --- old/waitress-0.8.6/setup.py 2013-08-12 06:59:40.000000000 +0200 +++ new/waitress-0.8.7/setup.py 2013-08-29 17:54:21.000000000 +0200 @@ -37,7 +37,7 @@ setup( name='waitress', - version='0.8.6', + version='0.8.7', author='Zope Foundation and Contributors', author_email='zope-...@zope.org', maintainer="Chris McDonough", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.6/waitress/channel.py new/waitress-0.8.7/waitress/channel.py --- old/waitress-0.8.6/waitress/channel.py 2013-05-24 01:02:12.000000000 +0200 +++ new/waitress-0.8.7/waitress/channel.py 2013-08-29 17:53:38.000000000 +0200 @@ -339,8 +339,18 @@ else: body = ('The server encountered an unexpected ' 'internal server error') + req_version = request.version + req_headers = request.headers request = self.parser_class(self.adj) request.error = InternalServerError(body) + # copy some original request attributes to fulfill + # HTTP 1.1 requirements + request.version = req_version + try: + request.headers['CONNECTION'] = req_headers[ + 'CONNECTION'] + except KeyError: + pass task = self.error_task_class(self, request) task.service() # must not fail else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.6/waitress/parser.py new/waitress-0.8.7/waitress/parser.py --- old/waitress-0.8.6/waitress/parser.py 2013-05-24 01:02:12.000000000 +0200 +++ new/waitress-0.8.7/waitress/parser.py 2013-08-29 17:53:38.000000000 +0200 @@ -123,6 +123,10 @@ self.header_bytes_received += datalen max_header = self.adj.max_request_header_size if self.header_bytes_received >= max_header: + # malformed header, we need to construct some request + # on our own. we disregard the incoming(?) requests HTTP + # version and just use 1.0. IOW someone just sent garbage + # over the wire self.parse_header(b'GET / HTTP/1.0\n') self.error = RequestHeaderFieldsTooLarge( 'exceeds max_header of %s' % max_header) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.6/waitress/task.py new/waitress-0.8.7/waitress/task.py --- old/waitress-0.8.6/waitress/task.py 2013-08-12 06:42:57.000000000 +0200 +++ new/waitress-0.8.7/waitress/task.py 2013-08-29 17:53:38.000000000 +0200 @@ -31,10 +31,9 @@ logger, ) -rename_headers = { +rename_headers = { # or keep them without the HTTP_ prefix added 'CONTENT_LENGTH': 'CONTENT_LENGTH', 'CONTENT_TYPE': 'CONTENT_TYPE', - 'CONNECTION': 'CONNECTION_TYPE', } hop_by_hop = frozenset(( @@ -318,7 +317,14 @@ self.content_length = cl self.response_headers.append(('Content-Length', str(cl))) self.response_headers.append(('Content-Type', 'text/plain')) - self.response_headers.append(('Connection', 'close')) + if self.version == '1.1': + connection = self.request.headers.get('CONNECTION', '').lower() + if connection == 'close': + self.response_headers.append(('Connection', 'close')) + # under HTTP 1.1 keep-alive is default, no need to set the header + else: + # HTTP 1.0 + self.response_headers.append(('Connection', 'close')) self.close_on_finish = True self.write(tobytes(body)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.6/waitress/tests/test_functional.py new/waitress-0.8.7/waitress/tests/test_functional.py --- old/waitress-0.8.6/waitress/tests/test_functional.py 2013-06-10 05:15:01.000000000 +0200 +++ new/waitress-0.8.7/waitress/tests/test_functional.py 2013-08-29 17:53:38.000000000 +0200 @@ -295,8 +295,9 @@ self.assertline(line, '400', 'Bad Request', 'HTTP/1.1') cl = int(headers['content-length']) self.assertEqual(cl, len(response_body)) + self.assertEqual(sorted(headers.keys()), + ['content-length', 'content-type', 'date', 'server']) self.assertEqual(headers['content-type'], 'text/plain') - self.assertEqual(headers['connection'], 'close') # connection has been closed self.send_check_error(to_send) self.assertRaises(ConnectionClosed, read_http, fp) @@ -963,7 +964,6 @@ cl = int(headers['content-length']) self.assertEqual(cl, len(response_body)) self.assertEqual(headers['content-type'], 'text/plain') - self.assertEqual(headers['connection'], 'close') # connection has been closed self.send_check_error(to_send) self.assertRaises(ConnectionClosed, read_http, fp) @@ -977,32 +977,111 @@ def tearDown(self): self.stop_subprocess() - def test_before_start_response(self): + def test_before_start_response_http_10(self): + to_send = "GET /before_start_response HTTP/1.0\n\n" + to_send = tobytes(to_send) + self.connect() + self.sock.send(to_send) + fp = self.sock.makefile('rb', 0) + line, headers, response_body = read_http(fp) + self.assertline(line, '500', 'Internal Server Error', 'HTTP/1.0') + cl = int(headers['content-length']) + self.assertEqual(cl, len(response_body)) + self.assertTrue(response_body.startswith(b'Internal Server Error')) + self.assertEqual(headers['connection'], 'close') + # connection has been closed + self.send_check_error(to_send) + self.assertRaises(ConnectionClosed, read_http, fp) + + def test_before_start_response_http_11(self): to_send = "GET /before_start_response HTTP/1.1\n\n" to_send = tobytes(to_send) self.connect() self.sock.send(to_send) fp = self.sock.makefile('rb', 0) line, headers, response_body = read_http(fp) + self.assertline(line, '500', 'Internal Server Error', 'HTTP/1.1') + cl = int(headers['content-length']) + self.assertEqual(cl, len(response_body)) + self.assertTrue(response_body.startswith(b'Internal Server Error')) + self.assertEqual(sorted(headers.keys()), + ['content-length', 'content-type', 'date', 'server']) + # connection has been closed + self.send_check_error(to_send) + self.assertRaises(ConnectionClosed, read_http, fp) + + def test_before_start_response_http_11_close(self): + to_send = tobytes( + "GET /before_start_response HTTP/1.1\n" + "Connection: close\n\n") + self.connect() + self.sock.send(to_send) + fp = self.sock.makefile('rb', 0) + line, headers, response_body = read_http(fp) + self.assertline(line, '500', 'Internal Server Error', 'HTTP/1.1') + cl = int(headers['content-length']) + self.assertEqual(cl, len(response_body)) + self.assertTrue(response_body.startswith(b'Internal Server Error')) + self.assertEqual(sorted(headers.keys()), + ['connection', 'content-length', 'content-type', 'date', + 'server']) + self.assertEqual(headers['connection'], 'close') + # connection has been closed + self.send_check_error(to_send) + self.assertRaises(ConnectionClosed, read_http, fp) + + def test_after_start_response_http10(self): + to_send = "GET /after_start_response HTTP/1.0\n\n" + to_send = tobytes(to_send) + self.connect() + self.sock.send(to_send) + fp = self.sock.makefile('rb', 0) + line, headers, response_body = read_http(fp) self.assertline(line, '500', 'Internal Server Error', 'HTTP/1.0') cl = int(headers['content-length']) self.assertEqual(cl, len(response_body)) self.assertTrue(response_body.startswith(b'Internal Server Error')) + self.assertEqual(sorted(headers.keys()), + ['connection', 'content-length', 'content-type', 'date', + 'server']) + self.assertEqual(headers['connection'], 'close') # connection has been closed self.send_check_error(to_send) self.assertRaises(ConnectionClosed, read_http, fp) - def test_after_start_response(self): + def test_after_start_response_http11(self): to_send = "GET /after_start_response HTTP/1.1\n\n" to_send = tobytes(to_send) self.connect() self.sock.send(to_send) fp = self.sock.makefile('rb', 0) line, headers, response_body = read_http(fp) - self.assertline(line, '500', 'Internal Server Error', 'HTTP/1.0') + self.assertline(line, '500', 'Internal Server Error', 'HTTP/1.1') + cl = int(headers['content-length']) + self.assertEqual(cl, len(response_body)) + self.assertTrue(response_body.startswith(b'Internal Server Error')) + self.assertEqual(sorted(headers.keys()), + ['content-length', 'content-type', 'date', 'server']) + # connection has been closed + self.send_check_error(to_send) + self.assertRaises(ConnectionClosed, read_http, fp) + + def test_after_start_response_http11_close(self): + to_send = tobytes( + "GET /after_start_response HTTP/1.1\n" + "Connection: close\n\n") + self.connect() + self.sock.send(to_send) + fp = self.sock.makefile('rb', 0) + line, headers, response_body = read_http(fp) + self.assertline(line, '500', 'Internal Server Error', 'HTTP/1.1') cl = int(headers['content-length']) self.assertEqual(cl, len(response_body)) self.assertTrue(response_body.startswith(b'Internal Server Error')) + self.assertEqual(sorted(headers.keys()), + ['connection', 'content-length', 'content-type', 'date', + 'server']) + self.assertEqual(headers['connection'], 'close') # connection has been closed self.send_check_error(to_send) self.assertRaises(ConnectionClosed, read_http, fp) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.6/waitress/tests/test_task.py new/waitress-0.8.7/waitress/tests/test_task.py --- old/waitress-0.8.6/waitress/tests/test_task.py 2013-08-12 06:44:22.000000000 +0200 +++ new/waitress-0.8.7/waitress/tests/test_task.py 2013-08-29 17:53:38.000000000 +0200 @@ -574,7 +574,7 @@ environ = inst.get_environment() self.assertEqual(environ['PATH_INFO'], '/bar') self.assertEqual(environ['SCRIPT_NAME'], '/foo') - + def test_get_environ_with_url_prefix_hit(self): inst = self._makeOne() inst.channel.server.adj.url_prefix = '/foo' @@ -593,16 +593,28 @@ 'CONTENT_TYPE': 'abc', 'CONTENT_LENGTH': '10', 'X_FOO': 'BAR', + 'CONNECTION': 'close', } request.query = 'abc' inst.request = request environ = inst.get_environment() + + # nail the keys of environ + self.assertEqual(sorted(environ.keys()), [ + 'CONTENT_LENGTH', 'CONTENT_TYPE', 'HTTP_CONNECTION', 'HTTP_X_FOO', + 'PATH_INFO', 'QUERY_STRING', 'REMOTE_ADDR', 'REQUEST_METHOD', + 'SCRIPT_NAME', 'SERVER_NAME', 'SERVER_PORT', 'SERVER_PROTOCOL', + 'SERVER_SOFTWARE', 'wsgi.errors', 'wsgi.file_wrapper', 'wsgi.input', + 'wsgi.multiprocess', 'wsgi.multithread', 'wsgi.run_once', + 'wsgi.url_scheme', 'wsgi.version']) + self.assertEqual(environ['REQUEST_METHOD'], 'GET') self.assertEqual(environ['SERVER_PORT'], '80') self.assertEqual(environ['SERVER_NAME'], 'localhost') self.assertEqual(environ['SERVER_SOFTWARE'], 'waitress') self.assertEqual(environ['SERVER_PROTOCOL'], 'HTTP/1.0') self.assertEqual(environ['SCRIPT_NAME'], '') + self.assertEqual(environ['HTTP_CONNECTION'], 'close') self.assertEqual(environ['PATH_INFO'], '/') self.assertEqual(environ['QUERY_STRING'], 'abc') self.assertEqual(environ['REMOTE_ADDR'], '127.0.0.1') @@ -629,7 +641,7 @@ from waitress.task import ErrorTask return ErrorTask(channel, request) - def test_execute(self): + def test_execute_http_10(self): inst = self._makeOne() inst.execute() lines = filter_lines(inst.channel.written) @@ -644,6 +656,55 @@ self.assertEqual(lines[7], b'body') self.assertEqual(lines[8], b'(generated by waitress)') + def test_execute_http_11(self): + inst = self._makeOne() + inst.version = '1.1' + inst.execute() + lines = filter_lines(inst.channel.written) + self.assertEqual(len(lines), 8) + self.assertEqual(lines[0], b'HTTP/1.1 432 Too Ugly') + self.assertEqual(lines[1], b'Content-Length: 43') + self.assertEqual(lines[2], b'Content-Type: text/plain') + self.assertTrue(lines[3]) + self.assertEqual(lines[4], b'Server: waitress') + self.assertEqual(lines[5], b'Too Ugly') + self.assertEqual(lines[6], b'body') + self.assertEqual(lines[7], b'(generated by waitress)') + + def test_execute_http_11_close(self): + inst = self._makeOne() + inst.version = '1.1' + inst.request.headers['CONNECTION'] = 'close' + inst.execute() + lines = filter_lines(inst.channel.written) + self.assertEqual(len(lines), 9) + self.assertEqual(lines[0], b'HTTP/1.1 432 Too Ugly') + self.assertEqual(lines[1], b'Connection: close') + self.assertEqual(lines[2], b'Content-Length: 43') + self.assertEqual(lines[3], b'Content-Type: text/plain') + self.assertTrue(lines[4]) + self.assertEqual(lines[5], b'Server: waitress') + self.assertEqual(lines[6], b'Too Ugly') + self.assertEqual(lines[7], b'body') + self.assertEqual(lines[8], b'(generated by waitress)') + + def test_execute_http_11_keep(self): + inst = self._makeOne() + inst.version = '1.1' + inst.request.headers['CONNECTION'] = 'keep-alive' + inst.execute() + lines = filter_lines(inst.channel.written) + self.assertEqual(len(lines), 8) + self.assertEqual(lines[0], b'HTTP/1.1 432 Too Ugly') + self.assertEqual(lines[1], b'Content-Length: 43') + self.assertEqual(lines[2], b'Content-Type: text/plain') + self.assertTrue(lines[3]) + self.assertEqual(lines[4], b'Server: waitress') + self.assertEqual(lines[5], b'Too Ugly') + self.assertEqual(lines[6], b'body') + self.assertEqual(lines[7], b'(generated by waitress)') + + class DummyError(object): code = '432' reason = 'Too Ugly' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.6/waitress.egg-info/PKG-INFO new/waitress-0.8.7/waitress.egg-info/PKG-INFO --- old/waitress-0.8.6/waitress.egg-info/PKG-INFO 2013-08-12 07:02:57.000000000 +0200 +++ new/waitress-0.8.7/waitress.egg-info/PKG-INFO 2013-08-29 17:56:58.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: waitress -Version: 0.8.6 +Version: 0.8.7 Summary: Waitress WSGI server Home-page: https://github.com/Pylons/waitress Author: Chris McDonough @@ -16,6 +16,15 @@ http://docs.pylonsproject.org/projects/waitress/en/latest/ . + 0.8.7 (2013-08-29) + ------------------ + + - The HTTP version of the response returned by waitress when it catches an + exception will now match the HTTP request version. + + - Fix: CONNECTION header will be HTTP_CONNECTION and not CONNECTION_TYPE + (see https://github.com/Pylons/waitress/issues/13) + 0.8.6 (2013-08-12) ------------------ @@ -290,8 +299,6 @@ - Initial release. - - Keywords: waitress wsgi server http Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable -- To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org For additional commands, e-mail: opensuse-commit+h...@opensuse.org