CGI-приложения на Turbo Pascal

Содержание:

  1. Введение. Что такое CGI
  2. Оправданность подхода
  3. Настройка веб-сервера Apache
  4. Основные моменты при написании CGI-приложений на Turbo Pascal
  5. Краткий список переменных окружения

Введение. Что такое CGI

CGI — сокращение от англ. Common Gateway Interface, в переводе — "общий интерфейс шлюза". Представляет собой стандарт интерфейса для взаимодействия внешней программы с веб-сервером. Программу, работающую по такому интерфейсу совместно с веб-сервером, принято называть шлюзом, но больше распространены названия "скрипт" или "CGI-приложение", мы условимся называть далее по тексту такую программу именно "CGI-приложением". Основными задачами CGI являются создание динамических веб-страниц, а так же сбор и обработка информации пользователей. Раскрыв более подробно эти определения, мы увидим ставшие привычными нам веб-конференции, интернет-магазины, поисковые системы, каталоги. Более того, даже реализация простейшей формы обратной связи на домашнем сайте была бы невозможна, без использования CGI. И в этой статье я покажу вам, как можно приобщиться к миру веб-разработок не отрываясь от хорошо знакомого Turbo Pascal 7.

Оправданность подхода

Сам интерфейс CGI был разработан таким образом, чтобы возможно было использовать любой язык программирования, который поддерживает работу со стандартными устройствами ввода/вывода. Хотя в настоящее время наиболее популярны для создания веб-сайтов интерпретируемые языки PHP, Perl, Python или приложения на Java, С++, но ничего не запрещает вам использовать и старый-добрый Turbo Pascal. Конечно, по мощности он едва ли сможет тягаться со своими более современными собратьями, но для обучения и создания относительно простых приложений вполне подойдет. И этот большой плюс позволит попробовать свои силы в программировании CGI-приложений людям, пока не имеющим времени/возможности/желания садиться изучать новый для себя язык.

Настройка веб-сервера Apache

По-умолчанию, для доступа к CGI-приложениям из веб-страницы и возможности выполнения, их исполняемые файлы должны быть помещены в директорию /cgi-bin сервера. Но если вы хотите, чтобы ваше приложение было доступно из другой директории, то надо создать в ней файл с именем .htaccess следующего содержания:
Options ExecCGI

Возможно, понадобится еще и строка:

AddHandler cgi-script .exe

За более детальными настройками CGI нужно обратиться к файлу httpd.conf веб-сервера. Как правило, он содержит поясняющие комментарии к каждой опции. Также множество документации по "тонкой" настройке можно найти в интернете.

Основные моменты при написании CGI-приложений на Turbo Pascal

По-сути, CGI-приложение практически ничем не отличается от обычного, за исключением нескольких моментов. Но прежде чем перейти к их рассмотрению, давайте разберем принципы работы CGI и напишем "Hello, World!".

Program hello;
BEGIN
   writeln('Content-Type: text/html');
   writeln;
   writeln('"Hello, world!"');
END.

Компилируем приложение, помещаем в директорию /cgi-bin. Открываем в браузере ссылку http://localhost/cgi/bin/hello.exe (предполагается, что вы используете сервер на локальном компьютере, а скомпилированная программа имеет имя hello.exe) и видим надпись Hello, world! крупными буквами.

Как видите, в программе используется обычный вывод строки. Вопрос может вызвать только вывод первого оператора WriteLn, в нем посылаются заголовки ответа, рассмотрим несколько из них:

Content-Type: – должен обязательно присутствовать, если есть тело ответа. Определяет MIME-тип ответа.

Пример: Content-Type: text/html

Location: - Должен содержать URL ресурса, на который перенаправляется запрос, обычно больше ничего не указывается (ведь запрос перенаправляется на другой сервер).

Пример: Location: http://www.google.com/search

Status: - Содержит код завершения работы CGI-скрипта. Если он не указан, то подразумевается 200 Ok

Пример: Status: 404 Not found

Далее, после CGI-заголовка, на STDOUT должна быть отправлена пустая строка, которая отделяет заголовок от тела ответа. И после этого посылается само тело ответа, тип которого был указан в Content-Type (картинка, текст, HTML или другое.).

Немного усложним наше CGI-приложение, посмотрим, как работает "ввод", а точнее передача параметров приложению. Параметры, в зависимости от метода HTTP-запроса передаются по-разному: при GET присоединяются к командной строке (разделяясь символом &), а при POST поступают как тело запроса на стандартный ввод (STDIN) приложения.

Итак, допустим у нас есть HTML-страничка с простейшей формой:

<form method="get" action="/cgi-bin/hello.exe">
Введите Ваше имя: <input name="name" size="20"/><br />
<input type="submit"/>
</form>

