Запросы и ответы HTTP
Что это такое
Обмен по HTTP — это сообщение запроса, за которым следует сообщение ответа по одному соединению. Запрос несёт метод, цель, заголовки и иногда тело; ответ несёт код состояния, заголовки и обычно тело. Всё остальное в веб-эксплуатации — кэширование, перенаправления, аутентификация, прокси — построено из этих частей, и внимательное их чтение отвечает на большинство вопросов о том, что на самом деле произошло.
Почему это важно
Сообщение — это интерфейс между компонентами, написанными отдельно: браузер, прокси, балансировщик нагрузки и приложение одинаково трактуют одни и те же заголовки, и ошибка в любой точке проявляется странным поведением в остальных. Большинство загадочных веб-проблем — это один отсутствующий, переписанный или напрасно доверенный заголовок. Чтение сырого обмена вместо отрисованной страницы — самый быстрый путь мимо них.
Ключевые идеи
Метод говорит, что значит запрос, и некоторые методы обязаны безопасно повторяться
Чтение не должно менять состояние и может повторяться; создание в принципе не безопасно повторять. Посредники и клиенты полагаются на эти свойства, поэтому эндпоинт, который меняет состояние при чтении, будет запрошен предзагрузчиком и изменён случайно. Именно уважение к смыслу метода позволяет существовать кэшам и повторным попыткам.
GET /orders/42 -> чтение, безопасно повторять
POST /orders -> создание, повтор может создать дубликат
PUT /orders/42 -> замена, повтор даёт тот же результат
Коды состояния говорят клиенту, что делать дальше
Семейство указывает на исход: успех, перенаправление, ошибка клиента, ошибка сервера. Перенаправления велят клиенту повторить запрос в другом месте — постоянно или временно; постоянное перенаправление кэшируется и запоминается, поэтому его опасно выдавать по ошибке. Различение ошибки клиента и ошибки сервера — первый шаг сортировки в любом сообщении.
Заголовки несут контекст, которого нет в теле
Узел, тип содержимого, длина содержимого, указания по кэшированию, аутентификация и заголовки пересылки, которые добавляет прокси. Поскольку часть из них задаёт компонент, ближайший к клиенту, а остальные им доверяют, прокси должен задавать их осознанно, а приложение не должно доверять им из недоверенного источника.
У тела есть длина и кодировка
Тело запроса или ответа должно быть отграничено длиной или блочной кодировкой и может быть сжато. Здесь появляются обрезанные загрузки и сломанный стриминг, и поэтому важны буфер и ограничения размера у прокси: тело больше предела отбрасывается раньше, чем его увидит приложение.
Кэширование согласуется через заголовки
Можно ли кэшировать ответ, на сколько и при каких условиях, решают заголовки от приложения, а соблюдают их посредники. Кэш перед аутентифицированным эндпоинтом — классическая катастрофа, и предотвращает её ответ, помечающий себя приватным.
Соединения переиспользуются, и это имеет последствия
Современный HTTP держит соединение открытым для многих обменов, поэтому прокси должен передавать дальше идентичность клиента и сведения о пересылке, а не позволять приложению выводить их из соединения. Это же объясняет, как один медленный ответ может задержать соединение, пока ждут остальные.
Практика
Прочитайте один обмен сырым
Загрузите страницу клиентом, который печатает все заголовки запроса и ответа, и определите заголовки кэширования, тип содержимого и заголовки, связанные с безопасностью.
Готово, когда: вы можете назвать, какой компонент задал каждый заголовок, и сохранит ли ответ кэш.
Сломайте перенаправление намеренно
Создайте временное перенаправление и постоянное, запросите каждое дважды и опишите, как клиент обращается с ними по-разному.
Готово, когда: вы можете объяснить, почему постоянное перенаправление опасно выдавать по ошибке и как очищается закэшированное.
Частые ошибки
- Менять состояние при чтении — предзагрузчики и повторы изменяют данные; исправить: держите чтение безопасным и используйте верный метод для изменений.
- Выдавать постоянное перенаправление из временной ситуации — клиенты помнят его долго после того, как ситуация изменилась; исправить: используйте временное перенаправление, если перенос не действительно постоянен.
- Доверять заголовку пересылки из интернета — клиент может заявить любое происхождение; исправить: пусть прокси задаёт его и отбрасывает его из недоверенного ввода.
- Игнорировать ограничения размера тела и тайм-аута — загрузки загадочно падают на прокси; исправить: согласуйте ограничения с тем, что ожидает приложение.
- Кэшировать аутентифицированный ответ — одному пользователю могут отдать данные другого; исправить: явно помечайте приватные ответы и проверяйте, что можно кэшировать.
Что читать дальше
- Основы сетей (HTTP / DNS / TLS) (06-cloud-devops/10-networking-fundamentals-http-dns-tls) — прикладной уровень, которому принадлежит это сообщение.
- Имена, адреса и TLS (06-cloud-devops/10-networking-fundamentals-http-dns-tls/02-names-addresses-and-tls) — как было найдено и защищено соединение, несущее это сообщение.
- Компьютерные сети (01-cs-fundamentals/03-computer-networks) — поведение транспорта под всем этим, объясняющее тайм-ауты и переиспользование соединений.