Can TidHttpServer (Delphi XE2) handle urlencoded characters?
I have a TidHttpServer listening to port 8844 with the following code:
procedure TForm1.IdHTTPServer1CommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
if ARequestInfo.Document <> '/favicon.ico' then
begin
Memo1.Text := ARequestInfo.Params.Text;
end;
end;
This is compiled with Delphi XE2. When I browse to
http://localhost:8844/document?Value=%F6 <-- %F6 is the encoded value for ö
...I get the result:
value=?
If i compile the application using Delphi 2007 I get the following result
value=ö
Is this a bug in Indy of something that I have missed?
In XE2, strings are Unicode. When TIdHTTPServer
decodes the ARequestInfo.Document
in D2009 and later, it requires percent-encoded data to decode into UTF-8 encoded data, which is then decoded into the final Unicode string. There is currently no option to change that (I have submitted a feature request to our issue trackers for it). %F6
does not represent a valid UTF-8 octet, which is why you end up with '?'
. In UTF-8, the 'ö'
character would be UTF-8 encoded as $C3 $B6
and thus percent-encoded as %C3%B6
, not %F6
.
In D2007, strings are Ansi. When TIdHTTPServer
decodes the ARequestInfo.Document
in D2007 and earlier, it provides the decoded data as-is, thus %F6
would decode into $F6
and be stored as #246
. That value is then interpretted by the RTL using whatever the local machine's default Ansi codepage is, so it would represent the 'ö'
character only for Ansi codepages that define it that way (Windows-1252 and ISO-8859-1 do, but ISO-8859-5 does not, for example).
I would suggest you change your server logic to use UTF-8 encoded URLs in both Delphi versions. In D2007, you can use the RTL's UTF8Decode()
function to decode a UTF-8 encoded AnsiString
into a WideString
, which you can then assign to another AnsiString
to convert the data into the Ansi value you were originally expecting. In D009+, that is handled automatically for you.
On a side note, accessing a UI component directly in the OnCommandGet
event is not thread-safe. ou have to synchronize with the main thread in order to access the UI safely.