Il s'agit d'un problème intéressant que je n'ai pas encore réussi à résoudre. Je suis en train d'écrire un client qui communique à travers Internet à un serveur. J'utilise le composant TIdTcpClient Internet Direct (Indy) dans Indy 10 en utilisant la personnalité native de RAD Studio 2007.Delphi Indy IdTcpClient opération de lecture renvoyant des données tronquées pour une requête spécifique
Pour obtenir des données du serveur, j'émets une requête HTTP en utilisant SSL sur le port 443 où les détails de ma demande sont contenus dans le corps du message HTTP. Jusqu'ici tout va bien. Le code fonctionne comme le charme, à une exception près.
Une demande que je soumets qui devrait produire une réponse d'environ 336 Ko du serveur (l'en-tête de réponse HTTP contient Content-Length: 344795). Le problème est que je ne récupère que 320KB. La réponse, qui est en XML, est clairement tronquée au milieu d'un élément XML.
Pour ce que ça vaut, le XML est un texte simple. Aucun caractère spécial ne peut expliquer la troncature. Mon composant TIdTcpClient signale simplement qu'après avoir reçu la réponse partielle, le serveur a fermé la connexion correctement (ce qui explique comment chaque réponse devrait être terminée, même celles qui ne sont pas tronquées, donc ce n'est pas un problème).
Je peux faire des appels presque identiques au même serveur où la réponse est aussi plus que quelques kilo-octets, et tout cela fonctionne très bien. Une demande que je fais renvoie environ 850 Ko, une autre renvoie environ 300 Ko, et ainsi de suite.
En résumé, je rencontre ce problème uniquement avec la requête spécifique. Toutes les autres demandes, qui sont nombreuses, reçoivent une réponse complète.
J'ai parlé au créateur du service, et ai fourni des exemples de ma demande. Il a signalé que la demande est correcte. Il m'a aussi dit que quand il envoie la même requête à son serveur, il obtient une réponse complète.
Je suis à perte. Soit le créateur du service se trompe, et il y a effectivement un problème avec la réponse à cette fin, ou il y a quelque chose de particulier dans ma demande.
Y at-il une solution ici qui me manque? Notez que j'ai également utilisé un certain nombre d'autres mécanismes de lecture (ReadString, ReadStrings, ReadBytes, etc) et tous produisent le même résultat, une troncature de cette réponse spécifique à la marque 320 Ko.
Le code n'est probablement pas pertinent, mais je vais l'inclure quand même. Désolé, mais je ne peux pas inclure la requête XML, car elle contient des informations propriétaires. (ReadTimeout est réglé à 20 secondes, mais le retour de la requête en 1 seconde, il est donc pas un problème de délai d'attente.)
function TClient.GetResponse(PayloadCDS: TClientDataSet): String; var s: String; begin try try s := GetBody(PayloadCDS); IdTcpClient1.Host := Host; IdTcpClient1.Port := StrToInt(Port); IdTcpClient1.ReadTimeout := ReadTimeout; IdTcpClient1.Connect; IdTcpClient1.IOHandler.LargeStream := True; //IdTcpClient1.IOHandler.RecvBufferSize := 2000000; IdTcpClient1.IOHandler.Write(s); Result := IdTcpClient1.IOHandler.AllData; except on E: EIdConnClosedGracefully do begin //eat the exception end; on e: Exception do begin raise; end; end; finally if IdTcpClient1.Connected then IdTcpClient1.Disconnect; end; end;
TIdHTTP prend en charge SSL de la même manière que TIdTCPClient - en affectant un IOHandler SSL avant la connexion. Vous devriez vraiment utiliser le composant TIdHTTP pour gérer le trafic HTTP. C'est pourquoi il existe en premier lieu. –
De même, dans la version actuelle d'Indy 10, la valeur par défaut de la propriété SSLOptions.Method n'est pas sslvSSLv2, elle est sslvTLSv1. Il est logique que la définition de la méthode sur sslvSSLv23 élimine certaines erreurs. Lorsque la méthode est définie sur autre chose que sslvSSLv23, l'autre partie * doit * utiliser cette version SSL spécifique à sa fin, sinon l'établissement de liaison SSL échouera. D'autre part, sslvSSLv23 est plus un joker qui accepte toutes les versions SSL de SSLv2 à TLSv1, et permet aux deux parties de négocier une version SSL compatible. –