Динамический 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&password=ps
Скрипту эта строка передается в виде переменной среды окружения QUERY_STRING. Эта переменная представляет собой строку, содержащую пары значений имя=значение, отделенные друг от друга символом &. В нашем случае это будет строка вида:
USERID=user1&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('&',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 обязательна!
Оставить комментарий
Вы должны войти, чтобы оставить комментарий.