12
votes

I have a simple php script on my web server which I need to upload a file using HTTP POST, which I am doing in Delphi.

Here is my code with Indy but aparantely it won't work and I can't figure out what i am not doing properly. How can I view what I send on the server is there such a tool ?

procedure TForm1.btn1Click(Sender: TObject);
var
  fname : string;
  MS,dump : TMemoryStream;
  http  : TIdHTTP;

const
  CRLF = #13#10;
begin
  if PromptForFileName(fname,'','','','',false) then
  begin
    MS := TMemoryStream.Create();
    MS.LoadFromFile(fname);
    dump := TMemoryStream.Create();
    http := TIdHTTP.Create();
    http.Request.ContentType:='multipart/form-data;boundary =-----------------------------7cf87224d2020a';
    fname := CRLF + '-----------------------------7cf87224d2020a' + CRLF + 'Content-Disposition: form-data; name=\"uploadedfile\";filename=\"test.png"' + CRLF;
    dump.Write(fname[1],Length(fname));
    dump.Write(MS.Memory^,MS.Size);
    fname := CRLF + '-----------------------------7cf87224d2020a--' + CRLF;
    dump.Write(fname[1],Length(fname));
    ShowMessage(IntToStr(dump.Size));
    MS.Clear;
    try
    http.Request.Method := 'POST';
    http.Post('http://posttestserver.com/post.php',dump,MS);
    ShowMessage(PAnsiChar(MS.Memory));
    ShowMessage(IntToStr(http.ResponseCode));
    except
    ShowMessage('Could not bind socket');
    end;
  end;
end;
3
"It doesn't work" is the least useful phrase possible when debugging something. What doesn't work? What does it do wrong?Mason Wheeler
@MasonWheeler if i knew the answer probably i was not asking this question . It doesn't upload to the webserver that is the problem my guess that the post header is malformed but I don't know what I am doing wrong.opc0de
why is MS.Clear; called before http.Post( URL, MS )?user497849
So you get no error messages or anything, just silently fails? That's what Doesn't Work means. Otherwise say "I get this error code" or whatever.Warren P

3 Answers

20
votes

Indy has TIdMultipartFormDataStream for this purpose:

procedure TForm1.SendPostData;
var
  Stream: TStringStream;
  Params: TIdMultipartFormDataStream;
begin
  Stream := TStringStream.Create('');
  try
   Params := TIdMultipartFormDataStream.Create;
   try
    Params.AddFile('File1', 'C:\test.txt','application/octet-stream');
    try
     HTTP.Post('http://posttestserver.com/post.php', Params, Stream);
    except
     on E: Exception do
       ShowMessage('Error encountered during POST: ' + E.Message);
    end;
    ShowMessage(Stream.DataString);
   finally
    Params.Free;
   end;
  finally
   Stream.Free;
  end;
end;
2
votes

Calling a PHP from Indy can fail because of the User-Agent, then you get 403 error.

Try this way, it fixed it for me:

var Answer: string;
begin
  GetHTML:= TIdHTTP.create(Nil);
  try
    GetHTML.Request.UserAgent:= 'Mozilla/3.0';
    Answer:= GetHTML.Get('http://www.testserver.com/test.php?id=1');
  finally
    GetHTML.Free;
  end;
end;
0
votes

You lost 2 characters '--'. It is better to do so:

http.Request.ContentType:='multipart/form-data;boundary='+myBoundery;
fname := CRLF + '--' + myBoundery + CRLF + 'Content-Disposition: form-data; name=\"uploadedfile\";filename=\"test.png"' + CRLF;