Advertisement
Guest User

WBCustomPostDataSender

a guest
May 3rd, 2012
598
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 5.68 KB | None | 0 0
  1. unit WBCustomPostDataSender;
  2.  
  3. interface
  4.  
  5. uses  EmbeddedWB, Classes, SysUtils, Variants, StrUtils, WideStrUtils, md5hash;
  6.  
  7. type
  8.   TCustomPostParam = record
  9.     name : string;
  10.     value : string;
  11.  
  12.     filename : string;
  13.     content_type : string;
  14.   end;
  15.  
  16.   TCustomPostDataSender = class
  17.   private
  18.     WB : TEmbeddedWB;
  19.  
  20.     FParams : array of TCustomPostParam;
  21.     FURL : string;
  22.     FContentType : string;
  23.     FBoundary : string;
  24.  
  25.     procedure GenerateNewBoundary();
  26.     function CheckBoundary(str : string):boolean;
  27.     function FGetHeader():string;
  28.     function StringToVariantArray(str: string): OleVariant;
  29.     procedure CheckUTF8(var str: string);
  30.   public
  31.     constructor Create(Browser : TEmbeddedWB); overload;
  32.  
  33.     procedure Clear();
  34.     function POST():integer;
  35.     function Count():integer;
  36.  
  37.     function AddParam(name, value : string; content_type : string = ''; filename : string = ''):integer;
  38.     procedure AddTextFile(name, path : string);
  39.     procedure AddFile(name, path, file_content_type : string);
  40.  
  41.     property url : string read FURL write FURL;
  42.     property content_type : string read FContentType write FContentType;
  43.   end;
  44.  
  45. implementation
  46.  
  47. { TCustomPostDataSender }
  48.  
  49.  
  50. function TCustomPostDataSender.AddParam(name, value: string; content_type : string = ''; filename : string = ''):integer;
  51. var
  52.   h : integer;
  53. begin
  54.   SetLength(FParams, Count() + 1);
  55.   h := high(FParams);
  56.  
  57.   FParams[h].name := name;
  58.   FParams[h].value := value;
  59.   FParams[h].content_type := content_type;
  60.   FParams[h].filename := filename;
  61.  
  62.   CheckBoundary(name + ' ' + value + ' ' + content_type);
  63.   result := h;
  64. end;
  65.  
  66. procedure TCustomPostDataSender.AddFile(name, path, file_content_type: string);
  67. var
  68.   s : TStringStream;
  69.   buf : string;
  70. begin
  71.   if not FileExists(path) then exit;
  72.   file_content_type := Trim(file_content_type);
  73.   if file_content_type = '' then file_content_type := 'text/plain';
  74.  
  75.   s := TStringStream.Create;
  76.   try
  77.     s.LoadFromFile(path);
  78.     buf := s.DataString;
  79.     if Pos('text', LowerCase(file_content_type)) = 1 then CheckUTF8(buf);
  80.     AddParam(name, buf, file_content_type, ExtractFileName(path));
  81.   finally
  82.     s.Free;
  83.   end;
  84. end;
  85.  
  86. procedure TCustomPostDataSender.AddTextFile(name, path: string);
  87. begin
  88.   if not FileExists(path) then exit;
  89.  
  90.   if LowerCase(ExtractFileExt(path)) = '.xml'
  91.     then AddFile(name, path, 'text/xml')
  92.     else AddFile(name, path, 'text/plain');
  93. end;
  94.  
  95. function TCustomPostDataSender.CheckBoundary(str: string):boolean;
  96. begin
  97.   result := pos(LowerCase(FBoundary), LowerCase(str)) <> 0;
  98.   if result then GenerateNewBoundary();
  99. end;
  100.  
  101. procedure TCustomPostDataSender.Clear;
  102. begin
  103.   SetLength(FParams, 0);
  104.   FURL := '';
  105.   FContentType := '';
  106.   GenerateNewBoundary();
  107. end;
  108.  
  109. function TCustomPostDataSender.Count: integer;
  110. begin
  111.   Result := Length(FParams);
  112. end;
  113.  
  114. constructor TCustomPostDataSender.Create(Browser: TEmbeddedWB);
  115. begin
  116.   WB := Browser;
  117.   Clear();
  118. end;
  119.  
  120. function TCustomPostDataSender.FGetHeader: string;
  121. begin
  122.   if FContentType = '' then FContentType := 'multipart/form-data';
  123.   Result := 'Content-Type: ' + FContentType + '; boundary=' + FBoundary;
  124.  
  125.   Result := Result + sLineBreak + 'Referer: ' + WB.LocationURL;
  126. end;
  127.  
  128. procedure TCustomPostDataSender.GenerateNewBoundary;
  129. var
  130.   i : integer;
  131. begin
  132.   FBoundary := MD5(DateTimeToStr(now));
  133.   delete(FBoundary, 14, MaxInt);
  134.   FBoundary := '---------------------------' + FBoundary;
  135.  
  136.   for i := 0 to Count - 1 do
  137.   if CheckBoundary(FParams[i].name + ' ' + FParams[i].value + ' ' + FParams[i].content_type) then break;
  138. end;
  139.  
  140. function TCustomPostDataSender.POST():integer;
  141. var
  142.   sURL, sFlags, sTargetFrame, sPostData, sHeaders : OleVariant;
  143.  
  144.   i : integer;
  145.   buf : string;
  146. begin
  147.   Result := 1;
  148.   if FURL = '' then exit;
  149.  
  150.   try
  151.     sURL := FURL;
  152.     sFlags := 64;   // Значение этого флага мне не известно, но браузер использует всегда именно такое
  153.     sHeaders := FGetHeader();
  154.  
  155.     buf := '';
  156.     for i := 0 to Count() - 1 do
  157.     begin
  158.       if i = 0 then buf := buf + '--' + FBoundary + sLineBreak;
  159.  
  160.       buf := buf + 'Content-Disposition: form-data; name="'+ FParams[i].name +'"';
  161.  
  162.       // Если файл
  163.       if FParams[i].filename <> ''
  164.         then buf := buf + '; filename="'+ FParams[i].filename +'"' + sLineBreak + 'Content-Type: ' + FParams[i].content_type;
  165.       buf := buf + sLineBreak + sLineBreak;
  166.  
  167.       buf := buf + FParams[i].value + sLineBreak;
  168.       buf := buf + '--' + FBoundary;
  169.  
  170.       if i = Count() - 1 then buf := buf + '--';
  171.       buf := buf + sLineBreak;
  172.     end;
  173.  
  174.     sPostData := StringToVariantArray(buf);
  175.     WB.Navigate2(sURL, sFlags, sTargetFrame, sPostData, sHeaders);
  176.     Clear();
  177.     Result := 0;
  178.   except
  179.     Result := 999;
  180.   end;
  181. end;
  182.  
  183. procedure TCustomPostDataSender.CheckUTF8(var str:string);
  184. var
  185.   del_bom : boolean;
  186. begin
  187.   if IsUTF8String(RawByteString(str)) then
  188.   begin
  189.     del_bom := HasUTF8BOM(RawByteString(str));
  190.     str := Utf8ToUnicodeString(RawByteString(str));
  191.     if del_bom then Delete(str, 1, 1);
  192.   end;
  193. end;
  194.  
  195. function TCustomPostDataSender.StringToVariantArray(str: string): OleVariant;
  196. var
  197.   pLocked: Pointer;
  198.   tmp : TMemoryStream;
  199.   RBuf : RawByteString;
  200. begin
  201.   tmp := TMemoryStream.Create;
  202.   try
  203.     //RBuf := StrEncodeUtf8(str);
  204.     RBuf := UTF8Encode(str);
  205.     tmp.WriteBuffer(RBuf[1], length(RBuf));
  206.  
  207.     Result := VarArrayCreate([0, tmp.Size-1], varByte);
  208.     pLocked := VarArrayLock(Result);
  209.     try
  210.       tmp.Position := 0;
  211.       tmp.ReadBuffer(pLocked^, tmp.Size);
  212.     finally
  213.       VarArrayUnlock(Result);
  214.     end;
  215.   finally
  216.     tmp.Free;
  217.   end;
  218. end;
  219.  
  220. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement