sonyps4.ru

Что такое http заголовок? Краткое описание протокола HTTP.

Этот пост - ответ на вопрос, заданный в к одной из моих статей.

В статье я хочу рассказать, что же из себя представляют HTTP-методы GET/POST/PUT/DELETE и другие, для чего они были придуманы и как их использовать в соответствии с REST.

HTTP

Итак, что же представляет из себя один из основных протоколов интернета? Педантов отправлю к RFC2616 , а остальным расскажу по-человечески:)

Этот протокол описывает взаимодействие между двумя компьютерами (клиентом и сервером), построенное на базе сообщений, называемых запрос (Request) и ответ (Response). Каждое сообщение состоит из трех частей: стартовая строка, заголовки и тело. При этом обязательной является только стартовая строка.

Стартовые строки для запроса и ответа имеют различный формат - нам интересна только стартовая строка запроса, которая выглядит так:

METHOD URI HTTP/VERSION ,

Где METHOD - это как раз метод HTTP-запроса, URI - идентификатор ресурса, VERSION - версия протокола (на данный момент актуальна версия 1.1).

Заголовки - это набор пар имя-значение, разделенных двоеточием. В заголовках передается различная служебная информация: кодировка сообщения, название и версия браузера, адрес, с которого пришел клиент (Referrer) и так далее.

Тело сообщения - это, собственно, передаваемые данные. В ответе передаваемыми данными, как правило, является html-страница, которую запросил браузер, а в запросе, например, в теле сообщения передается содержимое файлов, загружаемых на сервер. Но как правило, тело сообщения в запросе вообще отсутствует.

Пример HTTP-взаимодействия

Рассмотрим пример.

Запрос:
GET /index.php HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9b5) Gecko/2008050509 Firefox/3.0b5 Accept: text/html Connection: close
Первая строка - это строка запроса, остальные - заголовки; тело сообщения отсутствует

Ответ:
HTTP/1.0 200 OK Server: nginx/0.6.31 Content-Language: ru Content-Type: text/html; charset=utf-8 Content-Length: 1234 Connection: close ... САМА HTML-СТРАНИЦА...

Ресурсы и методы

Вернемся к стартовой строке запроса и вспомним, что в ней присутствует такой параметр, как URI. Это расшифровывается, как Uniform Resource Identifier - единообразный идентификатор ресурса. Ресурс - это, как правило, файл на сервере (пример URI в данном случае "/styles.css"), но вообще ресурсом может являться и какой-либо абстрактный объект ("/blogs/webdev/" - указывает на блок «Веб-разработка», а не на конкретный файл).

Тип HTTP-запроса (также называемый HTTP-метод) указывает серверу на то, какое действие мы хотим произвести с ресурсом. Изначально (в начале 90-х) предполагалось, что клиент может хотеть от ресурса только одно - получить его, однако сейчас по протоколу HTTP можно создавать посты, редактировать профиль, удалять сообщения и многое другое. И эти действия сложно объединить термином «получение».

Для разграничения действий с ресурсами на уровне HTTP-методов и были придуманы следующие варианты:

  • GET - получение ресурса
  • POST - создание ресурса
  • PUT - обновление ресурса
  • DELETE - удаление ресурса
Обратите внимание на тот факт, что спецификация HTTP не обязывает сервер понимать все методы (которых на самом деле гораздо больше, чем 4) - обязателен только GET, а также не указывает серверу, что он должен делать при получении запроса с тем или иным методом. А это значит, что сервер в ответ на запрос DELETE /index.php HTTP/1.1 не обязан удалять страницу index.php на сервере, так же как на запрос GET /index.php HTTP/1.1 не обязан возвращать вам страницу index.php, он может ее удалять, например:)

В игру вступает REST

REST (REpresentational State Transfer) - это термин был введен в 2000-м году Роем Филдингом (Roy Fielding) - одним из разработчиков протокола HTTP - в качестве названия группы принципов построения веб-приложений. Вообще REST охватывает более широкую область, нежели HTTP - его можно применять и в других сетях с другими протоколами. REST описывает принципы взаимодействия клиента и сервера, основанные на понятиях «ресурса» и «глагола» (можно понимать их как подлежащее и сказуемое). В случае HTTP ресурс определяется своим URI, а глагол - это HTTP-метод.

REST предлагает отказаться от использования одинаковых URI для разных ресурсов (то есть адреса двух разных статей вроде /index.php?article_id=10 и /index.php?article_id=20 - это не REST-way) и использовать разные HTTP-методы для разных действий. То есть веб-приложение, написанное с использованием REST подхода будет удалять ресурс при обращении к нему с HTTP-методом DELETE (разумеется, это не значит, что надо давать возможность удалить всё и вся, но любой запрос на удаление в приложении должен использовать HTTP-метод DELETE).

REST дает программистам возможность писать стандартизованные и чуть более красивые веб-приложения, чем раньше. Используя REST, URI для добавления нового юзера будет не /user.php?action=create (метод GET/POST), а просто /user.php (метод строго POST).

В итоге, совместив имеющуюся спецификацию HTTP и REST-подход наконец-то обретают смысл различные HTTP-методы. GET - возвращает ресурс, POST - создает новый, PUT - обновляет существующий, DELETE - удаляет.

Проблемы?

Да, есть небольшая проблема с применением REST на практике. Проблема эта называется HTML.

