Моя визитка
Урок 1. Хакинг
Урок 2. Антихакинг
Урок 3. Инструменты хакинга
Урок 4. Защита Windows 2000/XP
Урок 5. Проникновение в систему
Урок 6. Реализация цели вторжения
Урок 7. Сокрытие следов
Урок 8. Хакинг браузеров Web
Урок 9. Хакинг почтовых клиентов
Урок 10. Деструкция почтового клиента
Урок 11. Хакинг Web-сайтов
Урок 12. Атаки DoS
Урок 13. Хакинг компьютеров Windows 2000/XP
Урок 14. Хакинг средств удаленного управления
Урок 15. Хакинг брандмауэров
Урок 16. Перехват сетевых данных
Урок 17. Хакинг коммутируемого доступа
Приложение А
Приложение В
Приложение С
Приложение D
Приложение E

ПРИЛОЖЕНИЕ В

Подготовка набора данных формы
Передача набора данных формы
Обработка набора данных формы

Сценарии и протокол CGI

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

1. Клиентский браузер отображает полученный документ HTML с формой и ждет ввода данных в форму.

2. Пользователь вводит данные в форму - устанавливает флажки, переключатели, вводит текст и т.д. - и щелкает на кнопке подтверждения формы.

3. Браузер, на основании требований спецификации HTML 4 определяет набор данных формы, задает адрес URL, указанный в значении атрибута ACTION формы и устанавливает связь с соответствующим сервером Web для пересылки ему набора данных формы. При взаимодействии клиентского компьютера с сервером используется протокол HTTP, кратко описанный в Приложении С.

4. Сервер разрешает полученный адрес URL, преобразуя его в имя запрашиваемого файла и в полный, физический путь к этому файлу.

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

6. Сервер подготавливает набор системных параметров (называемых переменными окружения), требуемых программе для исполнения, и запускает программу. После этого данный сценарий начинает играть роль сервера-посредника между клиентом и сервером Web, хранящим запрашиваемый ресурс; такого рода серверы, по терминологии стандарта HTTP 1.1, называются шлюзами. Работа такого шлюза определяется протоколом CGI (Common Gateway Interface - Общий шлюзовой интерфейс). Этот протокол является сетевым стандартом, разработанным организацией NCSA (National Center for Supercomputing Applications - Национальный центр по применению суперкомпьютеров) специально для создания приложений, исполняемых на информационных серверах Web.

7. Далее работа шлюза зависит от метода, по которому сервер предоставляет ему полученный набор данных формы, указанного атрибутом METHOD элемента FORM. Спецификация HTML 4 поддерживает два метода - POST или GET, которые входят в набор методов запросных сообщений HTTP.

8. Шлюз выявляет (при необходимости) метод, использованный для передачи ему набора данных формы, извлекает данные и производит их обработку.

9. По завершении обработки данных шлюз передает результаты обработки серверу Web и завершает работу (или же шлюз может сам передать результаты клиентскому браузеру и завершить работу).

10. Сервер обнаруживает, что сценарий завершил работу, после чего отсылает (если необходимо) результаты работы сценария обратно клиентскому браузеру.

11. Клиентский браузер отображает полученные результаты в своем окне.

Итак, процесс взаимодействия сценария с формой регламентируется тремя следующими стандартами, каждый из которых отвечает за определенный этап клиент-серверного взаимодействия в сети Web.

• Спецификацией HTML 4, определяющей содержимое набора данных формы, отправляемого на сервер.

• Протоколом HTTP, отвечающим за передачу запроса от клиентского браузера на информационный сервер Web.

• Протоколом CGI, определяющим взаимодействие шлюза на Web-сервере с клиентским браузером.

Обсудим эти три аспекта сетевого взаимодействия более подробно.

Подготовка набора данных формы

Когда пользователь отправляет данные формы на сервер (например, щелкнув на кнопке подтверждения формы) для последующей обработки, клиентский браузер выполняет следующие действия.

1. Определяет успешные элементы управления, т.е. элементы управления, «пригодные» для отправки их значений на сервер. Правила, по которым браузер выявляет успешные элементы управления, описаны в разделе «Успешные элементы управления» чуть ниже.

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

3. Кодирует набор данных формы в соответствии с типом их содержимого, определенного атрибутом ENCTYPE элемента FORM.

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

