2013-08-29 5 views
1

Я пытаюсь загрузить файл через https с помощью компонентов Indy в delphi. Вот мой код:Публикация файла через https с использованием компонентов indy/delphi

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; 

Сервер не несет никакой ошибки. Просто файл не загружается. Что-то не так с моим кодом?

Я провел два дня, пытаясь заставить его работать: S.

Любая помощь будет оценена по достоинству. Я использую Delphi XE с Indy версии 10.1.1.

Обновление: Я использовал компонент Indy TIdLog и вот в результате. Я не могу найти ничего странного:

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-Dis‌​position: form-data; name="FileType"<EOL>Content-Type: text/plain<EOL>Content-Transfer-Encoding: quoted-printable<EOL><EOL>LOOPBACK<EOL>----------090513125207913<EOL>Content-Dis‌​position: 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> 

ответ

5

HTTP.Request.Host: = RemoteHOST;

Не устанавливайте это вручную. TIdHTTP поможет вам.

HTTP.Request.Accept: = 'multipart/mixed';

Сообщаете серверу, что вы принимаете ответы только на multipart/mixed, это то, что вы действительно хотите?

HTTP.Request.ContentType: = TestStream.RequestContentType;

Не устанавливайте это вручную при отправке TIdMultipartFormDataStream, Post().

HTTP.Post ('https://www.remotehost.com/controller?function=submitfile', TestStream, Resultado); memResultado.Lines.Add (Resultado.DataString);

Является ли сервер отправлением ответа в той же кодировке, которую вы инициализировали Resultado? Если нет, то считывание свойства DataString может завершиться неудачей и вернуть пустую строку (TEncoding не вызывает исключения, когда он не может кодировать/декодировать строку). Вы должны позволить Indy декодировать данные ответа для вас, так как он знает, что типа в ответ и в кодовом:

var 
    Resultado: string; 

Resultado := HTTP.Post('https://www.remotehost.com/controller?function=submitfile', TestStream); 
memResultado.Lines.Add(Resultado); 

Сервер не отправляет какую-либо ошибки. Просто файл не загружается.

Если сервер не отправляет обратно ошибочный ответ HTTP (который будет вызывать TIdHTTP поднять исключение), то это либо:

  1. отправки обратно ответ успеха HTTP, но посылая сообщение об ошибке в данных ответа.

  2. принимать файл, но затем отбрасывая его

  3. прием файла, но сохранить его под другим именем пути /, чем вы ожидаете.

Трудно сказать, так как вы не указали фактические данные HTTP-запроса/ответа, которые передаются.

Update: Сервер IS отправки обратно ошибку, используя # 1 выше. Сервер отправляет ответ HTTP 200 OK, но в ответе содержится ответ 'Failure!' (на самом деле ваш исходный код должен был регистрировать это сообщение в вашем TMemo). Вот почему TIdHTTP не создает исключение. Он ищет только ошибки HTTP, а не сообщения об ошибках в телеобъекте. Вы должны добавить дополнительный код, чтобы учесть такую ​​возможность, например:

Resultado := HTTP.Post('https://www.remotehost.com/controller?function=submitfile', TestStream); 
if TextStartsWith(Resultado, 'Failure') then 
begin 
    // Upload failed, do something... 
end; 

А почему сервер не может в первую очередь, вы должны связаться с администратором сервера и попросить об этом. Администратор, вероятно, будет иметь серверные журналы для устранения неполадок.

Однако, я упомянул, что TIdMultipartFormDataStream в настоящее время отправляет заголовок Content-Type: text/plain для текстовых полей, что хорошо (даже рекомендуется) для форм HTML 4, но это не нормально (это запрещено) для форм HTML 5, а некоторые серверы do Ошибка, если заголовок Content-Type присутствует для текстового поля. HTML5 разрешает его только по полям файлов. Это известная проблема с TIdMultipartFormDataStream, которая уже работает, но нет ETA, когда исправление будет доступно. Но вы можете спросить администратора сервера, как сервер реагирует на это условие.

+0

Прошу прощения за вопрос, но, как я могу получить данные запроса/ответа ?. : S – user2730930

+0

Поскольку вы запрашиваете URL-адрес HTTPS, сниффер пакетов, такой как Wireshark, не является опцией, поскольку данные шифруются. Однако вы можете использовать прокси-сервер отладки, например [Fiddler] (http://fiddler2.com), и настроить свойство 'TIdHTTP.ProxyParams' соответственно. Или вы можете присоединить один из собственных компонентов TIdLog ... 'TIdLog ...', например 'TIdLogFile', к свойству' TIdHTTP.Intercept', чтобы он мог записывать все 'TIdHTTP' отправляет перед шифрованием и получает после дешифрования. –

+0

Эта информация должна быть помещена в ваш первоначальный вопрос, а не в комментариях. –

Смежные вопросы