Интернет-решения от доктора Боба

       

Анализ


Среди переменных среды есть переменная с именем REQUEST_METHOD. Она должна иметь значение POST для нашего примера (Я не люблю другие методы). Затем мы должны найти размер информации, которая передана нам. Для этого мы должны получить переменную CONTENT_LENGTH. Сама информация поступает к нам через стандартный ввод (без маркера конца файла, поэтому наша задача не пытаться читать больше, чем нам передано). Данные поступающие через стандартный ввод имеют следующую форму FIELD=VALUE и разделяется с помощью символа '&'. Например: AUTHOR="Bob_Swart"&. Поскольку мы имеем весь входной поток, как одну длинную строку, то мы можем быстро найти параметр AUTHOR с помощью следующей функции:

 var

   Data: String;

   function Value(Const Field: ShortString): ShortString;

   var i: Integer;

   begin

     Result := '';

     i := Pos(Field+'=',Data);

     if i = 0 then

     begin

       Inc(i,Length(Field)+1);

       while Data[i] <> '&' do

       begin

         Result := Result + Data[i];

         Inc(i)

       end



     end

   end {Value};

Следующий шаблон кода показывает как динамически создать переменную TBDosEnvironment, прочитать информацию со стандартного ввода и получить строку готовую для анализа переменных формы.

 {$APPTYPE CONSOLE}

 var

   Data: String;

   ContentLength,i,j: Integer;

 begin

   writeln('HTTP/1.0 200 OK');

   writeln('SERVER: Dr.Bob''s Intranet WebServer 1.0');

   writeln('CONTENT-TYPE: TEXT/HTML');

   writeln;

   writeln('<HTML>');

   writeln('<BODY>');

   writeln('<I>Generated by Dr.Bob''s CGI-Expert on </I>',DateTimeToStr(Now));

   with TBDosEnvironment.Create(nil) do

   begin

     for i := 0 to Pred(DosEnvCount) do

     begin

       if Pos('REQUEST_METHOD',DosEnvList[i])  0 then

       begin

         Data := DosEnvList[i];

         Delete(Data,1,Pos('=',Data))

       end

     end;

     if Data = 'POST' then

     begin

       ContentLength := StrToInt(GetDosEnvStr('CONTENT_LENGTH'));

       SetLength(Data,ContentLength+1);

       j := 0;

       for i:=1 to ContentLength do

       begin

         Inc(j);

         read(Data[j]);

       end;

       Data[j+1] := '&';

       { now call Value or ValueAsInteger to obtain individual values }

     end;

Заметим, что первые три "writeln" строки, посылаемые на стандартный вывод, необходимы для браузера, что бы сообщить ему, что содержимое страницы имеет тип TEXT/HTML.



Содержание раздела