PUT/DELETE запросы можно отправлять посредством XMLHttpRequest, посредством обращения к серверу «вручную» (скажем, через curl или даже через telnet), но нельзя сделать HTML-форму, отправляющую полноценный PUT/DELETE-запрос.

Дело в том, спецификация HTML не позволяет создавать формы, отправляющие данные иначе, чем через GET или POST. Поэтому для нормальной работы с другими методами приходится имитировать их искусственно. Например, в Rack (механизм, на базе которого Ruby взаимодействует с веб-сервером; с применением Rack сделаны Rails, Merb и другие Ruby-фреймворки) в форму можно добавить hidden-поле с именем "_method", а в качестве значения указать название метода (например, «PUT») - в этом случае будет отправлен POST-запрос, но Rack сможет сделать вид, что получил PUT, а не POST.

1. Протокол HTTP. Введение

Сразу хочу уточнить одну маленькую вещь. Страшное слово протокол есть не что иное, как соглашение множества людей, просто в один прекрасный момент люди решили: "Давайте будем делать так, и тогда все будет в порядке". Бояться нечего, все просто до безобразия и это безобразие мы сейчас будем вскрывать. Итак, что же это такое протокол HTTP и с чем его едят?

1.1 Клиент и сервер

Чудес в мире, а тем более в мире программизма и интернета не бывает! Усвойте это как незыблемую истину. И, если программа не работает или работает не так как хочется, то, значит, скорее всего, она либо написана не правильно, либо содержит ошибки. Итак, как же все-таки браузер просит сервер прислать ему хоть что-нибудь? Да очень просто! Надо только немного расслабиться и начать получать удовольствие от процесса:-)

1.2. Пишем наш первый HTTP запрос

Если Вы думаете, что все слишком сложно, то Вы ошибаетесь. Человек так устроен, что просто не способен создавать что-то сложное, иначе он сам в этом запутается:-) Итак, есть браузер и есть Web-сервер. Инициатором обмена данными всегда выступает браузер. Web-сервер никому, никогда просто так ничего не пошлет, чтобы он что-нибудь отправил браузеру - надо, чтобы браузер об этом попросил. Простейший HTTP запрос моет выглядеть, например, так:


GET http : //www.php.net/ HTTP/1.0rnrn


* GET (В переводе с английского означает "получить") - тип запроса, тип запроса может быть разным, например POST, HEAD, PUT, DELETE (часть из них мы рассмотрим ниже).
* http://www.php.net/ - URI (адрес) от которого мы хотим получить хоть какую-нибудь информацию (естественно мы надеемся подучить HTML страницу).
* HTTP/1.0 - тип и версия протокола, который мы будем использовать в процессе общения с сервером.
* rn - конец строки, который необходимо повторить два раза, зачем, станет понятно немного позднее.

Вы можете выполнить данный запрос очень просто. Запустите программу telnet.exe, введите в качестве хоста www.php.net, укажите порт 80, и просто наберите данный запрос, нажав два раза Enter в качестве rnrn. В ответ вы получите HTML код главной страницы сайта www.php.net.

1.3 Структура запроса

Рассмотрим, из чего состоит HTTP запрос. Все достаточно просто. Начнем с того, что HTTP запрос - это вполне осмысленный текст. Из чего же он состоит в общем случае? Будем рассматривать протокол HTTP 1.0. Итак :


Request - Line [ General - Header | Request - Header | Entity - Header ] rn [ Entity - Body ]


* Request-Line - строка запроса
*

Формат : "Method Request-URI HTTP-Versionrn"
* Method -
метод , которым будет обрабатываться ресурс Request-URI, может быть GET, POST, PUT, DELETE или HEAD.
* Request-URI - относительная или абсолютная ссылка на страницу с набором параметров, например, /index.html или http://www.myhost.ru/index.html или /index.html?a=1&b=qq. В последнем случае серверу будет передан запрос с набором переменных a и b с соответствующими значениями, а знак "&" - амперсант служит разделителем между параметрами.
* HTTP-Version - версия HTTP протокола, в нашем случае "HTTP/1.0".

Нам крайне интересны методы обработки GET и POST. Методом GET можно просто передать параметры в скрипт, а методом POST можно эмулировать submit формы.

Для метода GET, Request-URI может выглядеть, например, так: "/index.html?param1=1¶m2=2".

* General-Header - главная часть заголовка.
Формат:
Может иметь только два параметра: Date или Pragma. Date - дата по Гринвичу в формате "День недели, Число Месяц Год ЧЧ:ММ:СС GMT", например, "Tue, 15 Nov 1994 08:12:31 GMT" - дата создания запроса. Pragma может иметь одно значение no-cache, которое запрещает кэширование страницы.

* Request-Header - часть заголовка , описывающая запрос .

Request-Header может иметь следующие параметры : Allow, Authorization, From, If-Modified-Since, Referer, User-Agent.
В данной главе мы не будем рассматривать параметр Autorization, так как он используется для доступа к закрытым ресурсам, что требуется не так уж часто. Вы можете самостоятельно изучить формирование заголовка для авторизованного доступа на сайте www.w3c.org.

* Allow - задает допустимые методы обработки.
Формат: "Allow: GET | HEADn".
Параметр игнорируется при указании метода обработки POST в Request-Line. Задает допустимые методы обработки запроса. Прокси сервера не модифицируют параметр Allow и он в неизменном виде доходит до сервера.

* From - e-mail адрес, пославшего запрос.
Формат: "From: adderssrn".
Например, "From: [email protected]".

