From 92b73a6f4f92c72106f61440d591c297357e5955 Mon Sep 17 00:00:00 2001 From: Harsha Narayana Date: Wed, 7 Nov 2018 19:06:56 +0530 Subject: [PATCH] fix Range header handling for static files (#1402) This commit fixes the issue in the `Range` header handling that was done while serving the file contents. As per the HTTP response standards, a status code of 206 will be used in case if the Range is returning a partial value and default of 200 in other cases. Signed-off-by: Harsha Narayana --- sanic/handlers.py | 6 +++--- sanic/response.py | 2 ++ tests/test_static.py | 8 ++++---- tests/test_url_for_static.py | 16 ++++++++-------- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/sanic/handlers.py b/sanic/handlers.py index 811ffeac..ee12ce36 100644 --- a/sanic/handlers.py +++ b/sanic/handlers.py @@ -167,17 +167,17 @@ class ContentRangeHandler: ) else: # this case represents `Content-Range: bytes 5-` - self.end = self.total + self.end = self.total - 1 else: if self.start is None: # this case represents `Content-Range: bytes -5` self.start = self.total - self.end - self.end = self.total + self.end = self.total - 1 if self.start >= self.end: raise ContentRangeError( "Invalid for Content Range parameters", self ) - self.size = self.end - self.start + self.size = self.end - self.start + 1 self.headers = { "Content-Range": "bytes %s-%s/%s" % (self.start, self.end, self.total) diff --git a/sanic/response.py b/sanic/response.py index fb9b3d6c..09c92225 100644 --- a/sanic/response.py +++ b/sanic/response.py @@ -302,6 +302,7 @@ async def file( _range.end, _range.total, ) + status = 206 else: out_stream = await _file.read() @@ -371,6 +372,7 @@ async def file_stream( _range.end, _range.total, ) + status = 206 return StreamingHTTPResponse( streaming_fn=_streaming_fn, status=status, diff --git a/tests/test_static.py b/tests/test_static.py index 80952538..91b7e454 100644 --- a/tests/test_static.py +++ b/tests/test_static.py @@ -84,11 +84,11 @@ def test_static_content_range_correct(app, file_name, static_file_directory): 'Range': 'bytes=12-19' } request, response = app.test_client.get('/testing.file', headers=headers) - assert response.status == 200 + assert response.status == 206 assert 'Content-Length' in response.headers assert 'Content-Range' in response.headers static_content = bytes(get_file_content( - static_file_directory, file_name))[12:19] + static_file_directory, file_name))[12:20] assert int(response.headers[ 'Content-Length']) == len(static_content) assert response.body == static_content @@ -104,7 +104,7 @@ def test_static_content_range_front(app, file_name, static_file_directory): 'Range': 'bytes=12-' } request, response = app.test_client.get('/testing.file', headers=headers) - assert response.status == 200 + assert response.status == 206 assert 'Content-Length' in response.headers assert 'Content-Range' in response.headers static_content = bytes(get_file_content( @@ -124,7 +124,7 @@ def test_static_content_range_back(app, file_name, static_file_directory): 'Range': 'bytes=-12' } request, response = app.test_client.get('/testing.file', headers=headers) - assert response.status == 200 + assert response.status == 206 assert 'Content-Length' in response.headers assert 'Content-Range' in response.headers static_content = bytes(get_file_content( diff --git a/tests/test_url_for_static.py b/tests/test_url_for_static.py index 32a39e48..7b316aef 100644 --- a/tests/test_url_for_static.py +++ b/tests/test_url_for_static.py @@ -212,11 +212,11 @@ def test_static_content_range_correct(app, file_name, static_file_directory): assert uri == app.url_for('static', name='static', filename='any') request, response = app.test_client.get(uri, headers=headers) - assert response.status == 200 + assert response.status == 206 assert 'Content-Length' in response.headers assert 'Content-Range' in response.headers static_content = bytes(get_file_content( - static_file_directory, file_name))[12:19] + static_file_directory, file_name))[12:20] assert int(response.headers[ 'Content-Length']) == len(static_content) assert response.body == static_content @@ -233,11 +233,11 @@ def test_static_content_range_correct(app, file_name, static_file_directory): filename='any') request, response = app.test_client.get(uri, headers=headers) - assert response.status == 200 + assert response.status == 206 assert 'Content-Length' in response.headers assert 'Content-Range' in response.headers static_content = bytes(get_file_content( - static_file_directory, file_name))[12:19] + static_file_directory, file_name))[12:20] assert int(response.headers[ 'Content-Length']) == len(static_content) assert response.body == static_content @@ -263,7 +263,7 @@ def test_static_content_range_front(app, file_name, static_file_directory): assert uri == app.url_for('static', name='static', filename='any') request, response = app.test_client.get(uri, headers=headers) - assert response.status == 200 + assert response.status == 206 assert 'Content-Length' in response.headers assert 'Content-Range' in response.headers static_content = bytes(get_file_content( @@ -284,7 +284,7 @@ def test_static_content_range_front(app, file_name, static_file_directory): filename='any') request, response = app.test_client.get(uri, headers=headers) - assert response.status == 200 + assert response.status == 206 assert 'Content-Length' in response.headers assert 'Content-Range' in response.headers static_content = bytes(get_file_content( @@ -314,7 +314,7 @@ def test_static_content_range_back(app, file_name, static_file_directory): assert uri == app.url_for('static', name='static', filename='any') request, response = app.test_client.get(uri, headers=headers) - assert response.status == 200 + assert response.status == 206 assert 'Content-Length' in response.headers assert 'Content-Range' in response.headers static_content = bytes(get_file_content( @@ -335,7 +335,7 @@ def test_static_content_range_back(app, file_name, static_file_directory): filename='any') request, response = app.test_client.get(uri, headers=headers) - assert response.status == 200 + assert response.status == 206 assert 'Content-Length' in response.headers assert 'Content-Range' in response.headers static_content = bytes(get_file_content(