Это просто пост-памятка, чтоб навести порядок в знаниях. Итак, что интересного есть внутри протокола HTTP/1.0 для разработчика веб-приложений? Как всё работает по стандарту и на практике?
Методы
HTTP/1.0 содержит следующие методы: GET (получение данных), POST (создание), PUT (создание или изменение), DELETE (удаление), HEAD, LINK и UNLINK.
LINK и UNLINK — задуманы для установления связи между ресурсами, не используются на практике и интереса не представляют.
HEAD отличается от GET только тем, что не содержит тело ответа и не поддерживает условный запрос (If-Modified-Since). На практике используется только чтобы удостовериться, что ресурс существует. GET и HEAD кэшируются.
Что интересно — ни от одного из методов не требуется идемпотентности, однако есть интересная оговорка, что только POST может создать ресурс (сервер в этом случае должен вернуть код состояния 201, а в тексте сообщения описать, что он создал). В описании метода также PUT впрочем, также сказано, что он тоже может создать ресурс, если данных достаточно.
PUT отличается от POST только смыслом, вкладываемым в имя ресурса: для POST это адрес какого-то обработчика данных, а для PUT – это именно идентификатор ресурса. POST не кэшируется. Про кеширование PUT и DELETE ничего не сказано, но логично предположить, что оно также невозможно.
Нужно отметить, что на практике далеко не всегда можно послать запросы PUT и DELETE. Поэтому их часто заменяют на POST, а дополнительную информацию об операцию производить передают косвенно. Например, для эмуляции DELETE можно просто оставить пустым тело запроса. А Google в своих протоколах использует поле X-HTTP-Method-Override для переопределения POST на PUT или DELETE.
Коды состояния
HTTP/1.0 описывает следующие коды состояния:
поля запросов
Pragma — используется только со значением no-cache. В этом случае использование кэшированных данных запрещается, соответственно прокси должен передать запрос далее, и клиент сможет получить гарантированно свежий ответ. Теоретически сервер тоже может посылать такое поле, но смысл такого действия в протоколе не определен и перекладывается на получателя.
Authorization — применяется для при аутентификации пользователя, ничем не интересно.
From — предназначен для отсылки почтового адреса пользователя, но только если пользователь разрешит. OMG. Сложно сказать, что творилось в голове разработчиков стандарта, когда они это сочиняли.
If-Modified-Since — очень интересное поле. Применяется только с GET и его наличие превращает запрос в “условный”. Алгоритм работы: если дата в поле валидна, ресурс с запрошенного времени не изменялся и код результата определенно будет 200, то вместо 200 следует вернуть 304. Таким образом экономим трафик или обновляем кэш.
Referer — в этом поле агент может указать адрес, где агент узнал адрес запрашиваемого ресурса. Пересылается далеко не всегда, и часто режется прокси.
User-Agent — в этом поле клиент указывает информацию о себе. Может и не соответствовать действительности.
Accept — в этом поле агент указывает ответ какого MIME-типа он желал бы получить. Обработка этого поля — это забота веб-сервера, что конечному разработчику обычно не интересно. Достаточно знать, что сервер может отдавать ответ блоками, т.н. chunks.
Accept-Charset — в этом поле агент указывает желаемую кодировку ответа. Поскольку практика давно показала, что кроме UTF-8 ничего применять нельзя, то особого интереса поле не представляет.
Accept-Encoding — в этом поле агент указывает возможную компрессию ответа. Поскольку компрессией контента обычно занимается отдельный сервер, и делает он это автоматически, то особого интереса поле не представляет.
Accept-Language — желаемый язык контента в ответе.
поля ответов
Date — дата запроса/ответа. Теоретически клиент тоже может послать такое поле, но смысл? А вот серверу всегда следует посылать такое поле, т.к. эта дата активно используется при кешировании и более того, если этого не делать, то клиент назначит эту дату самостоятельно.
Location — указывается для ответов 300/301/302 и означает новый адрес запрашиваемого ресурса.
Server — поле в котором сервер может указать информацию о себе. Интересно, но абсолютно бесполезно.
WWW-Authenticate — применяется для при аутентификации пользователя, ничем не интересно.
Allow — в этом заголовке сервер может перечислить методы, которые он поддерживает для указанного адреса. Почему-то нельзя возвращать это поле при POST-запросах. WTF. OMG. На практике, впрочем, всё равно не применяется.
Content-Encoding — если ответ сжат, то в этом поле указан метод сжатия;
Content-Length — это поле обязательно заполняется сервером если в ответе присутствует тело ответа. Если равно нулю, то считается, что тело ответа есть, но пустое.
Content-Type — содержит MIME-тип ответа и кодировку. Если кодировка не указана, то считается что она ISO-8859-1.
Expires — содержит дату, после которой ответ сервера считается протухшим. Точнее, если дата поля Expires меньше или равна дате поля Date, то клиент должен прекратить использование кэшированных данных. Ноль и невалидная дата также должны рассматриваться агентом как указание на незамедлительное протухание кэша. Действие поля не распространяется на использование кнопки “Назад” в браузере, так что обычно в этом случае возьмутся данные из кэша.
Last-Modified — дата последнего изменения передаваемого документа. Не может быть больше значения поля Date. В стандарте сказано, что если у получателя есть копия сообщения более старого, чем указывает заголовок Last-Modified, то можно считать эту копию протухшей. Поскольку новое сообщение и так затрет старое в кэше, то очевидно, это имеет смысл только для ответов без тела сообщения: HEAD, 204, 304. Что в свою очередь, если подумать, практического смысла не несет. Такое вот загадочное поле.
Content-Language — язык ответа.
Retry-After — поле только для кода 503. Информирует агента об интервале повторения запроса. На практике игнорируется мозиллой.
Title — заголовок/название ответа. Теоретически может пригодиться при передаче простых текстовых файлов. На практике похоже что браузеры этот заголовок вообще не понимают для любых типов возвращаемого контента.
URI — может содержать несколько адресов, по которым может быть идентифицирован и может быть доступен запрошенный ресурс.
ОБЩИЕ поля
Link — для методов LINK и UNLINK содержит информацию о связываемом ресурсе.
MIME-Version — в стандарте сказано, что его следует игнорировать. О как.
Выводы
Легко заметить, что стандарт местами весьма противоречив и исключительно бестолково написан. В следующей версии, HTTP/1.1, порядка немного добавили. С практической точки зрения, для разработчика веб-сервисов представляют интерес только методы GET, POST, PUT, DELETE и поля Pragma, Date, Expires, If-Modified-Since, Referer, User-Agent, Location, Content-Type, Retry-After. Не так уж и много. С некоторым удивлением осознал бесполезность поля Last-Modified.
0 коммент.:
Отправить комментарий