Advertisement
gdhami

Delphi Resumable Upload (Stream Override)

Mar 10th, 2012
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 6.04 KB | None | 0 0
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6.     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7.     Dialogs, Math, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP,
  8.     IdMultipartFormData, IdCoderMIME, IdGlobal, IdCustomHTTPServer;
  9.  
  10. type
  11.   TIdEventStream2 = class(TIdEventStream)
  12.   protected
  13.         FPosition      : Int64;
  14.         FInitialOffset : Int64;
  15.   private
  16.         procedure SeekTheStream(const AOffset : Int64; AOrigin : TSeekOrigin; var VPosition : Int64);
  17.         procedure ReadTheStream(var VBuffer : TIdBytes; AOffset, ACount : Longint; var VResult : Longint);
  18.   public
  19.         constructor Create(InitialPosition : Int64);
  20.         function    AddFormField(AFieldName, AFileName : String; AContentType : String = '') : TIdFormDataField;
  21.   end;
  22.  
  23.   TForm1 = class(TForm)
  24.     UploadBtn: TButton;
  25.     procedure UploadFile(FileName : String);
  26.     procedure UploadBtnClick(Sender: TObject);
  27.   private
  28.     { Private declarations }
  29.   public
  30.     { Public declarations }
  31.   end;
  32.  
  33. var
  34.    Form1 : TForm1;
  35.  
  36. implementation
  37.  
  38. {$R *.dfm}
  39.  
  40. // ------------------------------------------------------------------------------ //
  41. procedure TIdEventStream2.ReadTheStream(var VBuffer : TIdBytes; AOffset, ACount : Longint; var VResult : Longint);
  42. begin
  43.      // Implement custom read stream...
  44.      if (FPosition >= 0) And (ACount >= 0) then
  45.      begin
  46.           VResult := (Size - FPosition - FInitialOffset);
  47.           if (VResult > 0) then
  48.           begin
  49.                if (VResult > ACount) then VResult := ACount;
  50.  
  51.                // ******** CUSTOM READ IN PROGRESS (START) ********
  52.                // Read(VBuffer, VResult);
  53.                {ACount  := Longint(IndyMin(Int64(ACount), Size - StartPos));
  54.                VResult := TIdStreamHelper.ReadBytes(FSourceStream, VBuffer, ACount, AOffset + StartPos);  // }
  55.  
  56.                // Move(Pointer(Longint(Memory) + FPosition)^, VBuffer, VResult);
  57.                // ******** CUSTOM READ IN PROGRESS (END) ********
  58.  
  59.                Inc(FPosition, VResult);
  60.  
  61.                Exit;
  62.           end;
  63.      end;
  64.  
  65.      VResult      := 0;
  66. end;
  67. // ------------------------------------------------------------------------------ //
  68. procedure TIdEventStream2.SeekTheStream(const AOffset : Int64; AOrigin : TSeekOrigin; var VPosition : Int64);
  69. begin
  70.      // Implement custom seek...
  71.      VPosition := 0;
  72.  
  73.      case AOrigin of
  74.         soBeginning :
  75.         begin
  76.              if (AOffset = 0) then
  77.                 VPosition       := FInitialOffset;
  78.              else
  79.                  VPosition      := FPosition;
  80.         end;
  81.  
  82.         soCurrent   : VPosition := FPosition;
  83.  
  84.         soEnd       :
  85.         begin
  86.              if (AOffset = 0) then
  87.              begin
  88.                   // CalculateSize;
  89.                   VPosition     := (Size - FInitialOffset);
  90.              end
  91.              else
  92.                  VPosition      := FPosition;
  93.         end;
  94.      end;    // case
  95.  
  96. end;
  97. // ------------------------------------------------------------------------------ //
  98. function TIdEventStream2.AddFormField(AFieldName, AFileName : String; AContentType : String = '') : TIdFormDataField;
  99. var
  100.    TheItem : TIdFormDataField;
  101. begin
  102.      TheItem              := FFields.Add;  // <-- Should I copy all the FFields code???
  103.  
  104.      with TheItem do
  105.      begin
  106.           FieldName       := AFieldName;
  107.           FileName        := ExtractFileName(AFileName);
  108.           // FieldStream     := AFieldValue;  // FieldValue      := AFieldValue;
  109.           if AContentType <> '' then
  110.              ContentType  := AContentType
  111.           else
  112.               ContentType := sContentTypeTextPlain;
  113.  
  114.           ContentTransfer := sContentTransferQuotedPrintable;
  115.      end;    // with
  116.  
  117.      Result               := TheItem;
  118. end;
  119. // ------------------------------------------------------------------------------ //
  120. constructor TIdEventStream2.Create(InitialPosition : Int64);
  121. begin
  122.      FPosition      := InitialPosition;
  123.      FInitialOffset := InitialPosition;
  124. end;
  125. // ------------------------------------------------------------------------------ //
  126. procedure TForm1.UploadFile(FileName : String);
  127. var
  128.    IdHTTP   : TIdHTTP;
  129.    Stream   : TIdEventStream2{TIdMultipartFormDataStream};
  130.    StartPos : Int64;
  131. begin
  132.      // Upload File
  133.  
  134.      IdHTTP                  := TIdHTTP.Create(nil);
  135.      try
  136.         with IdHTTP do
  137.         begin
  138.              HTTPOptions     := [hoForceEncodeParams];
  139.              AllowCookies    := True;
  140.              HandleRedirects := True;
  141.              ProtocolVersion := pv1_1;
  142.         end;    // with
  143.  
  144.         // Get resume offset/point
  145.         IdHttp.Head('http://localhost/_tests/resume/large-file.bin');
  146.         StartPos            := IdHttp.Response.ContentLength;
  147.         Caption             := Format('Upload starting/resuming from byte %d', [StartPos]);
  148.  
  149.         // =========== //
  150.         // Upload File //
  151.         // =========== //
  152.         Stream              := TIdEventStream2.Create(StartPos);
  153.         try
  154.            with Stream do
  155.            begin
  156.                 OnRead      := ReadTheStream;
  157.                 OnSeek      := SeekTheStream;
  158.  
  159.                 with AddFormField('upload_file', FileName, 'application/octet-stream') do
  160.                 begin
  161.                      HeaderCharset  := 'utf-8';
  162.                      HeaderEncoding := '8';
  163.                 end;    // with
  164.            end;    // with
  165.  
  166.            with IdHTTP do
  167.            begin
  168.                 IOHandler.LargeStream := True;
  169.                 Post('http://localhost/_tests/resume/t1.php', Stream);
  170.            end;    // with
  171.         finally
  172.                FreeAndNil(Stream);
  173.         end;    // try/finally
  174.      finally
  175.             FreeAndNil(IdHTTP);
  176.      end;    // try/finally
  177. end;
  178. // ------------------------------------------------------------------------------ //
  179. procedure TForm1.UploadBtnClick(Sender: TObject);
  180. begin
  181.      UploadFile('B:\_Test\large-file.bin');
  182. end;
  183. // ------------------------------------------------------------------------------ //
  184. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement