AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Indy TIdCustomHttpServer utf-8 Bug - Workaround gesucht
Thema durchsuchen
Ansicht
Themen-Optionen

Indy TIdCustomHttpServer utf-8 Bug - Workaround gesucht

Ein Thema von ele · begonnen am 20. Okt 2010 · letzter Beitrag vom 1. Nov 2010
Antwort Antwort
ele

Registriert seit: 18. Feb 2009
129 Beiträge
 
Delphi 2010 Professional
 
#1

Indy TIdCustomHttpServer utf-8 Bug - Workaround gesucht

  Alt 20. Okt 2010, 15:37
Delphi-Version: 5
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:
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;
Das Hauptproblem scheint die konversion von UnicodeString zu RawByteString. Delphi nimmt dort irgendwie eine konversion vor, die gar nicht erwünscht ist.

Ich bin für jede Hilfe dankbar.
  Mit Zitat antworten Zitat
ele

Registriert seit: 18. Feb 2009
129 Beiträge
 
Delphi 2010 Professional
 
#2

AW: Indy TIdCustomHttpServer utf-8 Bug - Workaround gesucht

  Alt 1. Nov 2010, 15:57
Habe es wiedereinmal alleine gelöst...

Delphi-Quellcode:
s := TIdURI.URLDecode(CorrectedString);
  RBS := StringToAnsiStringAsIs(s); // !!! Hauptproblem ist hier
mit

Delphi-Quellcode:
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;
Allerdings frage ich mich ob es nicht etwas natives gibt...
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:29 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