Ignore:
Timestamp:
Dec 17, 2009, 8:25:15 AM (15 years ago)
Author:
george
Message:
  • Přidáno: Zobrazení ServerInfo.
  • Přidáno: Zpracování HTTP Cookies.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/DirectWeb/UHTTPServer.pas

    r85 r86  
    66
    77uses
    8   Classes, SysUtils, UTCPServer, UCommon, UMemoryStreamEx, UMIMEType;
     8  Classes, SysUtils, UTCPServer, UCommon, UMemoryStreamEx, UMIMEType,
     9  Synautil;
    910
    1011type
    1112
    12   { TQueryString }
    13 
    14   TQueryString = class(TStringList)
    15     procedure Parse(QueryString: string);
     13  TQueryParameterList = class(TStringList)
     14    procedure Parse(Text: string);
    1615    function Syntetize: string;
    1716  end;
    1817
     18  { TCookieList }
     19
     20  TCookieList = class(TStringList)
     21    procedure Parse(Text: string);
     22    function Syntetize: string;
     23  end;
     24
    1925  { THTTPRequest }
    2026
    2127  THTTPRequest = class
    22     Query: TQueryString;
     28    Query: TQueryParameterList;
    2329    Path: string;
    2430    Host: string;
    2531    Method: string;
     32    Headers: TStringList;
     33    Cookies: TCookieList;
    2634    constructor Create;
    2735    destructor Destroy; override;
     
    3442    Stream: TMemoryStreamEx;
    3543    Headers: TStringList;
     44    Cookies: TCookieList;
    3645    constructor Create;
    3746    destructor Destroy; override;
     
    7887  RequestHandler: TRequestHandler;
    7988  Line: string;
     89  LineIndex: Integer;
    8090  LineParts: array of string;
    8191  Request: THTTPRequest;
     
    90100    Response.Headers.Values['Server'] := Name;
    91101    Request := THTTPRequest.Create;
     102    LineIndex := 0;
    92103    repeat
    93104      Line := RecvString(10000);
    94105      LineParts := Explode(' ', Line);
    95       if Length(LineParts) > 0 then begin
    96         if (LineParts[0] = 'GET') or (LineParts[0] = 'HEAD') or
    97         (LineParts[0] = 'POST') then begin
    98           if Pos('?', LineParts[1]) > 0 then begin
    99             Request.Path := Copy(LineParts[1], 1, Pos('?', LineParts[1]) - 1);
    100             Request.Query.Parse(Copy(LineParts[1], Pos('?', LineParts[1]) + 1, Length(LineParts[1])));
    101           end else Request.Path := LineParts[1];
    102           Request.Method := LineParts[0];
    103         end else
    104         if LineParts[0] = 'Host:' then Request.Host := LineParts[1];
     106      if (LineIndex = 0) and (Length(LineParts) >= 3) then begin
     107        Request.Method := LineParts[0];
     108        if Pos('?', LineParts[1]) > 0 then begin
     109          Request.Path := Copy(LineParts[1], 1, Pos('?', LineParts[1]) - 1);
     110          Request.Query.Parse(Copy(LineParts[1], Pos('?', LineParts[1]) + 1, Length(LineParts[1])));
     111        end else Request.Path := LineParts[1];
     112      end else
     113      if (Length(LineParts) >= 2) and (LineParts[0][Length(LineParts[0])] = ':') then begin
     114        LineParts[0] := Copy(LineParts[0], 1, Length(LineParts[0]) - 1);
     115        Request.Headers.Values[LineParts[0]] := LineParts[1];
    105116      end;
     117      Inc(LineIndex);
    106118    until Line = '';
    107119
     120    // Parse cookies
     121    if Request.Cookies.IndexOfName('Cookie') <> -1 then
     122    Request.Cookies.Parse(Request.Headers.Values['Cookie']);
     123
    108124    Response.Stream.Clear;
     125    Response.Headers.Values['Content-Type'] := 'text/html';
     126
    109127    WriteLn('Requested path: ' + Request.Path);
    110128    RequestHandler := RequestHandlerList.IndexOfName(Request.Path);
     
    115133    with Response do begin
    116134      SendString('HTTP/1.0 200 OK'#13#10);
    117       SendString('Content-Length: ' + IntToStr(Stream.Size) + #13#10);
    118       SendString('Connection: close'#13#10);
    119       //SendString('Date: ' + RFC822DateTime(Now) + #13#10);
    120       // Send additional headers
     135      Headers.Values['Content-Length'] := IntToStr(Stream.Size);
     136      Headers.Values['Connection'] := 'close';
     137      Headers.Values['Date'] := RFC822DateTime(Now);
     138
     139      // Handle cookies
     140      for I := 0 to Cookies.Count - 1 do
     141        Headers.Values['Set-Cookie'] := Cookies.Names[I] + '=' + Cookies.ValueFromIndex[I];
     142        // + ';path=/;expires=' + RFC822DateTime(Now);
     143
     144      // Send headers
    121145      for I := 0 to Headers.Count - 1 do
    122146        SendString(Headers.Names[I] + ': ' + Headers.ValueFromIndex[I] + #13#10);
     
    180204begin
    181205  Stream := TMemoryStreamEx.Create;
     206  Cookies := TCookieList.Create;
    182207  Headers := TStringList.Create;
    183   Headers.Values['Content-Type'] := 'text/html';
    184208end;
    185209
     
    214238constructor THTTPRequest.Create;
    215239begin
    216   Query := TQueryString.Create;
     240  Query := TQueryParameterList.Create;
     241  Headers := TStringList.Create;
     242  Cookies := TCookieList.Create;
    217243end;
    218244
     
    220246begin
    221247  Query.Destroy;
     248  Headers.Destroy;
    222249  inherited Destroy;
    223250end;
    224251
    225 { TQueryString }
    226 
    227 procedure TQueryString.Parse(QueryString: string);
     252{ TQueryParameterList }
     253
     254procedure TQueryParameterList.Parse(Text: string);
    228255var
    229256  I: Integer;
     
    231258  Pair: TArrayOfString;
    232259begin
    233   Parts := Explode('&', QueryString);
     260  Clear;
     261  Parts := Explode('&', Text);
    234262  for I := 0 to Length(Parts) - 1 do begin
    235263    Pair := Explode('=', Parts[I]);
    236     Values[Pair[0]] := Pair[1];
    237   end;
    238 end;
    239 
    240 function TQueryString.Syntetize: string;
     264    if Length(Pair) >= 2 then
     265      Values[Pair[0]] := Pair[1];
     266  end;
     267end;
     268
     269function TQueryParameterList.Syntetize: string;
    241270var
    242271  I: Integer;
     
    246275    Result := Result + '&amp;' + Names[I] + '=' + ValueFromIndex[I];
    247276  Result := Copy(Result, 6, Length(Result));
    248 
     277end;
     278
     279{ TCookieList }
     280
     281procedure TCookieList.Parse(Text: string);
     282var
     283  I: Integer;
     284  Parts: TArrayOfString;
     285  Pair: TArrayOfString;
     286begin
     287  Clear;
     288  Parts := Explode(';', Text);
     289  for I := 0 to Length(Parts) - 1 do begin
     290    Pair := Explode('=', Parts[I]);
     291    if Length(Pair) >= 2 then
     292      Values[Trim(Pair[0])] := Trim(Pair[1]);
     293  end;
     294end;
     295
     296function TCookieList.Syntetize: string;
     297var
     298  I: Integer;
     299begin
     300  Result := '';
     301  for I := 0 to Count - 1 do
     302    Result := Result + '; ' + Names[I] + '=' + ValueFromIndex[I];
     303  Result := Copy(Result, 2, Length(Result));
    249304end;
    250305
Note: See TracChangeset for help on using the changeset viewer.