|
8 | 8 | """ |
9 | 9 | import requests |
10 | 10 | import threading |
| 11 | +import time |
11 | 12 | import hyper |
12 | 13 | import hyper.http11.connection |
13 | 14 | import pytest |
@@ -555,7 +556,6 @@ def socket_handler(listener): |
555 | 556 |
|
556 | 557 | self.tear_down() |
557 | 558 |
|
558 | | - |
559 | 559 | def test_resetting_stream_with_frames_in_flight(self): |
560 | 560 | """ |
561 | 561 | Hyper emits only one RST_STREAM frame, despite the other frames in |
@@ -650,6 +650,74 @@ def socket_handler(listener): |
650 | 650 |
|
651 | 651 | self.tear_down() |
652 | 652 |
|
| 653 | + def test_read_chunked_http2(self): |
| 654 | + self.set_up() |
| 655 | + |
| 656 | + recv_event = threading.Event() |
| 657 | + wait_event = threading.Event() |
| 658 | + |
| 659 | + def socket_handler(listener): |
| 660 | + sock = listener.accept()[0] |
| 661 | + |
| 662 | + # We get two messages for the connection open and then a HEADERS |
| 663 | + # frame. |
| 664 | + receive_preamble(sock) |
| 665 | + sock.recv(65535) |
| 666 | + |
| 667 | + # Now, send the headers for the response. This response has a body. |
| 668 | + f = build_headers_frame([(':status', '200')]) |
| 669 | + f.stream_id = 1 |
| 670 | + sock.send(f.serialize()) |
| 671 | + |
| 672 | + # Send the first two chunks. |
| 673 | + f = DataFrame(1) |
| 674 | + f.data = b'hello' |
| 675 | + sock.sendall(f.serialize()) |
| 676 | + f = DataFrame(1) |
| 677 | + f.data = b'there' |
| 678 | + sock.sendall(f.serialize()) |
| 679 | + |
| 680 | + # Now, delay a bit. We want to wait a half a second before we send |
| 681 | + # the next frame. |
| 682 | + wait_event.wait(5) |
| 683 | + time.sleep(0.5) |
| 684 | + f = DataFrame(1) |
| 685 | + f.data = b'world' |
| 686 | + f.flags.add('END_STREAM') |
| 687 | + sock.sendall(f.serialize()) |
| 688 | + |
| 689 | + # Wait for the message from the main thread. |
| 690 | + recv_event.set() |
| 691 | + sock.close() |
| 692 | + |
| 693 | + self._start_server(socket_handler) |
| 694 | + conn = self.get_connection() |
| 695 | + conn.request('GET', '/') |
| 696 | + resp = conn.get_response() |
| 697 | + |
| 698 | + # Confirm the status code. |
| 699 | + assert resp.status == 200 |
| 700 | + |
| 701 | + # Confirm that we can read this, but it has no body. First two chunks |
| 702 | + # should be easy, then set the event and read the next one. |
| 703 | + chunks = resp.read_chunked() |
| 704 | + first_chunk = next(chunks) |
| 705 | + second_chunk = next(chunks) |
| 706 | + wait_event.set() |
| 707 | + third_chunk = next(chunks) |
| 708 | + |
| 709 | + with pytest.raises(StopIteration): |
| 710 | + next(chunks) |
| 711 | + |
| 712 | + assert first_chunk == b'hello' |
| 713 | + assert second_chunk == b'there' |
| 714 | + assert third_chunk == b'world' |
| 715 | + |
| 716 | + # Awesome, we're done now. |
| 717 | + recv_event.wait(5) |
| 718 | + |
| 719 | + self.tear_down() |
| 720 | + |
653 | 721 |
|
654 | 722 | class TestRequestsAdapter(SocketLevelTest): |
655 | 723 | # This uses HTTP/2. |
|
0 commit comments