Успешные элементы управления

Успешный элемент управления - это тот, который удовлетворяет некоторым условиям, делающим возможным отправку его значения на сервер. Каждый успешный элемент управления должен иметь имя и текущее значение; эта пара включается в состав передаваемого набора данных формы. Также успешный элемент управления должен находиться в контейнере элемента FORM и удовлетворять следующим ограничениям.

• Успешным является любой установленный флажок.

• Если в форме содержится несколько кнопок подтверждения формы, успешной является только активированная пользователем кнопка.

• Для меню имя элемента управления задается элементом SELECT, а значения - выбранными элементами OPTION. Успешными могут быть только элементы управления SELECT с выбранными пунктами.

• Текущим значением элемента управления для выбора файлов является список из одного или нескольких имен файлов. После подтверждения формы содержимое каждого файла пересылается вместе с остальными данными формы. Содержимое передаваемого файла упаковывается в соответствии с типом содержимого формы.

• Для переключателя, кнопки которого имеют одинаковое значение атрибута NAME, успешной может быть только «включенная» кнопка.

• Текущее значение элемента управления, реализованного элементом OBJECT определяется конкретной реализацией объекта.

• Если элемент управления при подтверждении формы не имеет текущего значения, клиентские браузеры не должны считать его успешным. Более того, клиентские браузеры не должны считать успешными кнопку сброса и элементы OBJECT, у которых установлен атрибут DECLARE.

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

В данном случае текущее значение "myname" элемента управления будет сопоставлено с его именем "hide-text" и соответствующая пара имя/значение будет включена в набор данных формы.

Кодирование набора данных формы

Перед передачей на сервер набор данных формы кодируется в соответствии со значением атрибута ENCTYPE элемента FORM, который определяет тип содержимого, соответствующий пересылаемым данным. Клиентские браузеры должны поддерживать перечисленные в следующем разделе типы содержимого, в противном случае их поведение в процессе обработки формы будет непредсказуемо.

Tuп содержимого "application/x-www-form-urlencoded"

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

• Из формы извлекаются имена и значения элементов управления, после чего символы пробелов заменяются символами +. Символы, не являющиеся буквами или цифрами, заменяются кодом %НН, где за знаком процента следуют шестнадцатеричные цифры, представляющие код ASCII этого символа. Разрывы строк представляются парами CRLF (т.е. значением %OD%OA).

• Пары имя/значение элементов управления перечисляются согласно их позиции в тексте документа. Имя отделяется от значения с помощью символа =, а пары имя/значение отделяются друг от друга символом &.

Рассмотрим, например, следующую форму.

Подтверждение этой формы с введенным именем подписчика Ivan Petrov и адресом электронной почты petrov@email.com приведет к отправке такого набора данных формы:

firstname=lvan&lastname=Petrov&postal-

address=petrov@email.com&subscribe=on

Tun содержимого "multipart/form-data"

Тип содержимого "application/x-www-form-urlencoded" неэффективен для отправки большого количества двоичных данных или текста, содержащего символы, не входящие в набор ASCII. Для отправки набора данных формы, содержащего файлы или данные с символами, не входящими в набор ASCII, или двоичные данные, больше подходит тип содержимого "multipart/form-data".

Сообщение с типом содержимого "multipart/form-data" состоит из нескольких частей, каждая их которых представляет успешный элемент управления. Эти части пересылаются в программу обработки формы в том порядке, в котором соответствующие им элементы управления представлены в документе HTML. Каждая часть может содержать необязательный заголовок "Content-Type", значение которого по умолчанию равно "text/plain". Кроме этого, каждая часть должна содержать следующие компоненты.

• Заголовок "Content-Disposition", имеющий значение "form-data".

• Атрибут имени соответствующего элемента управления.

Например, для элемента управления с именем "control-name" соответствующая часть набора данных формы может выглядеть так:

Content-Disposition: form-data; name="control-name"

Если в наборе данных формы передаются данные, хранимые в файле, для этих данных должен быть определен тип содержимого (например, "application/octet-stream"). Если с помощью одного элемента формы было выбрано несколько файлов, они должны пересылаться с указанием типа содержимого "multipart/mixed".

В следующем примере показан результат кодирования согласно типу содержимого "multipart/form-data". Предположим, у нас имеется следующая форма.