* If-Modified-Since - указывает, что запрос не модифицировался с такого-то времени.
Формат: "If-Modified-Since: datern"
Используется только для метода обработки GET. Дата указывается по Гринвичу в таком же формате, как и для параметра Date в General-Header.

* Referrer - абсолютная ссылка на страницу, с которой произошла инициация запроса, т. е. ссылка на страницу, с которой пользователь перешел на нашу.
Формат: "Referrer: urln".
Пример: "Referrer: www.host.ru/index.htmln".
* User-Agent - тип браузера.
Например: "User-Agent: Mozilla/4.0n"

* Entity-Header - часть заголовка, описывающая данные Entity-Body.
В данной части запроса задаются параметры, которые описывают тело страницы. Entity-Header может содержать следующие параметры: Allow, Content-Encoding, Content-Length, Content-Type, Expires, Last-Modified, extension-header.

* Allow - параметр аналогичный Allow из General-Header.

* Content-Encoding - тип кодирования данных Entity-Body.
Формат: "Сontent-Encoding: x-gzip | x-compress | другой типn".
Пример: "Сontent-Encoding: x-gzipn". Символ "|" означает слово "или", то есть то или то или то и.т.д.
Другой тип может указывать на способ кодирования данных, например, для метода POST: "Сontent-Encoding: application/x-www-form-urlencodedn".

* Content-Length - количество байт, пересылаемых в Entity-Body. Значение Content-Length имеет совсем другой смысл для данных, пересылаемых в формате MIME, где он выступает как параметр описания части данных - "external/entity-body". Допустимыми являются целые числа от нуля и больше.
Пример: "Content-Length: 26457n".

* Content-Type - тип передаваемых данных.
Например: "Content-Type: text/htmln".

* Expires - Время, когда страница должна быть удалена из кэша браузера.
Формат: "Expires: daten". Формат даты алогичен формату даты для параметра Date из General-Header.

* Last-Modified - время последнего изменения пересылаемых данных.
Формат: "Last-Modified: daten". Формат даты алогичен формату даты для параметра Date из General-Header.

* Extention-header - часть заголовка, которая может предназначаться, например, для обработки браузером, или другой программой, которая принимает документ. В данной части можно описывать свои параметры в формате "ParameterName: parametervaluen". Данные параметры будут игнорироваться, если программа-клиент не знает, как их обработать.
Например: "Cookie: r=1rn" - устанавливает всем известные печеньки для страницы.

А теперь после таких страшных слов давайте попробуем немного успокоиться и понять, что же нам надо? Понимать мы естественно будем на примерах.

Давайте представим, что нам надо получить страницу с сайта, передав Cookies (Печеньки), иначе нас просто пошлют как незванных гостей, и более того, известно, что на данную страницу пускают только после того, как Вы побывали на главной странице сайта.

2 Метод GET

Напишем наш запрос.


GET http :
Host : www . site . rurn

Cookie : income = 1rn
rn


Данный запрос говорит нам о том, что мы хотим получить содержимое страницы по адресу http://www.site.ru/news.html, использую метод GET. Поле Host говорит о том, что данная страница находится на сервере www.site.ru, поле Referer говорит о том, что за новостями мы пришли с главной страницы сайта, а поле Cookie говорит о том, что нам была присвоена такая-то кука. Почему так важны поля Host, Referer и Сookie? Потому что нормальные программисты при создании динамических сайтов проверяют данные поля, которые появляются в скриптах (РНР в том числе) в виде переменных. Для чего это надо? Для того, например, чтобы сайт не грабили, т.е. не натравливали на него программу для автоматического скачивания, или для того, чтобы зашедший на сайт человек всегда попадал бы на него только с главной страницы и.т.д.

Теперь давайте представим, что нам надо заполнить поля формы на странице и отправить запрос из формы, пусть в данной форме будет два поля: login и password (логин и пароль),- и, мы естественно знаем логин и пароль.


GET http : //www.site.ru/news.html?login=Petya%20Vasechkin&password=qq HTTP/1.0rn
Host : www . site . rurn
Referer : http : //www.site.ru/index.htmlrn
Cookie : income = 1rn
rn


Логин у нас "Petya Vasechkin" Почему же мы должны писать Petya%20Vasechkin? Это из=за того, что специальные символы могут быть распознаны сервером, как признаки наличия нового параметра или конца запроса и.т.д. Поэтому существует алгоритм кодирования имен параметров и их значений, во избежание оштбочных ситуаций в запросе. Полное описание данного алгоритма можно найти здесь, а в PHP есть функции rawurlencode и rawurldecode для кодирования и декодирования соответственно. Хочу отметеить, что декодирование РНР делает сам, если в запросе были переданы закодированные параметры. На этом я закону первую главу знакомства c протоколом HTTP. В следуючей главе мы рассмотрим построение запросов типа POST (в переводе с английского - "отправить"), что будет гораздо интереснее, т.к. именно данный тип запросов используется при отправке данных из HTML форм.

3. Метод POST.

В случае HTTP запроса типа POST существует два варианта передачи полей из HTML форм, а именно, используя алгоритм application/x-www-form-urlencoded и multipart/form-data. Различия между данными алгоритмами весьма существенные. Дело в том, что алгоритм первого типа создавался давным-давно, когда в языке HTML еще не предусматривали возможность передачи файлов через HTML формы. Итак, давайте рассмотрим эти алгоритмы на примерах.

3.1 Content-Type: application/x-www-form-urlencoded.

