| 441 | |
| 442 | # Start test HTTP server |
| 443 | async def handle_request(reader, writer): |
| 444 | nonlocal received_body |
| 445 | try: |
| 446 | # Read all request data |
| 447 | request_data = b"" |
| 448 | while True: |
| 449 | chunk = await reader.read(8192) |
| 450 | if not chunk: |
| 451 | break |
| 452 | request_data += chunk |
| 453 | # Check if we have complete request (headers + body) |
| 454 | if b"\r\n\r\n" in request_data: |
| 455 | # Parse Content-Length from headers |
| 456 | header_end = request_data.find(b"\r\n\r\n") |
| 457 | headers = request_data[:header_end].decode( |
| 458 | "utf-8", errors="ignore" |
| 459 | ) |
| 460 | content_length = 0 |
| 461 | for line in headers.split("\r\n"): |
| 462 | if line.lower().startswith("content-length:"): |
| 463 | content_length = int(line.split(":")[1].strip()) |
| 464 | break |
| 465 | # Check if we have complete body |
| 466 | body_start = header_end + 4 |
| 467 | body_len = len(request_data) - body_start |
| 468 | if body_len >= content_length: |
| 469 | received_body = request_data[ |
| 470 | body_start : body_start + content_length |
| 471 | ] |
| 472 | break |
| 473 | if len(request_data) > 65536: |
| 474 | break |
| 475 | |
| 476 | # Send response |
| 477 | response_body = b"OK" |
| 478 | response = ( |
| 479 | f"HTTP/1.1 200 OK\r\n" |
| 480 | f"Content-Length: {len(response_body)}\r\n" |
| 481 | f"\r\n" |
| 482 | ).encode() + response_body |
| 483 | writer.write(response) |
| 484 | await writer.drain() |
| 485 | except Exception as e: |
| 486 | print(f"[Test Server] Error: {e}") |
| 487 | finally: |
| 488 | writer.close() |
| 489 | await writer.wait_closed() |
| 490 | |
| 491 | test_server = await asyncio.start_server(handle_request, "127.0.0.1", 0) |
| 492 | test_port = test_server.sockets[0].getsockname()[1] |