def test_416(self, client, asgi): client.app = create_app(asgi) client.app.add_route('/416', RangeNotSatisfiableResource()) response = client.simulate_request(path='/416', headers={'accept': 'text/xml'}) assert response.status == falcon.HTTP_416 assert response.content == falcon.HTTPRangeNotSatisfiable( 123456).to_xml() exp = (b'<?xml version="1.0" encoding="UTF-8"?><error>' b'<title>416 Range Not Satisfiable</title></error>') assert response.content == exp assert response.headers['content-range'] == 'bytes */123456' assert response.headers['content-length'] == str(len(response.content))
def _open_range(file_path, req_range): """Open a file for a ranged request. Args: file_path (str): Path to the file to open. req_range (Optional[Tuple[int, int]]): Request.range value. Returns: tuple: Three-member tuple of (stream, content-length, content-range). If req_range is ``None`` or ignored, content-range will be ``None``; otherwise, the stream will be appropriately seeked and possibly bounded, and the content-range will be a tuple of (start, end, size). """ fh = io.open(file_path, 'rb') size = os.fstat(fh.fileno()).st_size if req_range is None: return fh, size, None start, end = req_range if size == 0: # NOTE(tipabu): Ignore Range headers for zero-byte files; just serve # the empty body since Content-Range can't be used to express a # zero-byte body. return fh, 0, None if start < 0 and end == -1: # NOTE(tipabu): Special case: only want the last N bytes. start = max(start, -size) fh.seek(start, os.SEEK_END) # NOTE(vytas): Wrap in order to prevent sendfile from being used, as # its implementation was found to be buggy in many popular WSGI # servers for open files with a non-zero offset. return _BoundedFile(fh, -start), -start, (size + start, size - 1, size) if start >= size: fh.close() raise falcon.HTTPRangeNotSatisfiable(size) fh.seek(start) if end == -1: # NOTE(vytas): Wrap in order to prevent sendfile from being used, as # its implementation was found to be buggy in many popular WSGI # servers for open files with a non-zero offset. length = size - start return _BoundedFile(fh, length), length, (start, size - 1, size) end = min(end, size - 1) length = end - start + 1 return _BoundedFile(fh, length), length, (start, end, size)
def on_get(self, req, resp): raise falcon.HTTPRangeNotSatisfiable(123456)
def on_put(self, req, resp): raise falcon.HTTPRangeNotSatisfiable(123456, 'x-falcon/peregrine')
def test_http_range_not_satisfiable_with_headers(): try: raise falcon.HTTPRangeNotSatisfiable(resource_length=0, headers={'foo': 'bar'}) except falcon.HTTPRangeNotSatisfiable as e: assert e.headers['foo'] == 'bar'