当前位置: 首页 > news >正文

Indy HTTP Server 使用 OpenSSL 3.0

前言

使用 Indy HTTP Server 做一个 Web Server 或者一个 WebService Server,如果使用 Delphi 默认的 TIdServerIOHandlerSSLOpenSSL,只能加载 OpenSSL 1.0 的 DLL 库。

现如今 OpenSSL 已经是 3.0 了。

还好网上有开源的 TTaurusTLSServerIOHandler 可以用来替换 TIdServerIOHandlerSSLOpenSSL 加载 OpenSSL 3.0 的 DLL 库。

以下描述,基于 Delphi 12 社区版。

如何使用

OpenSSL 1.x 的库

首先,如果使用 TIdServerIOHandlerSSLOpenSSL 加载 OpenSSL 1.0 的动态链接库,应该给程序准备:

1. libeay32.dll

2. ssleay32.dll

上述两个文件的下载地址,请参考:

Securing Indy Network Connections - RAD Studio

上面那篇官方文档里面提到的下载地址是:

Index of /SSL

OpenSSL 3.x 的库

如果使用 OpenSSL 3.0 的动态链接库,则应该是给程序以下两个文件:

1. libcrypto-3.dll

2. libssl-3.dll

上述两个 OpenSSL 3.x 的文件的下载地址,在:

https://github.com/JPeterMugaas/TaurusTLS/tree/main

这个地址的首页里面有提供。

关于 TaurusTLS 的使用

首先去 https://github.com/JPeterMugaas/TaurusTLS/tree/main 下载这个控件的源代码。

然后在 Delphi 里面安装它。

问题:

它的官方页面里面提到:

  1. Set the INDY_PATH environment variable for your user account to the location where Indy is located.
  2. Open TaurusForIndy290All.groupproj in the TaurusTLS\Packages\d12 folder.
  3. Compile TaurusTLS_RTForIndy290.
  4. Compile TaurusTLS_DTForIndy290 and install it in the IDE.

但实际上,按照上述说法,没法安装。

问题的详情

TaurusTLS_RTForIndy290 的源文件里面:

requiresrtl,IndyCore290,IndySystem290,IndyProtocols290;

实际上 Delphi 自带的 Indy 里面,没有 IndyCore290.dcp 等上述三个带 290 的文件。

把上述代码的 290 删除掉,仅仅留下 IndyCore 以及另外两个同样去掉 290 的引用,编译能够通过,但整个硬盘到处找,也找不到编译后的 bpl 文件。

问题的解决

仔细观察这个控件所在的文件夹:

Delphi\Controls\TaurusTLS-main\Packages\d12

发现里面实际上有两个包文件,名字是:

TaurusTLS_RT.dpk

TaurusTLS_DT.dpk

打开这两个包文件来编译,安装控件成功!

因此,不应该按照它的说明,编译 TaurusTLS_DTForIndy290.dpk 和 TaurusTLS_RTForIndy290.dpk 这两个项目。

使用注意

在 Delphi 中创建一个 Soap Server 项目,选择 Stand alone 模式,因此它就自带了 Indy HTTP Server 作为内置的 Web Server。创建项目时,那个 https 的检查框不要勾选。

程序有了以后,顺便创建一个 WebService 的接口。给接口搞一个函数。我这里是:

{ Invokable interface IIndySSLTaurus }unit IndySSLTaurusIntf;interfaceuses Soap.InvokeRegistry, System.Types, Soap.XSBuiltIns;type{ Invokable interfaces must derive from IInvokable }IIndySSLTaurus = interface(IInvokable)['{CA6E9719-4ABF-4E22-8E81-C74231025E99}']{ Methods of Invokable interface must not use the default }{ calling convention; stdcall is recommended }function Hello(const S: string): string; stdcall;end;implementationinitialization{ Invokable interfaces must be registered }InvRegistry.RegisterInterface(TypeInfo(IIndySSLTaurus));end.

上述接口的实现部分的代码:

{ Invokable implementation File for TIndySSLTaurus which implements IIndySSLTaurus }unit IndySSLTaurusImpl;interfaceuses Soap.InvokeRegistry, System.Types, Soap.XSBuiltIns, IndySSLTaurusIntf;type{ TIndySSLTaurus }TIndySSLTaurus = class(TInvokableClass, IIndySSLTaurus)publicfunction Hello(const S: string): string; stdcall;end;implementation{ TIndySSLTaurus }function TIndySSLTaurus.Hello(const S: string): string;
beginResult := 'Hello, ' + S;
end;initialization
{ Invokable classes must be registered }InvRegistry.RegisterInvokableClass(TIndySSLTaurus);
end.

这个项目,Delphi IDE 默认给出的是 8080 端口。运行它。

然后,做一个 WebService 客户端程序,拖一个 HTTPRIO1 这个控件到 Form 上面。

这个时候,还没有实现 https,因此,给这个 HTTPRIO1.URL 赋值:

http://localhost:8080/soap 就可以了。

给客户端写测试代码:

procedure TForm2.Button1Click(Sender: TObject);
varIntf: IIndySSLTaurus;
beginIntf := HTTPRIO1 as IIndySSLTaurus;tryMemo1.Lines.Add(Intf.Hello(Edit1.Text));finallyIntf := nil;end;
end;

运行客户端,点击按钮,能够在 Memo1 里面看到从服务器端正确返回的值。测试通过。

为服务器端增加 OpenSSL 3.x 的支持

