Формирование запроса браузером
Взаимодействие сервера (серверной программы) и браузера осуществляется в виде запросов и ответов. Когда мы вводим в адресной строке браузера строку string,браузер последовательно выполняет следующие действия:
1. Выделяет из нее имя сервера и порт (если он указан),
2. Устанавливает соединение с сервером и посылает ему запрос:
GET string HTTP/1.0\n .....разная информация..... \n\n В запросе \n означает перевод на новую строку, а n/n/— маркер окончания запроса. Если сервер не получит маркера окончания, то запрос он обрабатывать не будет.
После строки, начинающейся со слова GET(так называемой GET-строки) в запросе могут содержаться другие строки. Эти строки называются заголовками, впрочем, как и сама GET-строка. Заголовков может быть довольно много. Их формирует браузер. Однако для запроса документа нужен только один GET. Чуть позже мы рассмотрим заголовки подробнее, а сейчас займемся разбором переданных сценарию параметров.
Если браузер вызывает сценарий, то, как правило, он передает ему какие-нибудь параметры:
GETсценарий?параметр=значение&параметр=значение НТТР/1.0\n
Как видите, после имени запрашиваемого документа следует знак вопроса, а за ним — строка параметров.
Формирование ответа сервером
Для формирования ответа сервера будем использовать специальный сценарий, который мы напишем на языке Си. Этот сценарий должен быть откомпилирован и помещен в каталог CGI-сценариев. Все, что будет делать сценарий, это отображать присланные ему параметры в окне браузера. При этом он не будет заниматься непосредственным разбором параметров, а только выведет все переданные параметры в браузер. Если вы не знаете языка Си, ничего страшного (хотя ничего хорошего в этом нет). Ниже приведено подробное описание сценария, так что вы без труда поймете назначение каждой строки сценария.
Простейшее CGI-приложение:
/* cgi.c - простейшее CGI-приложение */
#include <stdio.h>
#include <stdlib.h>
Int main()
{
char *Remote_IP = getenv("REMOTE_ADDR") ;
char *Query_String = getenv("QUERY_STRING");
printf("Content-type: text/html\n\n" ) ;
printf ("<htmlxbody><hl>Привет!</hl><p>") ;
printf("Ваш IP: %s" , Remote_IP);
printf("<р>Переданные вами параметры: %s",Query_String);
printf("</body></html>");
return 0; }
Сценарий сначала получает значение переменной окружения REMOTE_ADDR,а потом — значение переменной QUERY_STRING. Первая содержит значение IP-адреса удаленного пользователя, а вторая — строку переданных параметров. Для обращения к переменным окружения в Си используется функция getenvQ.
Затем сценарий выводит на стандартный вывод значения обеих переменных. Вот здесь и заключается огромная хитрость CGI. Если запустить программу просто в консоли, а не через браузер, то на экране мы увидим: Content-type: text/html<html><body><hl>Пpивeт!</h1><p>Ваш IP: <p>Переданные вами параметры: </body></html> Значения переменных окружения REMOTE_ADDR и QUERY_STRINGбудут недоступны, так как эту программу запустили мы сами, а не сервер. Сервер, запустив программу, считает все данные, которые программа выводит на стандартный вывод (stdout) и передает программе пользователя — браузеру.
Таким образом, если запустить программу, используя браузер, то в окне браузера мы увидим (при условии, что передали такие параметры: name=Denis&email=den@localhost): Привет! Ваш IP: 127.0.0.1 Переданные вами параметры: name=Denis&email=den@localhost
Программисту осталось сделать малое — только разобрать пары: параметр = значение. Он должен вручную (в смысле сами написать программу разбора) прочитать строку параметров, создать двумерный массив, содержащий имена параметров и их значения. Если понадобится имя параметра, необходимо перебрать все элементы массива в поисках нужного имени параметра. Язык РНР сам выполняет разбор параметров командной строки. Для обращения к значению параметра можно использовать имя параметра: echo "Ваше имя: $name"; echo "Email: $email";
Кроме того, как видно из этого сценария, РНРсам создает переменные, которые называются так же, как и переданные параметры. Это значит, что если сценарию передать параметр email,то в процессе работы сценария (а именно — сразу после его запуска) появится переменная $email,с которой можно будет работать, как с обыкновенной переменной.
Метод POST
Если используется метод POST,переданные сценарию параметры не отображаются в окне браузера. Да и сама передача происходит иначе: POSTсценарий HTTP/ 1.О\n. Content-lenath:5\n\n Hello
Сам блок пересылаемых данных находится уже после маркера окончания. Благодаря этому достигается принципиальная особенность метода POST. Эта особенность заключается в том, что при такой передаче данных сервер никак их не интерпретирует, а сразу передает сценарию. Это означает, что сценарий будет запущен сразу же после окончания заголовков (\n\n) и сервер просто передает ему POST-данные. Потом сценарий должен самостоятельно прочитать определенное число байтов, указанное в заголовке Content-length(длина слова Hello составляет пять символов). Поэтому при использовании метода POSTвсегда необходимо указывать значение переменной Content-length.
Параметры, переданные методом POST,будут преобразованы в переменные, с которыми можно работать в своем сценарии.
Метод POST обычно используется для передачи больших объемом данных, например, при загрузке файлов на сервер или же. когда нужно скрыть значения передаваемых параметров от глаз пользователя. Дело в том, что передаваемые параметры и их значения не отображаются в окне браузера, как это происходит с методом GET.
Переменные окружения CGI
Мы уже знакомы с двумя переменными окружения — REMOTE_ADDR и QUERY_STRING. Переменные окружения в языке РНР можно использовать, как самые обыкновенные переменные:
echo "IP: $REMOTE ADDR";
echo "Параметры: $QUERY_STRING";
Переменные окружения можно разбить на четыре большие группы:
* Формируемые сервером переменные.
* Специальные переменные сервера Apache.
* Переменные HTTP-полей запроса.
* Переменные SSL-соединения (защищенного соединения).
Первые три группы представлены в таблице
Таблица 1.1. Формируемые сервером переменные
Переменная | Описание |
AUTH_TYPE | Используемая схема аутентификации |
CONTENT_LENGTH | Длина содержимого |
CONTENT_TYPE | М1МЕ-тип содержимого, например text/html |
GATEWAY_INTERFACE | Версия CGI |
PATH_INFO | НТТР-путь к сценарию |
PATH_TRANSLATED | Полный путь к сценарию |
REMOTE_ADDR | 1Р-адрес запрашивающего компьютера-клиента |
REMOTE_HOST | Доменное имя запрашивающего компьютера-клиента |
REMOTE_PORT | Доменное имя запрашивающего компьютера |
REMOTE_USER | Порт, закрепленный за браузером для получения ответа от сервера |
QUERY_STRING | Имя пользователя прошедшего аутентификацию |
SERVER_ADDR | Строка переданных серверу параметров |
SERVER_NAME | 1Р-адрес сервера |
SERVER_PORT | Доменное имя сервера |
SERVER_PROTOCOL | ТСР-порт Wеb-сервера. Обычно 80 |
SERVER_SOFTWARE | Версия протокола НТТР |
SERVER_NAME | Программное обеспечение сервера |
SCRIPT_NAME | НТТР-путь к сценарию |
Таблица 1.2. Специальные переменные сервера Apachе
Переменная | Описание |
DOCUMENT_ROOT | Физический путь к корневому WWW-каталогу сервера |
SERVER_ADMIN | Адрес электронной почты администратора сервера |
SERVER_SIGNATURE | Подпись серверов |
Таблица 1.3. Переменные НТТР-полей запроса
HTTP_HOST | Имя вертуального хоста, которому адресован запрос |
HTTP_USER_AGENT | Програмное обеспичение вертуального хоста |
HTTP_ACCEPT | Список поддерживаемых клиентов типов содержимого |
HTTP_ACCEPT_LANGUAGE | Список поддежииваемых языковв в порядке предпочтения |
HTTP_ACCEPT_ENCODING | Список поддежииваемых методов сжатия |
HTTP_ACCEPT_CHARSET | Список поддежииваемых кодировок |
HTTP_CONNECTION | Тип соединения( если после ответа на запрос не нужно разрывать соединение, и если после ответа на запрос нужно закрыть соединение) |
HTTP_REFERER | В этом поле браузер передает URL-реурса, который ссылается на наш сервер |
HTTP_X_FORWARDED_FOR | Если пользователь работает через прокси сервер, то в этом поле будет 1Р-адресузла, обратившегося к прокси серверу. Еслт данное поле уже содержит значение то новое значение будет добавленно через запятую |