"Интернет решения от доктора Боба" - читать интересную книгу автора (Swart Bob)

2.2.4. Анализ

Среди переменных среды есть переменная с именем REQUEST_METHOD. Она должна иметь значение POST для нашего примера (Я не люблю другие методы). Затем мы должны найти размер информации, которая передана нам. Для этого мы должны получить переменную CONTENT_LENGTH. Сама информация поступает к нам через стандартный ввод (без маркера конца файла, поэтому наша задача не пытаться читать больше, чем нам передано). Данные поступающие через стандартный ввод имеют следующую форму FIELD=VALUE и разделяется с помощью символа 'amp;'. Например: AUTHOR="Bob_Swart"amp;. Поскольку мы имеем весь входной поток, как одну длинную строку, то мы можем быстро найти параметр 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] lt;gt; 'amp;' 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('lt;HTMLgt;');

   writeln('lt;BODYgt;');

   writeln('lt;Igt;Generated by Dr.Bob''s CGI-Expert on lt;/Igt;',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] := 'amp;';

       { now call Value or ValueAsInteger to obtain individual values }

     end;

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