From 6ccd3aef27bb3f5cf8c2986dfe80ced1c6abe360 Mon Sep 17 00:00:00 2001 From: Ben Darnell Date: Thu, 11 Jul 2013 14:00:37 -0400 Subject: [PATCH] Fix exception in StaticFileHandler when range requested is larger than file. --- tornado/test/web_test.py | 20 ++++++++++++++++++++ tornado/web.py | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/tornado/test/web_test.py b/tornado/test/web_test.py index 942a8917e..21035c908 100644 --- a/tornado/test/web_test.py +++ b/tornado/test/web_test.py @@ -900,6 +900,26 @@ class StaticFileTest(WebTestCase): self.assertEqual(response.headers.get("Content-Length"), "26") self.assertEqual(response.headers.get("Content-Range"), None) + def test_static_with_range_full_past_end(self): + response = self.fetch('/static/robots.txt', headers={ + 'Range': 'bytes=0-10000000'}) + self.assertEqual(response.code, 200) + robots_file_path = os.path.join(self.static_dir, "robots.txt") + with open(robots_file_path) as f: + self.assertEqual(response.body, utf8(f.read())) + self.assertEqual(response.headers.get("Content-Length"), "26") + self.assertEqual(response.headers.get("Content-Range"), None) + + def test_static_with_range_partial_past_end(self): + response = self.fetch('/static/robots.txt', headers={ + 'Range': 'bytes=1-10000000'}) + self.assertEqual(response.code, 206) + robots_file_path = os.path.join(self.static_dir, "robots.txt") + with open(robots_file_path) as f: + self.assertEqual(response.body, utf8(f.read()[1:])) + self.assertEqual(response.headers.get("Content-Length"), "25") + self.assertEqual(response.headers.get("Content-Range"), "bytes 1-25/26") + def test_static_with_range_end_edge(self): response = self.fetch('/static/robots.txt', headers={ 'Range': 'bytes=22-'}) diff --git a/tornado/web.py b/tornado/web.py index 363c97c44..63f5514c3 100644 --- a/tornado/web.py +++ b/tornado/web.py @@ -1827,6 +1827,10 @@ class StaticFileHandler(RequestHandler): return if start is not None and start < 0: start += size + if end is not None and end > size: + # Clients sometimes blindly use a large range to limit their + # download size; cap the endpoint at the actual file size. + end = size # Note: only return HTTP 206 if less than the entire range has been # requested. Not only is this semantically correct, but Chrome # refuses to play audio if it gets an HTTP 206 in response to -- 2.47.2