TIdHTTP访问从HTTP重定向到HTTPS页面出错问题的解决

使用TIdHttp 访问http协议的网页,碰到返回的页面自动重定向到https协议的地址,然后报不能创建SSL连接的错误。

网上搜索后发现只要在TidHttp对象创建后,再创建一个TIdSSLIOHandlerSocketOpenSSL 对象,将TIdHttp对象的IOHandler值设置为新创建的TIdSSLIOHandlerSocketOpenSSL对象,再次编译运行,问题就可以解决。可以自动获取跳转到https协议地址的网页内容。

Popularity: 4% [?]

Related

Delphi6总是提示要注册激活问题解决

好一段时间没有用 Delphi6了,今天在打开一个工程的时候竟然反复提示要注册。

就算是用Kg提供的SN与激活方法都失败了,激活步骤总是先提示注册成功,然后再提示注册失败,郁闷。。。

后来网上找到一篇:
找到注册表:
[HKEY_CURRENT_USER\Software\Borland\Delphi\6.0]

删除下面的 “LM” 键

照做后,再打开 Delphi6,果然全好了,继续使用Delphi6中…

Popularity: 4% [?]

Related

使用indy解析http协议的multipart上传数据

MMS彩信的数据附在Soap包后面,在正常解析soap的xml文件外,还需要对使用multipart/related编码上传的数据做解析处理,在indy中提供了解码类。

处理解码时,需要TIdMessageDecoderMIME负责实际的解码, TIdMIMEBoundary从头信息中做边界信息查找。
解码函数

  1. procedure DecodeFormData(const sHeader: String; ASourceStream:TStream; sSavePath: String);
  2. var
  3.   bEnd : Boolean;
  4.   sTmp: String;
  5.   Decoder: TIdMessageDecoderMIME;
  6.   ds: TStream;
  7. begin
  8.   bEnd := False;
  9.   Decoder := TIdMessageDecoderMIME.Create(nil);
  10.  
  11.   try
  12.     // 设置附件的边界
  13.     Decoder.MIMEBoundary := TIdMIMEBoundary.FindBoundary(sHeader);
  14.     Decoder.SourceStream := ASourceStream;
  15.     Decoder.ReadLn;
  16.    
  17.     repeat
  18.        Decoder.ReadHeader;  // 读入分块的Header信息
  19.        case Decoder.PartType of
  20.            mcptUnknown:
  21.                raise Exception.Create('Unknown form data detected');
  22.            mcptText:
  23.                begin
  24.                   sTmp := Decoder.Headers.Values['Content-Type'];  // 获取ContentType
  25.                   ds := TMemoryStream.Create;
  26.                   try
  27.                      Decoder := Decoder.ReadBody(ds,bEnd);
  28.                      // 如果取的数据仍然是由多块组成,则进行递归处理
  29.                      if AnsiSameText(Fetch(Tmp, ';'),'multipart/mixed') then
  30.                         DecodeFormData(sTmp, ds, sSavePath)
  31.                      else
  32.                         // 根据需要使用Dest的数据
  33.                   finally
  34.                      FreeAndNil(ds);
  35.                   end;//try
  36.                end; //  mcptText
  37.  
  38.            mcptAttachment:
  39.                begin
  40.                   // 处理附件的文件名
  41.                   sTmp := ExtractFileName(Decoder.FileName);
  42.                   if sTmp <> '' then
  43.                      sTmp := sSavePath + sTmp
  44.                   else
  45.                      sTmp := MakeTempFilename(sSavePath);
  46.  
  47.                   ds := TFileStream.Create(sTmp, fmCreate);
  48.                   try
  49.                       Decoder := Decoder.ReadBody(ds,bEnd);
  50.                   finally
  51.                       FreeAndNil(ds);
  52.                   end;//try
  53.              end;  // mcptAttachment
  54.         end; // case
  55.     until (Decoder = nil) or bEnd;
  56.   finally
  57.     FreeAndNil(Decoder);
  58.   end;//try
  59. end;

使用OnCreatePostStream 创建用来接受HttpPost数据的Stream

  1. CreatePostStream(ASender: TIdPeerThread; var VPostStream: TStream);
  2. begin
  3.    VPostStream := TMemoryStream.Create;
  4. end;

