![]() |
WriteRFCStrings Fehler
Hi DP-ler,
jetzt will ich Euch auf einen bösen Fehler in procedure TIdTCPConnection.WriteRFCStrings hinweisen. RFC Strings werden in vielen Text-basierten TCP-Protokollen genutzt. Dabei wird dem Empfänger nicht gesagt, wie viele Bytes zu erwarten sind, jedoch stillschweigend vereinbart, daß die Übertragung der Daten durch ein <CRLF>.<CRLF> beendet wird. Damit es nicht zu Mißverständnissen kommt, wenn eine Zeile übertragen wird, die lediglich einen Punkt . beinhaltet, werden, lt. Protokoll alle Zeilen, welche mit einem starten durch einen vorangestellten Punkt erweitert. Die Indy-WriteRFCStrings Prozedur versucht dieses wie folgend zu lösen:
Delphi-Quellcode:
Da liegt der Fehler einfach zu sehen. Das RFC gibt vor, daß alle Zeilen die mit einem Punkt starten einen weiteren vorangestellt bekommen, die Indy-Methode erweitert allerdings nur Zeilen, welche ausschließlich einen Punkt haben :shock:
procedure TIdTCPConnection.WriteRFCStrings(AStrings: TStrings);
var i: Integer; begin for i := 0 to AStrings.Count - 1 do begin // --- FEHLER !!! if AStrings[i] = '.' then begin WriteLn('..'); end else begin WriteLn(AStrings[i]); end; end; WriteLn('.'); end; Daß dieses wirklich ein Fehler ist, kann man an der Capture-Methode erkennen, dort werden nämlich alle Zeilen, welche mit zwei Punkten starten um einen gekürzt ;-)
Code:
Wie dem auch sei, da ihr ja die Source zu Indy habt, könnt Ihr die Methode WriteRFCStringsie folgend anpassen.
procedure TIdTCPConnection.PerformCapture(ADest: TObject; out VLineCount: Integer;
const ADelim: string; const AIsRFCMessage: Boolean); const [color=#ff0024]wDoublePoint = ord('.') shl 8 + ord('.');[/color] type PWord = ^Word; var s: string; begin VLineCount := 0; BeginWork(wmRead); try repeat s := ReadLn; if s = ADelim then begin Exit; end; // For RFC 822 retrieves // No length check necessary, if only one byte it will be byte x + #0. [color=#ff0000]if AIsRFCMessage and (PWord(PChar(S))^ = wDoublePoint) then begin Delete(s, 1, 1);[/color] end; // Write to output Inc(VLineCount); if ADest is TStrings then begin TStrings(ADest).Add(s); end else if ADest is TStream then begin TIdStream(ADest).WriteLn(s); end else if ADest <> nil then begin raise EIdObjectTypeNotSupported.Create(RSObjectTypeNotSupported); end; until False; finally EndWork(wmRead); end; end;
Code:
Weiterhin viel Spass mit den kleinen Indianern :mrgreen:
procedure TIdTCPConnection.WriteRFCStrings(AStrings: TStrings);
var i: Integer; begin for i := 0 to AStrings.Count - 1 do begin [color=#f50000]if Copy(AStrings[i], 1, 1) = '.' then begin WriteLn('.' + AStrings[i]);[/color] end else begin WriteLn(AStrings[i]); end; end; WriteLn('.'); end; ...:cat:... [edit=Chakotay1308]Titel angepasst. Mfg, Chakotay1308[/edit] |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz