Заголовки запросов и ответов CGI

Статья устаревшая, но понятная.

на эту информацию придется ориентироваться при написании 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=

Ответ HTTP-сервера.
Ответ идет от сервера.Состоит он из строки состояния и затем поля ответа Общий заголовок(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

Более подробное описание всех кодов можно найти в RFC-1945
Несколько примеров:

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

CGI-заголовок.
В том случае когда запрашиваемый URI есть CGI-скрипт сервер базируясь на данных запроса создает среду переменных CGI и передает управление скрипту скрипт должен выдать CGI-заголовок,после которого и идет тело ответа,сгенерированое скриптом.
Заголовок (CGI-Header) состоит из полей:
Content-Type:
Должно обязательно присутствовать,если есть тело.
Content-Type: text/html

Location:
Содержит URL ресурса на который скрипт перенаправляет запрос.Как правило,если присутствует это поле больше ничего не указывается.
Location: http://www.idsoftware.com/index.html

Status:
Позволяет CGI скрипту вернуть статус обработки,если это поле не задано,то сервер подразумевает "200 Ok"
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........

nph-скрипты.
Иногда возникает необходимость чтобы 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 Okayn";
print "Content-Type: multipart/x-mixed-replace;boundary=myboundarynn";

print "--myboundaryn";
for ($num=1;$num<=$times;$num++) {
   foreach $file (@files) {
      print "Content-Type: image/gifnn";
      open(PIC,"$file");
      print <PIC>;
      close(PIC);
      print "n--myboundaryn";
      sleep(3);
      }
   }
print "n--myboundary--n";

 

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

Ссылки и благодарности

Статья полностью скопирована с: http://mgraphics.ru/show_articles.php?act=read&aid=330