2012-03-30 15 views
1

Ich habe einen Server-Daemon geschrieben (Linux, Ubuntu), der mit PHP als Frontend-Layer kommuniziert.Freepascal, Indy SVN Stammversion, nichts vom PHP-Client beim Übertragen von XML empfangen, bis Encoding-Konvertierung entfernt

Vor kurzem habe ich sowohl FPC und die Indy-Bibliothek auf seine FPC 2.6.0 und Indy auf die Trunk-Version aktualisiert (bevor ich die Tiburon-Zweigstelle verwendet habe).

Alle kompiliert, und alles sah gut aus, aber beim Schreiben auf einen IOHandler wird nichts empfangen (vom PHP-Client), der Client meldet, dass 0 Bytes empfangen wurden.

Nach dem Tauchen in das Problem, sah ich, dass bei Verwendung der Schreib-Methoden aus dem IOHandler, die Codierung validiert und konvertiert, bevor die Antwort gesendet wird, in der ToBytes() -Methode in IdGlobal.pas.

Nun, wenn ich die Konvertierungszeilen in den ToBytes() - Routinen auskommentieren;

if ASrcEncoding <> ADestEncoding then begin 
    LBytes := TIdTextEncoding.Convert(ASrcEncoding, ADestEncoding, LBytes); 

Diesmal erhält der PHP-Client die Antwort.

Meine Frage ist, wie kann ich meine Indy TCP-Server oder IOHandlers zu stoppen, die Daten zu kodieren?

Antwort

1

Indy ruft TIdTextEncoding.Convert() auf, wenn es denkt, dass die beiden Kodierungen unterschiedlich sind, so dass Bytes von einem Zeichensatz in einen anderen konvertiert werden können. Indy erkennt jedoch noch nicht, wenn zwei TIdTextEncoding Objekte denselben Zeichensatz darstellen, so dass die Konvertierung übersprungen werden kann. Dies ist hauptsächlich auf eine Einschränkung in Embarcaderos SysUtils.TEncoding-Klasse in Delphi 2009-XE zurückzuführen, die diese Informationen nicht verfügbar macht (in Delphi XE2, TEncoding erhalten neue EncodingName und CodePage Eigenschaften, aber Indy wurde noch nicht aktualisiert, um sie zu verwenden). Indys TIdTextEncoding Klasse ist ein Alias ​​für TEncoding in Delphi 2009+ und ist in Delphi 5-2007 und FreePascal nach TEncoding modelliert, um eine einzige API in Indys Codepage beizubehalten.

Indy vergleicht gerade TIdTextEncoding Objektzeiger miteinander, was in Ordnung ist, wenn die Standardkodierungen aus den Klasseneigenschaften TIdTextEncoding verwendet werden, da sie als Singleton-Objekte im Speicher implementiert sind. Wenn Sie jedoch TIdTextEncoding Objekte mischen, die von der TIdTextEncoding.GetEncoding()-Methode abgerufen werden, z. B. von Indys CharsetToEncoding()-Funktion, stimmen die Objektzeiger nicht überein, auch wenn ihre Zeichensets dies tun. Unter idealen Bedingungen wäre das eine No-Op-Konvertierung von Zeichensatz zu Unicode zurück zum selben Zeichensatz.

Unter FreePascal verwendet jedoch TIdTextEncoding die ICONV-Bibliothek und Indys ICONV-Unterstützung ist unvollständig. Konvertierungen werden implementiert, eine vollständige Fehlerbehandlung ist jedoch noch nicht implementiert, hauptsächlich aufgrund von Problemen beim Zugriff auf die Variable errno auf verschiedenen Plattformen, die ICONV für die erweiterte Fehlerberichterstattung verwendet. Nicht alle Fehler von ICONV sind fatal, aber Indy kann sie noch nicht erkennen.

Schlimmer, TEncoding ist eingerichtet, keine Ausnahmen zu werfen, wenn Konvertierungsfehler auftreten, nur wenn Pufferfehler auftreten (Schande auf Embarcadero dafür). Wenn ein Datenkonvertierungsfehler auftritt, gibt TEncoding nur leere Daten zurück. Wir mussten dieses Verhalten in TIdTextEncoding unter Nicht-D2009 + Umgebungen wie FreePascal beibehalten. Ich nehme an, Indy könnte aktualisiert werden, um intern nach dieser Bedingung zu suchen und bei Bedarf eine eigene Ausnahme auszulösen.

Um Ihre Frage zu beantworten, gibt es nichts, was Sie tun können, um Indy zu sagen, den Anruf zu TIdTextEncoding.Convert() zu überspringen.Du müsstest es auskommentieren und Indy vorerst neu kompilieren. Dies ist ein bekanntes Problem in der aktuellen Indy-Version, und es wurden einige Arbeiten durchgeführt, um es zu beheben, aber es gibt noch keine ETA, wann diese für den öffentlichen Gebrauch bereit sein wird. In Indy 11 werden wir wahrscheinlich die Unterstützung für TEncoding fallen lassen und unsere eigene Charset-Engine nativ in Indy implementieren, zumindest für häufig verwendete Zeichensätze. Auf diese Weise sind wir nicht mehr an bestimmte plattformspezifische APIs gebunden. Aber wir haben noch nicht einmal mit der Arbeit an Indy 11 begonnen, oder wir haben sogar entschieden, was das Feature sein wird.

+0

Danke, ich hatte Angst davor, ich denke, ich werde einen Klassenhelfer hinzufügen, der die Routine mit der Konvertierung entfernt kopiert, so werde ich den Haupt-Indy-Code intakt halten, werde ich das Ergebnis, das hilfreich sein kann zu anderen. – Marius