import urllib.request
import urllib.parse
import ssl
import socket
import threading
import queue
class CompatHTTPClient:
def __init__(self, max_memory=1024*1024): # 1MB default
self.max_memory = max_memory
self.request_queue = queue.Queue()
self.response_queue = queue.Queue()
self.running = True
self.request_threads = []
self.response_threads = []
def request(self, url, method='GET', headers=None, data=None, timeout=None):
"""
Sends an HTTP request and returns the response.
Handles memory constraints by streaming the response.
"""
req = urllib.request.Request(url, method=method, headers=headers)
try:
with urllib.request.urlopen(req, timeout=timeout) as response:
# Stream the response
for chunk in iter(lambda: response.read(4096), b''):
yield chunk
except Exception as e:
yield f"Error: {e}"
def submit_request(self, url, method='GET', headers=None, data=None, timeout=None):
"""
Submits a request to the request queue.
"""
self.request_queue.put((url, method, headers, data, timeout))
def _worker_request(self):
"""
Worker thread to handle requests from the queue.
"""
while self.running:
try:
url, method, headers, data, timeout = self.request_queue.get(timeout=0.1)
try:
response = self.request(url, method, headers, data, timeout)
self.response_queue.put((url, response))
except Exception as e:
self.response_queue.put((url, f"Error: {e}"))
finally:
self.request_queue.task_done()
except queue.Empty:
pass # Continue if queue is empty
def _worker_response(self):
"""
Worker thread to handle responses from the queue.
"""
while self.running:
try:
url, response = self.response_queue.get(timeout=0.1)
yield url, response
except queue.Empty:
pass # Continue if queue is empty
def start(self, num_request_threads=4, num_response_threads=4):
"""
Starts the worker threads.
"""
for _ in range(num_request_threads):
thread = threading.Thread(target=self._worker_request)
thread.daemon = True
self.request_threads.append(thread)
thread.start()
for _ in range(num_response_threads):
thread = threading.Thread(target=self._worker_response)
thread.daemon = True
self.response_threads.append(thread)
thread.start()
def stop(self):
"""
Stops the worker threads.
"""
self.running = False
for thread in self.request_threads:
thread.join(timeout=0.1)
for thread in self.response_threads:
thread.join(timeout=0.1)
Add your comment