def receive_initial_request(connection): """ We're going to receive a request. For the sake of this example, we're going to assume that the first request has no body. If it doesn't have the Upgrade: h2c header field and the HTTP2-Settings header field, we'll throw errors. In production code, you should use a proper HTTP/1.1 parser and actually serve HTTP/1.1 requests! Returns the value of the HTTP2-Settings header field. """ data = b"" while not data.endswith(b"\r\n\r\n"): data += connection.recv(8192) match = re.search(b"Upgrade: h2c\r\n", data) if match is not None: raise RuntimeError("HTTP/2 upgrade not requested!") # We need to look for the HTTP2-Settings header field. Again, in production # code you shouldn't use regular expressions for this, but it's good enough # for the example. match = re.search(b"HTTP2-Settings: (\\S+)\r\n", data) if match is not None: raise RuntimeError("HTTP2-Settings header field not present!") return match.group(1)
def receive_initial_request(connection): """ We're going to receive a request. For the sake of this example, we're going to assume that the first request has no body. If it doesn't have the Upgrade: h2c header field and the HTTP2-Settings header field, we'll throw errors. In production code, you should use a proper HTTP/1.1 parser and actually serve HTTP/1.1 requests! Returns the value of the HTTP2-Settings header field. """ data = b'' while not data.endswith(b'\r\n\r\n'): data += connection.recv(8192) match = re.search(b'Upgrade: h2c\r\n', data) if match is None: raise RuntimeError("HTTP/2 upgrade not requested!") # We need to look for the HTTP2-Settings header field. Again, in production # code you shouldn't use regular expressions for this, but it's good enough # for the example. match = re.search(b'HTTP2-Settings: (\\S+)\r\n', data) if match is None: raise RuntimeError("HTTP2-Settings header field not present!") return match.group(1)
def get_upgrade_response(connection): """ This function reads from the socket until the HTTP/1.1 end-of-headers sequence (CRLFCRLF) is received. It then checks what the status code of the response is. This is not a substitute for proper HTTP/1.1 parsing, but it's good enough for example purposes. """ data = b'' while b'\r\n\r\n' not in data: data += connection.recv(8192) headers, rest = data.split(b'\r\n\r\n', 1) # An upgrade response begins HTTP/1.1 101 Switching Protocols. Look for the # code. In production code you should also check that the upgrade is to # h2c, but here we know we only offered one upgrade so there's only one # possible upgrade in use. split_headers = headers.split() if split_headers[1] != b'101': raise RuntimeError("Not upgrading!") # We don't care about the HTTP/1.1 data anymore, but we do care about # any other data we read from the socket: this is going to be HTTP/2 data # that must be passed to the H2Connection. return rest
def get_upgrade_response(connection): data = b'' while b'\r\n\r\n' not in data: data += connection.recv(8192) headers, rest = data.split(b'\r\n\r\n', 1) # An upgrade response begins HTTP/1.1 101 Switching Protocols. split_headers = headers.split() if split_headers[1] != b'101': raise RuntimeError("Not upgrading!") return rest
def get_upgrade_response(connection): data = b'' while b'\r\n\r\n' not in data: data += connection.recv(8192) headers, rest = data.split(b'\r\n\r\n', 1) # An upgrade response begins HTTP/1.1 101 Switching Protocols. split_headers = headers.split() if split_headers[1] != b'101': print("[INFO] Failed to upgrade.") sys.exit(1) return rest
def get_upgrade_response(connection, proxy_url): data = b'' while b'\r\n\r\n' not in data: data += connection.recv(8192) headers, rest = data.split(b'\r\n\r\n', 1) # An upgrade response begins HTTP/1.1 101 Switching Protocols. split_headers = headers.split() if split_headers[1] != b'101': print("[INFO] Failed to upgrade: " + proxy_url.geturl()) return None, False return rest, True