Динамический CGI скрипт
Теперь мы можем переходить к более сложным случаям. В этой главе мы напишем CGI скрипт, при помощи которого можно наладить взаимодействие с клиентом. Пусть нам нужно запросить имя пользователя и его пароль и на основании введенного значения показать в браузере надпись "доступ разрешен" если имя пользователя "user1", а пароль "password", или "ошибка авторизации" в противном случае. Для начала нужно создать html документ, содержащий форму для нашего скрипта. Как Вы может быть знаете, что данные формы могут быть переданы от клиента на сервер двумя методами: методом Get и методом Post. В этой главе мы рассмотрим оба метода.

3.1 Передача параметров методом Get
В нашем случае, для метода Get html документ будет иметь вид:

< HTML>
< HEAD>
< TITLE>Log in< /TITLE>
< /HEAD>
< BODY>
< H1>CGI Testing Example< /H2>
< HR>
< H3>Log in< /H3>
< FORM ACTION="/cgi-bin/cgi.exe" METHOD="get">
UserId< BR>
< INPUT TYPE=text NAME="USERID">< BR>
Password< BR>
< INPUT TYPE=text NAME="PASSWORD">
< P>
< INPUT TYPE=submit VALUE="Log in">< INPUT TYPE=RESET VALUE="Clear">
< /FORM>
< HR>
< /BODY>
< /HTML>

Запишем этот текст в файл login.htm и поместим в корневую директорию www сервера. Теперь можно приступить к созданию CGI скрипта. Заметим, что при передаче серверу запроса по методу Get, строка запроса записывается после URL скрипта, отделяясь от него символом "?". Например:

    http://localhost/cgi-bin/cgi.exe?userid=us&#038;password=ps

Скрипту эта строка передается в виде переменной среды окружения QUERY_STRING. Эта переменная представляет собой строку, содержащую пары значений имя=значение, отделенные друг от друга символом &. В нашем случае это будет строка вида:

USERID=user1&#038;PASSWORD=password

Необходимо отметить, что некоторые символы, содержащиеся в значении поля, заменяются на % и следующим за ним шестнадцатиричным кодом символа, а пробел заменяется на +. Итак давайте воспользуемся предыдущим примером скрипта и вставим в модуль CGIUN следующий код:

// ******************************
// файл: CGIUN.pas
// ******************************
unit CGIUN;
interface
uses SysUtils, Windows;
procedure Main;
implementation
var InParams: string;
// Читаем переданные параметры из переменной окружения
procedure InitParams;
var SS: string;
begin
SetLength(SS,10000);
GetEnvironmentVariable('QUERY_STRING',@SS[1],2000);
InParams:=PChar(@SS[1]);
end;
// Функция переводит шестнадчитиричный символ в число
function HexToInt(CH: char): integer;
begin
Result:=0;
case CH of
'0'..'9': Result:=Ord(CH)-Ord('0');
'A'..'F': Result:=Ord(CH)-Ord('A')+10;
'a'..'f': Result:=Ord(CH)-Ord('a')+10;
end;
end;
// Преобразует символы, записанные в виде %2B к правильному виду
function Decode(Value: string): string;
var I, L: integer;
begin
Result:='';
L:=0;
for I:=1 to Length(Value) do begin
if(Value[I]<>'%') and (Value[I]<>'+') and (L< 1) then begin
Result:=Result+Value[I];
end else begin
if(Value[I]='+') then
Result:=Result+' '
else if(Value[I]='%') then begin
L:=2;
if(I< Length(Value)-1) then begin
Result:=Result+Chr(HexToInt(Value[I+1])*16+HexToInt(Value[I+2]));
end;
end else
Dec(L);
end;
end;
end;
// Возвращает значение параметра, заданного в Name
function ParamByName(Name: string): string;
var SS, ST: string;
K: integer;
begin
Result:='';
SS:=InParams;
while Length(SS)< >0 do begin
K:=Pos('&#038;',SS);
if(K<>0) then begin
ST:=Copy(SS,1,K-1);
SS:=Copy(SS,K+1,10000);
end else begin
ST:=SS;
SS:='';
end;
K:=Pos('=',ST);
if(K<>0) then begin
if(Name=Copy(ST,1,K-1)) then begin
Result:=Decode(Copy(ST,K+1,6000));
end;
end;
end;
end;
procedure Main;
var UserId, Password: string;
begin
InitParams;
UserId:=ParamByName('USERID');
Password:=ParamByName('PASSWORD');
WriteLn('Content-Type: text/html');
WriteLn;
WriteLn('< html>');
WriteLn('< head>');
if(UserId='user1') and (Password='password') then begin
WriteLn('< title>СGI скрипт: доступ разрешен< /title>');
WriteLn('< /head>');
WriteLn('< body>');
WriteLn;
WriteLn('< h1>доступ разрешен< /h1>');
end else begin
WriteLn('< title>СGI скрипт: ошибка авторизации< /title>');
WriteLn('< /head>');
WriteLn('< body>');
WriteLn;
WriteLn('< h1>ошибка авторизации< /h1>');
end;
WriteLn(' UserID: < b>'+UserId+'< /b>');
WriteLn(' Password: < b>'+Password+'< /b>');
WriteLn('< /body>');
WriteLn('< /html>');
end;
end.

Теперь откомпилируем полученный проект и перепишем файл CGI.exe в директорию www сервера со скриптами. Теперь можно проверить работоспособность.
3.2 Передача параметров методом Post
В методе Post параметры передаются через стандартный поток ввода консольной программы. Для реализации этого метода в файле Login.htm нужно заменить строку

        < FORM ACTION="/cgi-bin/cgi.exe" METHOD="get">     на строку

        < FORM ACTION="/cgi-bin/cgi.exe" METHOD="post"> 

Теперь в файле CGIUN.pas процедура InitParams будет выглядить следующим образом:

procedure InitParams; var STR: string;
StdIn, Size, Actual: cardinal; // если компилируется на Delphi 2 или 3
// то тип должен быть integer
begin
StdIn := GetStdHandle(STD_INPUT_HANDLE);
Size := SetFilePointer(StdIn, 0, nil, FILE_END);
SetFilePointer(StdIn, 0, nil, FILE_BEGIN);
SetLength(STR,Size+1);
if (Size < = 0) then Exit;
ReadFile(StdIn, STR[1], Size, Actual, nil);
STR[Size+1] := #0;
InParams:=PChar(@STR[1])
end;

Аналогично проверяем работоспособность скрипта. Результат аналогичный методу Get.

4. Возврат CGI скриптом ссылку на другой ресурс
Искушенный читатель может заметить, что все описанное выше конечно прекрастно, но нак быть, если необходимо вернуть ссылку на другой ресурс (например стариницу)? Для этого в технологии CGI предусмотрен следующий механизм: вместо вывода в стандартный поток html старины нужно выдать "Location:", а затем необходимый URL. Нужно не забыть, что после этой строки необходимо два раза перевести каретку. Например:

   WriteLn('Location: http://www.aport.ru/'+#10#13#10#13);    




Постоянные ссылки

При копировании ссылка на TeaM RSN обязательна!

URI

Html (ЖЖ)

BB-код (Для форумов)

Оставить комментарий

Вы должны войти, чтобы оставить комментарий.