1. Computing & Technology

Discuss in my forum

Programmatically Executing HTTP POST

File Upload using TWebBrowser

By , About.com Guide

Code submitted by Jason Penny.

Upload Multiple Files

File uploads are most commonly carried out as HTTP POST. If you need to programmatically upload multiple files to an HTML form using the HTTP Post method - use the "UploadFilesHttpPost" procedure.

The "UploadFilesHttpPost" procedure takes six parameters: the TWebBrowser ("wb") instance, the target url ("URLstring") and the four file name arrays.

 procedure UploadFilesHttpPost(const wb:TWebBrowser; const URLstring: string; names, values, nFiles, vFiles: array of string) ;
 var
   strData, n, v, boundary: string;
   URL: OleVariant;
   Flags: OleVariant;
   PostData: OleVariant;
   Headers: OleVariant;
   idx: Integer;
 
   ms: TMemoryStream;
   ss: TStringStream;
 begin
   if Length(names) <> Length(values) then
     raise Exception.Create('UploadFilesHttpPost: Names and Values must have the same length.') ;
   if Length(nFiles) <> Length(vFiles) then
     raise Exception.Create('UploadFilesHttpPost: FileNames and FileValues must have the same length.') ;
 
   URL := 'about:blank';
   Flags := NavNoHistory or NavNoReadFromCache or NavNoWriteToCache or NavAllowAutosearch;
   wb.Navigate2(URL, Flags) ;
   while wb.ReadyState < READYSTATE_INTERACTIVE do Application.ProcessMessages;
 
   // anything random that WILL NOT occur in the data.
   boundary := '---------------------------123456789';
 
   strData := '';
   for idx := Low(names) to High(names) do
   begin
     n := names[idx];
     v := values[idx];
 
     strData := strData + '--' + boundary + #13#10 + 'Content-Disposition: form-data; name="' + n + '"' + #13#10#13#10 + v + #13#10;
   end;
 
   for idx := Low(nFiles) to High(nFiles) do
   begin
     n := nFiles[idx];
     v := vFiles[idx];
 
     strData := strData + '--' + boundary + #13#10 + 'Content-Disposition: form-data; name="' + n + '"; filename="' + v + '"' + #13#10;
 
     if v = '' then
     begin
        strData := strData + 'Content-Transfer-Encoding: binary''#13#10#13#10;
     end
     else
     begin
       if (CompareText(ExtractFileExt(v), '.JPG') = 0) or (CompareText(ExtractFileExt(v), '.JPEG') = 0) then
       begin
         strData := strData + 'Content-Type: image/pjpeg'#13#10#13#10;
       end
       else if (CompareText(ExtractFileExt(v), '.PNG') = 0) then
       begin
         strData := strData + 'Content-Type: image/x-png'#13#10#13#10;
       end
       else if (CompareText(ExtractFileExt(v), '.PDF') = 0) then
       begin
         strData := strData + 'Content-Type: application/pdf'#13#10#13#10;
       end
       else if (CompareText(ExtractFileExt(v), '.HTML') = 0) then
       begin
       end;
 
       strData := strData + 'Content-Type: text/html'#13#10#13#10;
 
       ms := TMemoryStream.Create;
       try
         ms.LoadFromFile(v) ;
         ss := TStringStream.Create('') ;
         try
           ss.CopyFrom(ms, ms.Size) ;
 
           strData := strData + ss.DataString + #13#10;
         finally
           ss.Free;
         end;
       finally
         ms.Free;
       end;
     end;
 
     strData := strData + '--' + boundary + '--'#13#10; // FOOTER
   end;
 
   strData := strData + #0;
 
   {2. you must convert a string into variant array of bytes and every character from string is a value in array}
   PostData := VarArrayCreate([0, Length(strData) - 1], varByte) ;
 
   { copy the ordinal value of the character into the PostData array}
   for idx := 1 to Length(strData) do PostData[idx-1] := Ord(strData[idx]) ;
 
   {3. prepare headers which will be sent to remote web-server}
   Headers := 'Content-Type: multipart/form-data; boundary=' + boundary + #13#10;
 
   {4. you must navigate to the URL with your script and send as parameters your array with POST-data and headers}
   URL := URLstring;
   wb.Navigate2(URL, Flags, EmptyParam, PostData, Headers) ;
   while wb.ReadyState < READYSTATE_INTERACTIVE do Application.ProcessMessages;
 end;
 

Here's an example of usage - the "blank.htm" file is uploaded to the "http://validator.w3.org/check" W3 validator:

UploadFilesHttpPost(
  WebBrowser1,
  'http://validator.w3.org/check',
  [],
  [],
  ['uploaded_file'],
  ['C:\blank.htm'] );

Note: you'll need a TWebBrowser (named "WebBrowser1") control on a form for the above to compile.

Delphi tips navigator:
» Preview HTTP Posted Data using Delphi and TWebBrowser
« Implementing OnActivate / OnDeactivate for MDI Child Forms - Get Previously Active

©2012 About.com. All rights reserved.

A part of The New York Times Company.