Используйте PUT для загрузки файла с помощью TIdHTTP

Я хотел бы загрузить файл с помощью PUT на TIdHtttp. Я нашел ответ от Реми Лебо, который сказал, что не следует использовать PUT, но вместо этого используйте POST.

Но в моем случае я не могу этого сделать, потому что я использую третий API, и он указывает, что мне нужно использовать PUT. Если я пытаюсь использовать POST, он возвращает мне сообщение о том, что метод не разрешен.

В основном я пытаюсь сделать что-то вроде этого:

Response := TStringStream.Create;
DS := TIdMultiPartFormDataStream.Create;
DS.AddFile('fileUpload2', 'C:\Users\r.rezino\Desktop\teste.po', 'application/octet-stream');
FHttpComunication.Request.ContentType := 'multipart/form-data';
FHttpComunication.Put(UrlCmd, DS, Response);

Но когда я это делаю, я получаю 500 - Internal server error,

Если я удалю:

FHttpComunication.Request.ContentType := 'multipart/form-data';

я получил 400 - Bad Request,

Я уже пытался сделать запрос прямо из браузера (Advanced REST клиент - Chrome), и он работает. Так что API работает. Заголовок сообщения, когда оно работает:

PUT / api / 2 / project / XXXXXXXX / resource / export1po / translation / en / HTTP / 1.1
ВЕДУЩИЙ: www.XXXXXXXXXXXXX.com
авторизация: базовая XXXXXXXXXXXXX
тип контента: multipart/form-data; граница =----WebKitFormBoundaryPWT8bUdkQ1ZVLHdL
принять: приложение / JSON
принять кодировку: gzip, deflate
язык принятия: en-US,en;q=0,8
пользовательский агент: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, как Gecko) Chrome/51.0.2704.103 Safari/537.36
длина контента: 1936   

------WebKitFormBoundaryPWT8bUdkQ1ZVLHdL
Content-Disposition: форма-данные; Name="fileUpload2"; имя файла ="teste.po"
Тип контента: приложение / октет-поток

Код не здесь, но да, я настроил информацию об авторизации, она работает, я могу проверить это, потому что я могу использовать вызов других API.

Обновить

Это API, который я пытаюсь использовать PUT: http://docs.transifex.com/api/translations/

Способы, которые я попробовал:

1) это одно возвращение 500 - Internal Server Error, Я пытался создать объект DS с типом контента application/octet-stream тоже. Но я получил ту же ошибку.

Response := TStringStream.Create;
DS := TIdMultiPartFormDataStream.Create;
DS.AddFile('fileUpload2', 'C:\Users\r.rezino\Desktop\teste.po', 'multipart/form-data');
try
    FHttpComunication.Request.ContentType := 'multipart/form-data';
    FHttpComunication.Put(UrlCmd, DS, Response);
    Result := Response.DataString;
finally
    Response.Free;
    DS.Free;
end;

2) Способ, который был предложен в ответах, но он не работает. Я получил ошибку 500 тоже.

PutData := TFileStream.Create('C:\Users\r.rezino\Desktop\teste.po', fmOpenRead or fmShareDenyWrite);
Response := TStringStream.Create;
try
    FHttpComunication.Request.ContentType := 'multipart/form-data'; //I tried with and without it 
    FHttpComunication.Put(UrlCmd, PutData, Response);
    Result := Response.DataString;
finally
    Response.Free;
    PutData.Free;
end;

2 ответа

Решение

Этот API не работает по замыслу. Вы не должны смешивать multipart/form-data а также PUT, Вы должны отправить это так

FPutData:=TFileStream.Create('yourfile.dat', fmOpenRead or fmShareDenyWrite);
FHTTP.Put('http://...', FPutData, FResponseStream);

Но если это не работает, проблема, вероятно, в том, что вы не установили правильный ContentType, это не включает границу. Исправить это так

FHTTP.Request.ContentType:=DS.RequestContentType;

куда DS твой TIdMultiPartFormDataStream,

Я нашел проблему. Это было о границе, которую я должен установить. Итак, окончательный результат:

DS := TIdMultiPartFormDataStream.Create;
DS.AddFile('fileUpload2', 'C:\Users\r.rezino\Desktop\teste.po', 'application/octet-stream');
try
    FHttpComunication.Request.ContentType := 'multipart/form-data; boundary=' + DS.Boundary;
    FHttpComunication.Request.AcceptEncoding := '';
    FHttpComunication.Request.Accept := '';
    FHttpComunication.Request.Host := '';
    FHttpComunication.Request.UserAgent := '';

    FHttpComunication.Put(UrlCmd, DS, Response);
finally
    DS.Free;
    Response.Free;
end;
Другие вопросы по тегам