From: David Wolever Date: Tue, 21 May 2013 04:14:46 +0000 (-0400) Subject: Send HTTP 200 in response to Range: bytes=0- X-Git-Tag: v3.1.0~56^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5b794deecc3b63fa3f9d47481db27da09cbd5d99;p=thirdparty%2Ftornado.git Send HTTP 200 in response to Range: bytes=0- --- diff --git a/tornado/test/web_test.py b/tornado/test/web_test.py index 00d0ea0d3..3d80b6ba5 100644 --- a/tornado/test/web_test.py +++ b/tornado/test/web_test.py @@ -756,6 +756,7 @@ class StaticFileTest(WebTestCase): # The expected MD5 hash of robots.txt, used in tests that call # StaticFileHandler.get_version robots_txt_hash = b"f71d20196d4caf35b6a670db8c70b03d" + static_dir = os.path.join(os.path.dirname(__file__), 'static') def get_handlers(self): class StaticUrlHandler(RequestHandler): @@ -794,8 +795,7 @@ class StaticFileTest(WebTestCase): ('/override_static_url/(.*)', OverrideStaticUrlHandler)] def get_app_kwargs(self): - return dict(static_path=os.path.join(os.path.dirname(__file__), - 'static')) + return dict(static_path=self.static_dir) def test_static_files(self): response = self.fetch('/robots.txt') @@ -879,6 +879,18 @@ class StaticFileTest(WebTestCase): self.assertEqual(response.headers.get("Content-Range"), "0-9/26") + def test_static_with_range_full_file(self): + response = self.fetch('/static/robots.txt', headers={ + 'Range': 'bytes=0-'}) + # Note: Chrome refuses to play audio if it gets an HTTP 206 in response + # to ``Range: bytes=0-`` :( + 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"), "0-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 690d2ecc4..0ffd9e164 100644 --- a/tornado/web.py +++ b/tornado/web.py @@ -52,6 +52,7 @@ request. from __future__ import absolute_import, division, print_function, with_statement + import base64 import binascii import datetime @@ -1797,11 +1798,17 @@ class StaticFileHandler(RequestHandler): with open(abspath, "rb") as file: data = file.read() if request_range: - # 206: Partial Content - self.set_status(206) + data_sliced = data[request_range] + # 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 ``Range: bytes=0-``. + if len(data) != len(data_sliced): + # 206: Partial Content + self.set_status(206) content_range = httputil.get_content_range(data, request_range) self.set_header("Content-Range", content_range) - data = data[request_range] + data = data_sliced if include_body: self.write(data) else: