Using a Different Transport Protocol (Non-HTTP)


Under the ATL Server samples in Visual Studio .NET is a documented sample called SoapTransport. The SoapTransport sample shows how to create an alternate entry point function in an ATL Server SOAP server and how to use it for SOAP processing, regardless of the transport protocol. The new entry point behaves in much the same way as HandleRequest behaves; its main purpose is to accept parameters that aren t designed for HTTP-specific usage.

Also, the SoapTransport sample provides implementations for SOAP over TCP/IP, over HTTP without a Web server, and even using a floppy disk. In doing so, the sample allows you to preserve the implementation of a SOAP server s methods . You must modify the class definition, making it inherit from a special class, which implements the entry point.

In this section we provide an alternate way of getting the ATL Server SOAP processing out of the HTTP/ISAPI context. The idea behind this solution is to create an environment that, as far as the SOAP server is concerned , behaves exactly as the HTTP context. Once this goal is reached, you can use even existing compiled ATL Server SOAP servers (application DLLs) to process SOAP requests received on any transport channel.

A simple implementation for the current section is available (with the other code samples from the book, which you ll find in the Downloads section of the Apress Web site [http://www.apress.com]) as the OverriddenTransport sample. After a few words on how it works, we present the main components of the sample and how you can use it. Some knowledge of the specification for ISAPI is recommended before you read this section.

Overriding the HTTP Transport

In the ATL Server processing model, the HTTP request is received by an ISAPI extension. The ISAPI extension is a dynamic link library (DLL) that exports three functions, and one of these functions ( HttpExtensionProc ) is called whenever a request must be processed . Internally, HttpExtensionProc will pass the processing job to a CIsapiExtension -based object. This object will read the request using the EXTENSION_CONTROL_BLOCK (ECB) provided as a parameter to HttpExtensionProc by the Web server. It will load the application DLL that s supposed to handle the request, which will then generate the response by writing through the same ECB.

Note  

There s a minor exception for this behavior: In a situation where the ISAPI module and the application module reside in the same DLL, the load the application DLL step is skipped . But this situation isn t of concern in this section.

The ECB is exposed in the CIsapiExtension based object through an interface, IHttpServerContext . The whole idea behind this section is to provide a custom implementation for IHttpServerContext that creates an object that behaves almost exactly as a CIsapiExtension derivative, and then uses these two components to load application DLLs (in particular, SOAP servers) and process SOAP requests.

The OverriddenTransport sample is such an engine for loading application DLLs. Using the same pattern as the SoapTransport\FloppyTransport sample on the Visual Studio CD, it loads a SOAP request from a file, and then processes the request and saves the response to another file. So, a file request produced by the SoapTransport\FloppyTransport\FloppyClient from the Visual Studio CD will be accepted as a valid request by this sample. This entire engine is available in the OverriddenTransport\TransportLoader project. Two sample request files (SOAPRequest.txt and WSDLRequest.txt) are provided in the same directory. A simple Hello, World! SOAP server is also available to enable you to see the application running without requiring additional code. You should find the code easy to review and understand once we ve described the major components of the TransportLoader project.

The application implements two important classes:

 CLoaderServerContext : public IHttpServerContext 

and

 CLoaderExtension: public IServiceProvider, public IIsapiExtension 

CLoaderServerContext behaves as a server context, meaning it provides everything an ECB would provide through the same interface that wraps the ECB. So, once an application DLL is loaded, in the most common usage it won t be able distinguish between this ECB wrapper and the one generated by the Web server.

The code for CLoaderServerContext closely follows the code from the CWrappedServerContext class, defined in atlisapi.h, which is the ATL Server implementation of the IHttpServerContext interface. Still, there are a few major differences, which we describe in the next section.

ReadClient/WriteClient

These ATL Server functions call their counterparts (with the same names ) that are a part of the ECB (provided by the Web server). Because there s no Web server in the sample, two streams are used, one for the request ( ReadClient ) and another for the response ( WriteClient ). The streams are defined in CLoaderServerContext as follows:

 CReadWriteStreamOnCString   m_requestStream;     CReadWriteStreamOnCString   m_responseStream; 

CReadWriteStreamOnCString is a helper class defined in the sample that provides an IStream implementation on top of a CString class.

Note  

Because a CString can be generated from any given XML buffer, and because a CString can contain any given XML buffer, a CString -based mechanism won t require HTTP at all. It can be used with any transport that can carry the XML, including TCP/IP, MSMQ, and even a floppy disk.

The main application is responsible for filling the m_requestStream before executing the request and forwarding the content of m_responseStream back to the client upon execution.

GetServerVariable

This function is frequently used by the ATL Server application DLL to access information provided by the Web server, such as the following:

  • PATH_INFO : The part of the URL request after the server name and before the query parameters

  • URL : The URL of the request

  • HTTP_SOAPACTION : The value of the SOAPAction HTTP header

  • CONTENT-LENGTH : The value of the Content-Length HTTP header

All of these variables are provided by the Web server. Because you aren t using a Web server in this example, you ll use a map (hash table) to store those variables that will be frequently requested during the SOAP request processing. The map is defined in CLoaderServerContext as follows:

 typedef CAtlMap<                  CStringA, CStringA,                  CStringElementTraitsI<CStringA>,                  CStringElementTraitsI<CStringA> > HeaderMapType;  HeaderMapType m_requestHeaderMap; 

The map is filled either with some default values or values dependant on the request in the CLoaderServerContext::SetUrl public function.

Mapping an HTTP Request Object to a Physical Object

Mapping an HTTP request to a physical object is another function provided by the Web server. The Web server keeps track of the physical location of the virtual Web directories and provides the physical local path of the objects pointed at by URLs. In this case, the application itself needs to parse the request and map it to a physical object.

The CLoaderServerContext class takes care of identifying the object name; therefore, it can filter out the DLL name (HelloWorld.dll) from a URL like this:

 http://localhost/someVirtualDirectory/HelloWorld.dll?Handler=GetHelloWorldWSDL 

The main application that uses the CLoaderServerContext class is responsible for mapping the HelloWorld.dll name to a physical path:

 C:\WokDir\HelloWorld\Debug\HelloWorld.dll 

Once the mapping is done, the main application has to call into CLoaderServerContext::SetSoapAppDllPath .

So far, the main application is responsible for the following:

  • Filling the m_requestStream member of the CLoaderServerContext class (it does this by using an XML stream obtained through any transport ”in this case through a call to LoadInputFile in the TransportLoader.cpp file, which loads the XML from a file).

  • Calling CLoaderServerContext::SetUrl and passing as parameters the URL of the request and the SOAP Action field. (The URL and the SOAP Action field are supposed to come from the client, usually on the same channel as the XML body. In this example, the URL is the first line of the input file and the SOAP Action field is the second. Everything else is supposed to be the body of the request.) At this point, CLoaderServerContext will parse the URL and identify the object name (the DLL name).

  • Associating the DLL name (contained, after SetUrl , in CLoaderServerContext::m_strDLLFileName ) to a physical path. The main application does this by using a table for mappings ( g_arMappings ) and then calling CLoaderServerContext::SetSoapAppDllPath .

Let s take a look now at CLoaderExtension . This class is a very simplified version of CIsapiExtension . The main function in this class is

 BOOL ExecuteRequestDirect(IHttpServerContext  *pServerContext) 

which closely follows the implementation of CIsapiExtension::DispatchStencilCall in atlisapi.h. Again, this is a very simplified version of the ISAPI extension. To keep the code simple, it doesn t contain a stencil cache and it doesn t fully implement the IServiceProvider interface. The AddService , RemoveService , and GetService methods return E_NOTIMPL , whereas QueryService returns only the DLL cache service. This implementation also differs from the ATL Server version in that it doesn t use the thread pool.

Note  

You can easily add all of these features, but we ve left them out to keep the code simple.

Just like the CIsapiExtension class, CLoaderExtension exposes two methods, Initialize and Uninitialize , to be called before and after usage, respectively.

The main entry point, ExecuteRequestDirect , takes as a parameter an IHttpServerContext interface, the kind exposed by the CLoaderServerContext class. Using the same DLL cache mechanism as in the ATL Server CIsapiExtension class implementation, CLoaderExtension will load an application DLL and execute what looks like an HTTP request.

In the main application, you need to add the following code (we ve omitted error checking for clarity):

 // The stand-alone ISAPI Extension  CLoaderServerContext srvCtxt;   CLoaderExtension  ext;  ext.Initialize();  ext.ExecuteRequestDirect(&srvCtxt);  ext.Uninitialize(); 

After this, if everything runs successfully (all the functions will return FALSE in case of an error), CLoaderServerContext::m_streamResponse contains the response buffer, the XML payload of the SOAP response. Once again, it s up to the main application to forward this response back to the client, using the transport protocol of choice (in this case, another file).

Once the sample is built and run, it will ask for an input file. The input file should contain the SOAP request in the following format (the content of the SOAPRequest.txt file):

 http://localhost/HW.dll?Handler=Default  "#HelloWorld"  <soap:Envelope    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:xsd="http://www.w3.org/2001/XMLSchema"    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">    <soap:Body      soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">      <snp:HelloWorld  xmlns:snp="urn:HWService">        <bstrInput>SomeInput</bstrInput>      </snp:HelloWorld>    </soap:Body>  </soap:Envelope> 

Notice how the first line of the file contains a URL indicating the application DLL (HW.dll). On the second line, you see SOAPAction: "#HelloWorld" followed by a valid SOAP request. Once the request is executed, the sample application prompts for an output file name, where the SOAP response will be generated.

Note  

The preceding solution describes how to send a SOAP request. But you can use this file format to send a regular, non-SOAP HTTP request. As an example, take a look at WSDLRequest.txt, which contains an HTTP request that returns a WSDL for the Web service http://localhost/HW.dll?Handler=GenHWWSDL. In this case, the complete WSDL of the SOAP server will be generated in the response file.

Please look at the SoapTransport sample that ships with Visual Studio for information on how to create a client for this stand-alone SOAP server.




ATL Server. High Performance C++ on. NET
Observing the User Experience: A Practitioners Guide to User Research
ISBN: B006Z372QQ
EAN: 2147483647
Year: 2002
Pages: 181

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net