最后在OnCommandGet中做解析处理

  1. OnCommandGet(ASender: TIdPeerThread; ARequestInfo: TIdHttpRequestInfo; AResponseInfo: TIdHttpResponseInfo);
  2. var
  3.    sContentType : String
  4. begin
  5.    sContentType := ARequestInfo.ContentType;
  6.  
  7.    if AnsiSameText(Fetch(S, ';'), 'multipart') then begin
  8.         DecodeFormData(sContentType, ARequestInfo.PostStream, 'c:temp');
  9.    end else
  10.             // 根据需要对请求数据做处理…
  11. end;

Popularity: 3% [?]

Related

Indy 的 ReadTimeOut 设置失效?

最近在做MMS彩信接口程序,因为不使用Java平台,运营商所提供的Java版的MMS开发包无用,只好按照通信协议用indy直接连接服务端发送拼装好的数据封包来做处理。

为了将自己程序发出的封包和使用java开发包发出的数据包做对比,使用indy做了一个简单的tcpserver来接收发出的封包数据做保存。发现设置的ReadTimeOut设置无效,到了设置的超时时间仍然会处于阻塞状态,只有连接断开才可以继续下去。

网上搜索了一下,发现这个问题是Indy早期版本存在的Bug,indy采用的是阻塞模式,如果Server端未返回信息,这个readln会一直等下去,设置的TimeOut不会起作用(处于死循环中,没有跳出条件),是个BUG。
INDY团队给出的解决办法如下:
第一种:
对ReadFromStack函数的最后一小段做修改:

until   (LByteCount   <>   0)   or   (Connected   =   False);

修改为:

until   (LByteCount   <>   0)   or   (Connected   =   False)   or   (Result  =   -1);

第二种:
在  ReadFromStack()  的后面 // TimeOut 后面位置

//   Timeout
if   ARaiseExceptionOnTimeout   then   begin
raise   EIdReadTimeout.Create(RSReadTimeout);
end;
Result   :=   -1;

修改为:

//   Timeout
Result   :=   -1;   //   MOVED!
if   ARaiseExceptionOnTimeout   then   begin
raise   EIdReadTimeout.Create(RSReadTimeout);
end   else   //   ADDED!
break;   //   ADDED!

按照以上方法中的一个做了修改,再次接受数据内容,不会处于死等问题。

Popularity: 3% [?]

Related

Delphi2009正式版发布了

Delphi2009发布了,在网上找了一些地址下载不过要么是连接数过多,无法下载,要么是要下载一个特别的下载工具再下载,最后总算找到一个有可以下载地址连接的页面。

http://www.soapui.cn/wordpress/index.php/archives/35

里面有文件下载地址,需要每个文件单独下载,麻烦,不过有FlashGet这样的工具,下载整个页面上连接文件也简单。
同时这个页面上还有特别文件的下载地址,就不要再到别处找了。

刚好周末了,回家慢慢下载,等着做Delphi2009的使用体验。

Popularity: 2% [?]

Related

使用Delphi4Php的模板功能

Delphi4php使用了smarty做为其内部的模板引擎,在实际使用中,我们只要设置 Page 的 TemplateEngine 属性值为 SmartyTemplate,并将 TemplateFileName 属性设置为该页面对应的 模板文件,在实际使用的时候就会使用模板中设置的布局来显示。

模板文件遵循Smarty 的风格,区别就是使用 {% 和 %} 来包含模板脚本内容, 而不是我们习惯的 { 和 }包含。

在模板中可以直接使用在 Page 上定义的属性,比如,在 Page 上放一个 Label 取名称 lbTest, 则在模板文件中可以通过 {% $lbTest %} 来将lbTest的Label显示出来, 被显示的lbTest将按照lbTest所定义的各种属性行为来表现,比如字体的大小颜色等,对 lbTest 定义的事件处理方法也会转化为相关的脚本调用。

默认模板可以使用在Page上放置的组件变量,如果要在模板中使用非Page上放置的组件对象,则需要设置Page 的 OnTemplate 事件, 比如。

  1.        function IndexTemplate($sender, $params)
  2.        {
  3.           // 获取使用的模板引擎对象
  4.           $smarty = $params['template']->_smarty;
  5.           // 为模板设置一些非控件的变量值,这儿设置变量名称为 test
  6.           $smarty->assign('test', "测试额外变量文字");
  7.        }

然后在模板中使用 {% $test %} 就可以显示在这儿设置的文字内容。

