Эволюция версий 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 | Длительность кеша preflight | 86400 |
Что тестировать: Убедитесь, что CORS-заголовки присутствуют в API-ответах, тестируйте корректность ответов на preflight OPTIONS-запросы, проверяйте, что wildcard (*) не используется при требовании credentials.
Заголовки безопасности
| Заголовок | Назначение | Риск при отсутствии |
|---|---|---|
Strict-Transport-Security (HSTS) | Принудительный HTTPS | Атаки понижения |
Content-Security-Policy (CSP) | Ограничения источников скриптов | XSS-атаки |
X-Frame-Options | Контроль встраивания в iframe | Clickjacking |
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
Продвинутое тестирование HTTP
Тестирование HTTP/2 Server Push
Server push позволяет серверу отправлять ресурсы до запроса клиента. Тестирование требует проверки:
- Отправляемые ресурсы соответствуют тому, что реально нужно странице
- Ресурсы не устарели (валидация кеша)
- Push не тратит полосу пропускания на ресурсы, которые клиент уже имеет
- Push promises используют корректные заголовки
# Проверка push promises HTTP/2 через nghttp
nghttp -v https://example.com | grep "push promise"
Атрибуты безопасности Cookie
Современные 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:
- Проверьте версию HTTP: Какую версию поддерживает сервер? Корректно ли проходит согласование?
- Проанализируйте заголовки кеширования: Кешируются ли статические ассеты? Не кешируются ли API-ответы?
- Проверьте политику CORS: API возвращает корректные CORS-заголовки? Протестируйте с другого домена.
- Проверьте заголовки безопасности: Настроен ли HSTS? Присутствует ли CSP?
- Измерьте тайминги: Каков разброс 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 первый визит остаётся уязвим к атакам понижения
Ключевые выводы
- Различия версий HTTP (1.1, 2, 3) имеют значительное влияние на нагрузочное тестирование и настройку тестовой инфраструктуры
- Кеширование, CORS и заголовки безопасности — критически важные точки проверки на каждом HTTP-эндпоинте
- Вкладка Network в DevTools браузера — самый ценный инструмент отладки HTTP для QA-инженеров
- Всегда тестируйте CORS в реальных браузерах — инструменты API-тестирования не применяют политики безопасности браузера