从控件面板,拖一个 TaurusTLSServerIOHandler1 到主界面上。然后为服务器端增加以下代码:

procedure TForm1.FormCreate(Sender: TObject);
beginFServer := TIdHTTPWebBrokerBridge.Create(Self);//必须用代码指定。设计期在属性面板里面指定的证书文件,没有效果。TaurusTLSServerIOHandler1.DefaultCert.PublicKey := 'mysite.net.cert.pem';TaurusTLSServerIOHandler1.DefaultCert.PrivateKey := 'mysite.net.key.pem';FServer.OnQuerySSLPort := OnQuerySSLPort;//写绝对路径也没问题
//  TaurusTLSServerIOHandler1.DefaultCert.PublicKey := 'D:\TestD12\IndySSL_Taurus\证书备份\mysite.net.cert.pem';
//  TaurusTLSServerIOHandler1.DefaultCert.PrivateKey := 'D:\TestD12\IndySSL_Taurus\证书备份\mysite.net.key.pem';FServer.IOHandler := TaurusTLSServerIOHandler1; TaurusTLS.LoadOpenSSLLibrary;
end;procedure TForm1.OnQuerySSLPort(APort: TIdPort; var AUseSSL: Boolean);
beginAPort := 8080;   //如果不加上这个,就只能走默认的 443AUseSSL := True;
end;

剩下的代码就是 Delphi IDE 在创建这个 Soap Server 的时候自动创建的代码了,如下:

procedure TForm1.StartServer;
beginif not FServer.Active thenbeginFServer.Bindings.Clear;FServer.DefaultPort := StrToInt(EditPort.Text); //这里默认是 8080FServer.OnQuerySSLPort := OnQuerySSLPort;FServer.Active := True;end;
end;

另外,还有个事件方法,是关于证书的密码的:

procedure TForm1.TaurusTLSServerIOHandler1GetPassword(ASender: TObject;var VPassword: string; const AIsWrite: Boolean; var VOk: Boolean);
beginVPassword := '';
end;

我的证书是自签发证书,没有密码。因此这个事件方法没有也能运行。

到这里,这个支持OpenSSL  3.x 的 https 的 Soap Server 就可以使用了。编译运行它。

把前面的客户端的 URL 改为:https://localhost:8080/soap 然后运行客户端,测试通过。

需要注意的问题

我在前面的代码里面,为这个控件,赋值了证书文件名:

TaurusTLSServerIOHandler1.DefaultCert.PublicKey := 'mysite.net.cert.pem';TaurusTLSServerIOHandler1.DefaultCert.PrivateKey := 'mysite.net.key.pem';

实际上,它在设计期的属性面板里面,有这两个属性。

但是,如果我们在设计期的属性面板里面填写上面的两个文件名,不管是填文件名,还是填写带绝对路径的文件名,只要没有用代码为它赋值,都不能正常工作。

对比起来,如果采用 Indy 自己的 IdServerIOHandlerSSLOpenSSL1(只支持 OpenSSL 1.x)的话,设计期填写的上述属性,也是能够正常工作的。

还有一个小问题

因为我使用的是自己签发的证书,所以在测试中,在 Debug 状态下,用浏览器访问本程序,Delphi IDE 会弹出不少异常提示,然后浏览器还是能够显示这个 Soap Server 的首页。但此时如果点击首页上的其它链接,比如查看接口,就会出错到页面完全无法显示。

但是,如果此时是使用 Delphi 自己的 Web Service 客户端去访问这个服务器,调用接口函数,没有任何问题,也没有异常错误提示。

结束

使用 Taurus 这个控件,确实能够让 Indy 调用 OpenSSL 3.x 的 DLL 库。

http://www.dtcms.com/a/348527.html

相关文章:

  • 采摘机器人设计cad+三维图+设计说明书
  • 学习记录(二十一)-Overleaf中图片文字间隔太大怎么办
  • 【QT入门到晋级】进程间通信(IPC)-共享内存
  • Java数据结构——7.二叉树(总览)
  • 机器学习周报十
  • 从文本树到结构化路径:解析有限元项目架构的自动化之道
  • Rust Web开发指南 第二章(Axum 路由与参数处理)
  • gcc报错解决办法
  • Maxwell学习笔记
  • 如何让FastAPI在百万级任务处理中依然游刃有余?
  • Node【文件+模块化+对象】详讲:
  • OSG库子动态库和插件等文件介绍
  • k8s原理及操作
  • LLM 中评价指标与训练概要介绍
  • AI Prompt 的原理与实战
  • 【LeetCode】分享|如何科学的刷题?
  • 【深度学习】骨干网络(Backbone)
  • 毛选一卷解析
  • VAREdit:深度解读
  • k8s部署,pod管理,控制器,微服务,集群储存,集群网络及调度,集群认证
  • 在Excel和WPS表格中打印时加上行号和列标
  • rosdep无法获取noetic源?
  • 深入解析 std::enable_if:原理、用法与现代 C++ 实践
  • 维修工人Springboot社区家电服务小程序
  • [身份验证脚手架] 技术栈特定安装逻辑
  • 人形机器人——电子皮肤技术路线:光学式电子皮肤及MIT基于光导纤维的分布式触觉传感电子皮肤
  • Java 学习笔记(基础篇9)
  • 有哪些工具可以帮助监测和分析JVM的内存使用情况?
  • 前端漏洞(上)- Django debug page XSS漏洞(漏洞编号:CVE-2017-12794)
  • jvm对象内存占用