Inconsistent responses from ISAPI DLL in mod_isapi.
- by William Leader
I have a ISAPI dll which I created with Delphi 2009, and I have been able to test that it functions as designed when I run it inside of IIS 5.1. However when I attempt to host the web service from within Apache on Windows XP using mod_isapi, I do not get consistent results.
The ISAPI dll implements a very simple SOAP service with two methods. One method is a simple echo service that sends back the string sent to it. The second method is used to send a file to the server using a TSoapAttachement (Mutipart MIME). The interface can be descibes as follows
IPdiSvc2 = interface(IInvokable)
['{532DCDD7-D66B-4D2C-924E-2F389D3E0A74}']
function Echo(data:string): string; stdcall;
function SendFile(request:TFileDescription; attachment:
TSOAPAttachment): TSendFileResponse; stdcall;
end;
What is interesting is if I only call the echo function Apache handles this without error every time. The webservice only returns an error after calling send File, but not every time.
There are three outcomes to calling send file that I have observed:
A normal result without an error (HTTP 200 OK).
A Soap encoded exception with the message: 'Required white space was missing.
Line: 11 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML.' (HTTP 500 Internal Error). This also generates a message in the Apache error.log 'Premature end of script headers: MYISAPI.dll'
A Soap encoded exception with the message: 'Access violation at address 01A53D57 in module MYISAPI.dll. Read of address 00000000.' (HTTP 200 OK).
What I find interesting is that the second third outcomes still occur if I call echo after calling send file.
Calling SendFile, SendFile, SendFile, SendFile results in outcomes 1, 2, 3, 1.
Calling Echo, SendFile, SendFile, SendFile results in outcomes 1, 1, 2, 3.
Calling SendFile, Echo, Echo, SendFile results in outcomes 1, 2, 3, 1.
The pattern I am seing is that after a Successful SendFile, the next to requests result in outcomes 2 and 3 regardless of what those two requests are.
My guess is that because Apache uses multiple threads to handle multiple requests that each request is getting handled in a slightly different way, and that the DLL may not have been initialized in the same way for each worker thread.
I do not think the problem exists in my code as when I attach the debugger to httpd.exe it does recognize the exceptions but it says the exceptions are in non-delphi code meaning that they are happening before the code inside my DLL has a chance to execute.
I suspect it may have something to do with the way I have apache configured. My Apache configuration is the defaults created by the 2.2.15 installer for windows with the following addition:
<IfModule isapi_module>
AddHandler isapi-handler .dll
ISAPILogNotSupported on
ISAPIFakeAsync on
ISAPIAppendLogToErrors on
</IfModule>
<IfModule alias_module>
ScriptAlias /myisapi/ "C:/path/to/myisapi/"
</IfModule>
<Directory "C:/path/to/myisapi/">
AllowOverride None
Options ExecCGI
Order allow,deny
Allow from all
</Directory>