|
11 | 11 | from tornado.ioloop import IOLoop
|
12 | 12 | from tornado.simple_httpclient import SimpleAsyncHTTPClient
|
13 | 13 | from tornado.testing import AsyncHTTPTestCase, LogTrapTestCase, get_unused_port
|
14 |
| -from tornado.web import Application, RequestHandler, asynchronous |
| 14 | +from tornado.web import Application, RequestHandler, asynchronous, url |
15 | 15 |
|
16 | 16 | class HelloWorldHandler(RequestHandler):
|
17 | 17 | def get(self):
|
@@ -50,18 +50,27 @@ def get(self):
|
50 | 50 | self.queue.append(self.finish)
|
51 | 51 | self.wake_callback()
|
52 | 52 |
|
| 53 | +class CountdownHandler(RequestHandler): |
| 54 | + def get(self, count): |
| 55 | + count = int(count) |
| 56 | + if count > 0: |
| 57 | + self.redirect(self.reverse_url("countdown", count - 1)) |
| 58 | + else: |
| 59 | + self.write("Zero") |
| 60 | + |
53 | 61 | class SimpleHTTPClientTestCase(AsyncHTTPTestCase, LogTrapTestCase):
|
54 | 62 | def get_app(self):
|
55 | 63 | # callable objects to finish pending /trigger requests
|
56 | 64 | self.triggers = collections.deque()
|
57 | 65 | return Application([
|
58 |
| - ("/hello", HelloWorldHandler), |
59 |
| - ("/post", PostHandler), |
60 |
| - ("/chunk", ChunkHandler), |
61 |
| - ("/auth", AuthHandler), |
62 |
| - ("/hang", HangHandler), |
63 |
| - ("/trigger", TriggerHandler, dict(queue=self.triggers, |
64 |
| - wake_callback=self.stop)), |
| 66 | + url("/hello", HelloWorldHandler), |
| 67 | + url("/post", PostHandler), |
| 68 | + url("/chunk", ChunkHandler), |
| 69 | + url("/auth", AuthHandler), |
| 70 | + url("/hang", HangHandler), |
| 71 | + url("/trigger", TriggerHandler, dict(queue=self.triggers, |
| 72 | + wake_callback=self.stop)), |
| 73 | + url("/countdown/([0-9]+)", CountdownHandler, name="countdown"), |
65 | 74 | ], gzip=True)
|
66 | 75 |
|
67 | 76 | def setUp(self):
|
@@ -176,3 +185,22 @@ def test_connection_limit(self):
|
176 | 185 | self.assertEqual(seen, [0, 1])
|
177 | 186 | self.assertEqual(len(client.queue), 0)
|
178 | 187 |
|
| 188 | + def test_follow_redirect(self): |
| 189 | + response = self.fetch("/countdown/2", follow_redirects=False) |
| 190 | + self.assertEqual(302, response.code) |
| 191 | + self.assertTrue(response.headers["Location"].endswith("/countdown/1")) |
| 192 | + |
| 193 | + response = self.fetch("/countdown/2") |
| 194 | + self.assertEqual(200, response.code) |
| 195 | + self.assertTrue(response.effective_url.endswith("/countdown/0")) |
| 196 | + self.assertEqual("Zero", response.body) |
| 197 | + |
| 198 | + def test_max_redirects(self): |
| 199 | + response = self.fetch("/countdown/5", max_redirects=3) |
| 200 | + self.assertEqual(302, response.code) |
| 201 | + # We requested 5, followed three redirects for 4, 3, 2, then the last |
| 202 | + # unfollowed redirect is to 1. |
| 203 | + self.assertTrue(response.request.url.endswith("/countdown/5")) |
| 204 | + self.assertTrue(response.effective_url.endswith("/countdown/2")) |
| 205 | + self.assertTrue(response.headers["Location"].endswith("/countdown/1")) |
| 206 | + |
0 commit comments