2016-07-27 2 views
0

Je voudrais télécharger un fichier en utilisant PUT sur TIdHtttp. J'ai trouvé une réponse de Remy Lebeau disant de ne pas utiliser PUT, mais d'utiliser POST à ​​la place.Utilisez PUT pour télécharger un fichier avec TIdHTTP

Mais, dans mon cas, je ne peux pas le faire parce que j'utilise une troisième API, et il précise que j'ai besoin d'utiliser PUT. Si j'essaie d'utiliser POST, il me renvoie un message disant que la méthode n'est pas autorisée.

Fondamentalement, je suis en train de faire quelque chose comme ceci:

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

Mais quand je le fais, je reçois un 500 - Internal server error.

Si je retire le:

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

Je reçois 400 - Bad Request.

J'ai déjà essayé de faire la demande directement depuis le navigateur (client REST avancé - chrome) et cela fonctionne. Donc, l'API fonctionne. L'en-tête du message quand il fonctionne est:

 
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 

Le code est pas là, mais oui, je configuré les informations d'autorisation, il travaille, je peux vérifier cela parce que je peux utiliser d'autres appellent à l'API.

Mise à jour

Ceci est l'API que je suis en train d'utiliser PUT: http://docs.transifex.com/api/translations/#put

façons que j'essayées:

1) Celui-ci retour 500 - Internal Server Error. Je l'ai essayé en créant l'objet DS avec le type de contenu application/octet-stream aussi. Mais j'ai eu la même erreur.

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) La façon dont cela a été suggéré sur les réponses, mais cela ne fonctionne pas. J'ai eu l'erreur 500 aussi.

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

Fournir le code complet avec tous les en-têtes que vous définissez. Le dernier paramètre de la procédure 'AddFile' devrait être' application/octet-stream'. Ne définissez pas 'ContentType' manuellement si vous n'utilisez pas' TIdMultiPartFormDataStream'. Sinon, utilisez la fonction 'RequestContentType' comme je l'ai mentionné. Enregistrez vos en-têtes à partir de TIdHTTP.Request.RawHeaders.Text' ou utilisez l'événement 'OnIdHTTPHeadersAvailable' et comparez vos en-têtes. Si vous envoyez exactement la même requête, cela doit fonctionner. – smooty86

Répondre

4

Cette API est cassée par conception. Vous ne devriez pas mélanger et PUT. Vous devez envoyer comme ça

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

Mais si cela ne fonctionne pas, le problème est probablement que vous ne définissez pas ContentType correcte, il ne comprend pas la limite. Résoudre le problème comme celui-ci

FHTTP.Request.ContentType:=DS.RequestContentType; 

DS est votre TIdMultiPartFormDataStream.

+2

'TIdMultipartFormDataStream' est destiné à être utilisé avec' Post() ', et cette version de' Post() 'définit' ContentType' en interne, avec boundary. Si vous mettez Put() 'TIdMultipartFormDataStream', alors oui, vous devez définir' ContentType' manuellement, et utiliser 'RequestContentType' pour cela. –

+0

Ça ne marche pas! Je reçois toujours une mauvaise demande. J'ai essayé les deux cas. Je impair plus d'informations sur la question. –

0

J'ai trouvé le problème. C'était à propos de la frontière que je dois définir. Donc, le résultat final est:

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

Quelle surprise! Je vous ai dit d'utiliser 'RequestContentType' hier et vous définissez manuellement les limites ... – smooty86

+0

oooo sorry! Je ne l'ai pas vu. Crée une réponse et je l'accepterai! –

+0

Mais il est mentionné dans la réponse ... – smooty86