else:
raise Exception("didn't get permanent or status arguments")
+class EmptyFlushCallbackHandler(RequestHandler):
+ @gen.engine
+ @asynchronous
+ def get(self):
+ # Ensure that the flush callback is run whether or not there
+ # was any output.
+ yield gen.Task(self.flush) # "empty" flush, but writes headers
+ yield gen.Task(self.flush) # empty flush
+ self.write("o")
+ yield gen.Task(self.flush) # flushes the "o"
+ yield gen.Task(self.flush) # empty flush
+ self.finish("k")
+
+ class HeaderInjectionHandler(RequestHandler):
+ def get(self):
+ try:
+ self.set_header("X-Foo", "foo\r\nX-Bar: baz")
+ raise Exception("Didn't get expected exception")
+ except ValueError, e:
+ assert "Unsafe header value" in str(e)
+ self.finish(b("ok"))
+
+
class WebTest(AsyncHTTPTestCase, LogTrapTestCase):
def get_app(self):
loader = DictLoader({
url("/flow_control", FlowControlHandler),
url("/multi_header", MultiHeaderHandler),
url("/redirect", RedirectHandler),
+ url("/empty_flush", EmptyFlushCallbackHandler),
+ url("/header_injection", HeaderInjectionHandler),
]
return Application(urls,
template_loader=loader,
response = self.fetch("/redirect?status=307", follow_redirects=False)
self.assertEqual(response.code, 307)
+ def test_empty_flush(self):
+ response = self.fetch("/empty_flush")
+ self.assertEqual(response.body, b("ok"))
+
+ def test_header_injection(self):
+ response = self.fetch("/header_injection")
+ self.assertEqual(response.body, b("ok"))
+
class ErrorResponseTest(AsyncHTTPTestCase, LogTrapTestCase):
def get_app(self):
# twisted under pypy takes a *very* long time. MySQL-python builds with
# pypy, but doesn't work.
+# In python 3, opening files in text mode uses a system-dependent encoding by
+# default. Run the tests with "C" (ascii) and "utf-8" locales to ensure
+# we don't have hidden dependencies on this setting.
+[testenv:py32]
+basepython = python3.2
+setenv = LANG=C
+
+[testenv:py32-utf8]
+basepython = python3.2
+setenv = LANG=en_US.utf-8
+
# No py32-full yet: none of our dependencies currently work on python3.
- basepython = python3.3
+
+[testenv:py33]
+# tox doesn't yet know "py33" by default
++basepython = python3.3