Skip to content

Commit

Permalink
Merge pull request #1711 from pallets/video-range
Browse files Browse the repository at this point in the history
range request always returns 206 status
  • Loading branch information
davidism authored Feb 6, 2020
2 parents 07e3c97 + 85eaee9 commit 0474354
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 15 deletions.
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ Unreleased
implementations. :pr:`1702`
- Support matching and building WebSocket rules in the routing system,
for use by async frameworks. :pr:`1709`
- Range requests that span an entire file respond with 206 instead of
200, to be more compliant with :rfc:`7233`. This may help serving
media to older browsers. :issue:`410, 1704`


Version 0.16.1
Expand Down
29 changes: 16 additions & 13 deletions src/werkzeug/wrappers/etag.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,28 +142,31 @@ def _process_range_request(self, environ, complete_length=None, accept_ranges=No
"""
from ..exceptions import RequestedRangeNotSatisfiable

if accept_ranges is None:
return False
self.headers["Accept-Ranges"] = accept_ranges
if not self._is_range_request_processable(environ) or complete_length is None:
if (
accept_ranges is None
or complete_length is None
or not self._is_range_request_processable(environ)
):
return False

parsed_range = parse_range_header(environ.get("HTTP_RANGE"))

if parsed_range is None:
raise RequestedRangeNotSatisfiable(complete_length)

range_tuple = parsed_range.range_for_length(complete_length)
content_range_header = parsed_range.to_content_range_header(complete_length)

if range_tuple is None or content_range_header is None:
raise RequestedRangeNotSatisfiable(complete_length)

content_length = range_tuple[1] - range_tuple[0]
# Be sure not to send 206 response
# if requested range is the full content.
if content_length != complete_length:
self.headers["Content-Length"] = content_length
self.content_range = content_range_header
self.status_code = 206
self._wrap_response(range_tuple[0], content_length)
return True
return False
self.headers["Content-Length"] = content_length
self.headers["Accept-Ranges"] = accept_ranges
self.content_range = content_range_header
self.status_code = 206
self._wrap_response(range_tuple[0], content_length)
return True

def make_conditional(
self, request_or_environ, accept_ranges=False, complete_length=None
Expand Down
4 changes: 2 additions & 2 deletions tests/test_wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -878,9 +878,9 @@ def test_range_request_with_complete_file():
response = wrappers.Response(wrap_file(env, f))
env["HTTP_RANGE"] = "bytes=0-%d" % (fsize - 1)
response.make_conditional(env, accept_ranges=True, complete_length=fsize)
assert response.status_code == 200
assert response.status_code == 206
assert response.headers["Accept-Ranges"] == "bytes"
assert "Content-Range" not in response.headers
assert response.headers["Content-Range"] == "bytes 0-%d/%d" % (fsize - 1, fsize)
assert response.headers["Content-Length"] == str(fsize)
assert response.data == fcontent

Expand Down

0 comments on commit 0474354

Please sign in to comment.