import asyncio
import json
from typing import Any, Optional
import http.client
import ssl
def request(host, port, data, use_ssl=False, ssl_context=None):
if use_ssl:
conn = http.client.HTTPSConnection(host, port, timeout=10, context=ssl_context)
else:
conn = http.client.HTTPConnection(host, port, timeout=10)
json_data = json.dumps(data)
headers = {"Content-Type": "application/json"}
print(f"{'https' if use_ssl else 'http'}: Sending request {host}:{port}", json_data)
conn.request("POST", "/", body=json_data, headers=headers)
resp = conn.getresponse()
return json.loads(resp.read().decode())
async def request_async(loop, host, port, data, use_ssl=False, ssl_context=None):
def send_request():
return request(host, port, data, use_ssl, ssl_context)
return await loop.run_in_executor(None, send_request)
class HTTPProtocol:
client: Any = None host: str
loop: asyncio.AbstractEventLoop
port: int
use_ssl: bool
ssl_context: Optional[ssl.SSLContext]
def __init__(
self,
host: str,
port: int,
client,
loop: asyncio.AbstractEventLoop,
use_ssl=False,
ssl_context=None,
):
self.client = client
self.host = host
self.loop = loop
self.port = port
self.use_ssl = use_ssl
self.ssl_context = ssl_context
async def connect(self):
request(
self.host,
self.port,
{"method": "server.ping", "params": []},
self.use_ssl,
self.ssl_context,
)
async def send_data_task(self, data: dict):
try:
response = await request_async(
self.loop, self.host, self.port, data, self.use_ssl, self.ssl_context
)
self.client._got_response(response)
except (http.client.HTTPException, ConnectionError) as e:
print("HTTP request failed:", e)
self.client.connection_lost(e)
except Exception as e:
print("Unexpected error occurred:", e)
self.client.connection_lost(e)
def send_data(self, data: dict):
self.loop.create_task(self.send_data_task(data))
def close(self):
pass