Browse Source

* Replaced by fpAsync and net/http.pp

sg 23 years ago
parent
commit
6fbae3273f
2 changed files with 0 additions and 1160 deletions
  1. 0 523
      fcl/inc/asyncio.pp
  2. 0 637
      fcl/inc/http.pp

+ 0 - 523
fcl/inc/asyncio.pp

@@ -1,523 +0,0 @@
-{
-    $Id$
-
-    Async_IO: Mananging class for asynchronous input/output
-    Copyright (C) 2000 by Sebastian Guenther ([email protected])
-
-    See the file COPYING.FPC, included in this distribution,
-    for details about the copyright.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-}
-
-{$MODE objfpc}
-{$H+}
-
-unit AsyncIO;
-
-interface
-
-{$i asyncioh.inc}    
-
-type
-  TAsyncIOManager = class;
-
-  TAsyncIONotify = procedure(UserData: TObject) of object;
-
-  TAsyncIONotifyInfo = record
-    Method: TAsyncIONotify;
-    UserData: TObject;
-  end;
-
-// -------------------------------------------------------------------
-//   TAsyncIOManager
-// -------------------------------------------------------------------
-
-
-  TAsyncIOManager = class
-  protected
-    DoBreak: Boolean;
-    IOdata : TIOdata;
-    ReadNotifies, WriteNotifies: array[0..MaxHandle] of TAsyncIONotifyInfo;
-    HighestHandle: Integer;
-    FTimeout: Integer;
-    TimeoutNotify: TAsyncIONotifyInfo;
-    procedure CalcHighestHandle(max: Integer);
-    procedure ExecuteNotify(const Notify: TAsyncIONotifyInfo);
-    function GetHandleAsync(AHandle: Integer): Boolean;
-    procedure SetHandleAsync(AHandle: Integer; AValue: Boolean);
-  public
-    constructor Create;
-    procedure Run;
-    procedure BreakRun;
-    procedure SetReadHandler(AHandle: Integer; AMethod: TAsyncIONotify; AUserData: TObject);
-    procedure ClearReadHandler(AHandle: Integer);
-    function GetReadHandler(AHandle: Integer): TAsyncIONotify;
-    procedure SetWriteHandler(AHandle: Integer; AMethod: TAsyncIONotify; AUserData: TObject);
-    procedure ClearWriteHandler(AHandle: Integer);
-    function GetWriteHandler(AHandle: Integer): TAsyncIONotify;
-    procedure SetTimeoutHandler(AMethod: TAsyncIONotify; AUserData: TObject);
-    procedure ClearTimeoutHandler;
-    function GetTimeoutHandler: TAsyncIONotify;
-    property Timeout: Integer read FTimeout write FTimeout;
-    property HandleAsync[AHandle: Integer]: Boolean read GetHandleAsync write SetHandleAsync;
-  end;
-
-
-// -------------------------------------------------------------------
-//   Line reader classes
-// -------------------------------------------------------------------
-
-  TLineNotify = procedure(const line: String) of object;
-
-  PBoolean = ^Boolean;
-
-  TGenericLineReader = class
-  protected
-    FDestroyedFlag: PBoolean;
-    RealBuffer, FBuffer: PChar;
-    FBytesInBuffer: Integer;
-    FOnLine: TLineNotify;
-
-    function  Read(var ABuffer; count: Integer): Integer; virtual; abstract;
-    procedure NoData; virtual; abstract;
-
-  public
-    destructor Destroy; override;
-    procedure Run;		// Process as many lines as possible
-
-    property Buffer: PChar read FBuffer;
-    property BytesInBuffer: Integer read FBytesInBuffer;
-    property OnLine: TLineNotify read FOnLine write FOnLine;
-  end;
-
-
-  TAsyncStreamLineReader = class(TGenericLineReader)
-  protected
-    FManager: TAsyncIOManager;
-    FDataStream: TStream;
-    FBlockingStream: THandleStream;
-    FOnEOF: TNotifyEvent;
-
-    function  Read(var ABuffer; count: Integer): Integer; override;
-    procedure NoData; override;
-    procedure StreamDataAvailable(UserData: TObject);
-  public
-    constructor Create(AManager: TAsyncIOManager; AStream: THandleStream);
-    constructor Create(AManager: TAsyncIOManager;
-      ADataStream: TStream; ABlockingStream: THandleStream);
-    destructor Destroy; override;
-
-    property DataStream: TStream read FDataStream;
-    property BlockingStream: THandleStream read FBlockingStream;
-    property OnEOF: TNotifyEvent read FOnEOF write FOnEOF;
-  end;
-
-
-// -------------------------------------------------------------------
-//   TWriteBuffer
-// -------------------------------------------------------------------
-
-  TWriteBuffer = class(TStream)
-  protected
-    FBuffer: PChar;
-    FBytesInBuffer: Integer;
-    FOnBufferEmpty: TNotifyEvent;
-
-    function  Seek(Offset: LongInt; Origin: Word): LongInt; override;
-    function  Write(const ABuffer; Count: LongInt): LongInt; override;
-    function  DoRealWrite(const ABuffer; Count: Integer): Integer; virtual; abstract;
-    procedure WritingFailed; virtual; abstract;
-    procedure WantWrite; virtual; abstract;
-    procedure BufferEmpty; virtual;
-
-    constructor Create;
-
-  public
-    EndOfLineMarker: String;
-
-    destructor Destroy; override;
-    procedure WriteLine(const line: String);
-    procedure Run;		// Write as many data as possible
-
-    property BytesInBuffer: Integer read FBytesInBuffer;
-    property OnBufferEmpty: TNotifyEvent read FOnBufferEmpty write FOnBufferEmpty;
-  end;
-
-
-  TAsyncWriteStream = class(TWriteBuffer)
-  protected
-    FManager: TAsyncIOManager;
-    FDataStream: TStream;
-    FBlockingStream: THandleStream;
-
-    function  DoRealWrite(const ABuffer; Count: Integer): Integer; override;
-    procedure WritingFailed; override;
-    procedure WantWrite; override;
-    procedure BufferEmpty; override;
-    procedure CanWrite(UserData: TObject);
-  public
-    constructor Create(AManager: TAsyncIOManager; AStream: THandleStream);
-    constructor Create(AManager: TAsyncIOManager;
-      ADataStream: TStream; ABlockingStream: THandleStream);
-    destructor Destroy; override;
-
-    property DataStream: TStream read FDataStream;
-    property BlockingStream: THandleStream read FBlockingStream;
-  end;
-
-
-
-// ===================================================================
-// ===================================================================
-
-implementation
-
-uses SysUtils;
-
-{$i asyncio.inc}
-
-// -------------------------------------------------------------------
-//   TAsyncIOManager
-// -------------------------------------------------------------------
-
-procedure TAsyncIOManager.ExecuteNotify(const Notify: TAsyncIONotifyInfo);
-begin
-  if Assigned(Notify.Method) then
-    Notify.Method(Notify.UserData);
-end;
-
-procedure TAsyncIOManager.SetTimeoutHandler(AMethod: TAsyncIONotify; AUserData: TObject);
-begin
-  TimeoutNotify.Method := AMethod;
-  TimeoutNotify.UserData := AUserData;
-end;
-
-procedure TAsyncIOManager.ClearTimeoutHandler;
-begin
-  TimeoutNotify.Method := nil;
-end;
-
-function TAsyncIOManager.GetTimeoutHandler: TAsyncIONotify;
-begin
-  Result := TimeoutNotify.Method;
-end;
-
-
-// -------------------------------------------------------------------
-//   TGenericLineReader
-// -------------------------------------------------------------------
-
-destructor TGenericLineReader.Destroy;
-begin
-  if Assigned(FDestroyedFlag) then
-    FDestroyedFlag^ := True;
-  if Assigned(RealBuffer) then
-  begin
-    FreeMem(RealBuffer);
-    RealBuffer := nil;
-  end;
-  inherited Destroy;
-end;
-
-procedure TGenericLineReader.Run;
-var
-  NewData: array[0..1023] of Byte;
-  p: PChar;
-  BytesRead, OldBufSize, CurBytesInBuffer, LastEndOfLine, i, LineLength: Integer;
-  line: String;
-  FirstRun, DestroyedFlag: Boolean;
-begin
-  FirstRun := True;
-  DestroyedFlag := False;
-  while True do
-  begin
-    BytesRead := Read(NewData, SizeOf(NewData));
-    //WriteLn('Linereader: ', BytesRead, ' bytes read');
-    if BytesRead <= 0 then begin
-      if FirstRun then
-        NoData;
-      break;
-    end;
-    FirstRun := False;
-    OldBufSize := FBytesInBuffer;
-
-    // Append the new received data to the read buffer
-    Inc(FBytesInBuffer, BytesRead);
-    ReallocMem(RealBuffer, FBytesInBuffer);
-    Move(NewData, RealBuffer[OldBufSize], BytesRead);
-
-    {Process all potential lines in the current buffer. Attention: FBuffer and
-     FBytesInBuffer MUST be updated for each line, as they can be accessed from
-     within the FOnLine handler!}
-    LastEndOfLine := 0;
-    if OldBufSize > 0 then
-      i := OldBufSize - 1
-    else
-      i := 0;
-
-    CurBytesInBuffer := FBytesInBuffer;
-
-    while i <= CurBytesInBuffer - 1 do
-    begin
-      if (RealBuffer[i] = #13) or (RealBuffer[i] = #10) then
-      begin
-        LineLength := i - LastEndOfLine;
-	SetLength(line, LineLength);
-	if LineLength > 0 then
-	  Move(RealBuffer[LastEndOfLine], line[1], LineLength);
-
-	if (i < CurBytesInBuffer - 1) and (RealBuffer[i] = #13) and
-	  (RealBuffer[i + 1] = #10) then
-	  Inc(i);
-	LastEndOfLine := i + 1;
-
-	if Assigned(FOnLine) then
-	begin
-	  FBuffer := RealBuffer + LastEndOfLine;
-	  FBytesInBuffer := CurBytesInBuffer - LastEndOfLine;
-	  FDestroyedFlag := @DestroyedFlag;
-	  FOnLine(line);
-	  FDestroyedFlag := nil;
-	  if DestroyedFlag then
-	    exit;
-	end;
-      end;
-      Inc(i);
-    end;
-
-    FBytesInBuffer := CurBytesInBuffer;
-
-    if LastEndOfLine > 0 then
-    begin
-      // Remove all processed lines from the buffer
-      Dec(FBytesInBuffer, LastEndOfLine);
-      GetMem(p, FBytesInBuffer);
-      Move(RealBuffer[LastEndOfLine], p^, FBytesInBuffer);
-      FreeMem(RealBuffer);
-      RealBuffer := p;
-    end;
-    FBuffer := RealBuffer;
-  end;
-end;
-
-
-// -------------------------------------------------------------------
-//   TAsyncStreamLineReader
-// -------------------------------------------------------------------
-
-function TAsyncStreamLineReader.Read(var ABuffer; count: Integer): Integer;
-begin
-  Result := FDataStream.Read(ABuffer, count);
-end;
-
-procedure TAsyncStreamLineReader.NoData;
-var
-  s: String;
-begin
-  if (FDataStream = FBlockingStream) or (FDataStream.Position = FDataStream.Size) then
-  begin
-
-    if (FBytesInBuffer > 0) and Assigned(FOnLine) then
-    begin
-      if FBuffer[FBytesInBuffer - 1] in [#13, #10] then
-        Dec(FBytesInBuffer);
-      SetLength(s, FBytesInBuffer);
-      Move(FBuffer^, s[1], FBytesInBuffer);
-      FOnLine(s);
-    end;
-
-    FManager.ClearReadHandler(FBlockingStream.Handle);
-    if Assigned(FOnEOF) then
-      FOnEOF(Self);
-  end;
-end;
-
-procedure TAsyncStreamLineReader.StreamDataAvailable(UserData: TObject);
-begin
-  Run;
-end;
-
-constructor TAsyncStreamLineReader.Create(AManager: TAsyncIOManager; AStream: THandleStream);
-begin
-  Self.Create(AManager, AStream, AStream);
-end;
-
-constructor TAsyncStreamLineReader.Create(AManager: TAsyncIOManager;
-  ADataStream: TStream; ABlockingStream: THandleStream);
-begin
-  ASSERT(Assigned(ADataStream) and Assigned(ABlockingStream));
-
-  inherited Create;
-  FManager := AManager;
-  FDataStream := ADataStream;
-  FBlockingStream := ABlockingStream;
-  AManager.SetReadHandler(FBlockingStream.Handle, @StreamDataAvailable, nil);
-  AManager.HandleAsync[FBlockingStream.Handle] := True;
-end;
-
-destructor TAsyncStreamLineReader.Destroy;
-var
-  Handler: TMethod;
-begin
-  Handler := TMethod(FManager.GetReadHandler(FBlockingStream.Handle));
-  if (Handler.Code = Pointer(@StreamDataAvailable)) and
-    (Handler.Data = Pointer(Self)) then
-    FManager.ClearReadHandler(FBlockingStream.Handle);
-  inherited Destroy;
-end;
-
-
-// -------------------------------------------------------------------
-//   TWriteBuffer
-// -------------------------------------------------------------------
-
-procedure TWriteBuffer.BufferEmpty;
-begin
-  if Assigned(FOnBufferEmpty) then
-    FOnBufferEmpty(Self);
-end;
-
-constructor TWriteBuffer.Create;
-begin
-  inherited Create;
-
-  FBuffer := nil;
-  FBytesInBuffer := 0;
-  EndOfLineMarker := #10;
-end;
-
-destructor TWriteBuffer.Destroy;
-begin
-  if Assigned(FBuffer) then
-    FreeMem(FBuffer);
-  inherited Destroy;
-end;
-
-function TWriteBuffer.Seek(Offset: LongInt; Origin: Word): LongInt;
-begin
-  if ((Offset = 0) and ((Origin = soFromCurrent) or (Origin = soFromEnd))) or
-     ((Offset = FBytesInBuffer) and (Origin = soFromBeginning)) then
-    Result := FBytesInBuffer
-  else
-    raise EStreamError.Create('Invalid stream operation');
-end;
-
-function TWriteBuffer.Write(const ABuffer; Count: LongInt): LongInt;
-begin
-  ReallocMem(FBuffer, FBytesInBuffer + Count);
-  Move(ABuffer, FBuffer[FBytesInBuffer], Count);
-  Inc(FBytesInBuffer, Count);
-  WantWrite;
-  Result := Count;
-end;
-
-procedure TWriteBuffer.WriteLine(const line: String);
-var
-  s: String;
-begin
-  s := line + EndOfLineMarker;
-  WriteBuffer(s[1], Length(s));
-end;
-
-procedure TWriteBuffer.Run;
-var
-  CurStart, written: Integer;
-  NewBuf: PChar;
-  failed: Boolean;
-begin
-  CurStart := 0;
-  failed := True;
-  repeat
-    if FBytesInBuffer = 0 then begin
-      BufferEmpty;
-      exit;
-    end;
-
-    written := DoRealWrite(FBuffer[CurStart], FBytesInBuffer - CurStart);
-    if written > 0 then begin
-      Inc(CurStart, written);
-      failed := False;
-      GetMem(NewBuf, FBytesInBuffer - CurStart);
-      Move(FBuffer[CurStart], NewBuf[0], FBytesInBuffer - CurStart);
-      FreeMem(FBuffer);
-      FBuffer := NewBuf;
-      Dec(FBytesInBuffer, CurStart);
-    end;
-  until written <= 0;
-
-  if failed then
-    WritingFailed;
-end;
-
-
-// -------------------------------------------------------------------
-//   TAsyncWriteStream
-// -------------------------------------------------------------------
-
-function TAsyncWriteStream.DoRealWrite(const ABuffer; Count: Integer): Integer;
-begin
-  Result := FDataStream.Write(ABuffer, count);
-end;
-
-procedure TAsyncWriteStream.WritingFailed;
-begin
-  if FDataStream <> FBlockingStream then
-    FManager.ClearWriteHandler(FBlockingStream.Handle);
-end;
-
-procedure TAsyncWriteStream.WantWrite;
-begin
-  FManager.SetWriteHandler(FBlockingStream.Handle, @CanWrite, nil);
-end;
-
-procedure TAsyncWriteStream.BufferEmpty;
-begin
-  FManager.ClearWriteHandler(FBlockingStream.Handle);
-  inherited BufferEmpty;
-end;
-
-procedure TAsyncWriteStream.CanWrite(UserData: TObject);
-begin
-  Run;
-end;
-
-constructor TAsyncWriteStream.Create(AManager: TAsyncIOManager; AStream: THandleStream);
-begin
-  Self.Create(AManager, AStream, AStream);
-end;
-
-constructor TAsyncWriteStream.Create(AManager: TAsyncIOManager;
-  ADataStream: TStream; ABlockingStream: THandleStream);
-begin
-  ASSERT(Assigned(ADataStream) and Assigned(ABlockingStream));
-
-  inherited Create;
-  FManager := AManager;
-  FDataStream := ADataStream;
-  FBlockingStream := ABlockingStream;
-  AManager.HandleAsync[FBlockingStream.Handle] := True;
-end;
-
-destructor TAsyncWriteStream.Destroy;
-begin
-  FManager.ClearWriteHandler(FBlockingStream.Handle);
-  inherited Destroy;
-end;
-
-
-end.
-
-
-{
-  $Log$
-  Revision 1.3  2000-08-24 22:29:37  sg
-  * Line reader now reports a read line after a single #10 at the end of the
-    current input buffer
-
-  Revision 1.2  2000/07/13 11:32:58  michael
-  + removed logs
- 
-}

+ 0 - 637
fcl/inc/http.pp

@@ -1,637 +0,0 @@
-{
-    $Id$
-
-    HTTP: Classes for dealing with HTTP requests
-    Copyright (C) 2000 by Sebastian Guenther ([email protected])
-
-    See the file COPYING.FPC, included in this distribution,
-    for details about the copyright.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-}
-
-
-{$MODE objfpc}
-{$H+}
-
-unit HTTP;
-
-interface
-
-uses Classes, AsyncIO, SSockets;
-
-const
-
-  fieldAccept = 'Accept';
-  fieldAcceptCharset = 'Accept-Charset';
-  fieldAcceptEncoding = 'Accept-Encoding';
-  fieldAcceptLanguage = 'Accept-Language';
-  fieldAuthorization = 'Authorization';
-  fieldContentEncoding = 'Content-Encoding';
-  fieldContentLanguage = 'Content-Language';
-  fieldContentLength = 'Content-Length';
-  fieldContentType = 'Content-Type';
-  fieldCookie = 'Cookie';
-  fieldDate = 'Date';
-  fieldExpires = 'Expires';
-  fieldFrom = 'From';
-  fieldIfModifiedSince = 'If-Modified-Since';
-  fieldLastModified = 'Last-Modified';
-  fieldLocation = 'Location';
-  fieldPragma = 'Pragma';
-  fieldReferer = 'Referer';
-  fieldRetryAfter = 'Retry-After';
-  fieldServer = 'Server';
-  fieldSetCookie = 'Set-Cookie';
-  fieldUserAgent = 'User-Agent';
-  fieldWWWAuthenticate = 'WWW-Authenticate';
-
-type
-
-  PHttpField = ^THttpField;
-  THttpField = record
-    Name, Value: String;
-  end;
-
-
-  THttpHeader = class
-  protected
-    FReader: TAsyncStreamLineReader;
-    FWriter: TAsyncWriteStream;
-    FOnCompleted: TNotifyEvent;
-    FFields: TList;
-    CmdReceived: Boolean;
-
-    procedure ParseFirstHeaderLine(const line: String); virtual; abstract;
-    procedure LineReceived(const line: String);
-    function  GetFirstHeaderLine: String; virtual; abstract;
-    procedure WriterCompleted(ASender: TObject);
-
-    function  GetFieldCount: Integer;
-    function  GetFields(AIndex: Integer): String;
-    function  GetFieldNames(AIndex: Integer): String;
-    procedure SetFieldNames(AIndex: Integer; const AName: String);
-    function  GetFieldValues(AIndex: Integer): String;
-    procedure SetFieldValues(AIndex: Integer; const AValue: String);
-
-
-    function  GetAccept: String;
-    procedure SetAccept(const AValue: String);
-    function  GetAcceptCharset: String;
-    procedure SetAcceptCharset(const AValue: String);
-    function  GetAcceptEncoding: String;
-    procedure SetAcceptEncoding(const AValue: String);
-    function  GetAcceptLanguage: String;
-    procedure SetAcceptLanguage(const AValue: String);
-    function  GetAuthorization: String;
-    procedure SetAuthorization(const AValue: String);
-    function  GetContentEncoding: String;
-    procedure SetContentEncoding(const AValue: String);
-    function  GetContentLanguage: String;
-    procedure SetContentLanguage(const AValue: String);
-    function  GetContentLength: Integer;
-    procedure SetContentLength(AValue: Integer);
-    function  GetContentType: String;
-    procedure SetContentType(const AValue: String);
-    function  Get_Cookie: String;
-    procedure Set_Cookie(const AValue: String);
-    function  GetDate: String;
-    procedure SetDate(const AValue: String);
-    function  GetExpires: String;
-    procedure SetExpires(const AValue: String);
-    function  GetFrom: String;
-    procedure SetFrom(const AValue: String);
-    function  GetIfModifiedSince: String;
-    procedure SetIfModifiedSince(const AValue: String);
-    function  GetLastModified: String;
-    procedure SetLastModified(const AValue: String);
-    function  GetLocation: String;
-    procedure SetLocation(const AValue: String);
-    function  GetPragma: String;
-    procedure SetPragma(const AValue: String);
-    function  GetReferer: String;
-    procedure SetReferer(const AValue: String);
-    function  GetRetryAfter: String;
-    procedure SetRetryAfter(const AValue: String);
-    function  GetServer: String;
-    procedure SetServer(const AValue: String);
-    function  Get_SetCookie: String;
-    procedure Set_SetCookie(const AValue: String);
-    function  GetUserAgent: String;
-    procedure SetUserAgent(const AValue: String);
-    function  GetWWWAuthenticate: String;
-    procedure SetWWWAuthenticate(const AValue: String);
-
-  public
-    HttpVersion: String;
-
-    constructor Create;
-    destructor Destroy; override;
-    procedure SetFieldByName(const AName, AValue: String);
-    function  GetFieldByName(const AName: String): String;
-
-    procedure AsyncSend(AManager: TAsyncIOManager; AStream: THandleStream);
-    procedure AsyncReceive(AManager: TAsyncIOManager; AStream: THandleStream);
-
-    property Reader: TAsyncStreamLineReader read FReader;
-    property Writer: TAsyncWriteStream read FWriter;
-    property FieldCount: Integer read GetFieldCount;
-    property Fields[AIndex: Integer]: String read GetFields;
-    property FieldNames[AIndex: Integer]: String read GetFieldNames write SetFieldNames;
-    property FieldValues[AIndex: Integer]: String read GetFieldValues write SetFieldValues;
-
-    property OnCompleted: TNotifyEvent read FOnCompleted write FOnCompleted;
-
-    property Accept: String read GetAccept write SetAccept;
-    property AcceptCharset: String read GetAcceptCharset write SetAcceptCharset;
-    property AcceptEncoding: String read GetAcceptEncoding write SetAcceptEncoding;
-    property AcceptLanguage: String read GetAcceptLanguage write SetAcceptLanguage;
-    property Authorization: String read GetAuthorization write SetAuthorization;
-    property ContentEncoding: String read GetContentEncoding write SetContentEncoding;
-    property ContentLanguage: String read GetContentLanguage write SetContentLanguage;
-    property ContentLength: Integer read GetContentLength write SetContentLength;
-    property ContentType: String read GetContentType write SetContentType;
-    property Cookie: String read Get_Cookie write Set_Cookie;
-    property Date: String read GetDate write SetDate;
-    property Expires: String read GetExpires write SetExpires;
-    property From: String read GetFrom write SetFrom;
-    property IfModifiedSince: String read GetIfModifiedSince write SetIfModifiedSince;
-    property LastModified: String read GetLastModified write SetLastModified;
-    property Location: String read GetLocation write SetLocation;
-    property Pragma: String read GetPragma write SetPragma;
-    property Referer: String read GetReferer write SetReferer;
-    property RetryAfter: String read GetRetryAfter write SetRetryAfter;
-    property Server: String read GetServer write SetServer;
-    property SetCookie: String read Get_SetCookie write Set_SetCookie;
-    property UserAgent: String read GetUserAgent write SetUserAgent;
-    property WWWAuthenticate: String read GetWWWAuthenticate write SetWWWAuthenticate;
-  end;
-
-
-  THttpRequestHeader = class(THttpHeader)
-  protected
-    procedure ParseFirstHeaderLine(const line: String); override;
-    function  GetFirstHeaderLine: String; override;
-  public
-    CommandLine: String;
-    Command: String;
-    URI: String;		// Uniform Resource Identifier
-  end;
-
-
-  THttpAnswerHeader = class(THttpHeader)
-  protected
-    procedure ParseFirstHeaderLine(const line: String); override;
-    function  GetFirstHeaderLine: String; override;
-  public
-    Code: Integer;
-    CodeText: String;
-    constructor Create;
-  end;
-
-
-  TCustomHttpConnection = class
-  protected
-    FManager: TAsyncIOManager;
-    FSocket: TInetSocket;
-    SendBuffer: TAsyncWriteStream;
-    FOnHeaderSent, FOnStreamSent, FOnHeaderReceived, FOnStreamReceived: TNotifyEvent;
-    RecvSize: Integer;	// How many bytes are still to be read. -1 if unknown.
-
-    procedure HeaderToSendCompleted(Sender: TObject);
-    procedure StreamToSendCompleted(Sender: TObject);
-    procedure ReceivedHeaderCompleted(Sender: TObject);
-    procedure DataAvailable(Sender: TObject);
-    procedure ReceivedStreamCompleted(Sender: TObject);
-
-    property OnHeaderSent: TNotifyEvent read FOnHeaderSent write FOnHeaderSent;
-    property OnStreamSent: TNotifyEvent read FOnStreamSent write FOnStreamSent;
-    property OnHeaderReceived: TNotifyEvent read FOnHeaderReceived write FOnHeaderReceived;
-    property OnStreamReceived: TNotifyEvent read FOnStreamReceived write FOnStreamReceived;
-
-  public
-    HeaderToSend: THttpHeader;
-    StreamToSend: TStream;
-    ReceivedHeader: THttpHeader;
-    ReceivedStream: TStream;
-
-    constructor Create(AManager: TAsyncIOManager; ASocket: TInetSocket);
-    destructor Destroy; override;
-    procedure Start;
-  end;
-
-  THttpConnection = class(TCustomHttpConnection)
-  public
-    property OnHeaderSent;
-    property OnStreamSent;
-    property OnHeaderReceived;
-    property OnStreamReceived;
-  end;
-
-
-
-// ===================================================================
-// ===================================================================
-
-implementation
-
-uses SysUtils;
-
-
-// -------------------------------------------------------------------
-//   THttpHeader
-// -------------------------------------------------------------------
-
-procedure THttpHeader.LineReceived(const line: String);
-var
-  i: Integer;
-begin
-  if Length(line) = 0 then
-  begin
-    FReader.OnLine := nil;	// Stop receiving
-    if Assigned(FOnCompleted) then
-      FOnCompleted(Self);
-    FReader.Free;
-    FReader := nil;
-  end else
-    if not CmdReceived then
-    begin
-      CmdReceived := True;
-      ParseFirstHeaderLine(line);
-    end else
-    begin
-      i := Pos(':', line);
-      SetFieldByName(Trim(Copy(line, 1, i - 1)), Trim(Copy(line, i + 1, Length(line))));
-    end;
-end;
-
-procedure THttpHeader.WriterCompleted(ASender: TObject);
-begin
-  if Assigned(FOnCompleted) then
-    FOnCompleted(Self);
-end;
-
-function THttpHeader.GetFieldCount: Integer;
-begin
-  Result := FFields.Count;
-end;
-
-function THttpHeader.GetFields(AIndex: Integer): String;
-begin
-  Result := FieldNames[AIndex] + ': ' + FieldValues[AIndex];
-end;
-
-function THttpHeader.GetFieldNames(AIndex: Integer): String;
-begin
-  Result := PHttpField(FFields.Items[AIndex])^.Name;
-end;
-
-procedure THttpHeader.SetFieldNames(AIndex: Integer; const AName: String);
-begin
-  PHttpField(FFields.Items[AIndex])^.Name := AName;
-end;
-
-function THttpHeader.GetFieldValues(AIndex: Integer): String;
-begin
-  Result := PHttpField(FFields.Items[AIndex])^.Value;
-end;
-
-procedure THttpHeader.SetFieldValues(AIndex: Integer; const AValue: String);
-begin
-  PHttpField(FFields.Items[AIndex])^.Name := AValue;
-end;
-
-function  THttpHeader.GetAccept: String; begin Result := GetFieldByName(fieldAccept) end;
-procedure THttpHeader.SetAccept(const AValue: String); begin SetFieldByName(fieldAccept, AValue) end;
-function  THttpHeader.GetAcceptCharset: String; begin Result := GetFieldByName(fieldAcceptCharset) end;
-procedure THttpHeader.SetAcceptCharset(const AValue: String); begin SetFieldByName(fieldAcceptCharset, AValue) end;
-function  THttpHeader.GetAcceptEncoding: String; begin Result := GetFieldByName(fieldAcceptEncoding) end;
-procedure THttpHeader.SetAcceptEncoding(const AValue: String); begin SetFieldByName(fieldAcceptEncoding, AValue) end;
-function  THttpHeader.GetAcceptLanguage: String; begin Result := GetFieldByName(fieldAcceptLanguage) end;
-procedure THttpHeader.SetAcceptLanguage(const AValue: String); begin SetFieldByName(fieldAcceptLanguage, AValue) end;
-function  THttpHeader.GetAuthorization: String; begin Result := GetFieldByName(fieldAuthorization) end;
-procedure THttpHeader.SetAuthorization(const AValue: String); begin SetFieldByName(fieldAuthorization, AValue) end;
-function  THttpHeader.GetContentEncoding: String; begin Result := GetFieldByName(fieldContentEncoding) end;
-procedure THttpHeader.SetContentEncoding(const AValue: String); begin SetFieldByName(fieldContentEncoding, AValue) end;
-function  THttpHeader.GetContentLanguage: String; begin Result := GetFieldByName(fieldContentLanguage) end;
-procedure THttpHeader.SetContentLanguage(const AValue: String); begin SetFieldByName(fieldContentLanguage, AValue) end;
-function  THttpHeader.GetContentLength: Integer; var s: String; begin s := GetFieldByName(fieldContentLength); if Length(s) = 0 then Result := -1 else Result := StrToInt(s) end;
-procedure THttpHeader.SetContentLength(AValue: Integer); begin SetFieldByName(fieldContentLength, IntToStr(AValue)) end;
-function  THttpHeader.GetContentType: String; begin Result := GetFieldByName(fieldContentType) end;
-procedure THttpHeader.SetContentType(const AValue: String); begin SetFieldByName(fieldContentType, AValue) end;
-function  THttpHeader.Get_Cookie: String; begin Result := GetFieldByName(fieldCookie) end;
-procedure THttpHeader.Set_Cookie(const AValue: String); begin SetFieldByName(fieldCookie, AValue) end;
-function  THttpHeader.GetDate: String; begin Result := GetFieldByName(fieldDate) end;
-procedure THttpHeader.SetDate(const AValue: String); begin SetFieldByName(fieldDate, AValue) end;
-function  THttpHeader.GetExpires: String; begin Result := GetFieldByName(fieldExpires) end;
-procedure THttpHeader.SetExpires(const AValue: String); begin SetFieldByName(fieldExpires, AValue) end;
-function  THttpHeader.GetFrom: String; begin Result := GetFieldByName(fieldFrom) end;
-procedure THttpHeader.SetFrom(const AValue: String); begin SetFieldByName(fieldFrom, AValue) end;
-function  THttpHeader.GetIfModifiedSince: String; begin Result := GetFieldByName(fieldIfModifiedSince) end;
-procedure THttpHeader.SetIfModifiedSince(const AValue: String); begin SetFieldByName(fieldIfModifiedSince, AValue) end;
-function  THttpHeader.GetLastModified: String; begin Result := GetFieldByName(fieldLastModified) end;
-procedure THttpHeader.SetLastModified(const AValue: String); begin SetFieldByName(fieldLastModified, AValue) end;
-function  THttpHeader.GetLocation: String; begin Result := GetFieldByName(fieldLocation) end;
-procedure THttpHeader.SetLocation(const AValue: String); begin SetFieldByName(fieldLocation, AValue) end;
-function  THttpHeader.GetPragma: String; begin Result := GetFieldByName(fieldPragma) end;
-procedure THttpHeader.SetPragma(const AValue: String); begin SetFieldByName(fieldPragma, AValue) end;
-function  THttpHeader.GetReferer: String; begin Result := GetFieldByName(fieldReferer) end;
-procedure THttpHeader.SetReferer(const AValue: String); begin SetFieldByName(fieldReferer, AValue) end;
-function  THttpHeader.GetRetryAfter: String; begin Result := GetFieldByName(fieldRetryAfter) end;
-procedure THttpHeader.SetRetryAfter(const AValue: String); begin SetFieldByName(fieldRetryAfter, AValue) end;
-function  THttpHeader.GetServer: String; begin Result := GetFieldByName(fieldServer) end;
-procedure THttpHeader.SetServer(const AValue: String); begin SetFieldByName(fieldServer, AValue) end;
-function  THttpHeader.Get_SetCookie: String; begin Result := GetFieldByName(fieldSetCookie) end;
-procedure THttpHeader.Set_SetCookie(const AValue: String); begin SetFieldByName(fieldSetCookie, AValue) end;
-function  THttpHeader.GetUserAgent: String; begin Result := GetFieldByName(fieldUserAgent) end;
-procedure THttpHeader.SetUserAgent(const AValue: String); begin SetFieldByName(fieldUserAgent, AValue) end;
-function  THttpHeader.GetWWWAuthenticate: String; begin Result := GetFieldByName(fieldWWWAuthenticate) end;
-procedure THttpHeader.SetWWWAuthenticate(const AValue: String); begin SetFieldByName(fieldWWWAuthenticate, AValue) end;
-
-constructor THttpHeader.Create;
-begin
-  inherited Create;
-  FFields := TList.Create;
-  HttpVersion := '1.0';
-end;
-
-destructor THttpHeader.Destroy;
-var
-  i: Integer;
-  field: PHttpField;
-begin
-  FReader.Free;
-  FWriter.Free;
-  for i := 0 to FFields.Count - 1 do begin
-    field := PHttpField(FFields.Items[i]);
-    SetLength(field^.Name, 0);
-    SetLength(field^.Value, 0);
-    Dispose(field);
-  end;
-  FFields.Free;
-  inherited Destroy;
-end;
-
-function THttpHeader.GetFieldByName(const AName: String): String;
-var
-  i: Integer;
-  name: String;
-begin
-  name := UpperCase(AName);
-  for i := 0 to FFields.Count - 1 do
-    if UpperCase(FieldNames[i]) = name then begin
-      Result := FieldValues[i];
-      exit;
-    end;
-  SetLength(Result, 0);
-end;
-
-procedure THttpHeader.SetFieldByName(const AName, AValue: String);
-var
-  i: Integer;
-  name: String;
-  field: PHttpField;
-begin
-  name := UpperCase(AName);
-  for i := 0 to FFields.Count - 1 do
-    if UpperCase(FieldNames[i]) = name then begin
-      FieldNames[i] := AName;	// preserve case
-      FieldValues[i] := AValue;
-      exit;
-    end;
-  New(field);
-  FillChar(field^, SizeOf(field^), 0);
-  field^.Name := AName;
-  field^.Value := AValue;
-  FFields.Add(field);
-end;
-
-procedure THttpHeader.AsyncSend(AManager: TAsyncIOManager; AStream: THandleStream);
-var
-  i: Integer;
-begin
-  FWriter.Free;
-  FWriter := TAsyncWriteStream.Create(AManager, AStream);
-  FWriter.OnBufferEmpty := @WriterCompleted;
-  FWriter.EndOfLineMarker := #13#10;
-  FWriter.WriteLine(GetFirstHeaderLine);
-  for i := 0 to FFields.Count - 1 do
-    FWriter.WriteLine(Fields[i]);
-  FWriter.WriteLine('');
-end;
-
-procedure THttpHeader.AsyncReceive(AManager: TAsyncIOManager; AStream: THandleStream);
-begin
-  CmdReceived := False;
-  FReader.Free;
-  FReader := TAsyncStreamLineReader.Create(AManager, AStream);
-  FReader.OnLine := @LineReceived;
-end;
-
-
-// -------------------------------------------------------------------
-//   THttpRequestHeader
-// -------------------------------------------------------------------
-
-procedure THttpRequestHeader.ParseFirstHeaderLine(const line: String);
-var
-  i: Integer;
-begin
-  CommandLine := line;
-  i := Pos(' ', line);
-  Command := Copy(line, 1, i - 1);
-  URI := Copy(line, i + 1, Length(line));
-  i := Pos(' ', URI);
-  if i > 0 then begin
-    HttpVersion := Copy(URI, i + 1, Length(URI));
-    URI := Copy(URI, 1, i - 1);
-    HttpVersion := Copy(HttpVersion, Pos('/', HttpVersion) + 1, Length(HttpVersion));
-  end;
-end;
-
-function THttpRequestHeader.GetFirstHeaderLine: String;
-begin
-  Result := Command + ' ' + URI;
-  if Length(HttpVersion) > 0 then
-    Result := Result + ' HTTP/' + HttpVersion;
-end;
-
-
-// -------------------------------------------------------------------
-//   THttpAnswerHeader
-// -------------------------------------------------------------------
-
-procedure THttpAnswerHeader.ParseFirstHeaderLine(const line: String);
-var
-  i: Integer;
-  s: String;
-begin
-  i := Pos('/', line);
-  s := Copy(line, i + 1, Length(line));
-  i := Pos(' ', s);
-  HttpVersion := Copy(s, 1, i - 1);
-  s := Copy(s, i + 1, Length(s));
-  i := Pos(' ', s);
-  if i > 0 then begin
-    CodeText := Copy(s, i + 1, Length(s));
-    s := Copy(s, 1, i - 1);
-  end;
-  Code := StrToInt(s);
-end;
-
-function THttpAnswerHeader.GetFirstHeaderLine: String;
-begin
-  Result := Format('HTTP/%s %d %s', [HttpVersion, Code, CodeText]);
-end;
-
-constructor THttpAnswerHeader.Create;
-begin
-  inherited Create;
-  Code := 200;
-  CodeText := 'OK';
-end;
-
-
-// -------------------------------------------------------------------
-//   TCustomHttpConnection
-// -------------------------------------------------------------------
-
-procedure TCustomHttpConnection.HeaderToSendCompleted(Sender: TObject);
-begin
-  //WriteLn('TCustomHttpConnection.HeaderToSendCompleted');
-  if Assigned(FOnHeaderSent) then
-    FOnHeaderSent(Self);
-  if Assigned(StreamToSend) then begin
-    SendBuffer := TAsyncWriteStream.Create(FManager, FSocket);
-    SendBuffer.CopyFrom(StreamToSend, StreamToSend.Size);
-    SendBuffer.OnBufferEmpty := @StreamToSendCompleted;
-    SendBuffer.Run;
-  end else
-    StreamToSendCompleted(nil);
-end;
-
-procedure TCustomHttpConnection.StreamToSendCompleted(Sender: TObject);
-begin
-  if Assigned(FOnStreamSent) then
-    FOnStreamSent(Self);
-  //WriteLn('TCustomHttpConnection.StreamToSendCompleted');
-  SendBuffer.Free;
-  SendBuffer := nil;
-end;
-
-procedure TCustomHttpConnection.ReceivedHeaderCompleted(Sender: TObject);
-var
-  BytesInBuffer: Integer;
-begin
-  //WriteLn('TCustomHttpConnection.ReceivedHeaderCompleted');
-  BytesInBuffer := ReceivedHeader.Reader.BytesInBuffer;
-  //WriteLn('BytesInBuffer: ', BytesInBuffer, ', Content length: ', ReceivedHeader.ContentLength);
-  if Assigned(FOnHeaderReceived) then
-    FOnHeaderReceived(Self);
-  RecvSize := ReceivedHeader.ContentLength;
-  if Assigned(ReceivedStream) then
-  begin
-    if BytesInBuffer > 0 then
-    begin
-      ReceivedStream.Write(ReceivedHeader.Reader.Buffer^, BytesInBuffer);
-      if RecvSize > 0 then
-        Dec(RecvSize, BytesInBuffer);
-      if BytesInBuffer = ReceivedHeader.ContentLength then
-      begin
-        ReceivedStreamCompleted(nil);
-	exit;
-      end;
-    end;
-    FManager.SetReadHandler(FSocket.Handle, @DataAvailable, nil);
-  end else
-    ReceivedStreamCompleted(nil);
-end;
-
-procedure TCustomHttpConnection.DataAvailable(Sender: TObject);
-var
-  FirstRun: Boolean;
-  ReadNow, BytesRead: Integer;
-  buf: array[0..1023] of Byte;
-begin
-  FirstRun := True;
-  while True do
-  begin
-    if RecvSize >= 0 then
-    begin
-      ReadNow := RecvSize;
-      if ReadNow > 1024 then
-        ReadNow := 1024;
-    end else
-      ReadNow := 1024;
-    BytesRead := FSocket.Read(buf, ReadNow);
-    //WriteLn('TCustomHttpConnection.DataAvailable: Read ', BytesRead, ' bytes; RecvSize=', RecvSize);
-    if BytesRead <= 0 then
-    begin
-      if FirstRun then
-        ReceivedStreamCompleted(nil);
-      break;
-    end;
-    FirstRun := False;
-    ReceivedStream.Write(buf, BytesRead);
-    if RecvSize > 0 then
-      Dec(RecvSize, BytesRead);
-    if RecvSize = 0 then
-    begin
-      ReceivedStreamCompleted(nil);
-      break;
-    end;
-  end;
-end;
-
-procedure TCustomHttpConnection.ReceivedStreamCompleted(Sender: TObject);
-begin
-  //WriteLn('TCustomHttpConnection.ReceivedStreamCompleted');
-  if Assigned(FOnStreamReceived) then
-    FOnStreamReceived(Self);
-  FManager.ClearReadHandler(FSocket.Handle);
-end;
-
-constructor TCustomHttpConnection.Create(AManager: TAsyncIOManager; ASocket: TInetSocket);
-begin
-  inherited Create;
-  FManager := AManager;
-  FSocket := ASocket;
-end;
-
-destructor TCustomHttpConnection.Destroy;
-begin
-  FManager.ClearReadHandler(FSocket.Handle);
-  inherited Destroy;
-end;
-
-procedure TCustomHttpConnection.Start;
-begin
-  // Start receiver
-  if Assigned(ReceivedHeader) then begin
-    ReceivedHeader.OnCompleted := @ReceivedHeaderCompleted;
-    ReceivedHeader.AsyncReceive(FManager, FSocket);
-  end;
-
-  // Start sender
-  if Assigned(HeaderToSend) then begin
-    // Set the 'Content-Length' field automatically, if possible
-    if (HeaderToSend.ContentLength = -1) and Assigned(StreamToSend) then
-      HeaderToSend.ContentLength := StreamToSend.Size;
-
-    HeaderToSend.OnCompleted := @HeaderToSendCompleted;
-    HeaderToSend.AsyncSend(FManager, FSocket)
-  end;
-end;
-
-
-end.
-
-
-{
-  $Log$
-  Revision 1.2  2000-07-13 11:32:59  michael
-  + removed logs
- 
-}