Пишем запрос, аналогичный нашему запросу GET для передачи логина и пароля, который был рассмотрен в предыдущей главе:


POST http : //www.site.ru/news.html HTTP/1.0rn
Host : www . site . rurn
Referer : http : //www.site.ru/index.htmlrn
Cookie : income = 1rn
Content - Type : application / x - www - form - urlencodedrn
Content - Length : 35rn
rn


Здесь мы видим пример использования Content-Type и Content-Length полей заголовка. Content-Length говорит, сколько байт будет занимать область данных, которая отделяется от заголовка еще одним переводом строки rn. А вот параметры, которые раньше для запроса GET помещались в Request-URI, теперь находятся в Entity-Body. Видно, что они формируются точно также, просто надо написать их после заголовка. Хочу отметить еще один важный момент, ничто не мешает, одновременно с набором параметров в Entity-Body, помещать параметры с другими именами в Request-URI, например:


POST http : //www.site.ru/news.html?type=user HTTP/1.0rn
.....
rn
login = Petya % 20Vasechkin & password = qq


3.2 Content-Type: multipart/form-data

Как только интернет мир понял, что неплохо бы было через формы отсылать еще и файлы, так W3C консорциум взялся за доработку формата POST запроса. К тому времени уже достаточно широко применялся формат MIME (Multipurpose Internet Mail Extensions - многоцелевые расширения протокола для формирования Mail сообщений), поэтому, чтобы не изобретать велосипед заново, решили использовать часть данного формата формирования сообщений для создания POST запросов в протоколе HTTP.

Каковы же основные отличия этого формата от типа application/x-www-form-urlencoded?

Главное отличие в том, что Entity-Body теперь можно поделить на разделы, которые разделяются границами (boundary). Что самое интересное - каждый раздел может иметь свой собственный заголовок для описания данных, которые в нем хранятся, т.е. в одном запросе можно передавать данные различных типов (как в Mail письме Вы одновременно с текстом можете передавать файлы).

Итак, приступим. Рассмотрим опять все тот же пример с передачей логина и пароля, но теперь в новом формате.


POST http : //www.site.ru/news.html HTTP/1.0rn
Host : www . site . rurn
Referer : http : //www.site.ru/index.htmlrn
Cookie : income = 1rn

Content - Length : 209rn
rn
-- 1BEF0A57BE110FD467Arn
Content - Disposition : form - data ; name = "login" rn
rn
Petya Vasechkinrn
-- 1BEF0A57BE110FD467Arn
Content - Disposition : form - data ; name = "password" rn
rn
qqrn
-- 1BEF0A57BE110FD467A -- rn


Теперь давайте разбираться в том что написано. :-) Я специально выделил некоторые символы rn жирным, чтобы они не сливались с данными. Присмотревшись внимательно можно заметить поле boundary после Content-Type. Это поле задает разделитель разделов - границу. В качестве границы может быть использована строка, состоящая из латинских букв и цифр, а так же из еще некоторых символов (к сожалению, не помню каких еще). В теле запроса в начало границы добавляется "--", а заканчивается запрос - границей, к которой символы "--" добавляются еще и в конец. В нашем запросе два раздела, первый описывает поле login, а второй поле password. Content-Disposition (тип данных в разделе) говорит, что это будут данные из формы, а в поле name задается имя поля. На этом заголовок раздела заканчивается и далее следует область данных раздела, в котором помещается значение поля (кодировать значение не требуется!).

Хочу обратить Ваше внимание та то, что в заголовках разделов не надо использовать Content-Length, а вот в заголовке запроса надо и его значение является размером всего Entity-Body, стоящего после второго rn, следующего за Content-Length: 209rn. Т.е. Entity-Body отделяется от заголовка дополнительным переводом строки (что можно заметить и в разделах).

А теперь давайте напишем запрос для передачи файла.


POST http : //www.site.ru/postnews.html HTTP/1.0rn
Host : www . site . rurn
Referer : http : //www.site.ru/news.htmlrn
Cookie : income = 1rn
Content - Type : multipart / form - data ; boundary = 1BEF0A57BE110FD467Arn
Content - Length : 491rn
rn
-- 1BEF0A57BE110FD467Arn
Content - Disposition : form - data ; name = "news_header" rn
rn
Пример новостиrn
-- 1BEF0A57BE110FD467Arn
Content - Disposition : form - data ; name = "news_file" ; filename = "news.txt" rn
Content - Type : application / octet - streamrn
Content - Transfer - Encoding : binaryrn
rn
А вот такая новость , которая лежит в файле news . txtrn
-- 1BEF0A57BE110FD467A -- rn


В данном примере в первом разделе пересылается заголовок новости, а во втором разделе пересылается файл news.txt. Внимательный да увидит поля filename и Content-Type во втором разделе. Поле filename задает имя пересылаемого файла, а поле Content-Type - тип данного файла. Application/octet-stream говорит о том, что это стандартный поток данных, а Content-Transfer-Encoding: binary говорит на о том, что это бинарные данные, ничем не закодированные.

Очень важный момент. Большинство CGI скриптов написано умными людьми, поэтому они любят проверять тип пришедшего файла, который стоит в Content-Type. Зачем? Чаще всего закачка файлов на сайтах используется для получения картинок от посетителя. Так вот, браузер сам пытается определить что за файл посетитель хочет отправить и вставляет соответствующий Content-Type в запрос. Скрипт его проверяет при получении, и, например, если это не gif или не jpeg игнорирует данный файл. Поэтому при "ручном" формировании запроса позаботьтесь о значении Content-Type, чтобы оно было наиболее близким к формату передаваемого файла.

