I'm trying to upload a file through https by using Indy components in delphi. Here is my code:
HTTP := TIdHTTP.Create(Self)
IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create;
HTTP.Request.Host := RemoteHost;
HTTP.Request.Connection := 'keep-alive';
HTTP.Request.Accept := 'multipart/mixed';
HTTP.IOHandler := IOHandler;
HTTP.ConnectTimeout := 0;
HTTP.ReadTimeout := 0;
//### CREATE FILE TO SEND
TestStream := TIdMultipartFormDataStream.Create;
try
//### POST PARAMETERS
TestStream.AddFormField('ReceiverId','LOOPTEST');
TestStream.AddFormField('FileType','LOOPBACK');
//### ADD FILE
TestStream.AddFile('filename','C:\PRUEBA.txt',GetMIMETypeFromFile('C:\PRUEBA.txt'));
HTTP.Request.ContentType := TestStream.RequestContentType;
HTTP.Post('https://www.remotehost.com/controller?function=submitfile',TestStream, Resultado);
memResultado.Lines.Add(Resultado.DataString);
finally
FreeAndNil(TestStream);
FreeAndNil(HTTP);
FreeAndNil(IOHandler);
end;
The server does not send any error. Just the file is not uploaded. Is there something wrong with my code?.
I've spent two days trying to make it work :S.
Any help will be appreciated. I'm using Delphi XE with Indy version 10.1.1.
Update: I used the Indy TIdLog
component and here is the result. I cannot find nothing strange:
Stat Connected.
Sent 05/09/2013 12:52:00 p.m.: POST /servlet/controller HTTP/1.1<EOL>Content-Type: application/x-www-form-urlencoded<EOL>Content-Length: 47<EOL>Host: ebmx.extra.client.com<EOL>Accept: text/html, /*<EOL>Accept-Encoding: identity<EOL>User-Agent: Mozilla/3.0 (compatible; Indy Library)<EOL><EOL>
Sent 05/09/2013 12:52:00 p.m.: function=login&username=******&password=******
Recv 05/09/2013 12:52:01 p.m.: HTTP/1.1 200 OK<EOL>Server: Sun-ONE-Web-Server/6.1<EOL>Date: Thu, 05 Sep 2013 17:51:22 GMT<EOL>Content-type: text/html<EOL>Set-cookie: JSESSIONID=8035B4F90EBA1A337E4923520558E5DC;Path=/servlet<EOL>Transfer-encoding: chunked<EOL><EOL>001a<EOL>Success! Member Type is 0<LF><EOL>
Recv 05/09/2013 12:52:01 p.m.: 0<EOL><EOL>
Stat Disconnected.
Stat Connected.
Sent 05/09/2013 12:52:11 p.m.: POST /servlet/controller?function=submitfile HTTP/1.1<EOL>Content-Type: multipart/form-data; boundary=--------090513125207913<EOL>Content-Length: 525<EOL>Host: ebmx.extra.client.com<EOL>Accept: text/html, */*<EOL>Accept-Encoding: identity<EOL>User-Agent: Mozilla/3.0 (compatible; Indy Library)<EOL>Cookie: JSESSIONID=8035B4F90EBA1A337E4923520558E5DC<EOL>Cookie2: $Version="1"<EOL><EOL>
Sent 05/09/2013 12:52:11 p.m.: ----------090513125207913<EOL>Content-Disposition: form-data; name="ReceiverId"<EOL>Content-Type: text/plain<EOL>Content-Transfer-Encoding: quoted-printable<EOL><EOL>LOOPTEST<EOL>----------090513125207913<EOL>Content-Disposition: form-data; name="FileType"<EOL>Content-Type: text/plain<EOL>Content-Transfer-Encoding: quoted-printable<EOL><EOL>LOOPBACK<EOL>----------090513125207913<EOL>Content-Disposition: form-data; name="filename"; filename="PRUEBA.txt"<EOL>Content-Type: text/plain<EOL>Content-Transfer-Encoding: binary<EOL><EOL>UKELELE 2013<EOL>----------090513125207913--<EOL>
Recv 05/09/2013 12:52:15 p.m.: HTTP/1.1 200 OK<EOL>Server: Sun-ONE-Web-Server/6.1<EOL>Date: Thu, 05 Sep 2013 17:51:36 GMT<EOL>Content-type: text/html<EOL>Transfer-encoding: chunked<EOL><EOL>0009<EOL>Failure!<LF><EOL>
Recv 05/09/2013 12:52:16 p.m.: 0<EOL><EOL>
HTTP.Request.Host := RemoteHost;
Don't set that manually. TIdHTTP will manage that for you.
HTTP.Request.Accept := 'multipart/mixed';
You are telling the server that you will only accept responses that are multipart/mixed
, is that what you really want?
HTTP.Request.ContentType := TestStream.RequestContentType;
Don't set that manually when sending a TIdMultipartFormDataStream
, Post()
will handle that for you.
HTTP.Post('https://www.remotehost.com/controller?function=submitfile',TestStream, Resultado); memResultado.Lines.Add(Resultado.DataString);
Is the server sending the response in the same charset that you initialized Resultado
with? If not, then reading the DataString
property may fail and return a blank string (TEncoding
does not raise an exception when it fails to encode/decode a string). You should let Indy decode the response data for you, since it knows the response's type and charset:
var
Resultado: string;
Resultado := HTTP.Post('https://www.remotehost.com/controller?function=submitfile', TestStream);
memResultado.Lines.Add(Resultado);
The server does not send any error. Just the file is not uploaded.
If the server is not sending back an HTTP error response (which would cause TIdHTTP
to raise an exception), then it is either:
sending back an HTTP success response, but sending an error message in the response data.
accepting the file, but then discarding it
accepting the file, but saving it under a different path/name than you are expecting.
Hard to say for sure since you did not show the actual HTTP request/response data that is being transmitted.
Update: The server IS sending back an error, using #1 above. The server is sending back an HTTP 200 OK
reply, but the content of the reply says 'Failure!'
(in fact, your original code should have been logging that message in your TMemo
). That is why TIdHTTP
is not raising an exception. It only looks for HTTP errors, not error messages in body content. You will have to add extra code to account for that possibility, eg:
Resultado := HTTP.Post('https://www.remotehost.com/controller?function=submitfile', TestStream);
if TextStartsWith(Resultado, 'Failure') then
begin
// Upload failed, do something...
end;
As for why the server is failing in the first place, you will have to contact the server admin and ask about that. The admin will likely have server-side logs to troubleshoot with.
However, I will mention that TIdMultipartFormDataStream
does currently send a Content-Type: text/plain
header for text fields, which is fine (even encouraged) for HTML 4 forms, but is not OK (it is forbidden) for HTML 5 forms, and some servers do fail if a Content-Type
header is present for a text field. HTML5 only allows it on file fields. This is a known issue with TIdMultipartFormDataStream
that is already being worked on, but there is no ETA on when the fix will be available. But you can ask the server admin how the server reacts to that condition.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With