——-
我测试时发现一个问题,如果在设计时指定好 Page 的 TemplateEngine 和 TemplateFileName,则在修改模板内容并做保存时,会将Page的事件处理关联关系去除,而且按F11不能编辑Page的属性了,不知道是Delphi4Php的Bug问题还是我的RP问题。
好在通过在设计时先不设置这两个属性的值,然后在Page的OnCreate中动态的设置这两个属性的值可以解决这个问题。

  1.        function IndexCreate($sender, $params)
  2.        {
  3.            $this->TemplateEngine = "SmartyTemplate";
  4.            $this->TemplateFilename = "index.tpl";
  5.        }

Popularity: 2% [?]

Related

Delphi4Php 2.0 使用浅尝

自前两天知道Delphi4Php推出2.0版后,于是就从网上下载了下来试一下后的感觉如下:

1.IDE的启动运行速度很快,而且占用资源不多,只有十来兆的内存。(和ZendStudio没有办法比,Delphi4PHP就好像轻装上阵的大奔,ZendStudio就好像肥胖的骡子拉车,毕竟还是原生的Win32程序在运行速度和资源占用上比java写的程序强很多)
2. Delphi4Php 2.0 的IDE原生支持简体中文,只要在 options 的Interface language 中选择 simplified chinese重新启动IDE环境就可以看到菜单什么的都变为中文提示了,只可惜帮助还是英文的,要是再有中文帮助就更好了。
3. 使用类似于Delphi VCL的组件,使php的编程方式延续以前delphi的一些风格,这个对以前用习惯了delphi使用的人还是比较方便的。(使用的是开源的 VCL4Php 包)
4. 使用 smarty 做后台模板处理引擎,但是使用 {% 和 %} 做 smarty 模板代码的识别标志,这样以前对php 的smarty 使用经验可以继续。
5. 有完好的代码完成功能,这个比直接用 EditPlus 编写php代码要方便很多,可以在很大程度上降低代码拼写错的几率
6. 其他一些作为一个ide所应该具有的特性,而且延续了delphi ide的一些功能
7. …

不过有缺憾,没有zend所支持的集成的版本控制库功能。

总的感觉作为一个php的IDE环境在运行速度,资源消耗和功能上还是可以的,但是通过使用VCL4PHP所写出来的代码执行效率就不知道会怎么样了,下次在做测试。

使用中发现一点小问题,当使用一个模板页面做测试时,运行后提示
Fatal error: Smarty error: the $compile_dir ‘/tmp’ does not exist, or is not a directory.
查看了一下SmartyTemplate.inc.php 文件代码,发现在WIN系统下要使用 $_ENV['TMP'] 值的,在我的环境中不知怎么这个为空,于是添加了几行小代码。

global $_ENV;
$_ENV['TMP'] ='d:\www\delphi4phptest\tmp';

在运行,问题解决。

还有就是js脚本对 firefox 的支持不是太好。
使用了一个简单的 button.click 事件的处理,用来设置一个标签上的文字,在IE下运行完好,但是在 firefox 下脚本却不起作用,后来google查找,发现这个地址有说明: FireFox对脚本的执行有限制,引用的js必须要和文件在同一个驱动器下才行(右键查看页面代码可以看到测试运行时,页面有对安装目录下的js引用,使用的是绝对路径),我的测试工程目录和delphi4php的安装目录不在同一个驱动器下,于是将测试工程挪到安装驱动器下继续测试,这时在firefox下打开正常。

Popularity: 3% [?]

Related

Delphi产品仍在继续,Delphi2009快出来了

继borland出售了IDE产品线后,以为相关IDE的产品开发就会停滞了,一段时间一来没有对Delphi的近况做关注。
今天google搜了一下Delphi发现IDE被收购后,Delphi的后续产品仍在继续,而且快发布最新的Delphi2009版了:

这儿是官方对IDE产品线的发展RoadMap.
官方的Delphi for php 2.0网站网页上有视频演示,所见即所得的PHP开发环境,延续了Delphi VCL的类库风格。
Delphi for php 2.0包含中文的多语言资源包
这儿有人列了 Delphi 2009 的一些新特性和使用视频,不过可能视频太大网速不够,没有能够打开看,只能看到一些文字说明。
这儿有人用中文写的对2009的试用评价。增强了unicode支持,扩展了类似于 java, c#的命名空间, 增添了期望已久的类似 C++ template功能的Generics单元。

不过奇怪他们的Delphi 2009 Beta版是怎么弄来的。目前没有程序不能亲自尝试体验,只能看看他们的试用介绍了。等待正式版发布再下载安装体验。

Popularity: 2% [?]

Related