structio/tests/tls_test.py

69 lines
2.5 KiB
Python

import structio
import sys
import time
_print = print
def print(*args, **kwargs):
sys.stdout.write(f"[{time.strftime('%H:%M:%S')}] ")
_print(*args, **kwargs)
async def test(host: str, port: int, bufsize: int = 4096, keepalive: bool = False):
print(f"Attempting a connection to {host}:{port} {'in keep-alive mode' if keepalive else ''}")
socket = await structio.socket.connect_tcp_ssl_socket(host, port)
buffer = b""
print("Connected")
# Ensures the code below doesn't run for more than 5 seconds
with structio.skip_after(5) as scope:
# Closes the socket automatically
async with socket:
print("Entered socket context manager, sending HTTP request data")
await socket.send_all(
f"GET / HTTP/1.1\r\nUser-Agent: Structio/0.1.0\r\nAccept: */*\r\nHost: {host}"
f"\r\nAccept-Encoding: gzip, deflate, br\r\nConnection: {'close' if not keepalive else 'keep-alive'}"
f"\r\n\r\n".encode()
)
print("Data sent")
while True:
# We purposely do NOT check for the end of the response (\r\n) so that when the
# connection is in keep-alive mode we hang and let our timeout expire the whole
# block
print(
f"Requesting up to {bufsize} bytes (current response size: {len(buffer)})"
)
data = await socket.receive(bufsize)
if data:
print(f"Received {len(data)} bytes")
buffer += data
else:
print("Received empty stream, closing connection")
break
if buffer:
data = buffer.decode().split("\r\n")
print(
f"HTTP Response below {'(might be incomplete)' if scope.timed_out else ''}:"
)
_print(f"Response: {data[0]}")
_print("Headers:")
content = False
for i, element in enumerate(data):
if i == 0:
continue
else:
if not element.strip() and not content:
sys.stdout.write("\nContent:")
content = True
if not content:
_print(f"\t{element}")
else:
for line in element.split("\n"):
_print(f"\t{line}")
_print("Done!")
structio.run(test, "google.com", 443, 256)
# With keep-alive on, our timeout will kick in
structio.run(test, "google.com", 443, 256, True)