使用PUT通过TIdHTTP上传文件

时间:2016-07-27 10:23:37

标签: delphi indy transifex

我想在TIdHtttp上使用PUT上传文件。我发现Remy Lebeau的答案是不使用PUT,而是使用POST。

但是,在我的情况下,我不能这样做,因为我使用的是第三个API,它指定我需要使用PUT。如果我尝试使用POST,它会返回一条消息,指出不允许使用Method。

基本上,我试图做这样的事情:

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

我已经尝试直接从浏览器(高级REST客户端 - chrome)执行请求,但它确实有效。所以API正在运行。消息工作时的标题是:

PUT /api/2/project/XXXXXXXX/resource/export1po/translation/en/ HTTP/1.1
HOST: www.XXXXXXXXXXXXX.com
authorization: Basic XXXXXXXXXXXXX
content-type: multipart/form-data; boundary=----WebKitFormBoundaryPWT8bUdkQ1ZVLHdL
accept: application/json
accept-encoding: gzip, deflate
accept-language: en-US,en;q=0.8
user-agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
content-length: 1936   

------WebKitFormBoundaryPWT8bUdkQ1ZVLHdL
Content-Disposition: form-data; name="fileUpload2"; filename="teste.po"
Content-Type: application/octet-stream

代码不在这里,但是我配置了授权信息,它正在运行,我可以检查一下,因为我可以使用其他人调用API。

更新

这是我尝试使用PUT的API:http://docs.transifex.com/api/translations/#put

我尝试的方式:

1)这一回归500 - Internal Server Error。我尝试过创建内容类型为application/octet-stream的DS对象。但我得到了同样的错误。

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 个答案:

答案 0 :(得分:4)

该API被设计破坏了。您不应该混用multipart/form-dataPUT。你应该像这样发送

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

但如果它不起作用,问题可能是你没有设置正确的ContentType,它不包括边界。像这样修复它

FHTTP.Request.ContentType:=DS.RequestContentType;

DSTIdMultiPartFormDataStream

答案 1 :(得分:0)

我发现了问题。这是我必须设定的边界。所以最终的结果是:

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;