1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
import socket, ssl
import h11
class MyHttpClient:
def __init__(self, host, port):
self.sock = socket.create_connection((host, port))
if port == 443:
ctx = ssl.create_default_context()
self.sock = ctx.wrap_socket(self.sock, server_hostname=host)
self.conn = h11.Connection(our_role=h11.CLIENT)
def send(self, *events):
for event in events:
data = self.conn.send(event)
if data is None:
# event was a ConnectionClosed(), meaning that we won't be
# sending any more data:
self.sock.shutdown(socket.SHUT_WR)
else:
self.sock.sendall(data)
# max_bytes_per_recv intentionally set low for pedagogical purposes
def next_event(self, max_bytes_per_recv=200):
while True:
# If we already have a complete event buffered internally, just
# return that. Otherwise, read some data, add it to the internal
# buffer, and then try again.
event = self.conn.next_event()
if event is h11.NEED_DATA:
self.conn.receive_data(self.sock.recv(max_bytes_per_recv))
continue
return event
|