def tearDown(self):
def stop_server():
self.server.stop()
- # Delay the shutdown of the IOLoop by one iteration because
+ # Delay the shutdown of the IOLoop by several iterations because
# the server may still have some cleanup work left when
# the client finishes with the response (this is noticeable
# with http/2, which leaves a Future with an unexamined
# StreamClosedError on the loop).
- self.server_ioloop.add_callback(self.server_ioloop.stop)
+ @gen.coroutine
+ def slow_stop():
+ # The number of iterations is difficult to predict. Typically,
+ # one is sufficient, although sometimes it needs more.
+ for i in range(5):
+ yield
+ self.server_ioloop.stop()
+ self.server_ioloop.add_callback(slow_stop)
self.server_ioloop.add_callback(stop_server)
self.server_thread.join()
self.http_client.close()
class XHeaderTest(HandlerBaseTestCase):
class Handler(RequestHandler):
def get(self):
+ self.set_header('request-version', self.request.version)
self.write(dict(remote_ip=self.request.remote_ip,
remote_protocol=self.request.protocol))
"127.0.0.1")
def test_trusted_downstream(self):
-
valid_ipv4_list = {"X-Forwarded-For": "127.0.0.1, 4.4.4.4, 5.5.5.5"}
- self.assertEqual(
- self.fetch_json("/", headers=valid_ipv4_list)["remote_ip"],
- "4.4.4.4")
+ resp = self.fetch("/", headers=valid_ipv4_list)
+ if resp.headers['request-version'].startswith('HTTP/2'):
+ # This is a hack - there's nothing that fundamentally requires http/1
+ # here but tornado_http2 doesn't support it yet.
+ self.skipTest('requires HTTP/1.x')
+ result = json_decode(resp.body)
+ self.assertEqual(result['remote_ip'], "4.4.4.4")
def test_scheme_headers(self):
self.assertEqual(self.fetch_json("/")["remote_protocol"], "http")
app = Application()
def request_callable(request):
- request.write(b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK")
- request.finish()
+ request.connection.write_headers(
+ ResponseStartLine("HTTP/1.1", 200, "OK"),
+ HTTPHeaders({"Content-Length": "2"}))
+ request.connection.write(b"OK")
+ request.connection.finish()
router = CustomRouter()
router.add_routes({
from tornado import gen
from tornado.httpclient import HTTPError, HTTPRequest
from tornado.log import gen_log, app_log
+from tornado.simple_httpclient import SimpleAsyncHTTPClient
from tornado.template import DictLoader
from tornado.testing import AsyncHTTPTestCase, gen_test, bind_unused_port, ExpectLog
from tornado.test.util import unittest, skipBefore35, exec_test
'message.html': '<b>{{ message }}</b>',
}))
+ def get_http_client(self):
+ # These tests require HTTP/1; force the use of SimpleAsyncHTTPClient.
+ return SimpleAsyncHTTPClient()
+
def tearDown(self):
super(WebSocketTest, self).tearDown()
RequestHandler._template_loaders.clear()