Image/gif для gif
image/jpeg для jpeg
image/png для png
image/tiff для tiff (что используется крайне редко, уж больно емкий формат)

В нашем примере формируется запрос, в котором передается текстовый файл. Точно так же формируется запрос для передачи бинарного файла.

4. Постскриптум.

Думаю, что о передаче запросов на сервер не стоит рассказывать подробно. Это уже дело чисто РНР техники:-). Достаточно внимательно прочитать раздел о функциях работы с сокетами, или о функциях модуля CURL в официальной документации РНР.

Из выше сказанного, надеюсь теперь понятно, почему вопрос: "Как мне сформировать POST запрос, используя функцию header?" - бессмысленен. Функция header(string) добавляет запись только в заголовок запроса, но никак не в тело запроса.

Назад

Вашему вниманию предлагается описание основных аспектов протокола HTTP - сетевого протокола, с начала 90-х и по сей день позволяющего вашему браузеру загружать веб-страницы. Данная статья написана для тех, кто только начинает работать с компьютерными сетями и заниматься разработкой сетевых приложений, и кому пока что сложно самостоятельно читать официальные спецификации.

HTTP - широко распространённый протокол передачи данных, изначально предназначенный для передачи гипертекстовых документов (то есть документов, которые могут содержать ссылки, позволяющие организовать переход к другим документам).

Аббревиатура HTTP расшифровывается как HyperText Transfer Protocol , «протокол передачи гипертекста». В соответствии со спецификацией OSI , HTTP является протоколом прикладного (верхнего, 7-го) уровня. Актуальная на данный момент версия протокола, HTTP 1.1, описана в спецификации RFC 2616 .

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

Задача, которая традиционно решается с помощью протокола HTTP - обмен данными между пользовательским приложением, осуществляющим доступ к веб-ресурсам (обычно это веб-браузер) и веб-сервером. На данный момент именно благодаря протоколу HTTP обеспечивается работа Всемирной паутины.

Также HTTP часто используется как протокол передачи информации для других протоколов прикладного уровня, таких как SOAP, XML-RPC и WebDAV. В таком случае говорят, что протокол HTTP используется как «транспорт».

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

Как правило, передача данных по протоколу HTTP осуществляется через TCP/IP-соединения. Серверное программное обеспечение при этом обычно использует TCP-порт 80 (и, если порт не указан явно, то обычно клиентское программное обеспечение по умолчанию использует именно 80-й порт для открываемых HTTP-соединений), хотя может использовать и любой другой.

Как отправить HTTP-запрос?

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

Предположим, что он ввёл в адресной строке следующее:

Http://alizar.habrahabr.ru/

Соответственно вам, как веб-браузеру, теперь необходимо подключиться к веб-серверу по адресу alizar.habrahabr.ru.

Для этого вы можете воспользоваться любой подходящей утилитой командной строки. Например, telnet:

Telnet alizar.habrahabr.ru 80

Сразу уточню, что если вы вдруг передумаете, то нажмите Ctrl + «]», и затем ввод - это позволит вам закрыть HTTP-соединение. Помимо telnet можете попробовать nc (или ncat) - по вкусу.

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

Для того, чтобы сформировать HTTP-запрос, необходимо составить стартовую строку, а также задать по крайней мере один заголовок - это заголовок Host, который является обязательным, и должен присутствовать в каждом запросе. Дело в том, что преобразование доменного имени в IP-адрес осуществляется на стороне клиента, и, соответственно, когда вы открываете TCP-соединение, то удалённый сервер не обладает никакой информацией о том, какой именно адрес использовался для соединения: это мог быть, например, адрес alizar.habrahabr.ru, habrahabr.ru или m.habrahabr.ru - и во всех этих случаях ответ может отличаться. Однако фактически сетевое соединение во всех случаях открывается с узлом 212.24.43.44, и даже если первоначально при открытии соединения был задан не этот IP-адрес, а какое-либо доменное имя, то сервер об этом никак не информируется - и именно поэтому этот адрес необходимо передать в заголовке Host.

Стартовая (начальная) строка запроса для HTTP 1.1 составляется по следующей схеме:

Например (такая стартовая строка может указывать на то, что запрашивается главная страница сайта):

Ну и, конечно, не забывайте, что любая технология становится намного проще и понятнее тогда, когда вы фактически начинаете ей пользоваться.

Удачи и плодотворного обучения!

Теги: Добавить метки

HTTP (HyperText Transfer Protocol - «протокол передачи гипертекста») - протокол прикладного уровня передачи данных (изначально - в виде гипертекстовых документов). Основой HTTP является технология «клиент-сервер», то есть предполагается существование потребителей (клиентов), которые инициируют соединение и посылают запрос, и поставщиков (серверов), которые ожидают соединения для получения запроса, производят необходимые действия и возвращают обратно сообщение с результатом.

HTTP используется также в качестве «транспорта» для других протоколов прикладного уровня, таких как SOAP , XML-RPC , WebDAV.

