Simone Nigro
Simone Nigro

Reputation: 4887

Delphi: Use TidHTTPServer for transfer file and monitoring byte send for single request

Using TIdHTTPServer (Indy 10.6), how do track how many bytes are sent to the client (user browser) for each request (on close connection)?

procedure onCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo;
begin
    AResponseInfo.ContentStream := TFileStream.Create('C:/HugeFile.zip', fmOpenRead or fmShareCompat);
    AResponseInfo.ContentLength := AResponseInfo.ContentStream.Size;
    AResponseInfo.WriteHeader;
    AResponseInfo.WriteContent;
    AResponseInfo.ContentStream.Free;
    AResponseInfo.ContentStream := nil;
end;

eg, in a log file:

2014-11-06 20:32:00 - IPAddress 84.XXX.XXX.XXX download 1000000 Bytes (100%)
2014-11-05 16:05:00 - IPAddress 72.XXX.XXX.XXX download 500000  Bytes (50%)

Upvotes: 2

Views: 3558

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 596256

If you just want to output a log at the end of the transfer saying how many bytes were sent, you can derive a new class from TFileStream and override its destructor to output a log message showing the stream's current Position relative to its Size. Whatever other information you need to log can be passed to the constructor and saved so the destructor can use it.

For example:

type
  TMyFileStream = class(TFileStream)
  private
    FContext: TIdContext;
  public
    constructor Create(const AFileName: string; AContext: TIdContext);
    destructor Destroy; override;
  end;

constructor TMyFileStream.Create(const AFileName: string; AContext: TIdContext);
begin
  inherited Create(AFileName, fmOpenRead or fmShareCompat);
  FContext := AContext;
end;

destructor TMyFileStream.Destroy;
var
  LPos, LSize: Int64;
  LPercent: Integer;
begin
  LPos := Position;
  LSize := Size;
  if LSize <> 0 then
    LPercent := (LPosition * 100) div LSize
  else
    LPercent := 100;
  MyLogFile.WriteLine(Format('%s IPAddress %s download %d Bytes (%d%%)', [FormatDateTime('YYYY-MM-DD HH:NN:SS', Now), AContext.Binding.PeerIP, LPos, LPercent]);
  inherited;
end;

procedure onCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo;
begin
  AResponseInfo.ContentStream := TMyFileStream.Create('C:/HugeFile.zip', AContext);
end;

Upvotes: 3

Related Questions