1

I have written a server daemon (Linux, Ubuntu) which communicates with PHP as frontend layer.

Recently, i updated both FPC and the Indy library to its FPC 2.6.0 and Indy to the trunk version (before i was using the Tiburon branch).

All compiled, and everything looked fine, but, when writing to an IOHandler, nothing gets received (by the PHP client), the client will report that 0 bytes were received.

After diving into the problem, i saw that when using the write methods from the IOHandler, the encoding is validated and converted before the response is sent, in the ToBytes() method in IdGlobal.pas.

Now if i comment out the conversion lines in the ToBytes() routines;

if ASrcEncoding <> ADestEncoding then begin
  LBytes := TIdTextEncoding.Convert(ASrcEncoding, ADestEncoding, LBytes);

This time, the PHP client receives the response.

My question is, how can i configure my Indy tcp server or IOHandlers to stop encoding the data ?

4

1 回答 1

1

当IndyTIdTextEncoding.Convert()认为两种编码不同时调用,因此可以将字节从一个字符集转换为另一个字符集。但是,Indy 尚未检测到两个TIdTextEncoding对象何时表示相同的字符集,因此可以跳过转换。这主要是由于SysUtils.TEncodingDelphi 2009-XE 中 Embarcadero 类的限制,它没有公开该信息(在 Delphi XE2 中,TEncoding收到了新的EncodingNameCodePage属性,但 Indy 尚未更新以使用它们)。Indy 的TIdTextEncoding类是TEncodingDelphi 2009+ 中的别名,并TEncoding以 Delphi 5-2007 和 FreePascal 为模型,以便在整个 Indy 代码页中维护单个 API。

Indy 目前只是将TIdTextEncoding对象指针相互比较,这在使用TIdTextEncoding类属性中的标准编码时很好,因为它们在内存中实现为单例对象。但是,如果您混合TIdTextEncoding通过该TIdTextEncoding.GetEncoding()方法获得的对象,例如从 Indy 的CharsetToEncoding()函数中获得的对象,那么即使它们的字符集匹配,对象指针也不会匹配。在理想情况下,这将是从 charset 到 Unicode 再到相同 charset 的无操作转换。

但是,在 FreePascal 下,TIdTextEncoding使用的是 ICONV 库,而 Indy 的 ICONV 支持是不完整的。实现了转换,但尚未实现完整的错误处理,主要是由于errno在不同平台上访问变量的问题,ICONV 使用该变量来扩展错误报告。并非所有 ICONV 的错误都是致命的,但 Indy 还无法检测到它们。

更糟糕的TEncoding是,设置为在发生转换错误时不抛出异常,仅在发生缓冲区错误时(Embarcadero 对此感到羞耻)。如果发生数据转换错误,TEncoding只返回空数据。TIdTextEncoding我们必须在非 D2009+ 环境下保持这种行为,比如 FreePascal。我想可以更新 Indy 以在内部检查该条件并在需要时引发自己的异常。

要回答您的问题,您无法告诉 Indy 跳过对TIdTextEncoding.Convert(). 您暂时必须将其注释掉并重新编译 Indy。这是当前 Indy 版本中的一个已知问题,并且已经完成了一些工作来解决它,但是还没有关于何时准备好供公众使用的 ETA。在 Indy 11 中,我们可能会放弃对 Indy 本地字符集引擎的支持TEncoding并实现我们自己的字符集引擎,至少对于常用字符集是这样。这样,我们就不再依赖于任何特定平台的 API。但是我们甚至还没有开始 Indy 11 的工作,甚至还没有决定它的功能集是什么。

于 2012-03-30T19:49:32.237 回答