Если пользователь введет в текстовое поле слово "Ivanov" и выберет текстовый файл "content.txt", то после подтверждения формы браузер отправляет следующий набор данных формы.

Здесь использован обязательный параметр boundary, задающий строку, разделяющую части передаваемых данных. Если пользователь выбрал второй файл с изображением "logo.gif", то клиентский браузер отправляет следующие части набора данных формы.

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

Передача набора данных формы

Согласно спецификации языка HTML 4 при отправке набора данных формы для их обработки клиентский браузер устанавливает связь с сервером HTTP и посылает ему запросное сообщение (выполняет транзакцию HTTP). Структура запросных и ответных сообщений HTTP описана в Приложении С, однако напомним, что каждое сообщение HTTP состоит из начальной строки, заголовков сообщения и тела сообщения, и запросное сообщение HTTP имеет ту же самую структуру, что и ответное, за исключением начальной строки. Эта строка в случае запросных сообщений называется строкой запроса, и она имеет такой вид.

Строка запроса=Метод SP Запрашиваемый_адрес_URL SP

Версия_протокола_НТТР CRLF

Здесь SP - это символ пробела ASCII (код 32), Метод - это название метода HTTP, который должен быть применен к ресурсу, указанному запрашиваемым адресом URL, a CRLF - это код возврата каретки (CR) и перевода строки (LF). Набор методов запроса HTTP перечислен в Приложении С, для нас же важны два следующих метода, поддерживаемые в язык HTML 4.

GET - Этот метод предназначен для запроса информации, предоставляемой ресурсом, указанным адресом URL запроса. Эта информация должна предоставляться в теле ответного сообщения.

POST - Этот метод применяется для запроса, который указывает серверу, что пересылаемое в запросе тело сообщения должно быть передано ресурсу, указанному адресом URL в строке запроса.

В языке HTML 4 метод HTTP, используемый для отправки формы в программу обработки, определяется атрибутом METHOD элемента FORM. Передача данных при этом происходит следующим образом.

• Если для атрибута METHOD установлено значение "get", а для атрибута ACTION указан адрес HTTP, то клиентский браузер берет значение атрибута ACTION, добавляет к нему символ «?», затем добавляет набор данных формы, закодированный с использованием типа содержимого "application/x-www-form-urlencoded". Затем браузер выполняет транзакцию GET протокола HTTP, отправляя этот адрес URL на сервер для обработки. При использовании метода GET набор данных формы ограничивается кодами ASCII.

• Если для атрибута METOD установлено значение "post", а атрибут ACTION определен как адрес HTTP, то клиентский браузер выполняет транзакцию POST протокола HTTP с использованием значения атрибута ACTION и сообщения, созданного в соответствии с типом содержимого, определенным атрибутом ENCTYPE (см. раздел «Кодирование набора данных формы» чуть выше).

Для других значений атрибута ACTION или METHOD способ обработки набора данных формы спецификацией HTML 4 не определен. После выполнения транзакций GET и POST протокола HTTP клиентские браузеры должны представлять пользователю полученные отклики на соответствующие транзакции.

Теперь посмотрим, что происходит с переданными данными на самом сервере.

0брабomкa набора данных формы

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

CGI-программа шлюза запускается сервером Web в ответ на запрос клиента в реальном масштабе времени. Сервер, действуя по протоколу CGI, обеспечивает передачу запроса пользователя шлюзу. Шлюз, в свою очередь, используя средства прикладной системы, возвращает клиенту результат обработки запроса!

Программа, реализующая шлюз, может быть закодирована на языках C/C++, PHP, Fortran, Perl, TCL, Unix Schell, Visual Basic, Apple Script и др. Исполняемый модуль программы должен храниться в специальном каталоге Web-сервера, который определяется используемой платформой (серверной операционной системой). Однако способ передачи данных в программу и результатов их обработки из программы не зависит от платформы и языка кодирования, поскольку протокол CGI имеет общий характер. Опишем сначала процесс передачи набора данных формы в программу-сценарий.

Передача данных шлюзам

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

Командная строка - это строка, вводимая на приглашение операционной системы для запуска какой либо программы. Каждый, кто работал в среде MS DOS или использовал командную строку Windows, уже знаком с этим понятием. Командная строка состоит из имени исполняемого модуля, сопровождаемого набором входных параметров, задающих режим работы программы и ее входные данные. Например, ввод командной строки

arj a archiv file.txt

означает запуск программы архиватора arj.exe в режиме пополнения (входной параметр а) архива с именем archiv файлом с именем file.txt.

Переменные окружения - это набор системных переменных, доступных программе, который содержит набор параметров вычислительного окружения программы. Эти переменные окружения устанавливаются в тот момент, когда сервер запускает программу шлюза, и существуют до момента завершения программы. Хотя в сети Web используется множество серверов с различными вычислительными платформами и операционными системами, все они предоставляют стандартный набор переменных окружения. Для получения переменных окружения в программе С следует использовать библиотечную функцию getenv().

Входной поток - это последовательность байтов данных, хранимых в памяти компьютера и доступных программе. Для доступа к этим данным в программах используются специальные библиотечные функции, входящие в набор всех распространенных средств разработки программного обеспечения. В случае использования языка С этот поток называется STDIN; для считывания данных из потока STDIN используется функция fgetc (stdin).

Информация шлюзам передается в следующей форме.

Имя1=Значение1&Имя2=Значение2&...

3десь Имя - это имя передаваемого программе параметра Данных (в нашем случае это имя элемента управления формы), а Значение - это фактическое значение параметра (т.е. значение элемента управления). Способ, по которому эта информация передается шлюзу, зависит от метода запроса, указанного атрибутом METHOD формы. Для определения метода запроса шлюз должен использовать переменную окружения REQUEST_METHOD (см. ниже).

В случае метода GET эта строка передается как часть адреса URL запроса, и будет передана шлюзу в переменной окружения QUERY_STRING.

В случае метода POST эта информация будет послана в стандартный поток ввода шлюза. В последнем случае объем информации, содержащийся в стандартном потоке ввода, определяется переменной окружения CONTENT_LENGTH, задающей число байтов в потоке. Тип передаваемых шлюзу данных определяется переменной окружения CONTENT_TYPE. Сервер не обязан посылать символ конца потока после успешной пересылки шлюзу значения переменной CONTENT_LENGTH.

Приведем пример обработки формы с помощью описанной выше процедуры. Возьмем в качестве примера следующую форму запроса.

После подтверждения формы и отправки ее данных на сервер для обработки методом POST (поскольку в элементе FORM атрибут METHOD равен "post") в программу-сценарий во входном потоке поступит 42 байта, закодированных таким образом:

postal-address=ivan@email.com&subscribe=on

В этом случае сервер установит значение переменной CONTENT_LENGTH равным 42, а значение переменной CONTENT_TYPE установит равным "application/x-www-form-urlencoded". Первым символом в стандартном потоке ввода для шлюза будет символ "р", за которым будет следовать остаток закодированной строки.

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

Аргументы командной cmpoкu

В командной строке шлюз получает от сервера следующие данные.

• Часть адреса URL, помещенную клиентским браузером сразу после имени шлюза. Эта часть передается шлюзу в качестве первого параметра (если в адресе URL указано только имя шлюза, первый параметр будет пуст). Остальная часть данных будет содержать следующие сведения.

• Если сценарий реализует машину поиска, в оставшуюся часть командной строки включается список ключевых слов, используемых для поиска.

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

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

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

Например, пусть на сервер поступает запрос сценария с представленным ниже адресом URL (играющим роль «виртуального» путевого имени к шлюзу, поскольку этот путь не имеет отношения к реальному пути к ресурсу по каталогам сервера).

http://www.anysite.com/prog/addsubs/text/template/?namel=valuel

&name2=value2

Тогда сервер вызовет шлюз с помощью такой командной строки.

/.../addsubs /text/template/ namel=valuel name2=value2

Здесь запись /.../ означает физический (т.е. по каталогам сервера) путь к программе-сценарию. Как видим, первым аргументом командной строки будет запись /text/template/. Эта запись передается шлюзу, после чего он может предпринять какие-либо действия, в зависимости от самого сценария (скажем, использовать какой-либо шаблон документа в указанном записью месте).

Пусть теперь адрес URL запроса будет следующим.

/prog/addsubs?namel=valuel&name2=value2

