J'essaie d'implémenter un POST
à un service Web. Je dois envoyer un fichier dont le type est variable (.docx
, .pdf
, .txt
) avec une chaîne au format JSON.Le téléchargement de fichier échoue, lors de la publication avec Indy et le nom de fichier contient des caractères grecs
je réussi à publier des fichiers avec succès avec un code similaire à ce qui suit:
procedure DoRequest;
var
Http: TIdHTTP;
Params: TIdMultipartFormDataStream;
RequestStream, ResponseStream: TStringStream;
JRequest, JResponse: TJSONObject;
url: string;
begin
url := 'some_custom_service'
JRequest := TJSONObject.Create;
JResponse := TJSONObject.Create;
try
JRequest.AddPair('Pair1', 'Value1');
JRequest.AddPair('Pair2', 'Value2');
JRequest.AddPair('Pair3', 'Value3');
Http := TIdHTTP.Create(nil);
ResponseStream := TStringStream.Create;
RequestStream := TStringStream.Create(UTF8Encode(JRequest.ToString));
try
Params := TIdMultipartFormDataStream.Create;
Params.AddFile('File', ceFileName.Text, '').ContentTransfer := '';
Params.AddFormField('Json', 'application/json', '', RequestStream);
Http.Post(url, Params, ResponseStream);
JResponse := TJSONObject.ParseJSONValue(ResponseStream.DataString) as TJSONObject;
finally
RequestStream.Free;
ResponseStream.Free;
Params.Free;
Http.Free;
end;
finally
JRequest.Free;
JResponse.Free;
end;
end;
Le problème apparaît lorsque je tente d'envoyer un fichier qui contient des caractères grecs et des espaces dans le nom du fichier. Parfois, il échoue et parfois il réussit.
Après beaucoup de recherches, je remarque que l'en-tête POST
est codée par classe d'Indy TIdFormDataField
en utilisant la fonction EncodeHeader()
. Lorsque le message échoue, le nom de fichier codé dans l'en-tête est divisé, par rapport à la publication réussie où n'est pas divisé.
Par exemple:
Επιστολή εκπαιδευτικο.docx
est codé comme=?UTF-8?B?zpXPgM65z4PPhM6/zrvOriDOtc66z4DOsc65zrTOtc+Fz4TOuc66zr8uZG9j?='#$D#$A' =?UTF-8?B?eA==?=
, qui échoue.Επιστολή εκπαιδευτικ.docx
est codé comme=?UTF-8?B?zpXPgM65z4PPhM6/zrvOriDOtc66z4DOsc65zrTOtc+Fz4TOuc66LmRvY3g=?=
, ce qui réussit.Επιστολή εκπαιδευτικ .docx
est codé comme=?UTF-8?B?zpXPgM65z4PPhM6/zrvOriDOtc66z4DOsc65zrTOtc+Fz4TOuc66?= .docx
, ce qui échoue.
J'ai essayé de changer le codage du nom de fichier, le AContentType
de la procédure AddFile()
et le ContentTransfer
, mais aucun de ceux changer le comportement, et je reçois encore des erreurs lorsque le nom de fichier codé est divisé.
Est-ce une sorte de bogue, ou ai-je oublié quelque chose?
Mon code fonctionne pour tous les cas sauf ceux que j'ai décrits ci-dessus. J'utilise Delphi XE3 avec Indy10.
Merci beaucoup @Remy pour la réponse et toutes les explications. J'ai contacté le propriétaire du serveur et nous allons essayer de le déboguer ensemble. En attendant, j'ai essayé la deuxième solution de contournement (8 bits) et travaillé comme un charme. – stmpakir