🕌
【Python】h2.connection とプレーンな socketを使って HTTP/2 リクエストを送信する
h2.connection の使い方を学ぶためにプレーンな socket で HTTP/2 リクエストを送信するクライアントコードの例を試してみた。
サーバーからのレスポンスをまとめて取得し、レスポンスデータを解析して生成することで生成されたイベントオブジェクトをもとにレスポンスヘッダーやボディを取得したり、ループの終了を行っている。
h2 モジュールのインストール
pip install h2
HTTP/2 クライアントのコード
client.py
import socket
import h2.connection
import h2.events
# https://github.com/python-hyper/h2/blob/master/examples/plain_sockets/plain_sockets_client.py
# h2c サーバー
# https://zenn.dev/masakielastic/articles/618f9f44f327f4
SERVER_NAME = '0.0.0.0'
SERVER_PORT = 8000
socket.setdefaulttimeout(15)
s = socket.create_connection((SERVER_NAME, SERVER_PORT))
c = h2.connection.H2Connection()
c.initiate_connection()
s.sendall(c.data_to_send())
headers = [
(':method', 'GET'),
(':path', '/'),
(':authority', SERVER_NAME),
(':scheme', 'http'),
]
c.send_headers(1, headers, end_stream=True)
s.sendall(c.data_to_send())
body = b''
response_stream_ended = False
while not response_stream_ended:
data = s.recv(65536 * 1024)
if not data:
break
events = c.receive_data(data)
for event in events:
print(event)
if isinstance(event, h2.events.DataReceived):
c.acknowledge_received_data(event.flow_controlled_length, event.stream_id)
body += event.data
if isinstance(event, h2.events.StreamEnded):
response_stream_ended = True
break
s.sendall(c.data_to_send())
print(body.decode())
c.close_connection()
s.sendall(c.data_to_send())
s.close()
Discussion