File size: 2,090 Bytes
5e0b58b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
"""Shared helpers for dashboard HTTP tests."""

from __future__ import annotations

import json
from http.client import HTTPConnection
from socketserver import BaseServer
from typing import Any, cast


def _server_address(server: BaseServer) -> tuple[str, int]:
    """Extract and cast the server address to typed host/port."""
    addr = cast(tuple[str, int], server.server_address)
    host, port = addr
    return host, port


def request_json(
    server: BaseServer,
    method: str,
    path: str,
    body: dict[str, Any] | None = None,
    timeout: float = 5,
) -> tuple[int, dict[str, Any]]:
    """Send a JSON request and return (status, parsed body)."""
    host, port = _server_address(server)
    conn = HTTPConnection(host, port, timeout=timeout)
    try:
        headers = {"Content-Type": "application/json"} if body is not None else {}
        data = json.dumps(body).encode() if body is not None else None
        conn.request(method, path, body=data, headers=headers)
        response = conn.getresponse()
        status = response.status
        raw = response.read()
        try:
            payload = json.loads(raw.decode())
        except json.JSONDecodeError:
            payload = {"raw": raw.decode(errors="replace")}
        return status, cast(dict[str, Any], payload)
    finally:
        conn.close()


def post_json(
    server: BaseServer,
    path: str,
    body: dict[str, Any],
) -> tuple[int, dict[str, Any] | str]:
    """Send a JSON POST request and return (status, parsed body or raw text)."""
    host, port = _server_address(server)
    conn = HTTPConnection(host, port)
    try:
        conn.request(
            "POST",
            path,
            json.dumps(body),
            {"Content-Type": "application/json"},
        )
        resp = conn.getresponse()
        data = resp.read()
        ct = resp.getheader("Content-Type", "")
        if "application/json" in ct:
            return resp.status, cast(dict[str, Any], json.loads(data))
        return resp.status, data.decode("utf-8", errors="replace")
    finally:
        conn.close()