Эволюция версий HTTP

HTTP значительно эволюционировал с момента создания, и каждая версия вносит изменения, которые напрямую влияют на тестирование веб-приложений. Понимание этих различий необходимо для диагностики проблем производительности и написания точных тестовых ассертов.

HTTP/1.1: Рабочая лошадка

HTTP/1.1 приводит в движение веб с 1997 года. Его ключевые возможности включают persistent-соединения (повторное использование TCP-соединения для нескольких запросов) и pipelining (отправка нескольких запросов без ожидания ответов). Однако HTTP/1.1 страдает от блокировки head-of-line — если один запрос медленный, все последующие запросы на том же соединении должны ждать.

Влияние на тестирование:

  • Браузеры открывают 6-8 параллельных соединений на домен для обхода блокировки head-of-line
  • Domain sharding (раздача ассетов с нескольких поддоменов) была распространённой оптимизацией — проверяйте корректность работы
  • Каждый запрос/ответ включает полные текстовые заголовки, добавляя оверхед

HTTP/2: Революция мультиплексирования

HTTP/2, стандартизированный в 2015 году, представил несколько прорывных возможностей:

  • Мультиплексирование: Несколько запросов и ответов разделяют одно TCP-соединение одновременно. Больше никакой блокировки head-of-line на уровне HTTP.
  • Сжатие заголовков (HPACK): Уменьшает оверхед заголовков на 85-90% с помощью таблицы сжатия.
  • Server push: Сервер может проактивно отправлять ресурсы до того, как клиент их запросит.
  • Бинарное фреймирование: HTTP/2 использует бинарный формат вместо текста, делая парсинг быстрее и менее подверженным ошибкам.

Влияние на тестирование:

  • Domain sharding фактически вредит производительности HTTP/2 — тестируйте с одним доменом
  • Server push может предзагружать критические ресурсы — убедитесь, что он работает и не отправляет устаревший контент
  • HTTP/2 по-прежнему работает поверх TCP, поэтому блокировка head-of-line на уровне TCP остаётся

HTTP/3: QUIC и UDP

HTTP/3, построенный на протоколе QUIC поверх UDP, решает оставшуюся проблему блокировки head-of-line в TCP:

  • Транспорт QUIC: На основе UDP со встроенным шифрованием (TLS 1.3 обязателен)
  • Установление соединения 0-RTT: Повторные соединения могут отправлять данные немедленно без handshake
  • Независимые потоки: Потеря в одном потоке не блокирует другие (в отличие от TCP, где один потерянный пакет блокирует всё)

Влияние на тестирование:

  • HTTP/3 использует UDP-порт 443 — файрволы могут его блокировать, вызывая откат к HTTP/2
  • 0-RTT имеет риски replay-атак — тестируйте безопасную обработку вашим приложением
  • Не все клиенты/серверы поддерживают HTTP/3 — тестируйте поведение отката

Продвинутые HTTP-заголовки

HTTP-заголовки несут метаданные, управляющие кешированием, безопасностью, согласованием контента и кросс-доменным поведением. QA-инженеры должны проверять эти заголовки на каждом эндпоинте.

Заголовки кеширования

ЗаголовокНазначениеПример
Cache-ControlДирективы кешированияmax-age=3600, public
ETagИдентификатор версии ресурса"v1.2.3-abc123"
Last-ModifiedВременная метка последнего измененияWed, 19 Mar 2026 10:00:00 GMT
VaryДифференциация ключа кешаAccept-Encoding, Accept-Language

Что тестировать: Убедитесь, что динамические API-ответы включают Cache-Control: no-store, а статические ассеты имеют подходящий max-age. Проверяйте, что условные запросы (If-None-Match, If-Modified-Since) корректно возвращают 304.

Заголовки CORS

ЗаголовокНазначениеПример
Access-Control-Allow-OriginРазрешённые источникиhttps://app.example.com
Access-Control-Allow-MethodsРазрешённые HTTP-методыGET, POST, PUT, DELETE
Access-Control-Allow-HeadersРазрешённые кастомные заголовкиAuthorization, Content-Type
Access-Control-Max-AgeДлительность кеша preflight86400

Что тестировать: Убедитесь, что CORS-заголовки присутствуют в API-ответах, тестируйте корректность ответов на preflight OPTIONS-запросы, проверяйте, что wildcard (*) не используется при требовании credentials.

Заголовки безопасности

ЗаголовокНазначениеРиск при отсутствии
Strict-Transport-Security (HSTS)Принудительный HTTPSАтаки понижения
Content-Security-Policy (CSP)Ограничения источников скриптовXSS-атаки
X-Frame-OptionsКонтроль встраивания в iframeClickjacking
X-Content-Type-OptionsПредотвращение MIME-сниффингаИнъекция контента

Техники отладки HTTP

Вкладка Network в DevTools браузера

Вкладка Network — самый мощный инструмент отладки HTTP для QA-инженеров:

  • Разбивка по времени: DNS lookup, TCP-соединение, TLS handshake, TTFB, загрузка контента
  • Заголовки запроса/ответа: Полная инспекция заголовков для каждого запроса
  • Фильтрация: По типу (XHR, JS, CSS), status code или текстовому поиску
  • Throttling: Симуляция медленных сетевых условий
  • Preserve log: Сохранение сетевой истории между навигациями

