Return a closure that starts an HTTP server and sends a forward proxy request. The closure starts a minimal HTTP server on the given port inside the sandbox, then sends a plain HTTP forward proxy request (non-CONNECT) through the sandbox proxy and returns the raw response.
()
| 199 | |
| 200 | |
| 201 | def _forward_proxy_with_server(): |
| 202 | """Return a closure that starts an HTTP server and sends a forward proxy request. |
| 203 | |
| 204 | The closure starts a minimal HTTP server on the given port inside the sandbox, |
| 205 | then sends a plain HTTP forward proxy request (non-CONNECT) through the sandbox |
| 206 | proxy and returns the raw response. |
| 207 | """ |
| 208 | |
| 209 | def fn(proxy_host, proxy_port, target_host, target_port): |
| 210 | import socket |
| 211 | import threading |
| 212 | import time |
| 213 | from http.server import BaseHTTPRequestHandler, HTTPServer |
| 214 | |
| 215 | class Handler(BaseHTTPRequestHandler): |
| 216 | def do_GET(self): |
| 217 | self.send_response(200) |
| 218 | body = b"forward-proxy-ok" |
| 219 | self.send_header("Content-Length", str(len(body))) |
| 220 | self.end_headers() |
| 221 | self.wfile.write(body) |
| 222 | |
| 223 | def log_message(self, *args): |
| 224 | pass # suppress log output |
| 225 | |
| 226 | srv = HTTPServer(("0.0.0.0", int(target_port)), Handler) |
| 227 | threading.Thread(target=srv.handle_request, daemon=True).start() |
| 228 | time.sleep(0.5) |
| 229 | |
| 230 | conn = socket.create_connection((proxy_host, int(proxy_port)), timeout=10) |
| 231 | try: |
| 232 | req = ( |
| 233 | f"GET http://{target_host}:{target_port}/test HTTP/1.1\r\n" |
| 234 | f"Host: {target_host}:{target_port}\r\n\r\n" |
| 235 | ) |
| 236 | conn.sendall(req.encode()) |
| 237 | data = b"" |
| 238 | conn.settimeout(5) |
| 239 | try: |
| 240 | while True: |
| 241 | chunk = conn.recv(4096) |
| 242 | if not chunk: |
| 243 | break |
| 244 | data += chunk |
| 245 | except socket.timeout: |
| 246 | pass |
| 247 | return data.decode("latin1") |
| 248 | finally: |
| 249 | conn.close() |
| 250 | srv.server_close() |
| 251 | |
| 252 | return fn |
| 253 | |
| 254 | |
| 255 | def _forward_proxy_raw(): |
no outgoing calls
no test coverage detected