Основным объектом манипуляции в HTTP является ресурс, на который указывает URI (Uniform Resource Identifier) в запросе клиента. Обычно такими ресурсами являются хранящиеся на сервере файлы, но ими могут быть логические объекты или что-то абстрактное. Особенностью протокола HTTP является возможность указать в запросе и ответе способ представления одного и того же ресурса по различным параметрам: формату, кодировке, языку и т. д. Именно благодаря возможности указания способа кодирования сообщения клиент и сервер могут обмениваться двоичными данными, хотя данный протокол является текстовым.

HTTP - протокол прикладного уровня, аналогичными ему являются FTP и SMTP - простой протокол передачи почты . Обмен сообщениями идёт по обыкновенной схеме «запрос-ответ». Для идентификации ресурсов HTTP использует глобальные URI . В отличие от многих других протоколов, HTTP не сохраняет своего состояния. Это означает отсутствие сохранения промежуточного состояния между парами «запрос-ответ». Компоненты, использующие HTTP, могут самостоятельно осуществлять сохранение информации о состоянии, связанной с последними запросами и ответами. Браузер, посылающий запросы, может отслеживать задержки ответов. Сервер может хранить IP-адреса и заголовки запросов последних клиентов. Однако сам протокол не осведомлён о предыдущих запросах и ответах, в нём не предусмотрена внутренняя поддержка состояния, к нему не предъявляются такие требования.

    Расширяемость

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

    HTTP/1.1 - текущая версия протокола. Новым в этой версии был режим «постоянного соединения»: TCP-соединение может оставаться открытым после отправки ответа на запрос, что позволяет посылать несколько запросов за одно соединение. Клиент теперь обязан посылать информацию об имени хоста, к которому он обращается, что сделало возможным более простую организацию виртуального хостинга.

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

Методы HTTP запроса

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

Каждый сервер обязан поддерживать как минимум методы GET и HEAD. Если сервер не распознал указанный клиентом метод, то он должен вернуть статус 501 (Not Implemented). Если серверу метод известен, но он не применим к конкретному ресурсу, то возвращается сообщение с кодом 405 (Method Not Allowed). В обоих случаях серверу следует включить в сообщение ответа заголовок Allow со списком поддерживаемых методов.

