Локальное тестирование HTTP-статусов небольшим сервером Python
Один код статуса не подтверждает пригодность ответа. Клиент может получить HTML со статусом 200 или успешный 204 без тела для декодирования. Локальный тестовый сервер воспроизводит эти случаи без внешнего сервиса ответов.
Пример использует Python 3.11 или новее и только стандартную библиотеку. Он привязывается к 127.0.0.1 и реализует GET для небольшого фиксированного набора маршрутов. Это средство разработки, а не сервер приложения.
Ход обработки
Обработчик выбирает статус и представление до записи заголовков. Ветка 204 завершается без тела и Content-Length, остальные записывают объявленное число байтов.
Сохраните полный сервер в status_server.py
import argparse
import json
import re
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from urllib.parse import urlsplit
SUPPORTED = {200, 201, 204, 400, 404, 429, 500, 503}
class StatusHandler(BaseHTTPRequestHandler):
def do_GET(self):
path = urlsplit(self.path).path
match = re.fullmatch(r"/status/([0-9]{3})", path)
requested = int(match.group(1)) if match else None
status = requested if requested in SUPPORTED else 404
content_type = "application/json; charset=utf-8"
body = json.dumps({"status": status}).encode("utf-8")
if path == "/html/200":
status = 200
content_type = "text/html; charset=utf-8"
body = b"<html><body>not JSON</body></html>"
self.send_response(status)
if status == 204:
self.end_headers()
return
self.send_header("Content-Type", content_type)
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
def log_message(self, format, *args):
pass
def make_server(port=8089):
return ThreadingHTTPServer(("127.0.0.1", port), StatusHandler)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--port", type=int, default=8089)
args = parser.parse_args()
if not 0 <= args.port <= 65535:
parser.error("port must be from 0 through 65535")
with make_server(args.port) as server:
print(f"http://127.0.0.1:{server.server_port}", flush=True)
try:
server.serve_forever()
except KeyboardInterrupt:
pass
API HTTP-сервера Python предоставляет обработку запросов и многопоточный слушатель. Неподдерживаемые пути или номера статусов возвращают JSON 404 тестового сервера. Маршрут /html/200 намеренно возвращает HTML с успешным статусом.
Запустите сервер в одном терминале, а запросы отправляйте из другого:
python3 status_server.py --port 8089
curl -i http://127.0.0.1:8089/status/500
curl -i http://127.0.0.1:8089/html/200
curl -i http://127.0.0.1:8089/status/204
Используйте порт 0, чтобы ОС выбрала свободный порт; сервер выведет фактический URL. Остановите его через Ctrl+C. Эти команды curl намеренно не включают --fail, чтобы можно было проверить и ответ с ошибкой.
| Запрос | Статус | Представление |
|---|---|---|
/status/200 |
200 | JSON со статусом 200 |
/html/200 |
200 | HTML, а не JSON |
/status/500 |
500 | JSON со статусом 500 |
/status/204 |
204 | Нет тела и Content-Length |
RFC 9110 запрещает Content-Length в ответах 204. Проверяйте доступность тела отдельно от проверки 2xx. Этот сервер проверяет статус, тип представления и границы сообщения, но не моделирует медленные ответы, TLS, аутентификацию или время повторных попыток. Для декодирования и сигналов ошибок на клиенте см. тесты ответов WebClient.
Обсуждение