Apache 托管 Web 服务不处理 TRemotable 类

发布于 2024-09-04 23:37:19 字数 2726 浏览 2 评论 0原文

我从使用 Delphi 2009 创建的 ISAPI DLL 开始,该模块在 Windows XP 上的 IIS 5.1 中运行时按预期执行。当使用 Apache 2.2.15 和 mod_isapi 托管时,同一模块无法正常运行。为了消除 mod_isapi 有缺陷的可能性,创建了同一服务的 Apache 共享对象模块。然而,作为 Apache 模块也会出现类似的问题。

通过创建两个共享实现代码的项目,我能够创建具有相同实现的 ISAPI DLL 和 Apache 模块。因此,它们之间的唯一区别在于它们连接到主机 Web 服务的方式。这为我提供了托管此服务的三个选项:

  • IIS + ISAPI DLL
  • Apache + Apache Module
  • Apache + mod_isapi + ISAPI DLL。

这两个项目都实现了一个简单的 Web SOAP 服务来进行测试。当您使用 Delphi IDE 创建新的 Soap Server 应用程序时,所有序列化、反序列化、封送处理等均由自动生成的代码处理。该界面有一些简单的测试功能。

为了创建 Apache 模块,我必须遵循以下说明:

SOAP 服务实现的接口非常简单。它有一些变体来测试不同的东西。

IPdiSvc2 = interface(IInvokable)
['{532DCDD7-D66B-4D2C-924E-2F389D3E0A74}']
  function Echo(data:string): string; stdcall;
  function SendFile1(request: TSendFileRequest; attachment: TSOAPAttachment):
    TSendFileResponse; stdcall;
  function SendFile2(request:string): TSendFileResponse; stdcall;
  function SendFile3():TSendFileResponse; stdcall;
  function SendFile4(attachment: TSoapAttachment): TSendFileResponse; stdcall;
  function SendFile5(request: TSendFileRequest):TSendFileResponse; stdcall;
end;

TSendFileRequest 和 TSendFileResponse 也非常简单。

TSendFileRequest = class(TRemotable)
  private
    FFilename: string;
  published
    Property Filename: string read FFilename write FFilename;
end;

TSendFileResponse = class(TRemotable)
  private
    FFileID: Int64;
  published
    Property FileID: Int64 read FFileId write FFileID;
end;

该接口的实现充满了虚拟代码,这些代码只是创建一个结果对象以发送回客户端。实现中不存在重要的代码。

当通过 ISAPI 托管在 IIS 中时,该服务公开的所有方法都可以完美运行。

当托管在 Apache 中时,任何包含 TRemotable 参数的方法都会出错。在此接口中,SendFile1 和 SendFile5 受到影响,因为它们有 TSendFileRequest 作为参数。对 SendFile1 或 SendFile5 的第一次调用按预期工作。成功调用 SendFile1 或 SendFile5 后对任何方法的下一次调用都会导致访问冲突。在 Apache 共享对象模块和使用 mod_isapi 的 ISAPI DLL 中都会观察到此行为。

我不确定问题出在哪里,但我看到三个选项:我的代码、Delphi 代码或 Apache 代码。我只是不知道在哪里。

这个问题非常令人沮丧,因为完全相同的二进制 ISAPI DLL 在 IIS 中可以工作,但在 Apache 中却不行。我将其归因于 ISAPI 主机中的实现差异,但在 Apache 共享对象模块中发生同样的错误意味着发生了其他情况。

为了完整起见,我决定创建同一 Web 服务的 CGI 版本。当在 IIS 下运行时,CGI 版本可以完美运行。在 Apache 中运行时,所有请求都会导致错误:“XML 文档必须具有顶级元素。行:0”

看来 Apache 今天很讨厌我。

I started with an ISAPI DLL which I created with Delphi 2009, This module perform as expected when running in IIS 5.1 on Windows XP. This same module when hosted using Apache 2.2.15 and mod_isapi does not function correctly. To eliminate the possibility that the mod_isapi has some flaw, an Apache Shared Object module of the same service has been created. However similar problems occur as an Apache module as well.

By creating two projects that share implementation code I have been able to create both an ISAPI DLL and an Apache Module that have identical implementations. So the only difference between them is how they connect to their host web service. This gives me three options to host this service:

  • IIS + ISAPI DLL
  • Apache + Apache Module
  • Apache + mod_isapi + ISAPI DLL.

Both projects implement a simple web SOAP service for testing. All the serialization, deserialization, marshaling, etc. is handled by the Auto Generated code when you create a new Soap Server Application using the Delphi IDE. The interface is has a few simple functions for testing.

In order to create an Apache Module I did have to follow these instructions:

The interface that the SOAP service implements is pretty simple. It has some variations to test different things.

IPdiSvc2 = interface(IInvokable)
['{532DCDD7-D66B-4D2C-924E-2F389D3E0A74}']
  function Echo(data:string): string; stdcall;
  function SendFile1(request: TSendFileRequest; attachment: TSOAPAttachment):
    TSendFileResponse; stdcall;
  function SendFile2(request:string): TSendFileResponse; stdcall;
  function SendFile3():TSendFileResponse; stdcall;
  function SendFile4(attachment: TSoapAttachment): TSendFileResponse; stdcall;
  function SendFile5(request: TSendFileRequest):TSendFileResponse; stdcall;
end;

TSendFileRequest and TSendFileResponse are also quite simple.

TSendFileRequest = class(TRemotable)
  private
    FFilename: string;
  published
    Property Filename: string read FFilename write FFilename;
end;

TSendFileResponse = class(TRemotable)
  private
    FFileID: Int64;
  published
    Property FileID: Int64 read FFileId write FFileID;
end;

The implementation of the interface is full of dummy code that just creates a result object to send back to the client. No significant code exists in the implementation.

When hosted in IIS via ISAPI, all methods exposed by the service work perfectly.

When hosted in Apache any method that contains a TRemotable parameter has an error. In this interface SendFile1 and SendFile5 are affected because they have a TSendFileRequest as a parameter. The first call to SendFile1 or SendFile5 works as expected. The next call to any method after a successful call to SendFile1 or SendFile5 results in an access violation. This behavior is observed with both an Apache Shared Object Module, and as an ISAPI DLL using mod_isapi.

I am uncertain where the problem is, but I see three options: my code, Delphi code, or Apache Code. I just can't figure out where.

This problem has been very frustrating since exactly the same binary ISAPI DLL works in IIS but not in Apache. I'd chalk it up to implementation differences in the ISAPI host, but the same mistakes occur in an Apache Shared Object Module means something else is going on.

For completeness I've decided to create a CGI version of the same webservice. When running under IIS the CGI version works perfectly. When running in Apache, all requests result in an error: "XML document must have a top level element. Line: 0"

It seems like Apache just hates me today.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

安静被遗忘 2024-09-11 23:37:19

要排除您是否错误地调用了它,请使用 SoapUI 来使用 WSDL 并发送一些测试消息。看看他们是否成功。如果它在 SoapUI 中工作,则说明客户端代码有问题。如果不起作用,那就是服务器端的问题。另请查看 SoapUI 构建请求对象的方式是否与您预期的不同。

To rule out whether or not your're calling it incorrectly, consume the WSDL with SoapUI and send some test messages. See if they are successful or not. If it works in SoapUI, it's a problem with the client code. If it doesn't work, then it's something on the server side. Also see if SoapUI builds the request object differently than you were expecting.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文