Я начал с ISAPI DLL, которую создал с Delphi 2009. Этот модуль работает должным образом при работе в IIS 5.1 в Windows XP.Этот же модуль при размещении с использованием Apache 2.2.15 и mod_isapi работает неправильно.Чтобы исключить возможность наличия у mod_isapi некоторого недостатка, был создан модуль Apache Shared Object того же сервиса.Однако аналогичные проблемы возникают и в модуле Apache.
Создав два проекта, которые совместно используют код реализации, я смог создать как библиотеку DLL ISAPI, так и модуль Apache, которые имеют идентичные реализации.Таким образом, единственная разница между ними заключается в том, как они подключаются к своему веб-сервису.Это дает мне три варианта размещения этой службы:
- IIS + ISAPI DLL
- Apache + модуль Apache
- Apache + mod_isapi + ISAPI DLL.
В обоих проектах реализован простой веб-сервис SOAP для тестирования.Все сериализация, десериализация, маршалинг и т. Д. Обрабатываются автоматически сгенерированным кодом при создании нового приложения сервера Soap с использованием Delphi IDE.Интерфейс имеет несколько простых функций для тестирования.
Чтобы создать модуль 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;
Реализация интерфейса полна фиктивного кода, который просто создает объект результата для отправки обратно клиенту.В реализации нет значимого кода.
При размещении в IIS через ISAPI все методы, предоставляемые службой, работают отлично.
При размещении в Apache любой метод, содержащий параметр TRemotable, имеет ошибку.В этом интерфейсе SendFile1 и SendFile5 затронуты, потому что они имеют TSendFileRequest в качестве параметра.Первый вызов SendFile1 или SendFile5 работает как положено.Следующий вызов любого метода после успешного вызова SendFile1 или SendFile5 приводит к нарушению доступа.Такое поведение наблюдается как с модулем общих объектов Apache, так и с библиотекой ISAPI, использующей mod_isapi.
Я не уверен, в чем проблема, но я вижу три варианта: мой код, код Delphi или код Apache.Я просто не могу понять, где.
Эта проблема была очень неприятной, поскольку точно такая же двоичная DLL ISAPI работает в IIS, но не в Apache.Я бы отнес это к различиям в реализации хоста ISAPI, но те же ошибки происходят в модуле общих объектов Apache, что означает, что происходит что-то еще.
Для полноты я решил создать версию CGI длятот же веб-сервис.При работе под IIS CGI-версия работает отлично.При работе в Apache все запросы приводят к ошибке: «XML-документ должен иметь элемент верхнего уровня. Строка: 0»
Похоже, что Apache сегодня просто ненавидит меня.