Кроме методов GET и HEAD, часто применяется метод POST.

  • Заголовки (параметры) HTTP запроса, ответа, сущности

    Все заголовки в протоколе HTTP разделяются на четыре основных группы (в нижеприведенном порядке рекомендуется посылать заголовки получателю):

      General Headers (Основные заголовки) - должны включаться в любое сообщение клиента и сервера.

      Request Headers (Заголовки запроса) - используются только в запросах клиента.

      Response Headers (Заголовки ответа) - только для ответов от сервера.

      Entity Headers (Заголовки сущности) - сопровождают каждую сущность сообщения. В отдельный класс заголовки сущности выделены для того, чтобы не путать их с заголовками запроса или заголовками ответа при передаче множественного содержимого (MIME).

    Все необходимые для функционирования HTTP заголовки описаны в основных RFC . При необходимости можно создавать свои заголовки. Традиционно к именам таких дополнительных заголовков добавляют префикс "X-" для избежания конфликта имён с возможно существующими.

    Строки после главной строки запроса (GET /index.html HTTP/1.1) имеют следующий формат: Параметр: значение. Таким образом задаются параметры запроса. Это является необязательным, все строки после главной строки запроса могут отсутствовать; в этом случае сервер принимает их значение по умолчанию или по результатам предыдущего запроса (при работе в режиме Connection: Keep-Alive).

      Параметр Connection (соединение) - может принимать значения Keep-Alive и close. В HTTP 1.0 за передачей сервером затребованных данных следует разъединение с клиентом, и транзакция считается завершённой, если не передан заголовок Connection: Keep Alive. В HTTP 1.1 сервер по умолчанию не разрывает соединение и клиент может посылать другие запросы. Поскольку во многие документы встроены другие документы - изображения, кадры, апплеты и т.д., это позволяет сэкономить время и затраты клиента, которому в противном случае пришлось бы для получения всего одной страницы многократно соединяться с одним и тем же сервером. Таким образом, в HTTP 1.1 транзакция может циклически повторяться, пока клиент или сервер не закроет соединение явно.

      Параметр User-Agent - значением является "кодовое обозначение" браузера.

      Параметр Accept - список поддерживаемых браузером типов содержимого в порядке их предпочтения данным браузером.

      Параметр Host - имя домена, с которого запрашивается ресурс. Полезно, если на сервере имеется несколько виртуальных серверов под одним IP- адресом. В этом случае имя виртуального домена определяется по этому полю.

      Параметр Last-Modified (модифицирован в последний раз) (W3C Last-Modified) - дата и время последнего изменения документа. Используя его, клиент, подобно случаю с ETag, может обращаться к серверу с запросом "If-Modified-Since" - в этом случае сервер должен сравнить дату последней модификации копии, сохраненной на клиенте, с актуальной датой последней модификации. Если они совпадут, это значит, что копия в кэше клиента не устарела, и повторное скачивание не нужно (код ответа "304 Not Modified"). Last-Modified также необходим для корректной обработки сайта роботами, которые используют информацию о дате модификации страниц в целях сортировки результатов поиска по дате, а также для определения частоты обновляемости Вашего сайта.

    Для SSI документов Apache будет выдавать "Last-Modified" в том случае, если указана директива "XBitHack full" (например, в файле.htaccess)

      Параметр ETag (объектная метка) - появился в HTTP 1.1(W3C ETag). ETag служит для присвоения каждой странице уникального идентификатора, значение которого меняется при изменении страницы (документа). ETag представляет собой хеш («отпечаток») байтов документа, если в документе изменится хоть один байт, то изменится и ETag. ETag используется при кэшировании документа. Этот заголовок сохраняется на клиенте, и в случае повторного обращения к документу позволяет браузеру обратиться к серверу с запросом ‘If-None-Match’, а сервер должен по значению ETag- метки определить, не изменился ли документ(страница), и если нет, ответить кодом ‘304 Not Modified’.

      Параметр Expires (истечение)(W3C Expires) - он сообщает браузеру, какой временной промежуток можно считать, что копия страницы в кэше свежа, и вообще не обращаться к серверу с запросами. Это удобно для таких файлов, о которых вы точно знаете, что они не изменятся ближайший час/день/месяц: фоновая картинка страницы, например.

    Другие заголовки HTTP:

      HTTP_X_FORWARDED_FOR

      HTTP_X_FORWARDED

      HTTP_FORWARDED_FOR

    • HTTP_X_COMING_FROM

      HTTP_COMING_FROM

    • HTTP_X_CLUSTER_CLIENT_IP

    • HTTP_XROXY_CONNECTION

      HTTP_PROXY_CONNECTION

      HTTP_USERAGENT_VIA - прокси

    Пример анализа HTTP запроса

    HTTP запрос состоит из трех частей: строки запроса (ответа), раздела заголовка, за которым следует необязательное тело. Заголовки представляют собой простой текст, при этом каждый заголовок отделен от следующего символом новой строки(\r\n), в то время как тело может быть как текстом, так и бинарными данными. Тело отделяется от заголовков двумя символами новой строки.

    Заголовок запроса состоит из главной (первой) строки запроса и последующих строк, уточняющих запрос в главной строке. Последующие строки также могут отсутствовать.

    Клиент инициирует транзакцию следующим образом:

      Клиент устанавливает связь с сервером по назначенному номеру порта, официальный номер порта по умолчанию - 80. Затем клиент посылает запрос документа, указав метод, адрес документа и номер версии HTTP. Например, в главной строке запроса GET /index.html HTTP/1.1

      используется метод GET , которым с помощью версии 1.1 HTTP запрашивается документ index.html.

      Клиент посылает информацию заголовка (необязательную, заголовок host обязателен), чтобы сообщить серверу информацию о своей конфигурации и данные о форматах документов, которые он может принимать. Вся информация заголовка указывается построчно, при этом в каждой строке приводится имя и значение. Например, приведённый ниже заголовок, посланный клиентом, содержит его имя и номер версии, а также информацию о некоторых предпочтительных для клиента типах документов: Host: list.mail.ru User-Agent: Mozilla/5.0 (Ubuntu; X11; Linux x86_64; rv:8.0) Gecko/20100101 Firefox/8.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

      Завершается заголовок пустой строкой.

      Послав запрос и заголовки, клиент может отправить и дополнительные данные, например, для CGI скриптов.

    Сервер отвечает на запрос клиента следующим образом:

      Первая часть ответа сервера - строка состояния, содержащая три поля: версию HTTP, код состояния и описание. Поле версии содержит номер версии HTTP, которой данный сервер пользуется для передачи ответа. Код состояния - это трехразрядное число, обозначающее результат обработки сервером запроса клиента. Описание, следующее за кодом состояния, представляет собой просто понятный для человека текст, поясняющий код состояния. Например, строка состояния HTTP/1.1 304 Not Modified

      говорит о том, что сервер для ответа использует версию HTTP 1.1. Код состояния 304 означает, что клиент запросил документ методом GET, использовал заголовок If-Modified-Since или If-None-Match и документ не изменился с указанного момента.

      После строки состояния сервер передает клиенту информацию заголовка, содержащую данные о самом сервере и затребованном документе. Ниже приведен пример заголовка: Date: Thu, 15 Dec 2011 09:34:15 GMT Server: Apache/2.2.21 (Debian) X-Powered-By: PHP/5.3.8-1+b1 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Vary: Accept-Encoding Content-Encoding: gzip Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: text/html; charset=utf-8

      Завершает заголовок пустая строка.

      Если запрос клиента успешен, то посылаются затребованные данные. Это может быть копия файла или результат выполнения CGI- программы. Если запрос клиента удовлетворить нельзя, передаются дополнительные данные в виде понятного для пользователя разъяснения причин, по которым сервер не смог выполнить данный запрос.

    HTTP status code

    Код состояния HTTP (HTTP status code) является частью первой строки ответа сервера. Он представляет собой целое число из трех цифр. Первая цифра указывает на класс состояния. За кодом ответа обычно следует отделённая пробелом поясняющая фраза на английском языке, которая разъясняет человеку причину именно такого ответа.

    Клиент может не знать все коды состояния, но он обязан отреагировать в соответствии с классом кода. В настоящее время выделено пять классов кодов состояния:

      1xx : Informational (Информационные). Информационные коды состояния, сообщающие клиенту, что сервер пребывает в процессе обработки запроса. Реакция клиента на данные коды не требуется;

      2xx : Success (Успешно).

      1. 200 OK (Хорошо). Появился в HTTP/1.0. Успешный запрос ресурса. Если клиентом были запрошены какие-либо данные, то они находятся в заголовке и/или теле сообщения.

      3xx : Redirection (Перенаправление(переадресация)). Коды класса 3xx сообщают клиенту, что для успешного выполнения операции необходимо сделать другой запрос (как правило по другому URI). Из данного класса пять кодов 301, 302, 303, 305 и 307 относятся непосредственно к перенаправлениям (редирект). Адрес, по которому клиенту следует произвести запрос, сервер указывает в заголовке Location. Многие клиенты при перенаправлениях с кодами 301 и 302 ошибочно применяют метод GET ко второму ресурсу несмотря на то, что к первому запрос был с иным методом. Чтобы избежать недоразумений в версии HTTP/1.1 были введены коды 303 и 307 вместо 302. Изменять метод запроса нужно только если сервер ответил 303. В остальных случаях следующий запрос производить с исходным методом.

      1. 302 Found (Найдено). Введено в HTTP/1.0. Запрошенный документ временно доступен по другому URI , указанному в заголовке в поле Location.

      4xx : Client Error (Ошибка клиента). Класс кодов 4xx предназначен для указания ошибок со стороны клиента. При использовании всех методов, кроме HEAD , сервер должен вернуть в теле сообщения гипертекстовое пояснение для пользователя.

      1. 404 Not Found (Не найдено). Появился в HTTP/1.0. Сервер понял запрос, но не нашёл соответствующего ресурса по указанному URI .

      5xx : Server Error (Ошибка сервера)

    Ссылки по теме HTTP 1.1

    HTTP/2

    HTTP/2 (изначально HTTP/2.0) - вторая крупная версия сетевого протокола HTTP. Протокол основан на SPDY (HTTP-совместимый протокол, разработанный Google).

    Протокол HTTP/2 является бинарным. По сравнению с предыдущим стандартом изменены способы разбития данных на фрагменты и транспортирования их между сервером и клиентом.

    В HTTP/2 сервер имеет право послать то содержимое, которое ещё не было запрошено клиентом. Это позволит серверу сразу выслать дополнительные файлы, которые потребуются браузеру для отображения страниц, без необходимости анализа браузером основной страницы и запрашивания необходимых дополнений.

