Даже если вы и знаете кое-что о HTTP все равно не лишне будет вспомнить о том как это все работает тем более на эту информацию придется ориентироваться при написании CGI скриптов.
Этапы соедирения.
Первый этап это когда HTTP -клиент(браузер) соединяется с сервером.для этого он использует протокол TCP/IP соединение происходит к известному клиенту TCP-порту (80 -номер порта HTTP) (другие сервисы сидят на других портах ,например FTP и SMTP на 21 и 25)
Вторым этапом идет запрос клиента:клиент передает заголовок запроса и возможно(в зависимости от метода) тело сообщения запроса.В заголовке обязательно указывается метод ,URI,и версия HTTP,и может быть еще несколько необязательных полей
Третий этап -ответ сервера,который опять таки состоит из заголовка,в котором сервер указывает версию HTTP и код статуса, который может говорить о успешном или неуспешном результате и его причинах.Далее идет тело ответа.
Четвертым этапом происходит разрыв TCP/IP соединения.
HTTP -запрос.
Запрос состоит из Строки запроса(она обязательна) и остальных полей. Синтаксис строки :МЕТОД <SP> URI <SP> HTTP/версия <CRLF>
где <SP> -пробел ,<CRLF> -переход на новую строку
Методы HTTP.
GET
Самый часто применяемый метод,в протоколе HTTP/0.9 был единственным методом,и применяется для извлечения информации по заданому URI
Может быть условным если в заголовке указано поле If-Modified-Since:
HEAD
Почти идентичен GET но отличается тем что сервер не возвращает тело обьекта а только его
заголовок (метаинформацию) программы могут применять его для проверки гиперссылок на
правильность,доступность и изменения.
POST
передает данные для обработки их программой ,указаной в URI сдесь обязательно указывается поле
Content-Length:
Сушествуют и другие ,реже применяемые методы,например PUT -для сохранения передавемых данных в указаном URI
и DELETE для удаления ресурса.
Поля заголовка запроса.
После строки запроса идут поля заголовка запроса. Поля общего(general-header) заголовка (он общий как для запросов так и для ответов):
Date:
Указывает дату запроса,например:
Date: Sun, 20 Nov 1994 08:12:31 GMT
MIME-version:
Указывает версию MIME (по умолчанию 1.0)
MIME-version: 1.0
Pragma:
Содержит указания для таких промежуточных агентов как прокси и шлюзы,
Pragma: no-cache
Поля относящиеся к запросу(Request-Header):
Authorization:
Содержит информацию аутентификации
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
From:
Браузер может посылать адрес пользователя серверу
From: quake@doom.ru
If-Modified-Since:
используется при методе GET ресурс возвращается ,если он был изменен с указаного момента, может использоваться при кешировании.
If-Modified-Since:Mon 15 Jul 1997 00:15:24 GMT
Referer:
Содержит URL предшествующего ресурса.
Referer: http://www.uic.nnov.ru/~paaa/index.html
User-Agent:
Програмное обеспечение клиента.
User-Agent: Mozilla/3.0
Заголовок информации сообщения (Entity-Header) применяется как в запросах так и в ответах (при этом некоторые поля только в ответах):
Allow: (в ответе сервера)
Список методов,поддерживаемых ресурсом.
Allow: GET, HEAD
Content-Encoding:
идентифицирует метод кодировки,которым был закодирован ресурс
Content-Encoding: x-gzip
Content-Length:
Длина тела сообщения
Content-Length: 102
Content-Type:
Содержит тип ресурса(MIME),для текстовых еще и кодировку символов(необязательно)
Content-Type: text/html; charset=windows-1251
Expires: (в ответе сервера)
Дата окончания действия ресурса,применяется в кешировании для запрета кеширования устаревших ресурсов (в ответе)
Expires: Tue, 24 Sep 1998 23:00:15 GMT
Last-Modified: (в ответе сервера)
Время последнего обновления ресурса
Last-Modified: Tue, 23 sep 1998 13:48:40 GMT
Другие поля:
Поля Accept: указывают серверу выдавать только указаные форматы данных,которые клиент может распознать.
Accept: text/html
Accept: text/plain
Accept: image/gif
Поле Host: служит для того , чтобы указать, к какому хосту идет обращение. Данное поле не входит в число обязательных. Однако оно является необходимым в тех случаях, когда одному физическому серверу соответствует несколько виртуальных хостов. В этом поле тогда указывается какой из виртуальных хостов имеется в виду.
Host: www.nnov.city.ru
Примеры запросов:
Простейший запрос: GET /index.html HTTP/1.0 Посложнее: GET /somedir/somedoc.html HTTP/1.0 User-Agent: Mozilla/2.0 Accept: text/html Accept: text/plain Accept: image/gif Передача данных CGI- скрипту через метод GET GET /~paaa/cgi-bin/test.cgi?name=Dmitry&organization=%D3%ED%E8%E2%E5%F0%F1%E8%F2%E5%F2+ %CD%E8%E6%ED%E5%E3%EE+%CD%EE%E2%E3%EE%F0%EE%E4%E0&Name=&email=&comment= HTTP/1.0 User-Agent: Mozila/2.0 Accept: text/html Accept: image/gif Используя метод POST данные передаются в теле сообщения запроса: POST /~paaa/cgi-bin/test.cgi HTTP/1.0 User-Agent: Mozila/2.0 Accept: text/html Accept: image/gif Content-Type: application/x-www-form-urlencoded Content-Length: 131 name=Lesha &organization=%D3%ED%E8%E2%E5%F0%F1%E8%F2%E5%F2+%CD%E8%E6%ED%E5%E3%EE+ %CD%EE%E2%E3%EE%F0%EE%E4%E0&Name= &email= &comment=
Ответ идет от сервера.Состоит он из строки состояния и затем поля ответа Общий заголовок(General-Header) и заголовок тела сообщения (Entity-Header),которые уже описаны при обсуждении запроса. и еще идет заголовок ответа(Response-Header).
Строка состояния имеет следующий формат:
HTTP/version <SP> Status-Code <SP> Status-Phrase
где HTTP/version версия,Status-Code -3х значный код,и Status-Phrase текстовая фраза, поясняющая код ,пример: HTTP/1.0 200 Ok
,200 -код означающий успешную обработку запроса,что и поясняет "Ok" Заголовок ответа состоит из полей:
Location:
Содержит URI ресурса,может быть использован для переключения клиента в другое место, если например ресурс был перемещен в другое место или на другой сервер.
Location: http://www.uic.nnov.ru/newlocation/index.html
Server:
Информация о програмном обеспечении сервера
Server: Apache/1.1
WWW-Autenticate:
Параметры аутентификации.
WWW-Autenticate: Basic realm="doomsday"
Коды ответов HTTP.
Код статуса | Значение |
200 | OK |
201 | Успешная команда POST |
202 | Запрос принят |
203 | Запрос GET или HEAD выполнен |
204 | Запрос выполнен но нет содержимого |
300 | Ресурс обнаружен в нескольких местах |
301 | Ресурс удален навсегда |
302 | Ресурс отсутствует временно |
304 | Ресурс был изменен |
400 | Плохой запрос от клиента |
401 | Неавторизованый запрос |
402 | Необходима оплата за ресурс |
403 | Доступ Запрещен |
404 | Ресурс не найден |
405 | Метод не применим для данного ресурса |
406 | Недопустимый тип ресурса |
410 | Ресурс Недоступен |
500 | Внутренняя ошибка сервера (это по вашу душу,юные CGI-программисты ;( ) |
501 | Метод не выполнен |
502 | Неисправный шлюз либо перегруз сервера |
503 | Сервер недоступен/тайм-аут шлюза |
504 | Вторичный шлюз/тай-аут сервера |
Несколько примеров:
HTTP/1.0 200 Ok Date: Wed, 25 Sep 1998 23:00:00 GMT Server: Apache/1.1 MIME-version: 1.0 Last-Modified: Mon 15 Nov 1996 15:20:12 GMT Content-Type: text/html Content-Length: 2000 <HTML><HEAD><TITLE>Hello</TITLE></HEAD> <BODY bgcolor="green" text="yellow"> ...... </HTML>
А вот такое сервер выдаст в неудачном случае:
HTTP/1.0 404 Not Found
В том случае когда запрашиваемый URI есть CGI-скрипт сервер базируясь на данных запроса создает среду переменных CGI и передает управление скрипту скрипт должен выдать CGI-заголовок,после которого и идет тело ответа,сгенерированое скриптом.
Заголовок (CGI-Header) состоит из полей:
Content-Type:
Должно обязательно присутствовать,если есть тело.
Content-Type: text/html
Location:
Содержит URL ресурса на который скрипт перенаправляет запрос.Как правило,если присутствует это поле больше ничего не указывается.
Location: http://www.idsoftware.com/index.html
Status:
Позволяет CGI скрипту вернуть статус обработки,если это поле не задано,то сервер
подразумевает
Status: 404 Not found
На базе этой информации сервер и формирует окончательный заголовок,который и передается клиенту.
Примеры:
Обычно такое выдает скрипт: Content-Type: text/html <HTML><HEAD>....... Но иногда такое(когда он служит для перенаправления): Location: http://www.mustdie.ru/
А вот пример возврата статуса:
Content-Type: image/gif Status: 190 Its seems great like a playing doom! WOW! GIF89a........
Иногда возникает необходимость чтобы CGI -скрипт сам отвечал напрямую клиенту, минуя разбор заголовка.Это во-первых уменьшает нагрузку на сервер,и во вторых, что самое главное такой прямой ответ клиенту позволяет скрипту полностью контролировать транзакцию.Для этого существуют nph-скрипты(Not Parse Header) ,имя скрипта должно начинатьс с префикса "nph-" ,Например "nph-animate.cgi" .Такие скрипты сами формируют HTTP-ответ клиенту,что полезно при анимации:
#!/usr/bin/perl #nph-animate.cgi $times = 20; #Заготовте несколько небольних gif-файлов для этой программы @files = qw(img0.gif img1.gif img2.gif img3.gif); select (STDOUT); $|=1; #autoflush mode on #Generate header print "HTTP/1.0 200 Okay\n"; print "Content-Type: multipart/x-mixed-replace;boundary=myboundary\n\n"; print "--myboundary\n"; for ($num=1;$num<=$times;$num++) { foreach $file (@files) { print "Content-Type: image/gif\n\n"; open(PIC,"$file"); print <PIC>; close(PIC); print "\n--myboundary\n"; sleep(3); } } print "\n--myboundary--\n";
Этот пример вам выдаст анимацию ,составленую из нескольких .gif -файлов.Если же вы получили вместо анимации сообщение об ошибках,то вам следует,может быть перейти к следующей главе, которая поведает вам о правах доступа- того,без чего Unix не был бы Unixом.