• Delphi XE2 里面string 与 ansistring 转换导致kbmMW 的一个bug


        昨天本来准备写一个kbmMW 做webserver 的一个例子,可是在调试过程中发现不能正常显示图片文件。跟踪了很长时间

    才发现是string 和 ansistring 在XE2 里面转换造成的问题,经过修改后,终于可以正常运行了。耽搁了半天时间,因此记录一下,

    给同学们一个参考,以后在编程时注意一下。

      原来的程序代码是这样的:

    procedure TkbmMWAJAXResponseTransportStream.InternalDeliver(const AInfo:IkbmMWCustomTransportInfo);
    var
    i,j,k:integer;
    s,sr:string; // 注意,这一块原来定义的是string;
    ba:TkbmMWBytes;
    hlp,hlpReq:TkbmMWHTTPTransportStreamHelper;
    begin
    hlp:=TkbmMWHTTPTransportStreamHelper(Helper);
    hlpReq:=TkbmMWHTTPTransportStreamHelper(RequestTransportStream.Helper);

    // Make sure we respond using same version as using for request.
    hlp.HTTPVersion:=hlpReq.HTTPVersion;

    // Check if to deliver XML Response or not.
    if not (Params.Values[KBMMW_AJAX_PARAMS_XMLRESPONSE]='1') then
    begin
    // Check which HTTP header to send.
    if Self.IsError then
    begin
    MimeType:='text/html';
    s:=hlp.HTTPBuildErrorResponseHeaderFromStatusCode('',TkbmMWAJAXTransportStreamHelper(Helper).Header,
    Self.StatusCode,Self.StatusText);
    kbmMWDebugDumpString(mwdlAdvanced,mwdtTransport,kbmMWDebugWhere,'AJAX Response deliver HTML body',s);

    AInfo.CloseConnectionAfterTransmit:=true;

    ba:=kbmMWString2Bytes(AnsiString(s));
    TProtTransport(Transport).DoTransmitBuffer(AInfo,ba,length(ba));
    end
    else
    begin
    // If the result is an array, the first element is the header instead of us generating one.
    if not VarIsArray(Result) then
    begin
    // Send ok response with data.
    sr:=Result; // result 原来的值是ansistring, 现在转换成string 类型了
    s:=hlp.HTTPBuildOKResponseHeader('',TkbmMWAJAXTransportStreamHelper(Helper).Header,length(sr))+sr; // length(sr) 是unicodestring 的长度,理论上<= ansistring 的值,因此封装是就使用了一个

    // 一个错误的content-length, 导致客户端与服务器端的数据不一致。
    ba:=kbmMWString2Bytes(AnsiString(s));
    kbmMWDebugDumpString(mwdlAdvanced,mwdtTransport,kbmMWDebugWhere,'AJAX Response deliver HTML',s);
    TProtTransport(Transport).DoTransmitBuffer(AInfo,ba,length(ba));

    下面是修改后的代码:

    procedure TkbmMWAJAXResponseTransportStream.InternalDeliver(const AInfo:IkbmMWCustomTransportInfo);
    var
    i,j,k:integer;
    s,sr:ansistring; // 这一块使用ansistgring, 与原始的数据类型保持一致
    ba:TkbmMWBytes;
    hlp,hlpReq:TkbmMWHTTPTransportStreamHelper;
    begin
    hlp:=TkbmMWHTTPTransportStreamHelper(Helper);
    hlpReq:=TkbmMWHTTPTransportStreamHelper(RequestTransportStream.Helper);

    // Make sure we respond using same version as using for request.
    hlp.HTTPVersion:=hlpReq.HTTPVersion;

    // Check if to deliver XML Response or not.
    if not (Params.Values[KBMMW_AJAX_PARAMS_XMLRESPONSE]='1') then
    begin
    // Check which HTTP header to send.
    if Self.IsError then
    begin
    MimeType:='text/html';
    s:=hlp.HTTPBuildErrorResponseHeaderFromStatusCode('',TkbmMWAJAXTransportStreamHelper(Helper).Header,
    Self.StatusCode,Self.StatusText);
    kbmMWDebugDumpString(mwdlAdvanced,mwdtTransport,kbmMWDebugWhere,'AJAX Response deliver HTML body',s);

    AInfo.CloseConnectionAfterTransmit:=true;

    ba:=kbmMWString2Bytes(AnsiString(s));
    TProtTransport(Transport).DoTransmitBuffer(AInfo,ba,length(ba));
    end
    else
    begin
    // If the result is an array, the first element is the header instead of us generating one.
    if not VarIsArray(Result) then
    begin
    // Send ok response with data.
    sr:=Result;
    s:=hlp.HTTPBuildOKResponseHeader('',TkbmMWAJAXTransportStreamHelper(Helper).Header,length(sr))
    //hlp.HTTPBuildOKResponseHeader 返回的是string, 而且是纯英文的,转换成ansistrng, 不会丢失数据。同时后面不能加sr, 不然的话,会把sr 又转换成string 了, 再转会到 ansistring, 就丢东西了

    s:=s+sr; // 两个ansistring 相加, 保证数据类型一致,不产生隐形变换。
    ba:=kbmMWString2Bytes(s);


    经过上面修改,系统可以正常在XE2 下运行了。当然在d2007 以前,原来的代码没有问题的,看来作者没有在d2009 以后的版本没有好好测试。

    好隐蔽的bug, 浪费了我好几个小时。 特记之。

  • 相关阅读:
    [转]IIS 6.0中配置HTTP Gzip压缩
    SmartPhone下解决rm、rmvb等格式电影播放的方案(参考意见)
    提取文件夹下所有文件,按类型进行提取
    重学JSP—设置CATALINA_HOME环境变量
    android学习笔记
    用myeclipse配置hibernate
    Java 回调函数 转自:http://blog.sina.com.cn/s/blog_48cf38890100go6x.html
    fastadmin单独控制编辑、删除按钮的展示和隐藏
    fastadmin导出图片
    php计算坐标距离
  • 原文地址:https://www.cnblogs.com/xalion/p/2337860.html
Copyright © 2020-2023  润新知