2016-07-27 32 views
0

Ich möchte eine Datei mit PUT auf TIdHtttp hochladen. Ich habe eine Antwort von Remy Lebeau gefunden, die sagt, dass ich PUT nicht verwenden soll, sondern stattdessen POST.Verwenden Sie PUT zum Hochladen von Datei mit TIdHTTP

Aber in meinem Fall kann ich es nicht tun, weil ich eine dritte API verwende, und es gibt an, dass ich PUT verwenden muss. Wenn ich versuche, POST zu verwenden, gibt es mir eine Nachricht zurück, die besagt, dass die Methode nicht erlaubt ist.

Grundsätzlich versuche ich, so etwas zu tun:

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); 

Aber wenn ich es tun, erhalte ich eine 500 - Internal server error.

Wenn ich entfernen das:

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

I 400 - Bad Request bekommen.

Ich habe bereits versucht, die Anfrage direkt vom Browser (Advanced REST-Client - Chrom) zu tun, und es funktioniert. Also die API funktioniert. Der Header der Nachricht, wenn es funktioniert, ist:

 
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 

Der Code ist nicht hier, aber ja ich die Autorisierungsinformationen konfiguriert, dass es funktioniert, kann ich dies überprüfen, weil ich andere nennen API verwenden können.

aktualisieren

Dies ist die API, die ich PUT zu verwenden, ich versuche: http://docs.transifex.com/api/translations/#put

Wege, die ich versucht:

1) Diese eine Rückkehr 500 - Internal Server Error. Ich habe es versucht, das DS-Objekt mit Inhaltstyp application/octet-stream zu erstellen. Aber ich habe den gleichen Fehler.

2) Die Art und Weise, die auf Antworten vorgeschlagen wurde, aber es funktioniert nicht. Ich habe auch den Fehler 500 bekommen.

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; 
+0

Geben Sie den vollständigen Code mit allen von Ihnen festgelegten Headern ein. Der letzte Parameter in der 'AddFile'-Prozedur sollte' application/octet-stream 'sein. Setzen Sie 'ContentType' NICHT manuell, wenn Sie' TIdMultiPartFormDataStream' nicht verwenden. Ansonsten verwende 'RequestContentType', wie ich bereits erwähnt habe. Speichern Sie Ihre Header von 'TIdHTTP.Request.RawHeaders.Text oder verwenden Sie das Ereignis "OnIdHTTPHeadersAvailable" und vergleichen Sie Ihre Kopfzeilen. Wenn Sie genau die gleiche Anfrage senden, muss es funktionieren. – smooty86

Antwort

4

Diese API ist durch das Design gebrochen. Sie sollten multipart/form-data und PUT nicht mischen. Sie sollten es wie dieses

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

senden Aber wenn es nicht funktioniert, ist das Problem wahrscheinlich ist, dass Sie keine korrekte ContentType gesetzt haben, ist es nicht Grenze enthalten. Fix it wie diese

FHTTP.Request.ContentType:=DS.RequestContentType; 

Wo DS Ihre TIdMultiPartFormDataStream ist.

+2

'TIdMultiPartFormDataStream' soll mit' Post() 'verwendet werden, und diese Version von' Post() 'setzt intern den' ContentType' mit der Grenze. Wenn Sie 'Put' '' '' 'TIdMultiPartFormDataStream' 'eingeben, dann müssen Sie den' ContentType' manuell setzen und dafür 'RequestContentType' verwenden. –

+0

Es funktioniert nicht! Ich bekomme immer noch eine schlechte Anfrage. Ich habe beide Fälle ausprobiert. Ich habe mehr Informationen über die Frage. –

0

Ich habe das Problem gefunden. Es ging um die Grenze, die ich setzen musste. Das Endergebnis lautet also:

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; 
+1

Was für eine Überraschung! Ich habe dir gestern gesagt, 'RequestContentType' zu ​​verwenden und die Grenze manuell erneut zu setzen ... – smooty86

+0

oooo sorry! Ich habe es nicht gesehen. Erstelle eine Antwort und ich akzeptiere sie! –

+0

Aber es ist in der Antwort erwähnt ... – smooty86