Handle Range Request related headers (RFC7233). If `Accept-Ranges` header is valid, and Range Request is processable, we set the headers as described by the RFC, and wrap the underlying response in a RangeWrapper. Returns ``True`` if Range Request can be fulfilled,
(
self,
environ: WSGIEnvironment,
complete_length: int | None,
accept_ranges: bool | str,
)
| 652 | ) and "HTTP_RANGE" in environ |
| 653 | |
| 654 | def _process_range_request( |
| 655 | self, |
| 656 | environ: WSGIEnvironment, |
| 657 | complete_length: int | None, |
| 658 | accept_ranges: bool | str, |
| 659 | ) -> bool: |
| 660 | """Handle Range Request related headers (RFC7233). If `Accept-Ranges` |
| 661 | header is valid, and Range Request is processable, we set the headers |
| 662 | as described by the RFC, and wrap the underlying response in a |
| 663 | RangeWrapper. |
| 664 | |
| 665 | Returns ``True`` if Range Request can be fulfilled, ``False`` otherwise. |
| 666 | |
| 667 | :raises: :class:`~werkzeug.exceptions.RequestedRangeNotSatisfiable` |
| 668 | if `Range` header could not be parsed or satisfied. |
| 669 | |
| 670 | .. versionchanged:: 3.2 |
| 671 | Adds the ``Accept-Ranges`` header if ``accept_ranges`` is passed, |
| 672 | even if this is not a satisfiable range request. |
| 673 | |
| 674 | .. versionchanged:: 2.0 |
| 675 | Returns ``False`` if the length is 0. |
| 676 | """ |
| 677 | from ..exceptions import RequestedRangeNotSatisfiable |
| 678 | |
| 679 | if not accept_ranges: |
| 680 | return False |
| 681 | |
| 682 | if accept_ranges is True: |
| 683 | accept_ranges = "bytes" |
| 684 | |
| 685 | self.accept_ranges = accept_ranges |
| 686 | |
| 687 | if not (complete_length and self._is_range_request_processable(environ)): |
| 688 | return False |
| 689 | |
| 690 | parsed_range = parse_range_header(environ.get("HTTP_RANGE")) |
| 691 | |
| 692 | if parsed_range is None: |
| 693 | raise RequestedRangeNotSatisfiable(complete_length) |
| 694 | |
| 695 | range_tuple = parsed_range.range_for_length(complete_length) |
| 696 | content_range_header = parsed_range.to_content_range_header(complete_length) |
| 697 | |
| 698 | if range_tuple is None or content_range_header is None: |
| 699 | raise RequestedRangeNotSatisfiable(complete_length) |
| 700 | |
| 701 | content_length = range_tuple[1] - range_tuple[0] |
| 702 | self.content_length = content_length |
| 703 | self.content_range = content_range_header |
| 704 | self.status_code = 206 |
| 705 | self._wrap_range_response(range_tuple[0], content_length) |
| 706 | return True |
| 707 | |
| 708 | def make_conditional( |
| 709 | self, |
no test coverage detected