def test_filename_star(): # NOTE(vytas): Generated by requests_toolbelt 0.9.1 on Py2 # (interestingly, one gets a "normal" filename on Py3.7). data = ( b'--a0d738bcdb30449eb0d13f4b72c2897e\r\n' b'Content-Disposition: form-data; name="file"; ' b"filename*=utf-8''%E2%AC%85%20Arrow.txt\r\n\r\n" b'A unicode arrow in the filename.\r\n' b'--a0d738bcdb30449eb0d13f4b72c2897e--\r\n' ) handler = media.MultipartFormHandler() content_type = ('multipart/form-data; boundary=' + 'a0d738bcdb30449eb0d13f4b72c2897e') stream = BufferedReader(io.BytesIO(data).read, len(data)) form = handler.deserialize(stream, content_type, len(data)) for part in form: assert part.filename == '⬅ Arrow.txt' assert part.secure_filename == '__Arrow.txt' data = data.replace(b'*=utf-8', b'*=esoteric') stream = BufferedReader(io.BytesIO(data).read, len(data)) form = handler.deserialize(stream, content_type, len(data)) for part in form: with pytest.raises(falcon.HTTPBadRequest): part.filename
def test_readline_with_size(): source = (b'Hello, world! This is a short village name in Wales.\n' b'Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch') stream = BufferedReader(io.BytesIO(source).read, len(source)) assert stream.readline(37) == b'Hello, world! This is a short village' assert stream.readline(37) == b' name in Wales.\n' assert stream.readline(8) == b'Llanfair' assert stream.readline(16) == b'pwllgwyngyllgoge' assert stream.readline(64) == b'rychwyrndrobwllllantysiliogogogoch'
def test_peek_eof(): source = b'Hello, world!\n' source_stream = io.BytesIO(source) stream = BufferedReader(source_stream.read, len(source) - 1) assert stream.peek(0) == b'' assert stream.peek(1) == b'H' assert stream.peek(2) == b'He' assert stream.peek(16) == b'Hello, world!' assert stream.peek(32) == b'Hello, world!' assert source_stream.read() == b'\n'
def __init__(self, stream, boundary, content_length, parse_options): # NOTE(vytas): More lenient check whether the provided stream is not # already an instance of BufferedReader. # This approach makes testing both the Cythonized and pure-Python # streams easier within the same test/benchmark suite. if not hasattr(stream, 'read_until'): if isinstance(stream, BoundedStream): stream = BufferedReader(stream.stream.read, content_length) else: stream = BufferedReader(stream.read, content_length) self._stream = stream self._boundary = boundary # NOTE(vytas): Here self._dash_boundary is not prepended with CRLF # (yet) for parsing the prologue. The CRLF will be prepended later to # construct the inter-part delimiter as per RFC 7578, section 4.1 # (see the note below). self._dash_boundary = b'--' + boundary self._parse_options = parse_options
def test_empty_filename(): data = (b'--a0d738bcdb30449eb0d13f4b72c2897e\r\n' b'Content-Disposition: form-data; name="file"; filename=\r\n\r\n' b'An empty filename.\r\n' b'--a0d738bcdb30449eb0d13f4b72c2897e--\r\n') handler = media.MultipartFormHandler() content_type = 'multipart/form-data; boundary=' + 'a0d738bcdb30449eb0d13f4b72c2897e' stream = BufferedReader(io.BytesIO(data).read, len(data)) form = handler.deserialize(stream, content_type, len(data)) for part in form: assert part.filename == '' with pytest.raises(falcon.MediaMalformedError): part.secure_filename
def test_from_buffered_stream(): data = (b'--BOUNDARY\r\n' b'Content-Disposition: form-data; name="empty"\r\n' b'Content-Coolness: fair\r\n' b'Content-Type: text/plain\r\n\r\n' b'\r\n' b'--BOUNDARY--\r\n') handler = media.MultipartFormHandler() stream = BufferedReader(io.BytesIO(data).read, len(data)) form = handler.deserialize(stream, 'multipart/form-data; boundary=BOUNDARY', len(data)) for part in form: assert part.data == b''
def test_parsing_correctness(buffer_size, chunk_size): example = EXAMPLES['boundary'] handler = media.MultipartFormHandler() stream = BufferedReader(io.BytesIO(example).read, len(example), buffer_size) form = handler.deserialize( stream, 'multipart/form-data; boundary=boundary', len(example)) for part in form: if part.name in ('lorem1', 'lorem2'): part_stream = part.stream result = [] while True: chunk = part_stream.read(chunk_size) if not chunk: break result.append(chunk) assert b''.join(result) == LOREM_IPSUM
def test_readline(): source = (b'Hello, world!\n' b'A line.\n' b'\n' b'A longer line... \n' + b'SPAM ' * 7 + b'\n' + b'\n') stream = BufferedReader(io.BytesIO(source).read, len(source)) assert stream.readline() == b'Hello, world!\n' assert stream.readline() == b'A line.\n' assert stream.readline() == b'\n' assert stream.readline() == b'A longer line... \n' assert stream.readline() == b'SPAM SPAM SPAM SPAM SPAM SPAM SPAM \n' assert stream.readline() == b'\n' assert stream.readline() == b'' assert stream.readline() == b''
def test_headers_edge_cases(max_headers_size): data = ( b'--a0d738bcdb30449eb0d13f4b72c2897e\r\n' b'X-Falcon: Peregrine\r\n' b'Content-Type: application/vnd.oasis.opendocument.text\r\n' b'Junk\r\n' b'Content-Disposition: form-data; name="file"; filename=hd.txt\r\n\r\n' b'No, it is not an ODT document...\r\n' b'--a0d738bcdb30449eb0d13f4b72c2897e--\r\n' ) handler = media.MultipartFormHandler() handler.parse_options.max_body_part_headers_size = max_headers_size content_type = ('multipart/form-data; boundary=' + 'a0d738bcdb30449eb0d13f4b72c2897e') stream = BufferedReader(io.BytesIO(data).read, len(data)) form = handler.deserialize(stream, content_type, len(data)) if max_headers_size < 142: with pytest.raises(falcon.HTTPBadRequest): list(form) else: assert len(list(form)) == 1
def test_bounded_read(): stream = io.BytesIO(b'Hello, world!') buffered = BufferedReader(stream.read, len('Hello, world')) buffered.read() assert stream.read() == b'!'
def fragmented_stream(): stream = FragmentedStream(TEST_DATA) return BufferedReader(stream.read, len(TEST_DATA))
def shorter_stream(): TEST_BYTES_IO.seek(0) return BufferedReader(TEST_BYTES_IO.read, 1024, 128)
def _reader_fixture(chunk_size=None): TEST_BYTES_IO.seek(0) return BufferedReader(TEST_BYTES_IO.read, len(TEST_DATA), chunk_size)
def test_read_until_shared_boundary(chunk_size): source = b'-boundary-like-' * 4 + b'--some junk--\n' + b'\n' * 1024 source_stream = io.BytesIO(source) stream = BufferedReader(source_stream.read, len(source), chunk_size) assert stream.read_until(b'-boundary-like---') == b'-boundary-like-' * 3 assert stream.peek(17) == b'-boundary-like---'