Рассмотрим эту форму подробнее. Тег <form> имеет два атрибута:

method — указывает на метод передачи данных приложению (GET или POST);

action — путь к приложению (может быть как относительный, так и полный).

В текстовое поле с именем "name" мы можем ввести данные, кнопка "submit" соответственно отправляет форму.

Содержимое hello.exe:

Program hello; 
var name: String;
BEGIN
  name:=GetEnv('QUERY_STRING');
  for i:=1 To GetEnv('CONTENT_LENGHT') do
     if name[i] == '=' Then
     begin
         name:=Delete(name, 0, i);
         Break;
     end;
     writeln('Content-Type: text/html');
     writeln;
     writeln('<p>Привет, <b>', name , '</b>!</p>');
END.

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

Строка name будет содержать имя, которое мы ввели в форме, но не всегда. Сначала нам придется считать в нее все содержимое GET-запроса, это выполняется функцией GetEnv('QUERY_STRING'), которая служит для считывания значений переменных окружения CGI, в данном случае нам нужна QUERY_STRING, которая содержит строку запроса при использовании метода GET. Длина тела запроса хранится в переменной CONTENT_LENGTH.

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

Таким образом, мы получаем значение из переданной формы и выводим в браузер сообщение  Привет, user! (где user - введенное имя). При этом в адресной строке вашего браузера вы увидите адрес наподобие http://localhost/cgi-bin/hello.exe?name=user, можете поэкспериментировать с приложением, меняя значение переменной прямо в адресной строке.

Итак, рассмотрев этот простой пример, мы уже можем выделить основные моменты при написании CGI-приложений на Turbo Pascal:

  • Для вывода используем стандартный вывод STDOUT.
  • Не забываем до начала вывода данных выводить необходимые HTTP-заголовки и отделять переводом строки тело от заголовков.
  • Для получение POST-запросов используем стандартный ввод STDIN.
  • Для получения GET-запроса используем соответствующую переменную окружения.
  • Для доступа к переменным окружения используем функцию GetEnv('ПЕРЕМЕННАЯ_ОКРУЖЕНИЯ').
  • Так как в Turbo Pascal нет встроенных средств для комфортной работы с HTTP-запросами придется написать свой личный набор базовых функций для считывания переменных из форм, проверки их значений и др.

Вот в принципе и все, что вам нужно знать для успешного начала работы с CGI. Turbo Pascal прекрасно позволит освоить азы, понять фундаментальные принципы построения веб-приложений. Если вас заинтересует данное направление в программировании, вы сможете перейти к более мощным средствам разработки и продолжить совершенствовать свои навыки.

Далее приводится краткий список переменных окружения, которые могут вам понадобиться в ходе изучения CGI.

Краткий список переменных окружения

REQUEST_METHOD Служит для определения метода запроса HTTP

Пример: REQUEST_METHOD=POST
QUERY_STRING Содержит строку запроса при методе GET

Пример: QUERY_STRING= name=user&age=20&work=pascal
CONTENT_LENGTHДлина тела запроса в байтах

Пример: CONTENT_LENGTH=41
CONTENT_TYPE MIME-тип тела запроса

Пример: CONTENT_TYPE=text/html
GATEWAY_INTERFACE Версия протокола CGI

Пример: GATEWAY_INTERFACE=CGI/1.1
REMOTE_ADDR IP-адрес клиента, делающего данный запрос

Пример: REMOTE_ADDR=192.168.3.1
REMOTE_HOST Доменное имя, если у клиента оно есть, в противном случае - тот же IP-адресс что и в REMOTE_ADDR

Пример: REMOTE_HOST=tpdn.ru
SCRIPT_NAME Имя приложения, использованное в запросе. Для получения реального пути на сервере используйте SCRIPT_FILENAME

Пример: SCRIPT_NAME=/~home/script.cgi
SCRIPT_FILENAMEИмя файла скрипта на сервере

Пример: SCRIPT_FILENAME=/var/www/home/cgi-bin/script.cgi
SERVER_NAMEИмя серера ,чаще всего доменное как www.google.com, но в редких случаях за неимением такового может быть IP-адресом как 192.168.4.1

Пример: SERVER_NAME=www.tpdn.ru
SERVER_PORTTCP-порт сервера использующийся для соединения. По умолчанию HTTP-порт 80, хотя в некоторых случаях может быть другим

Пример: SERVER_PORT=80
SERVER_PROTOCOLВерсия протокола сервера

Пример: SERVER_PROTOCOL=HTTP/1.1
SERVER_SOFTWAREПрограммное обеспечение сервера

Пример: Apache/1.0
AUTH_TYPE, REMOTE_USERЭти переменные определены в случае, когда запрошенный ресурс требует аутентификации пользователя.
Автор: Кравцов А.Н.
Дата публикации: 26.05.2010