|
15 | 15 | from h2.frame_buffer import FrameBuffer
|
16 | 16 | from hyper.compat import ssl
|
17 | 17 | from hyper.contrib import HTTP20Adapter
|
| 18 | +from hyper.common.util import HTTPVersion |
18 | 19 | from hyperframe.frame import (
|
19 | 20 | Frame, SettingsFrame, WindowUpdateFrame, DataFrame, HeadersFrame,
|
20 | 21 | GoAwayFrame, RstStreamFrame
|
@@ -935,6 +936,100 @@ def socket_handler(listener):
|
935 | 936 |
|
936 | 937 | self.tear_down()
|
937 | 938 |
|
| 939 | + def test_version_after_tls_upgrade(self, monkeypatch): |
| 940 | + self.set_up() |
| 941 | + |
| 942 | + # We need to patch the ssl_wrap_socket method to ensure that we |
| 943 | + # forcefully upgrade. |
| 944 | + old_wrap_socket = hyper.http11.connection.wrap_socket |
| 945 | + |
| 946 | + def wrap(*args): |
| 947 | + sock, _ = old_wrap_socket(*args) |
| 948 | + return sock, 'h2' |
| 949 | + |
| 950 | + monkeypatch.setattr(hyper.http11.connection, 'wrap_socket', wrap) |
| 951 | + |
| 952 | + send_event = threading.Event() |
| 953 | + |
| 954 | + def socket_handler(listener): |
| 955 | + sock = listener.accept()[0] |
| 956 | + |
| 957 | + receive_preamble(sock) |
| 958 | + |
| 959 | + # Send the headers for the response. This response has no body. |
| 960 | + f = build_headers_frame( |
| 961 | + [(':status', '200'), ('content-length', '0')] |
| 962 | + ) |
| 963 | + f.flags.add('END_STREAM') |
| 964 | + f.stream_id = 1 |
| 965 | + sock.sendall(f.serialize()) |
| 966 | + |
| 967 | + # Wait for the message from the main thread. |
| 968 | + send_event.wait() |
| 969 | + sock.close() |
| 970 | + |
| 971 | + self._start_server(socket_handler) |
| 972 | + c = hyper.HTTPConnection(self.host, self.port, secure=True) |
| 973 | + |
| 974 | + assert c.version is HTTPVersion.http11 |
| 975 | + assert c.version is not HTTPVersion.http20 |
| 976 | + c.request('GET', '/') |
| 977 | + send_event.set() |
| 978 | + assert c.version is HTTPVersion.http20 |
| 979 | + |
| 980 | + self.tear_down() |
| 981 | + |
| 982 | + def test_version_after_http_upgrade(self): |
| 983 | + self.set_up() |
| 984 | + self.secure = False |
| 985 | + |
| 986 | + send_event = threading.Event() |
| 987 | + |
| 988 | + def socket_handler(listener): |
| 989 | + sock = listener.accept()[0] |
| 990 | + |
| 991 | + # We should get the initial request. |
| 992 | + data = b'' |
| 993 | + while not data.endswith(b'\r\n\r\n'): |
| 994 | + data += sock.recv(65535) |
| 995 | + assert b'upgrade: h2c\r\n' in data |
| 996 | + |
| 997 | + send_event.wait() |
| 998 | + |
| 999 | + # We need to send back a response. |
| 1000 | + resp = ( |
| 1001 | + b'HTTP/1.1 101 Upgrade\r\n' |
| 1002 | + b'Server: socket-level-server\r\n' |
| 1003 | + b'Content-Length: 0\r\n' |
| 1004 | + b'Connection: upgrade\r\n' |
| 1005 | + b'Upgrade: h2c\r\n' |
| 1006 | + b'\r\n' |
| 1007 | + ) |
| 1008 | + sock.sendall(resp) |
| 1009 | + |
| 1010 | + # We get a message for connection open, specifically the preamble. |
| 1011 | + receive_preamble(sock) |
| 1012 | + |
| 1013 | + # Send the headers for the response. This response has a body. |
| 1014 | + f = build_headers_frame( |
| 1015 | + [(':status', '200'), ('content-length', '0')] |
| 1016 | + ) |
| 1017 | + f.stream_id = 1 |
| 1018 | + f.flags.add('END_STREAM') |
| 1019 | + sock.sendall(f.serialize()) |
| 1020 | + |
| 1021 | + self._start_server(socket_handler) |
| 1022 | + |
| 1023 | + c = hyper.HTTPConnection(self.host, self.port) |
| 1024 | + assert c.version is HTTPVersion.http11 |
| 1025 | + c.request('GET', '/') |
| 1026 | + send_event.set() |
| 1027 | + resp = c.get_response() |
| 1028 | + assert c.version is HTTPVersion.http20 |
| 1029 | + assert resp.version is HTTPVersion.http20 |
| 1030 | + |
| 1031 | + self.tear_down() |
| 1032 | + |
938 | 1033 |
|
939 | 1034 | class TestRequestsAdapter(SocketLevelTest):
|
940 | 1035 | # This uses HTTP/2.
|
|
0 commit comments