Delphi-Version: 5
Indy TIdCustomHttpServer utf-8 Bug - Workaround gesucht
Hallo Leute,
Ich habe da ein kleines Problem, das mir Kopfschmerzen bereitet. Folgendes Szenario: Ich habe einen Delphi-Web-Server der auf den Indy-Komponenten aufbaut. Wenn der Browser einen Get oder Post-Request absetzt, welcher in den Parametern Unicode-Zeichen (Umlaute, Akzente etc.) enthält, so werden diese vom Browser mit UrlEncode codiert. Also z.B ein Parameter namens MyParam mit dem Wert 'Über': MyParam=%C3%9Cber Das Problem liegt daran, dass Indy (D2010) zuerst ein Utf8Decode vornimmt und erst danach das UrlDecode macht, was leider ein Problem ist, denn die Zeichen #$C3 und #$9C werden als einzelne Zeichen gesetzt. Konkret wird dann daraus: MyParam=Ã'#$009C'ber oder Hexadezimal: $4D $00 $79 $00 $50 $00 $61 $00 $72 $00 $61 $00 $6D $00 $3D $00 $C3 $00 $9C $00 $62 $00 $65 $00 $72 $00 Was ich aber gerne hätte ist: MyParam=Ü'ber oder Hexadezimal: $4D $00 $79 $00 $50 $00 $61 $00 $72 $00 $61 $00 $6D $00 $3D $00 $DC $00 $62 $00 $65 $00 $72 $00 Der fehler liegt klar bei Indy, weil zuerst das Utf8decode vorgenommen wird und danach das UrlDecode gemacht wird anstatt umgekehrt. Ich weiss nicht ob der Fehler in einer aktuelleren Version behoben worden ist, aber erste Versuche mit einer aktuellen Version sind an anderen Problemen gescheitert (veränderte API und ein noch ungeklärtes Problem mit der Cookie-Version). Deshalb suche ich einen Workaround. Und zwar habe ich mir gedacht ich könnte den fehlerhaften String wieder zurückkonvertieren, dass er so aussieht wie der Browser ihn gesendet hat und danach die Korrekte decodierung vornehmen. Aber die Theorie scheitert an der Praxis, es will mir einfach nicht gelingen den ursprünglichen String wiederherzustellen:
Delphi-Quellcode:
Das Hauptproblem scheint die konversion von UnicodeString zu RawByteString. Delphi nimmt dort irgendwie eine konversion vor, die gar nicht erwünscht ist.
uses
IdURI; function URLEncode(Text: String): String; var i: Integer; begin Result := ''; i := 1; while i <= Length(Text) do begin if CharInSet(Text[i], ['A'..'Z', 'a'..'z', '0'..'9', '-', '_', '.', '~' , '/']) and not CharInSet(Text[i], ['!', '*', '''', '(', ')', ';', ':', '@', '&', '=', '+', '$', ',', '?', '#', '%', '[', ']']) then begin Result := Result + Text[i]; Inc(i); end else begin Result := Result + '%' + IntToHex(Ord(Text[i]), 2); inc(i); end; end; end; procedure TForm1.Button1Click(Sender: TObject); var Input: String; WrongString: String; CorrectedString: String; RightString: String; RBS: RawByteString; s: string; Output: String; begin Input := '%C3%9Cber'; // Der Ausgangsstting WrongString := TIdURI.URLDecode(UTF8ToString(Input)); // Das ist das was Indy liefert RightString := 'Über'; // So müsste das Ergebnis aussehen { URLEncode rückgängig machen: TidURI.URLEncode mag es nicht wenn der übergebene String keine URL ist - bzw. das Protokoll fehlt. Deswegen wird hier meine eigene Version von URLDecode() verwendet. } s := URLEncode(WrongString); // Utf8Decode rückgängig machen CorrectedString := UTF8Encode(s); // und richtig decodieren s := TIdURI.URLDecode(CorrectedString); RBS := s; // !!! Hauptproblem ist hier { s : $C3 $00 $9C $00 $62 $00 $65 $00 $72 $00 RBS: $C3 $3F $62 $65 $72 gewünscht wäre: $C3 $9C $62 $65 $72 } Output := UTF8ToString(RBS); ShowMessage('Expected String: ' + RightString + #13 + 'Computed String:' + Output); end; Ich bin für jede Hilfe dankbar. |
AW: Indy TIdCustomHttpServer utf-8 Bug - Workaround gesucht
Habe es wiedereinmal alleine gelöst...
Delphi-Quellcode:
mit
s := TIdURI.URLDecode(CorrectedString);
RBS := StringToAnsiStringAsIs(s); // !!! Hauptproblem ist hier
Delphi-Quellcode:
Allerdings frage ich mich ob es nicht etwas natives gibt...
function StringToAnsiStringAsIs(const A: String): AnsiString;
var i: Integer; begin SetLength(Result, Length(A)); for i := 1 to Length(A) do Result[i] := AnsiChar(Ord(A[I])); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:20 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz