Hello community, here is the log from the commit of package python3-aiohttp for openSUSE:Factory checked in at 2015-04-25 09:53:19 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python3-aiohttp (Old) and /work/SRC/openSUSE:Factory/.python3-aiohttp.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python3-aiohttp" Changes: -------- --- /work/SRC/openSUSE:Factory/python3-aiohttp/python3-aiohttp.changes 2015-04-23 08:03:56.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python3-aiohttp.new/python3-aiohttp.changes 2015-04-25 11:25:55.000000000 +0200 @@ -1,0 +2,8 @@ +Thu Apr 23 15:27:14 UTC 2015 - arun@gmx.de + +- update to version 0.15.3: + * Fix graceful shutdown handling + * Fix Expect header handling for not found and not allowed routes + #340 + +------------------------------------------------------------------- Old: ---- aiohttp-0.15.2.tar.gz New: ---- aiohttp-0.15.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python3-aiohttp.spec ++++++ --- /var/tmp/diff_new_pack.ZyT1Nf/_old 2015-04-25 11:25:56.000000000 +0200 +++ /var/tmp/diff_new_pack.ZyT1Nf/_new 2015-04-25 11:25:56.000000000 +0200 @@ -17,7 +17,7 @@ Name: python3-aiohttp -Version: 0.15.2 +Version: 0.15.3 Release: 0 Url: https://pypi.python.org/pypi/aiohttp Summary: Http client/server for asyncio ++++++ aiohttp-0.15.2.tar.gz -> aiohttp-0.15.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiohttp-0.15.2/CHANGES.txt new/aiohttp-0.15.3/CHANGES.txt --- old/aiohttp-0.15.2/CHANGES.txt 2015-04-19 05:52:36.000000000 +0200 +++ new/aiohttp-0.15.3/CHANGES.txt 2015-04-22 18:51:31.000000000 +0200 @@ -1,6 +1,14 @@ CHANGES ======= +0.15.3 (04-22-2015) +------------------- + +- Fix graceful shutdown handling + +- Fix `Expect` header handling for not found and not allowed routes #340 + + 0.15.2 (04-19-2015) ------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiohttp-0.15.2/PKG-INFO new/aiohttp-0.15.3/PKG-INFO --- old/aiohttp-0.15.2/PKG-INFO 2015-04-19 05:53:43.000000000 +0200 +++ new/aiohttp-0.15.3/PKG-INFO 2015-04-22 18:56:33.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: aiohttp -Version: 0.15.2 +Version: 0.15.3 Summary: http client/server for asyncio Home-page: https://github.com/KeepSafe/aiohttp/ Author: Nikolay Kim @@ -146,6 +146,14 @@ CHANGES ======= + 0.15.3 (04-22-2015) + ------------------- + + - Fix graceful shutdown handling + + - Fix `Expect` header handling for not found and not allowed routes #340 + + 0.15.2 (04-19-2015) ------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiohttp-0.15.2/aiohttp/__init__.py new/aiohttp-0.15.3/aiohttp/__init__.py --- old/aiohttp-0.15.2/aiohttp/__init__.py 2015-04-19 05:52:36.000000000 +0200 +++ new/aiohttp-0.15.3/aiohttp/__init__.py 2015-04-22 18:50:05.000000000 +0200 @@ -1,6 +1,6 @@ # This relies on each of the submodules having an __all__ variable. -__version__ = '0.15.2' +__version__ = '0.15.3' from . import hdrs # noqa diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiohttp-0.15.2/aiohttp/protocol.py new/aiohttp-0.15.3/aiohttp/protocol.py --- old/aiohttp-0.15.2/aiohttp/protocol.py 2015-04-15 21:28:42.000000000 +0200 +++ new/aiohttp-0.15.3/aiohttp/protocol.py 2015-04-21 01:28:03.000000000 +0200 @@ -28,6 +28,7 @@ CONTINUATION = (' ', '\t') EOF_MARKER = object() EOL_MARKER = object() +STATUS_LINE_READY = object() RESPONSES = http.server.BaseHTTPRequestHandler.responses @@ -36,6 +37,8 @@ HttpVersion10 = HttpVersion(1, 0) HttpVersion11 = HttpVersion(1, 1) +RawStatusLineMessage = collections.namedtuple( + 'RawStatusLineMessage', ['method', 'path', 'version']) RawRequestMessage = collections.namedtuple( 'RawRequestMessage', @@ -133,7 +136,7 @@ self.allowed_methods = [m.upper() for m in allowed_methods] def __call__(self, out, buf): - raw_data = yield from buf.waituntil(b' ', 24) + raw_data = yield from buf.waituntil(b' ', 12) method = raw_data.decode('ascii', 'surrogateescape').strip() # method diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiohttp-0.15.2/aiohttp/server.py new/aiohttp-0.15.3/aiohttp/server.py --- old/aiohttp-0.15.2/aiohttp/server.py 2015-04-18 01:15:44.000000000 +0200 +++ new/aiohttp-0.15.3/aiohttp/server.py 2015-04-21 01:44:27.000000000 +0200 @@ -83,6 +83,7 @@ _keep_alive_handle = None # keep alive timer handle _timeout_handle = None # slow request timer handle + _request_prefix = aiohttp.HttpPrefixParser() # http method parser _request_parser = aiohttp.HttpRequestParser() # default request parser def __init__(self, *, loop=None, @@ -117,11 +118,12 @@ def keep_alive_timeout(self): return self._keep_alive_period - def closing(self): + def closing(self, timeout=15.0): """Worker process is about to exit, we need cleanup everything and stop accepting requests. It is especially important for keep-alive connections.""" self._keep_alive = False + self._keep_alive_on = False self._keep_alive_period = None if (not self._reading_request and self.transport is not None): @@ -131,6 +133,14 @@ self.transport.close() self.transport = None + elif self.transport is not None and timeout: + if self._timeout_handle is not None: + self._timeout_handle.cancel() + + # use slow request timeout for closing + # connection_lost cleans timeout handler + self._timeout_handle = self._loop.call_later( + timeout, self.cancel_slow_request) def connection_made(self, transport): super().connection_made(transport) @@ -227,6 +237,13 @@ payload = None try: + # read http request method + prefix = reader.set_parser(self._request_prefix) + yield from prefix.read() + + # start reading request + self._reading_request = True + # start slow request timer if self._timeout and self._timeout_handle is None: self._timeout_handle = self._loop.call_later( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiohttp-0.15.2/aiohttp/web.py new/aiohttp-0.15.3/aiohttp/web.py --- old/aiohttp-0.15.2/aiohttp/web.py 2015-04-18 00:49:45.000000000 +0200 +++ new/aiohttp-0.15.3/aiohttp/web.py 2015-04-22 18:31:01.000000000 +0200 @@ -127,8 +127,13 @@ @asyncio.coroutine def finish_connections(self, timeout=None): + # try to close connections in 90% of graceful timeout + timeout90 = None + if timeout: + timeout90 = timeout / 100 * 90 + for handler in self._connections.keys(): - handler.closing() + handler.closing(timeout=timeout90) @asyncio.coroutine def cleanup(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiohttp-0.15.2/aiohttp/web_urldispatcher.py new/aiohttp-0.15.3/aiohttp/web_urldispatcher.py --- old/aiohttp-0.15.2/aiohttp/web_urldispatcher.py 2015-04-15 18:15:34.000000000 +0200 +++ new/aiohttp-0.15.3/aiohttp/web_urldispatcher.py 2015-04-22 18:38:42.000000000 +0200 @@ -205,8 +205,22 @@ directory=self._directory) +class SystemRoute(Route): + + def __init__(self, name): + super().__init__(hdrs.METH_ANY, None, name) + + def url(self, **kwargs): + return '' + + def match(self, path): + return None + + class _NotFoundMatchInfo(UrlMappingMatchInfo): + route = SystemRoute('') + def __init__(self): super().__init__({}, None) @@ -214,10 +228,6 @@ def handler(self): return self._not_found - @property - def route(self): - return None - @asyncio.coroutine def _not_found(self, request): raise HTTPNotFound() @@ -228,6 +238,8 @@ class _MethodNotAllowedMatchInfo(UrlMappingMatchInfo): + route = SystemRoute('') + def __init__(self, method, allowed_methods): super().__init__({}, None) self._method = method @@ -237,10 +249,6 @@ def handler(self): return self._not_allowed - @property - def route(self): - return None - @asyncio.coroutine def _not_allowed(self, request): raise HTTPMethodNotAllowed(self._method, self._allowed_methods) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiohttp-0.15.2/aiohttp/worker.py new/aiohttp-0.15.3/aiohttp/worker.py --- old/aiohttp-0.15.2/aiohttp/worker.py 2015-04-08 06:44:33.000000000 +0200 +++ new/aiohttp-0.15.3/aiohttp/worker.py 2015-04-21 01:01:41.000000000 +0200 @@ -48,6 +48,7 @@ port=port, logger=self.log, debug=is_debug, + timeout=self.cfg.timeout, keep_alive=self.cfg.keepalive, access_log=self.log.access_log, access_log_format=self.cfg.access_log_format) @@ -67,7 +68,7 @@ # stop alive connections tasks = [ handler.finish_connections( - timeout=self.cfg.graceful_timeout / 100 * 80) + timeout=self.cfg.graceful_timeout / 100 * 95) for handler in servers.values()] yield from asyncio.wait(tasks, loop=self.loop) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiohttp-0.15.2/aiohttp.egg-info/PKG-INFO new/aiohttp-0.15.3/aiohttp.egg-info/PKG-INFO --- old/aiohttp-0.15.2/aiohttp.egg-info/PKG-INFO 2015-04-19 05:53:38.000000000 +0200 +++ new/aiohttp-0.15.3/aiohttp.egg-info/PKG-INFO 2015-04-22 18:56:27.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: aiohttp -Version: 0.15.2 +Version: 0.15.3 Summary: http client/server for asyncio Home-page: https://github.com/KeepSafe/aiohttp/ Author: Nikolay Kim @@ -146,6 +146,14 @@ CHANGES ======= + 0.15.3 (04-22-2015) + ------------------- + + - Fix graceful shutdown handling + + - Fix `Expect` header handling for not found and not allowed routes #340 + + 0.15.2 (04-19-2015) ------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiohttp-0.15.2/docs/client.rst new/aiohttp-0.15.3/docs/client.rst --- old/aiohttp-0.15.2/docs/client.rst 2015-04-15 21:28:37.000000000 +0200 +++ new/aiohttp-0.15.3/docs/client.rst 2015-04-21 01:58:27.000000000 +0200 @@ -146,12 +146,14 @@ Streaming Response Content -------------------------- -While methods ``read()``, ``json()`` and ``text()`` are very convenient -you should use them carefully. All this methods loads the whole response in memory. -For example if you want to download several gigabyte sized files, this methods -will load all the data in memory. Instead you can use the ``ClientResponse.content`` -attribute. It is an instance of the ``aiohttp.StreamReader`` class. The ``gzip`` -and ``deflate`` transfer-encodings are automatically decoded for you. +While methods ``read()``, ``json()`` and ``text()`` are very +convenient you should use them carefully. All this methods loads the +whole response in memory. For example if you want to download several +gigabyte sized files, this methods will load all the data in +memory. Instead you can use the ``ClientResponse.content`` +attribute. It is an instance of the ``aiohttp.StreamReader`` +class. The ``gzip`` and ``deflate`` transfer-encodings are +automatically decoded for you. .. code:: @@ -179,8 +181,8 @@ Custom Headers -------------- -If you need to add HTTP headers to a request, pass them in a ``dict`` to the -``headers`` parameter. +If you need to add HTTP headers to a request, pass them in a +:class:`dict` to the *headers* parameter. For example, if you want to specify the content-type for the previous example:: @@ -198,7 +200,7 @@ Custom Cookies -------------- -To send your own cookies to the server, you can use the ``cookies`` +To send your own cookies to the server, you can use the *cookies* parameter:: >>> url = 'http://httpbin.org/cookies' @@ -213,7 +215,7 @@ ------------------------------ Typically, you want to send some form-encoded data — much like an HTML form. -To do this, simply pass a dictionary to the ``data`` argument. Your +To do this, simply pass a dictionary to the *data* argument. Your dictionary of data will automatically be form-encoded when the request is made:: >>> payload = {'key1': 'value1', 'key2': 'value2'} @@ -230,8 +232,9 @@ ... } -If you want to send data that is not form-encoded you can do it by passing a ``string`` -instead of a ``dict``. This data will be posted directly. +If you want to send data that is not form-encoded you can do it by +passing a :class:`str` instead of a :class:`dict`. This data will be +posted directly. For example, the GitHub API v3 accepts JSON-Encoded POST/PATCH data:: @@ -264,9 +267,9 @@ >>> yield from aiohttp.request('post', url, data=data) -If you pass a file object as data parameter, aiohttp will stream it to the server -automatically. Check :class:`aiohttp.stream.StreamReader` for supported format -information. +If you pass a file object as data parameter, aiohttp will stream it to +the server automatically. Check :class:`~aiohttp.streams.StreamReader` +for supported format information. .. seealso:: :ref:`aiohttp-multipart` @@ -274,7 +277,7 @@ Streaming uploads ----------------- -aiohttp support multiple types of streaming uploads, which allows you to +:mod:`aiohttp` supports multiple types of streaming uploads, which allows you to send large files without reading them into memory. As a simple case, simply provide a file-like object for your body:: @@ -284,7 +287,7 @@ ... 'post', 'http://some.url/streamed', data=f) -Or you can provide an ``asyncio`` coroutine that yields bytes objects:: +Or you can provide an :ref:`coroutine<coroutine>` that yields bytes objects:: >>> @asyncio.coroutine ... def my_coroutine(): @@ -294,12 +297,13 @@ ... yield chunk .. note:: - It is not a standard ``asyncio`` coroutine as it yields values so it + It is not a standard :ref:`coroutine<coroutine>` as it yields values so it can not be used like ``yield from my_coroutine()``. - ``aiohttp`` internally handles such coroutines. + :mod:`aiohttp` internally handles such coroutines. -Also it is possible to use a ``StreamReader`` object. Lets say we want to upload -a file from another request and calculate the file sha1 hash:: +Also it is possible to use a :class:`~aiohttp.streams.StreamReader` +object. Lets say we want to upload a file from another request and +calculate the file sha1 hash:: >>> def feed_stream(resp, stream): ... h = hashlib.sha1() @@ -321,8 +325,9 @@ >>> file_hash = yield from feed_stream(resp, stream) -Because the response content attribute is a StreamReader, you can chain get and -post requests together:: +Because the response content attribute is a +:class:`~aiohttp.streams.StreamReader`, you can chain get and post +requests together:: >>> r = yield from aiohttp.request('get', 'http://python.org') >>> yield from aiohttp.request('post', @@ -335,8 +340,8 @@ Keep-Alive, connection pooling and cookie sharing ------------------------------------------------- -To share cookies between multiple requests you can create an -``aiohttp.ClientSession`` object: +To share cookies between multiple requests you can create an +:class:`~aiohttp.client.ClientSession` object: >>> session = aiohttp.ClientSession() >>> yield from session.get( @@ -355,9 +360,10 @@ >>> json['headers']['Authorization'] 'Basic bG9naW46cGFzcw==' -By default aiohttp does not use connection pooling. In other words multiple -calls to ``aiohttp.request`` will start a new connection to host each. -``aiohttp.ClientSession`` object will do connection pooling for you. +By default aiohttp does not use connection pooling. In other words +multiple calls to :func:`~aiohttp.client.request` will start a new +connection to host each. :class:`~aiohttp.client.ClientSession` +object will do connection pooling for you. Connectors diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiohttp-0.15.2/docs/web.rst new/aiohttp-0.15.3/docs/web.rst --- old/aiohttp-0.15.2/docs/web.rst 2015-04-15 18:15:34.000000000 +0200 +++ new/aiohttp-0.15.3/docs/web.rst 2015-04-21 01:58:27.000000000 +0200 @@ -128,6 +128,15 @@ app.router.add_route('GET', '/greet/{name}', handler.handle_greeting) +.. versionadded:: 0.15.2 + + :meth:`UrlDispatcher.add_route` supports wildcard as *HTTP method*:: + + app.router.add_route('*', '/path', handler) + + That means the handler for ``'/path'`` is applied for every HTTP method. + + Custom conditions for routes lookup ----------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiohttp-0.15.2/docs/web_reference.rst new/aiohttp-0.15.3/docs/web_reference.rst --- old/aiohttp-0.15.2/docs/web_reference.rst 2015-04-08 06:44:33.000000000 +0200 +++ new/aiohttp-0.15.3/docs/web_reference.rst 2015-04-21 01:58:27.000000000 +0200 @@ -935,7 +935,8 @@ .. seealso:: :ref:`Route classes <aiohttp-web-route>` - .. method:: add_route(method, path, handler, *, name=None, expect_handler=None) + .. method:: add_route(method, path, handler, *, \ + name=None, expect_handler=None) Append :ref:`handler<aiohttp-web-handler>` to the end of route table. @@ -946,6 +947,14 @@ Pay attention please: *handler* is converted to coroutine internally when it is a regular function. + :param str method: HTTP method for route. Should be one of + ``'GET'``, ``'POST'``, ``'PUT'``, + ``'DELETE'``, ``'PATCH'``, ``'HEAD'``, + ``'OPTIONS'`` or ``'*'`` for any method. + + The parameter is case-insensitive, e.g. you + can push ``'get'`` as well as ``'GET'``. + :param str path: route path :param callable handler: route handler diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiohttp-0.15.2/setup.cfg new/aiohttp-0.15.3/setup.cfg --- old/aiohttp-0.15.2/setup.cfg 2015-04-19 05:53:43.000000000 +0200 +++ new/aiohttp-0.15.3/setup.cfg 2015-04-22 18:56:33.000000000 +0200 @@ -5,7 +5,7 @@ ignore = N801,N802,N803,E226 [egg_info] -tag_build = tag_date = 0 tag_svn_revision = 0 +tag_build = diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiohttp-0.15.2/tests/test_http_server.py new/aiohttp-0.15.3/tests/test_http_server.py --- old/aiohttp-0.15.2/tests/test_http_server.py 2015-04-18 01:15:54.000000000 +0200 +++ new/aiohttp-0.15.3/tests/test_http_server.py 2015-04-21 01:49:13.000000000 +0200 @@ -67,6 +67,23 @@ self.assertIsNone(srv._request_handler) self.assertTrue(request_handler.cancel.called) + def test_closing_during_reading(self): + srv = server.ServerHttpProtocol(loop=self.loop) + srv._keep_alive = True + srv._keep_alive_on = True + srv._reading_request = True + srv._timeout_handle = timeout_handle = unittest.mock.Mock() + transport = srv.transport = unittest.mock.Mock() + + srv.closing() + self.assertFalse(transport.close.called) + self.assertIsNotNone(srv.transport) + + # cancel existing slow request handler + self.assertIsNotNone(srv._timeout_handle) + self.assertTrue(timeout_handle.cancel.called) + self.assertIsNot(timeout_handle, srv._timeout_handle) + def test_double_closing(self): srv = server.ServerHttpProtocol(loop=self.loop) srv._keep_alive = True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiohttp-0.15.2/tests/test_urldispatch.py new/aiohttp-0.15.3/tests/test_urldispatch.py --- old/aiohttp-0.15.2/tests/test_urldispatch.py 2015-04-08 06:44:33.000000000 +0200 +++ new/aiohttp-0.15.3/tests/test_urldispatch.py 2015-04-22 18:39:02.000000000 +0200 @@ -10,7 +10,8 @@ from aiohttp.protocol import HttpVersion, RawRequestMessage from aiohttp.web_urldispatcher import (_defaultExpectHandler, DynamicRoute, - PlainRoute) + PlainRoute, + SystemRoute) class TestUrlDispatcher(unittest.TestCase): @@ -43,6 +44,11 @@ return handler + def test_system_route(self): + route = SystemRoute('test') + self.assertIsNone(route.match('any')) + self.assertEqual(route.url(), '') + def test_register_route(self): handler = self.make_handler() route = PlainRoute('GET', handler, 'test', '/handler/to/path') @@ -181,7 +187,7 @@ req = self.make_request('PUT', '/') match_info = self.loop.run_until_complete(self.router.resolve(req)) - self.assertIsNone(match_info.route) + self.assertIsInstance(match_info.route, SystemRoute) self.assertEqual({}, match_info) with self.assertRaises(HTTPMethodNotAllowed) as ctx: @@ -198,7 +204,7 @@ req = self.make_request('GET', '/b') match_info = self.loop.run_until_complete(self.router.resolve(req)) - self.assertIsNone(match_info.route) + self.assertIsInstance(match_info.route, SystemRoute) self.assertEqual({}, match_info) with self.assertRaises(HTTPNotFound) as ctx: @@ -359,7 +365,7 @@ req = self.make_request('GET', '/handler/tail') match_info = self.loop.run_until_complete(self.router.resolve(req)) - self.assertIsNone(match_info.route) + self.assertIsInstance(match_info.route, SystemRoute) self.assertEqual({}, match_info) with self.assertRaises(HTTPNotFound): self.loop.run_until_complete(match_info.handler(req)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiohttp-0.15.2/tests/test_web.py new/aiohttp-0.15.3/tests/test_web.py --- old/aiohttp-0.15.2/tests/test_web.py 2015-04-18 01:06:56.000000000 +0200 +++ new/aiohttp-0.15.3/tests/test_web.py 2015-04-21 01:42:01.000000000 +0200 @@ -143,7 +143,7 @@ manager.connection_lost(handler, None) self.assertEqual(manager.connections, []) - handler.closing.assert_called_with() + handler.closing.assert_called_with(timeout=None) transport.close.assert_called_with() def test_finish_connection_timeout(self): @@ -158,5 +158,5 @@ manager.connection_lost(handler, None) self.assertEqual(manager.connections, []) - handler.closing.assert_called_with() + handler.closing.assert_called_with(timeout=0.09) transport.close.assert_called_with() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiohttp-0.15.2/tests/test_web_functional.py new/aiohttp-0.15.3/tests/test_web_functional.py --- old/aiohttp-0.15.2/tests/test_web_functional.py 2015-04-19 05:32:41.000000000 +0200 +++ new/aiohttp-0.15.3/tests/test_web_functional.py 2015-04-22 18:33:21.000000000 +0200 @@ -469,6 +469,54 @@ self.loop.run_until_complete(go()) + def test_100_continue_for_not_found(self): + + @asyncio.coroutine + def handler(request): + return web.Response() + + @asyncio.coroutine + def go(): + app, _, url = yield from self.create_server('POST', '/') + app.router.add_route('POST', '/', handler) + + form = FormData() + form.add_field('name', b'123', + content_transfer_encoding='base64') + + resp = yield from request( + 'post', url + 'not_found', data=form, + expect100=True, # wait until server returns 100 continue + loop=self.loop) + + self.assertEqual(404, resp.status) + + self.loop.run_until_complete(go()) + + def test_100_continue_for_not_allowed(self): + + @asyncio.coroutine + def handler(request): + return web.Response() + + @asyncio.coroutine + def go(): + app, _, url = yield from self.create_server('POST', '/') + app.router.add_route('POST', '/', handler) + + form = FormData() + form.add_field('name', b'123', + content_transfer_encoding='base64') + + resp = yield from request( + 'GET', url, data=form, + expect100=True, # wait until server returns 100 continue + loop=self.loop) + + self.assertEqual(405, resp.status) + + self.loop.run_until_complete(go()) + def test_http10_keep_alive_default(self): @asyncio.coroutine diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiohttp-0.15.2/tests/test_worker.py new/aiohttp-0.15.3/tests/test_worker.py --- old/aiohttp-0.15.2/tests/test_worker.py 2015-01-14 23:34:18.000000000 +0100 +++ new/aiohttp-0.15.3/tests/test_worker.py 2015-04-21 01:40:51.000000000 +0200 @@ -139,7 +139,7 @@ self.loop.run_until_complete(self.worker.close()) app.finish.assert_called_with() - handler.finish_connections.assert_called_with(timeout=80.0) + handler.finish_connections.assert_called_with(timeout=95.0) srv.close.assert_called_with() self.assertIsNone(self.worker.servers)