2

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.

Bruce McGee
  • 15,076
  • 6
  • 55
  • 70
William Leader
  • 814
  • 6
  • 20
  • Not that I know anything about threading models for isapi modules, but it does sound like a threading issue. Maybe if you selected a different threading model for your dll, Apache would be happier? – Marjan Venema Jun 11 '10 at 06:40
  • @Marjan: I did stumble upon this page: http://www.drbob42.com/examines/examin80.htm while searching for information on CoInitFlags and COINIT_MULTITHREADED trying to find information about threading in apache. Based on that information I have been able to create a project that produces an Apache Module which is nice because basically now I have one code base that defines the service and two project files one that produces an ISAPI DLL and another that produces an Apache module. I'm now testing the Apache Module to see if this solves the problem. – William Leader Jun 11 '10 at 13:37
  • I've also had to use the information on this page to make an Apache 2.2 module instead of an Apache 2.0 module: http://leonardorame.blogspot.com/2009/04/apache-22x-modules-with-delphi.html – William Leader Jun 11 '10 at 13:38
  • Well I am seeing similar errors running the same code as an Apache module so I think it has something to do with my usage of TRemotable objects. – William Leader Jun 11 '10 at 14:00

1 Answers1

-1

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.

Chris Thornton
  • 15,620
  • 5
  • 37
  • 62
  • I can assure you it is being called correctly. I have already setup IIS with the ISAPI dll and called it the test client without error. I can then configure Apache to host the DLL at the same URL so that to the test client it appears to be exactly the same server. The Test client is not changed between tests. The DLL is not changed between tests. The only difference is if Apache is hosting or IIS is hosting. – William Leader Jun 23 '10 at 10:38