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

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

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

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

Сообщение jsa » 15.11.2023 08:16:30

Здравствуйте.
Имеется на одном сайте 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
и сайт принимает файл
jsa
постоялец
 
Сообщения: 261
Зарегистрирован: 28.11.2017 13:46:04

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

Сообщение Alex2013 » 16.11.2023 14:35:44

Все просто "хорошо сформулированный вопрос содержит как минимум половину ответа "! :idea: :wink:
Alex2013
долгожитель
 
Сообщения: 2957
Зарегистрирован: 03.04.2013 11:59:44

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

Сообщение sts » 16.11.2023 15:08:06

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

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

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

Добавлено спустя 1 минуту 44 секунды:
jsa писал(а):Хороший тут форум.
Волшебный :lol:

да, на тех где много народу обхаяли бы в первых 20 ответов, у тут просто некому обхаять
sts
постоялец
 
Сообщения: 415
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

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

Сообщение DedFrend » 18.11.2023 11:20:32

Дык, пока формулируешь вопрос, еще десять раз обдумаешь проблему. У меня случалось, что проблема решалась еще до того, как вопрос отправлю!
DedFrend
постоялец
 
Сообщения: 156
Зарегистрирован: 25.11.2018 12:21:50


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 90

Рейтинг@Mail.ru