curl для отладки HTTP

# Подробный вывод со всеми заголовками и таймингом
curl -v https://api.example.com/users

# Разбивка по времени
curl -w "DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nTTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n" -o /dev/null -s https://api.example.com

# Принудительно HTTP/2
curl --http2 -v https://api.example.com

# Тестирование конкретного IP без DNS
curl --resolve api.example.com:443:10.0.0.1 https://api.example.com
sequenceDiagram participant C as Клиент participant S as Сервер Note over C,S: HTTP/1.1 — Последовательный C->>S: Запрос 1 S-->>C: Ответ 1 C->>S: Запрос 2 S-->>C: Ответ 2 C->>S: Запрос 3 S-->>C: Ответ 3 Note over C,S: HTTP/2 — Мультиплексированный C->>S: Запрос 1 + Запрос 2 + Запрос 3 S-->>C: Ответ 2 S-->>C: Ответ 1 S-->>C: Ответ 3

Продвинутое тестирование HTTP

Тестирование HTTP/2 Server Push

Server push позволяет серверу отправлять ресурсы до запроса клиента. Тестирование требует проверки:

  1. Отправляемые ресурсы соответствуют тому, что реально нужно странице
  2. Ресурсы не устарели (валидация кеша)
  3. Push не тратит полосу пропускания на ресурсы, которые клиент уже имеет
  4. Push promises используют корректные заголовки
# Проверка push promises HTTP/2 через nghttp
nghttp -v https://example.com | grep "push promise"

Современные cookie должны включать атрибуты безопасности, которые QA должен проверять:

АтрибутНазначениеТест
SecureОтправляется только через HTTPSПроверить отсутствие cookie на HTTP
HttpOnlyНедоступна для JavaScriptПопробовать document.cookie в консоли
SameSite=StrictБез кросс-сайтовой отправкиТестировать с другого источника
SameSite=LaxОтправляется при top-level навигацииТестировать из ссылок vs. форм

Тестирование HSTS

# Проверить заголовок HSTS
curl -sI https://example.com | grep -i strict-transport

# Проверить соответствие требованиям HSTS preload
# Заголовок должен включать: max-age=31536000; includeSubDomains; preload

Connection Coalescing в HTTP/2

HTTP/2 позволяет повторно использовать соединение для нескольких доменов, если они разделяют один IP-адрес и TLS-сертификат. Это может вызывать неожиданное поведение при тестировании:

  • Запросы к api.example.com и cdn.example.com могут разделять соединение
  • Если у одного домена другие требования CORS или авторизации, совместное использование вызывает проблемы
  • Тестируйте, что coalescing не обходит границы безопасности

Практическое упражнение

Проведите аудит HTTP-конфигурации сайта с помощью curl и DevTools:

  1. Проверьте версию HTTP: Какую версию поддерживает сервер? Корректно ли проходит согласование?
  2. Проанализируйте заголовки кеширования: Кешируются ли статические ассеты? Не кешируются ли API-ответы?
  3. Проверьте политику CORS: API возвращает корректные CORS-заголовки? Протестируйте с другого домена.
  4. Проверьте заголовки безопасности: Настроен ли HSTS? Присутствует ли CSP?
  5. Измерьте тайминги: Каков разброс DNS, TLS и TTFB? Где узкие места?
Подход к решению
# 1. Проверить версию HTTP
curl -sI https://example.com | head -1
curl --http2 -sI https://example.com | head -1

# 2. Заголовки кеширования
curl -sI https://example.com/style.css | grep -i cache
curl -sI https://api.example.com/data | grep -i cache

# 3. CORS (тест с другого источника)
curl -H "Origin: https://evil.com" -sI https://api.example.com/data | grep -i access-control

# 4. Заголовки безопасности
curl -sI https://example.com | grep -iE "strict-transport|content-security|x-frame|x-content-type"

# 5. Тайминг
curl -w "DNS:%{time_namelookup} TLS:%{time_appconnect} TTFB:%{time_starttransfer} Total:%{time_total}\n" -o /dev/null -s https://example.com

Советы профессионала

  • Всегда проверяйте используемую версию HTTP — поведение HTTP/2 существенно отличается от HTTP/1.1, особенно в управлении соединениями и обработке заголовков
  • Тестируйте CORS из браузера, а не только curl — браузеры применяют CORS, а curl нет, что создаёт ложную уверенность при тестировании только из командной строки
  • Проверяйте заголовки кеширования на каждом эндпоинте — некорректное кеширование — одна из самых частых причин багов устаревших данных в продакшене
  • Используйте curl --resolve для тестирования конкретных IP серверов без изменения DNS — незаменимо для тестирования деплоев до переключения DNS
  • Проверяйте HSTS preload на критически важных приложениях — без preload первый визит остаётся уязвим к атакам понижения

Ключевые выводы

  1. Различия версий HTTP (1.1, 2, 3) имеют значительное влияние на нагрузочное тестирование и настройку тестовой инфраструктуры
  2. Кеширование, CORS и заголовки безопасности — критически важные точки проверки на каждом HTTP-эндпоинте
  3. Вкладка Network в DevTools браузера — самый ценный инструмент отладки HTTP для QA-инженеров
  4. Всегда тестируйте CORS в реальных браузерах — инструменты API-тестирования не применяют политики безопасности браузера