Цель работы: исследовать простейшей Telnet-клиент, с помощью которого можно подключиться к любому серверному порту и выполнять команды прямо на сервере.
1. ТЕОРЕТИЧЕСКОЕ ВВЕДЕНИЕ
Для создания Telnet-клиента будет использоваться компонент Id Telnet расположенный на закладке IndyClients Палитры компонентов.
При создании Telnet-клиента будут использоваться следующие свойства компонента:
· Terminal - вид терминала;
· Host - IP-адрес иди имя сервера;
· Port - номер порта сервера;
· Connected - признак установленного соединения. Для взаимодействия с удаленным сервером Telnet-клиент примени следующие методы:
· Connect - установление соединения;
· Disconnect - разрыв соединения;
· SendCh - передача очередного символа на сервер. При получении ответа от сервера компонент Idtelnet обрабатывает следующие события;
· OnConnected - событие происходит при установлении соединения с сервером;
· OnDataAvailable - событие происходит при получении данных сервера;
· OnStatus событие происходит при изменении состояния канала связи с сервером.
2. ЗАДАНИЕ ПО ПРАКТИЧЕСКОМУ ЗАНЯТИЮ
2.1. Создание приложения Telnet-клиента
Создайте приложение Telnet- клиента, изображенное на рис. 1, для чего необходимо выполнить следующие пункты.
Рис. 1
1) Перенесите на форму компоненты, перечисленные в табл.
Таблица 1
Компоненты, устанавливаемые на форме
Компонент | Класс | Описание |
IdTelnet1 | TIdTelnet | Компонент telnet-клиент. Закладка IdClients Палитры компонентов |
StatusBarl | TSlatusBar | Панель состояния. Закладка Win32 Палитры компонентов |
Panel1 | TPanel | Панель, на которой размешаются командные кнопки и окна ввода приложения |
Memo1 | TMemo | Многострочное окно ввода. В данном окне отображаются команды, вводимые пользователем, и выводятся ответы серверов |
Label1 | TLabel | Метка «Сервер» |
Label2 | TLabel | Метка «Порт» |
Labe3 | TLabel | Метка «Терминал» |
Edit1 | TEdit | Окно ввода IP-адреса или имени сервера |
SpinEdit1 | TSpinEdit | Окно ввода номера порта. Закладка Samples Палитры компонентов |
ComboBoxl | TComboBox | Список выбираемых терминалов |
Buttonl | TButton | Кнопка «Connect» |
Button2 | TButton | Кнопка «Disconnect» |
2) Для компонента Editl (Сервер) установите в свойстве Text IP-адрес или имя сервера. В данном примере стоит адрес- 127.0.0.1.
3) Для компонента SpinEdit1 (Порт) установите в свойстве Value значение порта сервера по умолчанию. В данном примере стоит номер порта 21 (FTP -сервер).
4) Для компонента ComboBox 1 (Терминал) установите в свойстве Text значение - VT100, а в свойстве Items - список терминалов, как показано на рис. 2.
Рис. 2
5) Для события OnCiick кнопки «Conned» запишите следующий программный код:
procedure TTelnetForm.Button1Click(Sender: TObject);
begin
IdTelnetl.Terminal:= ComboBox1.Text;
IdTelnetl.Host:= Edit1.Text;
IdTelnetl.port:= SpinEditl.Value;
IdTelnetl.Connect;
end;
Этот программный код записывает для компонента IdTelnet1 тип пользуемого терминала, адрес сервера, номер порта сервера и выполняет соединение с сервером.
6) Для события OnCiick кнопки «Disconnect» запишите следующий программный код:
procedureTTelnetForm.Button2Click(Sender: (Object);
begin
If IdTelnet1.Connected then IdTelnetl.Disconnect;
end;
Здесь вызывается метод Disconnect компонента IdTelnetl, что приводит к отключению от сервера.
7) Для отправки команд на сервер для компонента Memo1 следует создать обработчик события OnKeyPress. В этом обработчике напишите следующий программный код:
procedure TTelnetForm.Memo1KeyPress(Sender: TObject: var Key: Char);
begin
if IdTelnetl.Connected then
begin
IdTelnetl.SendCh(Key);
end;
end;
Здесь происходит проверка: если компонент IdTelnetl подключен к серверу, то символ нажатой клавиши нужно передать на сервер. Для этого используется метод SendCh компонента IdTelnetl, а в качестве параметра этому методу передается нажатый символ. Теперь при нажатии любой клавиши для ввода символа в компонент Memol этот символ сразу же передается на сервер.
8) Для события OnConnected компонента IdTelnetl запишите следующий программный код:
procedure TTelnetForm.IdTelnetlConnected(Sender: TObject);
begin
Memol.Lines.Add('Клиент подключен');
Memol.Lines.Add('Может выполнять команды');
Memol.Lines.Add(‘’);
end;
Работа этого обработчика направлена на то, чтобы проинформировать пользователя о том, что соединение произошло успешно.
9) Для события OnDataAvailable компонента IdTelnetl запишите следующий программный код:
procedure TTelnetForm.Id'T'elnet1 DataAvailable(Sender: TldTelnet;
const Buffer: String);
const
// коды символов возврата строки и перевода каретки
CR=#13;
LF=#10;
var
Start, Stop: Integer;
Begin
Memol.Lines. Add(");
Start:= 1;
// Поиск символа возврата каретки
Stop:= Pos(CR, Buffer);
// Если символ возврата каретки не найден, то в поле Memo1 выводится
// содержимое всего полученного буфера данных
if Stop = 0 then
Stop:= Length(Buffer) + 1;
// Цикл, пока не встретится конец буфера
while Start <= Length(Buffer) do
begin
//Запись в поле Memo1 очередной строки
Memo1.Lines.Strings[Memo1.Lines.Count-1]:=
Memo1.Lines.Strings[Memo1.Lines.Count - l]+Copy(Buffer, Start, Stop -
Start);
if Buffer[Stop]=CR then
begin
Memol.Lines.Add(");
end;
Start:= Stop + 1;
//Обработка строки в полученном от сервера буфере данных
if Start>Length(Buffer) then
Break;
If Buffert[Start]=LF then
Start:=Start + 1;
Stop:= Start;
while (Buffer[Stop]<>CR) and (Stop<= Length(Buffer)) do
Stop:=Stop + 1;
end;
end;
Этот обработчик вызывается каждый раз, когда с сервера поступаю данные.
Весь написанный в листинге код направлен на вывод пришедшего текста с помощью компонента Memol. Для этого ищутся символы конца строки и перевода каретки, и если они найдены, то в компонент добавляется новая строка. Для облегчения поиска заведены две константы CR и LF с шестнадцатеричными значениями #13 и #10, которые являются кодами символов конца строки и перевода каретки.
10) Для события OnStatus компонента IdTelnet1 запишите следующий программный код:
procedure TTelnetForm.IdTelnetl Status(axSender: TObject; const axStatus: TIdStatus: const asStatusText: Siring); begin
if axStatus =hsDisconnected then
Memo1.Lines.Аdd(‘Сессия закончена');
end;
11) Для события OnCloseQuery формы запишите следующий программный код:
procedure TTelnetForm.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
begin
if ldTelnetl.Connected then
IdTelnetl.Disconnect;
end;
Здесь при попытке закрыть приложение выполняется проверка наличия соединения с каким-либо сервером, и если соединение установлено, то оно разрывается.
2.2. Исследование Telnet-клиента
1) Выполните проверку и исследуйте соединение данного Telnet-клиента с сервером Echo (порт 7). Сервер возвращает все данные, которые ему послали, то есть любой переданный на сервер символ будет им возвращен.
2) Выполните проверку и исследуйте соединение данного telnet-клиента с сервером времени (порт 13). Сервер времени должен переслать клиенту точные дату и время.
3) Выполните проверку и исследуйте соединение данного telnet-клиента c сервером FTP (порт 21). После того как соединение установлено, выполните следующие команды:
· User anonymous;
· Pass;
· Help;
· List;
и т. д.;
· Quit.
Последняя команда разрывает соединение с FTP-cервером.
4) Выполните проверку и исследуйте соединение данного telnet-клиента с сервером электронной почты SMTP (порт 25). После того как соединение установлено, выполните следующие команды:
· Echo;
и т. д.
· Quit.
ЛИТЕРАТУРА
1. Киммел П. Создание приложений в Delphi /Пер. с англ. М., Издательский дом «Вильямс», 2003. 640 с.
2. Фленов М. Е. Программирование в Delphi глазами хакера. СПб., БХВ-Петербург, 2004. 368 с.
КОНТРОЛЬНЫЕ ВОПРОСЫ
1. Назначение Telnet-клиента.
2. С помощью каких команд компонент IdTelnet устанавливает и разрывает соединение?
3. Как передать данные на сервер с помощью компонента IdTelnet?
4. Какое событие компонента IdTelnet происходит, когда поступают данные от сервера?
ЗАНЯТИЕ №21
РАЗРАБОТКА CGI-ПРОГРАММ
Цели работы: практически освоить методы создания CGI-программ на основе консольных приложений Delphi, разработать исполняемый файл, устанавливаемый на Web-сервере и выполняющий определенные действия в зависимости от получаемых параметров.
1. ТЕОРЕТИЧЕСКОЕ ВВЕДЕНИЕ
В теоретическом введении рассматриваются следующие вопросы.
· Принцип работы CGI-программ.
· Описание тега FORM.
· Описание тега FORM.
· CGI-переменные окружения.
1.1. Принцип работы CGI-программ
Common Gateway Interface - это спецификация интерфейса взаимодействия Web-сервера с внешними прикладными программами. Главное назначение CGI - обеспечение единообразного потока данных между сервером и работающим на нем приложением. Программы, написанные в соответствии со спецификацией CGI, называются CGI-скриптами (CGI-программами).
Обычно гипертекстовые документы, возвращаемые по запросу клиента WWW-сервером, содержат статические данные. CGI обеспечивает средства создания динамических Web-страниц на основе данных, полученных от пользователя. CGI-программа запускается Web-сервером, возвращает результаты работы серверу и завершает свое выполнение.
Схема работы CGI-программы приведена на рис. 1.
Рис. 1. Схема взаимодействия CGI-программы
CGI-программа работает по следующему принципу.
1) CGI-программа устанавливается на Web-сервере.
2) Пользователь запускает HTML-страницу, содержащую тег FORM.
3) С помощью тега FORM пользователь вводит параметры запроса и передает запрос на Web-сервер.
4) Web-сервер передает полученные данные CGI-программе, указанной в запросе.
5) CGI-программа обрабатывает запрос и формирует новую HTML-страницу, которую возвращает Web-серверу.
6) Web-сервер передает данную страницу клиенту.
Обмен данными по спецификации CGI реализуется обычно через переменные окружения и стандартный ввод-вывод. Выбор механизма передачи параметров определяется методом доступа, который указывается в форме в атрибуте METHOD. Если используется метод GET, то передача параметров происходит с помощью переменных окружения, которые сервер создает при запуске внешней программы. Через них передается приложению как служебная информация (версия программного обеспечения, доменное имя сервера и др.), так и сами данные (в переменной QUERY_STRING). При методе POST для передачи используется стандартный ввод. А в переменных окружения фиксируются тип и длина передаваемой информации (CONTENT_TYPE и CONTENT_LENGTH).
Стандартный вывод используется CGI-скриптом для возврата данных серверу. При этом вывод состоит из заголовка и собственно данных. Результат работы скрипта может передаваться клиенту без каких-либо преобразований со стороны сервера, если скрипт обеспечивает построение полного НTTР-заголовка, в противном случае сервер модифицирует заголовок в соответствии со спецификацией HTTP.
1.2. Описание тега FORM
Тег FORM определяет форму для заполнения в HTML-документе. В одном документе может быть определено несколько форм для заполнения, но вложенные теги FORM запрещены. Формат тега FORM выглядит следующим образом:
<FORM ACTION="url" METHOD ="POST”>...</FORM>.
Его атрибуты следующие:
ACTION - URL сервера запросов, куда будет отослано содержание формы после подтверждения. Если это поле отсутствует, будет использовано URL текущего документа. Данное поле указывает на CGI-программу.
METHOD - метод, используемый для посылки содержания заполненной формы на сервер. Этот метод зависит от того, как работает конкретный сервер запросов. Настоятельно рекомендуется использование метода POST.
Возможные варианты следующие:
• GET - это метод по умолчанию, который приводит к добавлению содержимого заполненной формы к URL, как и в нормальном запросе;
• POST - при использовании этого метода содержимое заполненной формы пересылается не как часть URL, а как содержимое тела запроса;
• ENCTYPE - задает тип кодирования содержимого заполненной формы. Этот атрибут действует только когда используется метод POST и даже в этом случае имеет только одно возможное значение (которое является значением но умолчанию) - application/x-www-form-urlencoded.
Внутри FORM оператора может находиться все, что угодно, кроме другого оператора FORM. Согласно спецификации, для задания интерфейсных элементов внутри оператора FORM используются теги INPUT, SELECT и TEXTAREA.
1.2.1. Тег INPUT
Тег INPUT используется для задания простого элемента ввода внутри FORM. Это одиночный тег, его ничего не окружает, и он не имеет закрывающего тега.
Атрибуты для тега INPUT перечислены ниже.
TYPE должен быть один из:
· «hidden» - пользователю не предлагаются поля для ввода, но содержимое тега передается при подтверждении и посылке формы. Это значение может быть использовано для передачи информации состояния при взаимодействии клиента и сервера;
· «image» - картинка, по которой вы можете сделать щелчок «мышью» или другим указывающим устройством, что приводит к немедленному подтверждению и отсылке формы. Координаты выбранной точки измеряются в пикселях от верхнего левого угла и возвращаются (наряду с другими компонентами формы);
· «text» - поле ввода текста, значение по умолчанию;
· «password» - поле ввода пароля; вводимые символы представляются как звездочки;
· «checkbox» - кнопка, принимающая положения on (включено) и off (выключено);
· «radio» - кнопка, принимающая положения on и off; причем остальные кнопки с тем же параметром NAME ведут себя по принципу «одна из многих»;
· «submit» - кнопка, действие которой сводится к отсылке содержимого заполненной формы на сервер запросов;
· «reset» - кнопка, которая устанавливает во всех интерфейсных элементах значения по умолчанию.
NAME - символическое имя (оно не показывается) для этого поля ввода. Это поле должно присутствовать для всех полей ввода кроме «submit»
и «reset», т. к. оно используется в строке запроса при идентификации поля ввода при посылке ее на сервер после подтверждения формы.
VALUE - для полей ввода текста или пароля, может быть использовано для задания начального содержания поля. Для checkbox или radio VALUE задает значение кнопки, когда она находится в отмеченном состоянии (неотмеченные кнопки опускаются при посылке запроса); значение по умолчанию для checkbox или radio - «on». Для типов «submit» и «reset» VALUE может быть использовано для задания надписи на этих кнопках.
CHECKED - значение не требуется. Указывает, что данная кнопка типа checkbox или radio отмечена по умолчанию. Это поле работает только для кнопок типа checkbox и radio.
SIZE - физический размер поля ввода в символах; это поле действует только для элементов ввода текста или пароля.
MAXLENGTH - максимальное количество введенных символов, которые будут приниматься для ввода, верно только для полей ввода текста и пароля (и только в однострочных элементах). По умолчанию - неограниченно. Подразумевается, что поля ввода должны прокручиваться.
1.2.2. Тег SELECT
Внутри <FORM >... </FORM> может присутствовать любое количество тегов SELECT, свободно перемешанных с другими HTML-элементами (включая INPUT и TEXTAREA) и текстом (но не дополнительных элементов FORM). Тег SELECT во многих графических клиентах представляется как меню или список.
В отличие от INPUT, SELECT имеет открывающий и закрывающий теги. Внутри оператора SELECT разрешена только последовательность тегов OPTION, за каждым из которых следует некоторое количество простого текста (без HTML-выражений), например:
<SELECT NAME="a-menu">
<OPTION> First option.
<OPTION> Second option.
</SELECT>.
Атрибуты оператора SELECT следующие:
NAME - символическое имя для этого SELECT-элемента. Это поле должно присутствовать, т. к. оно используется при посылке запроса (аналогично оператору INPUT).
SIZE - если SIZE равен 1 или если этот атрибут опущен, по умолчанию SELECT будет представлен как меню опций Motif. Если SIZE=2 или более, SELECT будет представлен как окно выбора; значение SIZE тогда будет определять, сколько элементов списка будут видны.
MULTIPLE - если присутствует, то задает, что SELECT должен позволять множественный выбор из списка. Наличие MULTIPLE принуждает SELECT быть представленным как список выбора, вне зависимости от значения SIZE.
Атрибутом OPTION является SELECTED, который задает, что эта опция выбрана по умолчанию. Если SELECT позволяет множественный выбор (с помощью атрибута MULTIPLE), то может быть помечено несколько опций.
1.2.3. Тег TEXTAREA
Тег TEXTAREA может быть использован для расположения многострокового поля ввода с необязательным содержимым по умолчанию в форме. Атрибуты тега TEXTAREA следующие:
NAME - символическое имя поля ввода;
ROWS - число строк в поле ввода (высота);
COLS - число столбцов в поле ввода (ширина).
TEXTAREA имеет полосы прокрутки, так что может быть введено любое количество текста. Элемент TEXTAREA требует и открывающий и закрывающий теги. TEXTAREA без содержания по умолчанию выглядит примерно так:
<TEXTAREA NAME-"foo" ROWS=4 COLS=40>
</ТЕХТАREА>
TEXTAREA с содержанием по умолчанию выглядит так:
<TEXTAREA NAME=”foo" ROWS=4 COLS=40>
Default contents go here.
</TЕХТАREА>.
Содержание по умолчанию должно быть строгим ASCII-текстом. Символы перевода строки воспринимаются (в примере до и после текста «Default contents go here» будет пустая Строка).
13. Подтверждение и посылка запроса CGI-программе
Для метода GET
Когда нажимается кнопка submit, содержимое формы будет добавлено к URL в следующей форме: action?name=value&name=value&name=value, где «action» - URL, заданное атрибутом ACTION в теге FORM, или URL текущего документа, если атрибут ACTION не был задан.
Для полей ввода текста и пароля значением будет то, что введет пользователь. Если пользователь оставит это поле пустым, значение value также будет пустым, но в строке запроса будет присутствовать фрагмент «name=».
Для кнопок типа checkbox и radio значение value определяется атрибутом VALUE в том случае, когда кнопка отмечена. Неотмеченные кнопки при составлении строки запроса игнорируются целиком. Несколько кнопок типа checkbox могут иметь один атрибут NAME (и различные VALUE), если это необходимо. Кнопки типа radio предназначены для того, чтобы вести себя по принципу «одна из всех» и должны иметь одинаковый атрибут NAME и различные атрибуты VALUE.
Для метода POST
Содержимое формы кодируется точно как для метода GET, но вместо добавления содержимого формы к URL, заданной атрибутом формы ACTION в качестве запроса, содержимое посылается блоком данных как часть операции POST. Если присутствует атрибут ACTION, то значение URL, которое там находится, определяет, куда послать этот блок данных. Этот метод особенно рекомендуется при посылке больших блоков данных
1.4. CGI-переменные окружения
Следующие переменные окружения CGI-программ устанавливаются для всех запросов.
SERVER_SOFTWARE - название и версия информационного сервера, который отвечает на запрос (и запускает шлюз). Формат: имя/версия.
SERVER_NAME - имя хоста, на котором запущен сервер; DNS-имя или IP-адрес в том виде, в котором он представлен в URL.
GATEWAY_INTERFACE - версия CGI-спецификации на тот момент, когда компилировался сервер. Формат: CGI/версия.
Следующие переменные окружения являются специфичными для разных запросов и заполняются Web-сервером перед вызовом CGI-программы:
SERVER_PROTOCOL - имя и версия информационного протокола, в котором пришел запрос. Формат: протокол/версия;
SERVER_PORT - номер порта, на который был послан запрос;
REQUEST_METHOD - метод, который был использован для запроса. Для HTTP - это «GET», «HEAD», «POST» и т.д.;
PATH_INFO - дополнительная информация о пути, которую передал клиент. Другими словами, доступ к шлюзу может быть осуществлен по виртуальному пути, за которым следует некоторая дополнительная информация. Эта информация передается в PATH_INFO;
PATH_TRANSLATED - сервер передает преобразованную версию PATH_INFO, которая включает путь, преобразованный из виртуального в физический;
SCRIPT_NAME - виртуальный путь к CGI-программе, которая должна выполняться (содержится в URL);
QUERY_STRING - информация, следующая за «?» в URL, к которое относится данная CGI-программа. Это информации представляет собой строку запроса. Она не должна быть декодирована никоим образом. Вне зависимости от командной строки эта переменная всегда должна быть установлена при наличии такой информации;
REMOTE_HOST - имя хоста, производящего запрос. Если сервер не имеет такой информации, он должен установить REMOTE_ADDR, а это поле оставить не установленным:
REMOTE_ADDR - IP-адрес хоста, производящего запрос;
AUTH_TYPE - если сервер поддерживает идентификацию пользователя и шлюз является защищенным от постороннего доступа, этот специфичный для протокола метод идентификации используется для проверки пользователя;
REMOTE_USER - используется в ситуациях, аналогичных предыдущему случаю, для хранения имени пользователя;
REMOTE_IDENT - если HTTP-сервер поддерживает идентификацию пользователя согласно RFC 931, то эта переменная будет содержать имя пользователя, полученное от сервера;
CONTENT_TYPE - для запросов, которые содержат дополнительную добавочную информацию, такие, как HTTP POST и PUT, здесь содержится тип данных этой информации;
CONTENT_LENGTH -длина данных, которую передает клиент.
2. ЗАДАНИЕ ПО ПРАКТИЧЕСКОМУ ЗАНЯТИЮ
2.1. Создание простейшего серверного приложения
Разработайте консольное приложение. Для этого выполните следующие действия.
1) Выберите в главном меню Delphi команду File / New, затем выберите в открывшемся окне хранилища объектов значок Console Application и щелкните на кнопке ОК.
ПРИМЕЧАНИЕ. Если в окне хранилища объектов отсутствует значок Console Application, то выберите значок Application, в главном меню Delphi выберите команду View / Units и откройте файл проекта. Затем создайте шаблон консольного приложения, которой имеет следующий вид:
program Project 1;
{@APPTYPE CONSOLE}
uses
SysUtils:
Begin
// Здесь будет располагаться CGI-программа
end.
2) Введите следующий текст CGI-программы (вместо комментария):
// Заголовок ответа
Writeln('Content-Type:text/html');
//Пустая строка, которая отделяет заголовок от тела ответа
Writeln;
Writeln('<HTML>');
Writeln('<HEAD>');
Writeln('<TITLE-> Пример СGI-приложения-</TITLЕ>');
Writeln(‘</HEAD>');
Writeln('<BODY>');
Wrileln('<H2 ALIGN=CENTER> Hello, World! </H2>');
Writeln('</BODY>');
Writeln('</HTML');.
3) Откомпилируйте полученное приложение и запишите полученный исполняемый файл в каталог Web-сервера, предназначенный для размещения исполняемых файлов и сценариев.
4) Для полученного приложения необходимо создать HTML-документ, из которого будет производиться вызов CGI-приложения. Так как в данном случае не требуется получать какие-либо данные от пользователя, то можно использовать вызов приложения с помощью тега «FORM» и как обычную ссылку (тег «А HREF=...»). Создайте следующий HTML-документ:
<HTML>
<HEAD>
<TITLE> Пример СGI-приложения</ТIТLЕ>
</HEAD>
<BODY>
<Н2> Работа с тегом Form. Метод GET </Н2>
<FORM METHOD="GET" ACT1ON=http://myself/temp/hello.exe>
<INPUT TYPE="SUBMIT">
</FORM>
<HR>
<BR>
<A HREF="http://myself/temp/hello.exe">
Вызов приложения с помощью тега "A HREF"
</А>
</BODY>
</HTML>.
5) Запустите созданный HTML-документ с помощью Internet Explorer (IE). В окне IE отобразится документ, содержаний одну кнопку и одну ссылку (рис. 2). При щелчке на любом из этих элементов в окне IE отобразится документ, соответствующий ответу запущенного CGI-сценария (рис. 3).
Рис. 2
Рис. 3
2.2. Передача CGI-приложению параметров, введенных пользователем, и получение дополнительной информации из переменных окружения
Создайте консольное приложение, результатом работы которого будет вывод используемого метода и передаваемой строки параметров.
1) Запишите в файл проекта следующий программный код:
program param;
{@APPTYPE CONSOLE}
uses
SysUtils,
Windows;
Var
buff: PChar;
ContentLength, i: Integer;
St1,St2: String;
C: Char;
Begin
// Выделение памяти под строку параметров
GetMem(buff,50);
// Получение строки параметров
GetEnvironmentVariable('REQUEST_METHOD', buff, 50):
//Преобразование строки PChar в паскалевскую строку
St1:= StrPas(buff);
// Освобождение памяти
Freemem(buff);
i:=length(St1);
While i>0 do
begin
St1[i]:=Upcase(St1[i]);
dec(i);
end;
If St1='GET’ then
begin
GetMem(buff, 200);
GetEnvironmentVariable(‘QUERY_STRING', buff 200);
St2:=StrPas(buff);
Freemem(buff);
end;
If St1=’POST’ then
begin
GetMem(buff, 50);
GetEnvironmentVariable('CONTENT_LENGTH', buff 50);
St2:= StrPas(buff);
Freemem(buff);
ContentLength:= StrToInt(St2);
St2:=";
For i:=1 to ContentLength do
begin
Read(C);
St2:= St2+C;
end;
end;
St1:='Method'+St1;
St1:= '<H2 ALIGN=CENTER>'+St1+’</H2>';
Writeln('Content-Type: text/html');
Writeln;
Writeln('<HTML>');
Writeln('<HEAD>');
Writeln('<TITLE> Пример CGI-приложения </ТIТLЕ>');
Writeln(‘<</HEAD>');
Writeln('<BODY>');
Writeln('<H2 ALIGN=CENTER>METHOD’+St1+'</H2>');
Writeln('<BR>');
Writeln('<H2 ALIGN=CENTER>PARAMETRS:'+St2+'</H2>');
Writeln('</BODY>');
Writeln(‘</HTML>');
end.
2) Откомпилируйте полученное приложение и запишите полученный исполняемый файл в каталог Web-сервера, предназначенный для размещения исполняемых файлов и сценариев.
3) Для проверки работоспособности полученного приложения необходимо создать следующий HTML-документ:
<HTML>
<HEAD>
<TITLE> Пример СGI-приложения</Т1ТLЕ>
</HEAD>
<BODY>
<Н2> Метод GET </H2>
<FORM METHOD="GET"
ACTION= http://myself/temp/param.exe >
<INPUT TYPE="TEXT" NAME="Edit1" VALUE="test">
<BR><BR>
<INPUT TYPE="SUBMIT">
</FORM>
<HR>
<BR> <BR>
<H2> Метод POST </H2>
<FORM METHOD="POST”
ACTION="http://myself/temp/param.exe">
<INPUT TYPE="TEXT" NAME="Edit1" VALUE="test">
<BR><BR>
<INPUT TYPE="SUBMIT">
</FORM>
<BODY>
<HTML>.
4) Запустите созданный HTML-документ с помощью IE. В окне IE отобразится документ, изображенный на рис. 4. При выборе метода GET
отобразится документ, изображенный на рис. 5, при выборе метода POST отобразится документ, изображенный на рис. 6.
Рис. 4 Рис. 5
Рис. 6
5) Измените программный код приложения таким образом, чтобы CGI-программа выводила на экран переменные окружения, указанные в табл. 1,
Таблица 1
Переменные окружения
Название | Описание |
REQUEST_METHOD | Метод передачи информации от пользователя (GET или POST) |
SERVER_NAME | IР-адрес или имя сервера |
SERVER_PORT | Номер порта, используемый при обращении к серверу |
SERVER_PROTOCOL | Название и версия протокола, по которому был передан запрос |
PATH_INFO | Строка параметров, расположенная в запросе после имени приложения |
REMOTE_ADDR | IP-адрес узла, с которого был послан запрос |
REMOTE_HOST | Доменное имя узла, с которого поступил запрос |
2.3. Разработайте CGI-приложение, которое проверяет результат умножения
1) Создайте HTML-документ, с помощью которого пользователь вводит число, которое, по его мнению, должно получиться в результате умножения 2x2. При нажатии на кнопку «SUBMIT» результат передается CGI-приложению.
2) CGI-приложение сравнивает полученное число с эталонным значением и возвращает результат пользователю.
ЛИТЕРАТУРА
1. Дарахвелидзе П. Г., Марков Е. П. Разработка Web-служб средствами Delphi. СПб., БXB-Петербург, 2003.672 с.
2. Киммел П. Создание приложений в Delphi /Пер. с англ. М., Издательский дом «Вильямс», 2003. 640 с.
3. Петров В. Н. Информационные системы. СПб., Питер, 2002.688 с.
КОНТРОЛЬНЫЕ ВОПРОСЫ
1. Назовите основные элементы тега FORM.
2. Чем отличаются методы GET и POST?
3. Перечислите особенности CGI-приложений.
4. Какие Вы знаете переменные окружения CGI-программ?
ЗАНЯТИЕ № 22
РАЗРАБОТКА WEB-ПРИЛОЖЕНИЯ
Цель работы: практически освоить специальные средства Delphi для разработки Web-приложений.
В теоретическом введении рассматриваются следующие вопросы.
• Общее описание компонента TWEBMODULE.
• Параметр REQUEST.
• Параметр RESPONSE.
• События TWEBMODULE.
1. ТЕОРЕТИЧЕСКОЕ ВВЕДЕНИЕ
1.1. Общее описание компонента TWEBMODULE
Компонент TWebModule является основой любых Web-приложений, разрабатываемых в Delphi. С помощью этого компонента приложение осуществляет интерпретацию HTTP-запросов.
Основное свойство компонента TWebModule - свойство Action, которое содержит список действий, являющихся обработчиками запросов, поступающих от клиентов.
Каждый элемент этого списка имеет тип TWebActionItem и характеризуется следующими свойствами.
• PathInfo: String - указывает, при какой строке параметров (расположенной в запросе после имени программы, но до данных запроса) будет вызываться данное действие.
• MethodType: TMethodType - указывает метод, используемый клиентом, для передачи запроса, на который данное действие может ответить. Возможны следующие значения: mtGet, mtPost, mtHead, mtPut, mtAny.
• Default: Boolean - используется для задания обработчика по умолчанию. Если это свойство установлено равным true, то действие будет обрабатывать запросы со строками параметров, для которых не заданы обработчики.
• Enabled: Boolean - указывает, может (true) или нет (false) данное действие обработать НТTР-запрос с параметрами PathInfo и MethodType, соответствующими свойствам данного действия.
• Producer: TCustomContentProducer - указатель на специальный компонент, используемый для формирования ответа web-приложения. В данной работе не используется.
Каждый элемент списка Actions может обрабатывать всего одно событие OnActions. Обработчик события OnActions имеет следующий вид:
procedure TWebModule1.WebModule1 WebActionItem1 Action (Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);.
С помощью параметра Request передается запрос, полученный от клиента. Параметр Response используется для формирования ответа. Параметр Handled применяется в том случае, когда требуется указать, что запрос не обработан. Для этого параметру следует присвоить значение false.
1.2. Параметр REQUEST
Параметр Request является экземпляром класса TWebRequest - базового класса для передачи информации Web-приложениям. Основные свойства данного класса:
· Property Content: String - строка параметров, переданная с помощью метода POST. Фактически эта строка содержит тело HTTP-запроса, полученного от клиента;
· Property ContentFields: TStrings - «разобранная» строка параметров, переданная с помощью метода POST. Каждый элемент коллекции СontentFields представляет собой строку, соответствующую одному элементу управления, расположенному в теге FORM, и представляет собой имя управляющего элемента и его значение, разделенные знаком равенства;
· Property Query: String - строка параметров, переданная клиенту с помощью метода GET;
· Property QueryFields: TStrings - «разобранная» строка параметров. переданная с помощью метода GET;
· Property RemoteAddr: String - IP-адрес клиента, пославшего запрос;
· Property RemoteHost: String – доменное имя клиента, пославшего запрос;
· Property Method: String – метод, используемый для передачи данных
серверу.
1.3. Параметр RESPONSE
Параметр Response является экземпляр класса TWeb Response - базового класса, предназначенного для формирования ответа на HTTP-запрос. Основные свойства данного класса:
· Property ContentType: String тип данных, содержащих в теле ответа;
· Property ContentLength: Integer – число символов, содержащихся в теле ответа;
· Properly Content: String - содержимое тела ответа;
· Property ContentStream: TStream - определяет объект TStream, который будет передан клиенту. Данное свойство обычно используется для передачи клиенту бинарных файлов.
1.4. События TWEBMODULE
Для выполнения обработки запросов и изменения содержимого ответа можно использовать действия, задаваемые в свойстве Actions, а также события самого компонента TWebModule. В этом компоненте предусмотрена возможность обработки четырех событий: AfterDispatch, BeforeDispatch, OnCreate и OnDestroy.
Описание данных событий:
· AfterDispatch: THTTPMethodEvent - вызывается после того, как HTTP-ответ был успешно сформирован (в обработчике OnActions какого-либо действия из списка Actions), но еще не передан клиенту;
· BeforeDispatch: THTTPMethodEvent - вызывается перед тем, как диспетчер устанавливает соответствие HTTP-запроса с каким-либо действием. Может использоваться для предварительной обработки HTTP-запроса;
· OnCreate: TNotifyEvent - вызывается при создании экземпляра TWebModule. Данное событие обычно вызывается для инициализации переменных и, объектов, содержащихся в приложении. Например, сайт модуль содержит базу данных, в обработчике этого события можно выполнить подключение базы данных;
· OnDestroy: TNotifyEvent - вызывается перед уничтожением TWebModule. Обычно используется для освобождения объектов, созданных динамически. При использовании баз данных в обработчике данного события можно, например, разрывать соединение с базой данных.
2. ЗАДАНИЕ ПО ПРАКТИЧЕСКОМУ ЗАНЯТИЮ
2.1. Создание WEB-приложения с помощью компонента Delphi -WEBMODULE
Создайте Web-приложение, выполняющее проверку знаний таблицы умножения. Серверное приложение выполняет два действия:
· первое - анализирует ответ клиента;
· второе - создает основной документ HTML.
Для создания данного приложения выполните следующие действия.
Этап 1: создание нового Web -приложения.
1) Выберите в главном меню Delphi команду File / New, затем выберите е открывшемся окне диалога значок Web Server Application и щелкните на кнопке ОК.
2) В открывшемся окне диалога выберите необходимый тип приложения. В данном случае следует использовать вариант «CGI Stand-alone executable». В результате будет создано новое CGI-приложение, содержащее компонент TWebModule.
Этап 2: задание действий, выполняющих обработку запросов клиентов.
1) Выберите в инспекторе объектов компонент TWebModule и щелкните на кнопке с многоточием в поле ввода свойства Action этого компонента. При этом откроется окно редактора действий (рис. 1).
2) Создайте два новых действия. Для этого следует воспользоваться либо кнопками на панели инструментов редактора действий (кнопка Add New), либо командой Add контекстного меню редактора действий, которое открывается при щелчке правой кнопкой «мыши» в окне редактора действий.
Рис. 1
3) Запрограммируйте первое действие. Для этого в окне редактора действий (рис. 1) выберите первое действие. Установите свойство PahtInfo равным «/1». Это приведет к тому, что данное действие будет обрабатывать HTTP-запрос только в том случае, если при вызове CGI-программы после ее имени будет указана строка «/1», например: http://nts/tmp/mult.exe/l. Значение всех остальных параметров оставьте без изменения.
4) Задайте обработчик запроса первого действия. Для этого выберите в инспекторе объектов вкладку Events и дважды щелкните «мышью» в поле ввода события OnAction. Введите следующий программный код:
procedure TWebModule1.WebModule1 WebAclionItem1 Action(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
VAR
Num1, num2, result: integer;
begin
num1: StrToInt(Request.ContentFields.Values[‘num1']);
num2: StrToInt(Request.ContentFields.Values['num2']);
result:= num1*num2;
If Request.ContentFields.Values['resuIt']=IntToStr(result)
then Response.Content:=
'<b> Поздравляю!!! </b><p> Вы прекрасно знаете таблицу умножения!'
else Response.Content:=
'Вы немного забыли таблицу умножения <р>'+
'<a href="http://myself/temp/mult.exe">'+
'<р> Попробуйте еще раз </а></р>';
Handled:= True;
end;.
5) Запрограммируйте второе действие. Для второго действия свойство PathInfo оставьте пустым, а свойство Default установите равным True. Это означает, что по умолчанию будет вызываться данное действие. В обработчик OnAction второго действия запишите следующий программный код:
procedure TWebModule1.WebModule1 WebActionItem2Action(Sender:
TObject;
Request: TWebRequest; Response: TWebResponse: var Handled: Boolean);
Var
num1, num2: Word;
begin
Randomize;
Num1:= Random(8)+l;
num2:=Random(8)+1;
Response.Content:='<html><head> <Title>Таблица умножения'+
'</title></head><body>'+
‘<h1 >Проверьте свое знание таблицы умножения</h1>';
Response.Content:= Response.Content+
'Запишите в окне, чему равно произведение,‘+
'и нажмите кнопку "Ответ"';
Response.Content:= Response.Content+
‘<form method="POST” ‘+
'action="http://myself/temp/mult.exe/1 "<table>'+
'<table> <tr><td> <input type="text" name="num1" size=" 1"'+
!value='+IntToStr(num1)+ '></td><td> x'+
'<td> <input type="text" name="num2" size="1" value='+
IntToStr(num2)+'></td><td>='+
'<td> <input type="text" name="result" size="3"> </td>'+
'<td> <input type=”submit" name="post" value="Ответ">'+
'</td></tr><table></form>'+
‘<form method="POST"’+
'action="http://myself/temp/mult.exe">'+
'<p><input type="submit" value="Новые числа" ‘+
'name="New"></p></form></body></html>';
Handled:=True;
end;.
6) В результате вызова второго действия (действия по умолчанию) на экране появится HTML-страница, изображенная на рис. 2.
7) При нажатии на кнопку «Ответ» активизируется второе действие. Если пользователь ответил на вопрос правильно, на экране появится HTML-страница, изображенная на рис. 3, если - неправильно, то HTML-cграница, изображенная на рис. 4.
Этап 3: компиляция и выполнение приложения
1) Откомпилируйте приложение и запишите его в каталог Web-сервера, допускающий выполнение приложений.
2) Запустите Internet Explorer и в поле «Адрес» укажите URL данного приложение в виде: http://nts/tmp/mult.exe. Так как после имени программы не указано действие, то будет выполняться действие по умолчанию, а именно действие два.
ПРИМЕЧАНИЕ
При повторном открытии созданного приложения компонент TWebModule автоматически не загружается. Для его открытия надо выполнить пункт главного меню File / Open и в открывшемся диалоговом не выбрать созданный вами для этого приложения файл с расширением *.pas.
Рис. 2
|
Рис. 4
ЛИТЕРАТУРА
1. Дарахвелидзе П. Г., Марков Е. П. Разработка Web-служб средствами Delphi. СПб., БХВ-Петербург, 2003. 672 с.
2. Киммел П. Создание приложений в Delphi /Пер. с англ. М., Издательский дом «Вильямс», 2003. 640 с.
3. Петров В. Н. Информационные системы. СПб. Питер, 2002. 688 с.
КОНТРОЛЬНЫЕ ВОПРОСЫ
1. Назовите основные свойства компонента TWebModule.
2. Как получить доступ к полученным данным с помощью компонента TWebModule?
3. Как передать данные с помощью компонента TWebModule?
4. Как задать действие по умолчанию?