FreePascal strings are not UTF-16 encoded like they are in Delphi 2009+. In FreePascal, and in Delphi 2007 and earlier, your code needs to take the actual string encoding into account. That is why Indy exposes additional Ansi-based parameters/properties for those platforms.
When TIdHTTPServer
writes out the ContentText
using TIdIOHandler.Write()
, the ASrcEncoding
parameter is not used on non-Unicode platforms, so you will have to use the TIdIOHandler.DefAnsiEncoding
property instead to let Write()
know what the encoding of the ContentText
is, eg:
procedure TMyServer.DoCommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
const
UNI: WideString = '中文';
begin
AResponseInfo.ContentText := UTF8Encode('<html>' + UNI + '</html>');
AResponseInfo.ContentType := 'text/html';
// this tells TIdHTTPServer what to encode bytes to during socket transmission
AResponseInfo.CharSet := 'utf-8';
// this tells TIdHTTPServer what encoding the ContentText is using
// so it can be decoded to Unicode prior to then being charset-encoded
// for output. If the input and output encodings are the same, the
// Ansi string data gets transmitted as-is without decoding/reencoding...
AContext.Connection.IOHandler.DefAnsiEncoding := IndyUTF8Encoding;
end;
Or, more generically:
{$I IdCompilerDefines.inc}
procedure TMyServer.DoCommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
const
UNI{$IFNDEF STRING_IS_UNICODE}: WideString{$ENDIF} = '中文';
begin
{$IFDEF STRING_IS_UNICODE}
AResponseInfo.ContentText := '<html>' + UNI + '</html>';
{$ELSE}
AResponseInfo.ContentText := UTF8Encode('<html>' + UNI + '</html>');
{$ENDIF}
AResponseInfo.ContentType := 'text/html';
AResponseInfo.CharSet := 'utf-8';
{$IFNDEF STRING_IS_UNICODE}
AContext.Connection.IOHandler.DefAnsiEncoding := IndyUTF8Encoding;
{$ENDIF}
end;