Вашему вниманию предлагается описание основных аспектов протокола HTTP - сетевого протокола, с начала 90-х и по сей день позволяющего вашему браузеру загружать веб-страницы. Данная статья написана для тех, кто только начинает работать с компьютерными сетями и заниматься разработкой сетевых приложений, и кому пока что сложно самостоятельно читать официальные спецификации.

HTTP - широко распространённый протокол передачи данных, изначально предназначенный для передачи гипертекстовых документов (то есть документов, которые могут содержать ссылки, позволяющие организовать переход к другим документам).

Аббревиатура HTTP расшифровывается как HyperText Transfer Protocol , «протокол передачи гипертекста». В соответствии со спецификацией OSI , HTTP является протоколом прикладного (верхнего, 7-го) уровня. Актуальная на данный момент версия протокола, HTTP 1.1, описана в спецификации RFC 2616 .

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

Задача, которая традиционно решается с помощью протокола HTTP - обмен данными между пользовательским приложением, осуществляющим доступ к веб-ресурсам (обычно это веб-браузер) и веб-сервером. На данный момент именно благодаря протоколу HTTP обеспечивается работа Всемирной паутины.

Также HTTP часто используется как протокол передачи информации для других протоколов прикладного уровня, таких как SOAP, XML-RPC и WebDAV. В таком случае говорят, что протокол HTTP используется как «транспорт».

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

Как правило, передача данных по протоколу HTTP осуществляется через TCP/IP-соединения. Серверное программное обеспечение при этом обычно использует TCP-порт 80 (и, если порт не указан явно, то обычно клиентское программное обеспечение по умолчанию использует именно 80-й порт для открываемых HTTP-соединений), хотя может использовать и любой другой.

Как отправить HTTP-запрос?

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

Предположим, что он ввёл в адресной строке следующее:

Http://alizar.сайт/

Соответственно вам, как веб-браузеру, теперь необходимо подключиться к веб-серверу по адресу alizar.сайт.

Для этого вы можете воспользоваться любой подходящей утилитой командной строки. Например, telnet:

Telnet alizar.сайт 80

Сразу уточню, что если вы вдруг передумаете, то нажмите Ctrl + «]», и затем ввод - это позволит вам закрыть HTTP-соединение. Помимо telnet можете попробовать nc (или ncat) - по вкусу.

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

Для того, чтобы сформировать HTTP-запрос, необходимо составить стартовую строку, а также задать по крайней мере один заголовок - это заголовок Host, который является обязательным, и должен присутствовать в каждом запросе. Дело в том, что преобразование доменного имени в IP-адрес осуществляется на стороне клиента, и, соответственно, когда вы открываете TCP-соединение, то удалённый сервер не обладает никакой информацией о том, какой именно адрес использовался для соединения: это мог быть, например, адрес alizar..ru или m.. Однако фактически сетевое соединение во всех случаях открывается с узлом 212.24.43.44, и даже если первоначально при открытии соединения был задан не этот IP-адрес, а какое-либо доменное имя, то сервер об этом никак не информируется - и именно поэтому этот адрес необходимо передать в заголовке Host.

Стартовая (начальная) строка запроса для HTTP 1.1 составляется по следующей схеме:

Например (такая стартовая строка может указывать на то, что запрашивается главная страница сайта):

Ну и, конечно, не забывайте, что любая технология становится намного проще и понятнее тогда, когда вы фактически начинаете ей пользоваться.

Удачи и плодотворного обучения!

Теги:

  • http
  • alizar
  • spdy
Добавить метки

Загрузка...