Omnis Technical Note TNWS0001 August 2008

Using Omnis Studio as a SOAP host

For Omnis Studio 4.2 or above
By Rudolf Bargholz, Online Travel, Zurich

The following tech note was kindly provided by Rudolf Bargholz, Senior Developer and joint Managing Director of Online Travel, a leading provider of online solutions for the travel industry in Europe. Let Rudolf explain...

Omnis Studio has a Web Services plug-in that simplifies creating an Omnis Studio web services host capable of receiving and processing SOAP calls, as well as allowing you to use Omnis Studio to call public web services. The Omnis Web Services (OWS) plug-in was added to Omnis Studio 4.2 and has been used by many Omnis developers to access web services.

The following describes a solution to a problem, when using Omnis Studio as a SOAP host application, where the SOAP client sends an incorrect HTTP header, specifically the SOAPAction HTTP header, to the Omnis Studio SOAP host.

Web Server plug-in

To use Omnis as a Web Service Provider, you must install one of the following plug-ins into your web server, for example, in the /cgi-bin, /scripts, or /webapps folder depending on your platform. We use the Apache module on a Linux host, but there are other plug-ins you can use for other platforms. Web Server plug-ins are available for ISAPI for Win32, for CGI, and Apache, as follows:

Plug-in Platform(s) Notes
owsisapi.dll Win32 ISAPI extension for IIS
nph-owscgi Win32, Mac OS X, Unix CGI executable
mod_ows.so Win32, Mac OS X Apache module. Available for Apache 2 on Win32, and Apache 1 and 2 on Mac OS X. Not available for Unix as there is an XML parser incompatibility between the module and Apache. Configuring the module is very similar to mod_omnis.so (web client server plug-in), except that the source file name used for the Apache 1 configuration is owsapach.cpp. You are recommended to use the path /ows_apache to map to the module.

Note: Apache on Linux can only use the nph-owscgi. We copy the file into the "cgi-bin" directory of our web server and set the appropriate access parameters to allow the execution of the cgi. See the Omnis Web Services manual for further details about setting up and using the OWS plug-in.

The SOAP client call

The CGI will receive SOAP calls and retransmit these to the Omnis Studio application server. The SOAP client calls the SOAP Service using the following example URL:

http://192.168.2.99/cgi-bin/nph-owscgi/testsoaplibrary/test_ws

testsoaplibrary – the Omnis Studio Library that contains the remote task that will address the SOAP request and prepare the response
test_ws – the web service name of a remote task that will address the SOAP request and prepare the response

At this point the CGI processing the SOAP request does not know where the Omnis Studio application server is to which the SOAP request needs to be forwarded to. This information is provided in the HTTP Header

SOAPAction: "http://192.168.2.11:5912"

The web server is on the IP address 192.168.2.99, while the Omnis Studio application server is on the IP address 192.168.2.11 and is listening on the port 5912.

With the SOAPAction HTTP header information, the OWS CGI is able to send the SOAP request to the appropriate server on the given port, including the specified library and remote task.

OWS requires the use of a SOAPAction parameter in the header of the HTTP request so it knows where the Omnis Application Server is to which the SOAP Request is forwarded. Some SOAP client applications are not able to send extra HTTP header parameters to a web service (at least this was the case with a .NET client trying to access our web service). Often the caller simply enters a URL to access the web service, adding the same URL as the SOAPAction parameter. This implies that the application server is on the same server as the web server, which is generally the case for a .NET application. The OWS however has a problem with this process and has no way of knowing where the application server is located. In order to work around this limitation of SOAP clients, on Apache 2.x you can dynamically add the SOAPAction parameter to an HTTP Header before the CGI call is processed by the OWS web service module. This can be achieved by loading the mod_headers Apache module in your web server. The module is a standard module installed with Apache.

The following URL describes the Apache mod_headers module:
http://httpd.apache.org/docs/2.2/mod/mod_headers.html

In the httpd.conf of Apache, remove the comment (#) from the line that loads the mod_headers.so module; the line should now read:

LoadModule headers_module modules/mod_headers.so

In a section below this entry, add the following to the httpd.conf:

<Files "nph-owscgi.exe">
  RequestHeader set SOAPAction "http://192.168.2.11:5912"
</Files>

This example assumes you are using the "nph-owscgi.exe" for Omnis Web Services on Apache. One advantage of this process is the EXE could be renamed for different customers on the same web server and each EXE according to its name could route to a different application server in a network.

Apache 1.3 does support the mod_headers module, but not the function RequestHeader, so the above will not work in Apache 1.x configurations. We have not found a solution to this problem using Windows IIS.

Please note that under Linux the CGI does not have the ".exe" ending on the nph-owcgi.

The following is a SOAP request and response including the HTTP headers:

SOAP Request before modification

Host: 192.168.2.99
Content-Length: 359
SOAPAction: "http://192.168.2.99/cgi-bin/nph-owscgi.exe/testsoaplibrary/test_ws"
User-Agent: Jakarta Commons-HttpClient/3.0.1
Content-Type: text/xml;charset=UTF-8

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:test="http://192.168.2.99/cgi-bin/nph-owscgi.exe/testsoaplibrary/test_ws.wsdl">
   <soapenv:Header/>
   <soapenv:Body>
     <test:validateProjectNumber>
       <test:ProjectNumber>100000</test:ProjectNumber>
     </test:validateProjectNumber>
   </soapenv:Body>
</soapenv:Envelope>

SOAP Request after modification

Host: 192.168.2.99
Content-Length: 359
SOAPAction: "http://192.168.2.11:5912"
User-Agent: Jakarta Commons-HttpClient/3.0.1
Content-Type: text/xml;charset=UTF-8

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:test="http://192.168.2.99/cgi-bin/nph-owscgi.exe/testsoaplibrary/test_ws.wsdl">
   <soapenv:Header/>
   <soapenv:Body>
     <test:validateProjectNumber>
       <test:ProjectNumber>100000</test:ProjectNumber>
     </test:validateProjectNumber>
   </soapenv:Body>
</soapenv:Envelope>

SOAP Response

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soap:Body>
     <validateProjectNumberResponse xmlns="http://192.168.2.99/cgi-bin/nph-owscgi.exe/testsoaplibrary/test_ws.wsdl">
       <return><?xml version='1.0' encoding='ISO8859-1' ?>
<Projects><Project Seq="1531" Code="100000" Description="Division General Costs"/></Projects></return>
     </validateProjectNumberResponse>
   </soap:Body>
</soap:Envelope>

One further point you may want to consider: as far as I am aware, SOAP 1.2 does not require the use of a SOAPAction parameter. Most .NET SOAP clients I have looked at do not need a SOAPAction parameter and most do not allow you to enter a specific value for the SOAPAction. The URL, a username and password are normally used to call a web service. One of our customers, for example, does not import WSDL files to call web services, they use a URL with an optional username and password. Perhaps there is some other method to tell the OWS module on which server the Omnis application server is listening without the use of the SOAPAction parameter.