Plain Sockets Example ClientΒΆ
This example is a basic HTTP/2 client written using plain Python sockets, and ssl TLS/SSL wrapper for socket objects.
This client is not a complete production-ready HTTP/2 client and only intended as a demonstration sample.
This example shows the bare minimum that is needed to send an HTTP/2 request to a server, and read back a response body.
1#!/usr/bin/env python3
2
3"""
4plain_sockets_client.py
5~~~~~~~~~~~~~~~~~~~~~~~
6
7Just enough code to send a GET request via h2 to an HTTP/2 server and receive a response body.
8This is *not* a complete production-ready HTTP/2 client!
9"""
10
11import socket
12import ssl
13import certifi
14
15import h2.connection
16import h2.events
17
18
19SERVER_NAME = 'http2.golang.org'
20SERVER_PORT = 443
21
22# generic socket and ssl configuration
23socket.setdefaulttimeout(15)
24ctx = ssl.create_default_context(cafile=certifi.where())
25ctx.set_alpn_protocols(['h2'])
26
27# open a socket to the server and initiate TLS/SSL
28s = socket.create_connection((SERVER_NAME, SERVER_PORT))
29s = ctx.wrap_socket(s, server_hostname=SERVER_NAME)
30
31c = h2.connection.H2Connection()
32c.initiate_connection()
33s.sendall(c.data_to_send())
34
35headers = [
36 (':method', 'GET'),
37 (':path', '/reqinfo'),
38 (':authority', SERVER_NAME),
39 (':scheme', 'https'),
40]
41c.send_headers(1, headers, end_stream=True)
42s.sendall(c.data_to_send())
43
44body = b''
45response_stream_ended = False
46while not response_stream_ended:
47 # read raw data from the socket
48 data = s.recv(65536 * 1024)
49 if not data:
50 break
51
52 # feed raw data into h2, and process resulting events
53 events = c.receive_data(data)
54 for event in events:
55 print(event)
56 if isinstance(event, h2.events.DataReceived):
57 # update flow control so the server doesn't starve us
58 c.acknowledge_received_data(event.flow_controlled_length, event.stream_id)
59 # more response body data received
60 body += event.data
61 if isinstance(event, h2.events.StreamEnded):
62 # response body completed, let's exit the loop
63 response_stream_ended = True
64 break
65 # send any pending data to the server
66 s.sendall(c.data_to_send())
67
68print("Response fully received:")
69print(body.decode())
70
71# tell the server we are closing the h2 connection
72c.close_connection()
73s.sendall(c.data_to_send())
74
75# close the socket
76s.close()