From 34a285865e98be86c47cf6ab8425b75d3b377bf9 Mon Sep 17 00:00:00 2001 From: Ben Darnell Date: Wed, 15 May 2013 21:44:34 -0400 Subject: [PATCH] Add a missing stack_context.wrap in SSLIOStream.connect. Run some of simple_httpclient test in both HTTP and HTTPS modes, which would have detected this bug. Closes #787. --- tornado/iostream.py | 2 +- tornado/test/simple_httpclient_test.py | 35 ++++++++++++++++++-------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/tornado/iostream.py b/tornado/iostream.py index 60126e81b..425d3299d 100644 --- a/tornado/iostream.py +++ b/tornado/iostream.py @@ -872,7 +872,7 @@ class SSLIOStream(IOStream): def connect(self, address, callback=None, server_hostname=None): # Save the user's callback and run it after the ssl handshake # has completed. - self._ssl_connect_callback = callback + self._ssl_connect_callback = stack_context.wrap(callback) self._server_hostname = server_hostname super(SSLIOStream, self).connect(address, callback=None) diff --git a/tornado/test/simple_httpclient_test.py b/tornado/test/simple_httpclient_test.py index 8f028e240..5a0d9b1bd 100644 --- a/tornado/test/simple_httpclient_test.py +++ b/tornado/test/simple_httpclient_test.py @@ -17,7 +17,7 @@ from tornado.log import gen_log from tornado.simple_httpclient import SimpleAsyncHTTPClient, _DEFAULT_CA_CERTS from tornado.test.httpclient_test import ChunkHandler, CountdownHandler, HelloWorldHandler from tornado.test import httpclient_test -from tornado.testing import AsyncHTTPTestCase, AsyncTestCase, bind_unused_port, ExpectLog +from tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, bind_unused_port, ExpectLog from tornado.test.util import unittest, skipOnTravis from tornado.web import RequestHandler, Application, asynchronous, url @@ -93,11 +93,7 @@ class HostEchoHandler(RequestHandler): self.write(self.request.headers["Host"]) -class SimpleHTTPClientTestCase(AsyncHTTPTestCase): - def setUp(self): - super(SimpleHTTPClientTestCase, self).setUp() - self.http_client = SimpleAsyncHTTPClient(self.io_loop) - +class SimpleHTTPClientTestMixin(object): def get_app(self): # callable objects to finish pending /trigger requests self.triggers = collections.deque() @@ -131,8 +127,7 @@ class SimpleHTTPClientTestCase(AsyncHTTPTestCase): SimpleAsyncHTTPClient(io_loop2)) def test_connection_limit(self): - client = SimpleAsyncHTTPClient(self.io_loop, max_clients=2, - force_instance=True) + client = self.create_client(max_clients=2) self.assertEqual(client.max_clients, 2) seen = [] # Send 4 requests. Two can be sent immediately, while the others @@ -160,8 +155,7 @@ class SimpleHTTPClientTestCase(AsyncHTTPTestCase): def test_redirect_connection_limit(self): # following redirects should not consume additional connections - client = SimpleAsyncHTTPClient(self.io_loop, max_clients=1, - force_instance=True) + client = self.create_client(max_clients=1) client.fetch(self.get_url('/countdown/3'), self.stop, max_redirects=3) response = self.wait() @@ -307,6 +301,27 @@ class SimpleHTTPClientTestCase(AsyncHTTPTestCase): response.error) +class SimpleHTTPClientTestCase(SimpleHTTPClientTestMixin, AsyncHTTPTestCase): + def setUp(self): + super(SimpleHTTPClientTestCase, self).setUp() + self.http_client = self.create_client() + + def create_client(self, **kwargs): + return SimpleAsyncHTTPClient(self.io_loop, force_instance=True, + **kwargs) + + +class SimpleHTTPSClientTestCase(SimpleHTTPClientTestMixin, AsyncHTTPSTestCase): + def setUp(self): + super(SimpleHTTPSClientTestCase, self).setUp() + self.http_client = self.create_client() + + def create_client(self, **kwargs): + return SimpleAsyncHTTPClient(self.io_loop, force_instance=True, + defaults=dict(validate_cert=False), + **kwargs) + + class CreateAsyncHTTPClientTestCase(AsyncTestCase): def setUp(self): super(CreateAsyncHTTPClientTestCase, self).setUp() -- 2.47.2