Files Delphi

Title: HTTP POST using Delphi and TWebBrowser - Multiple File Upload
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 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 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.