Тогда сервер вызовет шлюз с помощью такой командной строки.

/.../addsubs '' namel=valuel name2=value2

Здесь на месте первого аргумента указан пропуск.

Переменные oкpужения

Перечислим список переменных окружения, устанавливаемых сервером для запускаемых шлюзов CGI, независимо от типа запроса.

SERVER_SOFTWARE - название и версия информационного сервера, который отвечает на запрос и запускает шлюз. Формат переменной таков: имя/версия. Например, эта переменная может иметь такое значение: HTTP/1.1.

SERVER_NAME - имя Web-сервера, представленное либо в виде DNS-имени, либо в виде IP-адреса (это имя должно совпадать с переданным в запросе адресом URL). Эта информация может оказаться полезной для генерации в программе шлюза адресов URL данного сервера. Вот пример значения этой переменной: www.anyserver.com

GATEWAY_INTERFACE - версия спецификации CGI, использованной на момент, когда компилировался сервер. Формат переменной таков: CGI/версия. Вот пример значения этой переменной: CGI/1.1.

Перечисленные выше переменные окружения являются специфичными для разных запросов и заполняются перед запуском CGI-программы шлюза.

А теперь приведем необязательные переменные окружения шлюзов CGI.

SERVKR_PROTOCOL - имя и версия информационного протокола, использованного в полученном запросе. Формат переменной таков: протокол/версия. Например, эта переменная может иметь такое значение: HTTP/1.1

SERVER_PORT - номер порта, на который был послан запрос, например, 80.

REQUEST_METHOD - метод, который был использован для запроса. Для запросов HTTP 1.1 эти методы перечислены в Приложении С.

PATH_INFO - дополнительная информация о пути, которую клиентский браузер поместил в конец адреса URL запроса сценария. Например, если указанный в запросе адрес URL имеет вид http://www.any-site.com/prog/handler.exe/text/dot, то требуемый сценарий называется handler.exe, а в переменную PATH_INFO будет помещено значение "text/dot". Другими словами, доступ к шлюзу может быть осуществлен по виртуальному пути, за которым следует некоторая дополнительная информация. Эта информация и передается в PATH_INFO.

PATH_TRANSLATED - эта переменная поддерживается лишь отдельными серверами и содержит физический путь к программе-сценарию, полученный преобразованием виртуального пути в адресе URL.запроса. Например, пусть абсолютный физический адрес к корневому каталогу Web-сервера будет /usr/local/etc/httpd/htdocs. Предположим также, что каталог cgi-bin со сценариями находится на первом уровне корневого каталога сервера, т.е. для обращения к нему следует использовать такой виртуальный путь: http://www.anyserver.com/cgi-bin. Тогда адрес URL запроса сценария http://www.anyserver.com/cgi-bin/handler сервер преобразует в такое значение PATH TRANSLATED: /usr/local/etc/httpd/htdocs//cgi-bin/handler т.е. виртуальный адрес превращается в физический путь к программе шлюза, составленного согласно файловой системе сервера.

SCRIPT_NAME - виртуальный путь к шлюзу, который должен выполняться для данного запроса. Это значение можно использовать для получения в программе шлюза адреса URL (с целью, например, отправки его обратно клиентскому браузеру вместе с ответным документом HTML, после чего браузер может применять этот адрес для повторных вызовов шлюза). Вот пример значения этой переменной: /cgi-bin/handler.exe

QUERY_STRING - информация, следующая за символом "?" в адресе URL, переданного в строке HTTP-запроса данного шлюза. Она не должна быть декодирована никоим образом. Вне зависимости от командной строки эта переменная окружения всегда должна быть установлена при наличии соответствующей информации. Например, пусть полученный в запросе адрес URL будет таков: http://www.anysite.com/handler7postat-addresss= ivan@email.com&subscribe=on Тогда в переменную QUERY_STRING будет помещено такое значение: postal-address=ivan@email.com&subscribe=on.

REMOTE_HOST - имя клиентского компьютера, с которого получен запрос. Если сервер не имеет такой информации, он должен установить переменную REMOTE_ADDR, а это поле оставить пустым.

REMOTE_ADDR - IP-адрес клиентского компьютера, с которого получен данный запрос. Например: 199.23.155.34.

AUTH_TYPE - если сервер поддерживает идентификацию пользователей и шлюз является защищенным от постороннего доступа, этот специфичный для протокола метод идентификации используется для проверки пользователя. Для доступа по протоколу HTTP 1.1 значения этой переменной определены в документе RFC2616. Переменная может быть равной или так называемой схеме идентификации HTTP (например, "challenge"), или равна NULL.

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

REMOTE_IDENT - если HTTP-сервер поддерживает идентификацию пользователя согласно спецификации RFC931, то эта переменная будет содержать имя пользователя, полученное от Сервера. Эта информация практически бесполезна, поскольку пользователи могут указать для нее любое значение.

CONTENT_TYPE - для запросов, которые содержат передаваемую на сервер информацию, типа запросов POST и PUT протокола HTTP, здесь содержится MIME-тип этой информации, например, "application/x-www-form-urlenCoded".

CONTENT_LENGTH - объем данных, которые передает клиент. Если запрос включает информацию, переданную по методу POST, этой переменной присваивается значение, равное числу байтов данных во входном потоке шлюза обработки данных.

НТТР_АССЕРТ - список типов содержимого (MIME-типов), которые может обрабатывать клиентский браузер. Этот список поступает от самого клиентского браузера. Каждый тип содержимого в этом списке должен быть отделен запятой согласно спецификации HTTP. Формат этой переменной таков: тип/подтип, тип/подтип... Вот пример такого списка: image/gif, image/x-xbitmap, image/jpeg

HTTP_USER__AGENT - имя клиентского браузера, пославшего данный запрос. Общий формат переменной таков: программа/версия библиотека/версия. Вот пример значения этой переменной: Netscape/4.6 (win2000)

Вывод результатов oбработки

После обработки полученных данных шлюз выводит результаты в стандартный поток вывода STDOUT, который определяется для каждой запущенной программы одновременно с потоком ввода. Содержимое этого вывода может представлять собой или документ HTML, сгенерированный шлюзом, или директиву серверу, указывающую, где ему следует получить необходимый документ HTML.

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

Вывод, контролируемый сервером

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

Content-type - указывает тип содержимого возвращаемых данных.

Location - Эта директива используется в случае, когда необходимо указать серверу, что возвращается не сам документ, а ссылка на него. Если аргументом директивы является адрес URL, то сервер передаст клиенту указание на перенаправление запроса. Если аргумент представляет собой виртуальный путь, сервер вернет клиенту заданный этим путем документ, как если бы клиент запрашивал его непосредственно.

Status - Эта директива используется для указания серверу HTTP строки состояния, которую он должен переслать клиенту. Формат строки таков: NNN XXXXX, где NNN - это код состояния, состоящий из трех цифр, а XXXXX - текстовая строка с пояснением кода состояния, например, такая: Forbidden (Запрещено).

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

Далее приведена простейшая программа на языке С, которая в ответ на запрос формы, приведенной в разделе «Передача данных шлюзам» выше, отображает на экране клиентского браузера поздравление пользователю.

Эта программа не делает никакой обработки - она просто передает в выходной поток строки с тегами HTML, используя библиотечную функцию printf () языка С. Сервер обрабатывает выходной поток и формирует корректное ответное сообщение HTTP, передаваемое клиентскому браузеру.

Теперь рассмотрим шлюз, который в определенных случаях должен отсылать клиентскому браузеру документ anydoc.txt, хранимый в каталоге /text/ данного сервера. При этом он действует так, как если бы этот документ был непосредственно запрошен клиентским браузером с помощью ссылки на адрес http://www.anyserver.com/text/anydoc.txt. В этом случае, вывод шлюза будет таков.

Наконец, предположим, что шлюз возвращает ссылки на сервер FTP, например, с таким адресом: ftp://ftp.cso.uiuc.edu. Вывод шлюза будет таков.

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

Вывод, не контролируемый сервером

Допустим теперь, что у нас имеется шлюз, который общается с клиентом непосредственным образом. Как уже отмечалось, его имя должно начинаться с префикса nph- и он должен возвращать клиентскому браузеру корректный заголовок HTTP. В этом случае, если сервер при запуске программы шлюза установил для переменной окружения SERVER_PROTOCOL значение "HTTP/1.1", его вывод должен удовлетворять протоколу HTTP 1.1.

Hosted by uCoz