Отправка файла через idHTTP.Put

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
jsa
постоялец
Сообщения: 295
Зарегистрирован: 28.11.2017 12:46:04

Отправка файла через idHTTP.Put

Сообщение jsa »

Здравствуйте.
Имеется на одном сайте API для передачи файла ZIP (так осуществляется сбор информации о мед.обследованиях)

На одном и том же файле делаю тесттовую отправку через ARC client и через нашу программу.
При отправке файла нужно так же отправить хэш файла.
Хэш файла получаю в нашей программе, вставляю его в заголовок в ARC, файл уходит и в ответ получаю подтверждение, что он принят.
Когда я его же с этим же хэшом отправляю в программе, в ответ получаю ошибку "<message>Хэш-сумма загруженного файла не совпадает с ожидаемой. Возможно файл был загружен не полностью.</message>"

Получается сам метод отправки "не тот".
Как понять причину?

Код: Выделить всё

var FileHash, filename, url:string; 
	IdHTTP_Put: TidHTTP;
    sResp: RawByteString; 
    STRM: TIdMultiPartFormDataStream;    
begin
	 url:='https://......';
	 filename:= 'D:testtest01.zip';
     FileHash := MD5Print(MD5File(filename));
     FileHash := TIdEncoderMIME.EncodeString(FileHash);  
	 
	 IdHTTP_Put:=TidHTTP.Create(nil);
     IdHTTP_Put.IOHandler:=TIdSSLIOHandlerSocketOpenSSL.Create(nil);
     TIdSSLIOHandlerSocketOpenSSL(IdHTTP_Put.IOHandler).SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
     TIdSSLIOHandlerSocketOpenSSL(IdHTTP_Put.IOHandler).SSLOptions.Method := sslvTLSv1_2;

     IdHTTP_Put.Request.CustomHeaders.AddValue('Authorization', 'Bearer '+token );
     IdHTTP_Put.Request.CustomHeaders.AddValue('Content-MD5', FileHash );
     IdHTTP_Put.Request.UserAgent:='Mozilla/3.0 (compatible; Indy Library)';
     IdHTTP_Put.Request.ContentType:='application/x-zip-compressed';
     IdHTTP_Put.Request.Charset:='utf-8';
     IdHTTP_Put.Request.ContentLength:=1;
     IdHTTP_Put.HTTPOptions:=[hoForceEncodeParams,hoWaitForUnexpectedData,hoWantProtocolErrorContent, hoNoProtocolErrorException];

     STRM := TIdMultiPartFormDataStream.Create;
     STRM.AddFile('file', filename, 'application/x-zip-compressed'); //'application/octet-stream' // 'application/x-zip-compressed'
     STRM.Position:=0;     

	 sResp:= IdHTTP_Put.Put(url, STRM, IndyTextEncoding_UTF8 ); 
	 
	 STRM.Free;
	 IdHTTP_Put.Disconnect;
	 IdHTTP_Put.Free;  
end;
В логе программы

Код: Выделить всё

---request PUT
https://.......
D:testtest01.zip
Content-MD5=OTM1NWE5MDc0ZTE1MjMxYTM3Yjg0ZGFmNTZkNTQ0ZDQ=

response Headers
Content-Length: 19979
Authorization: Bearer ZX.....jA=
Content-MD5: OTM1NWE5MDc0ZTE1MjMxYTM3Yjg0ZGFmNTZkNTQ0ZDQ=
Host: .....ru
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/3.0 (compatible; Indy Library)

---response PUT
ResponseCode=400
Body
<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <code>InvalidMd5Sum</code>
  <message>Хэш-сумма загруженного файла не совпадает с ожидаемой. Возможно файл был загружен не полностью.</message>
  <requestId></requestId>
</Error>

response Headers
Server: nginx
Date: Tue, 14 Nov 2023 04:48:48 GMT
Content-Type: application/xml; charset=UTF-8
Content-Length: 19966
Transfer-Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=15
P3P: policyref="/bitrix/p3p.xml", CP="NON DSP COR CUR ADM DEV PSA PSD OUR UNR BUS UNI COM NAV INT DEM STA"
X-Powered-CMS: Bitrix Site Manager (3e0207e37f595a3549e838893c4)
Set-Cookie: PHPSESSID=9lsbtqs7aejj9d3p9; path=/; HttpOnly
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Добавлено спустя 46 минут 9 секунд:
Размер контента разный
в ARC client
content-length: 19771

а в программе
Content-Length: 19966

Видимо поток формируется по разному. И в TIdMultiPartFormDataStream как-то по другому

Добавлено спустя 1 час 8 минут 1 секунду:
Хороший тут форум.
Волшебный :lol:
Очень часто бьюсь над проблемой. Потом пишу вопрос, и после написания вопроса, в течении пары тройки часов нахожу решение сам. 8)

Сделал по другому формирование потока.

Код: Выделить всё

var STRM: TFileStream;
	...
begin
	...
	STRM := TFileStream.Create(filename, fmOpenRead);
	STRM.Position:=0;
	...
	sResp:= IdHTTP_Put.Put(url, STRM , IndyTextEncoding_UTF8 );
	...
end;	 
Вот таким способом
content-length: 19771
и сайт принимает файл
Alex2013
долгожитель
Сообщения: 3230
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

Все просто "хорошо сформулированный вопрос содержит как минимум половину ответа "! :idea: :wink:
sts
энтузиаст
Сообщения: 548
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

Сообщение sts »

jsa писал(а):Видимо поток формируется по разному. И в TIdMultiPartFormDataStream как-то по другому
судя по названию он бьет данные на куски соответственно оборачивая их дополнительными признаками
в свою очередь в Content-MD5 ожидается, судя по названию, хэш именно контента, т.е. его надо считать от результата работы TIdMultiPartFormDataStream

в итоге вы сделал все верно

Добавлено спустя 1 минуту 44 секунды:
jsa писал(а):Хороший тут форум.
Волшебный :lol:
да, на тех где много народу обхаяли бы в первых 20 ответов, у тут просто некому обхаять
DedFrend
постоялец
Сообщения: 157
Зарегистрирован: 25.11.2018 11:21:50

Сообщение DedFrend »

Дык, пока формулируешь вопрос, еще десять раз обдумаешь проблему. У меня случалось, что проблема решалась еще до того, как вопрос отправлю!
Ответить