Modifying the HTTP Header

Overview

Often a client needs to send application specific information as part of its message while making service calls. You can add this custom information to the standard information provided in the HTTP header. For example, you might want to describe the contents of the message body (payload) or provide a context for the message. Hydra provides the ability to customize the HTTP header through a handler.
This article describes how to create a custom handler that adds a version number header to a service response. We will use the basic-cpp tutorial as a starting point for the example. The current headers on the response from HelloWorld service are:
HTTP/1.1 200 OK
Content-Length: 254
Connection: close
 
Our goal is to add a new header with a version number.
HTTP/1.1 200 OK
Version: 1.1
Content-Length: 254
Connection: close
 
Implementation
The HelloWorld service needs no modification to implement our handler. We will, however, need to modify rwagent.xml and to write the handler, HeaderHandler.
Modifying rwagent.xml
For this example, we will add the HeaderHandler on the response after the SOAP handler has processed the message. Looking into rwagent.xml we see the agentChain defines the handler, soap-processor-server-response, that processes the soap response. Remembering that response handlers run in the opposite order of their  declartion, we’ll add the HeaderHandler immediately before the other response handlers so that the HeaderHandler response handler will run after the SOAP, security, and MIME response handlers.
 <rwsf:handler-chain name="agentChain">
    <rwsf:handler name="header-response"
                  class="HeaderHandler.createHeaderHandler" type="response">
    </rwsf:handler>
    <rwsf:handler name="mime-server-response"       ...>
    <rwsf:handler name="security-server-response"       ...>
    <rwsf:handler name="soap-processor-server-response"       ...>
</rwsf:handler-chain>
 
 
The class property indicates that the handler is in the library, HeaderHandler12d.dll (or .so) and the class name for the handler is HeaderHandler.
HeaderHandler.cpp
Our handler derives from MessageInfoHandlerImp and must implement two virtual functions, init() and invoke().
class RWSF_HANDLERS_EXPORT HeaderHandler : public rwsf::MessageInfoHandlerImp
{
public:
 virtual void init(const rwsf::Config& config,
                    const rwsf::AgentContext& context);
 virtual bool invoke(rwsf::MessageInfo& message);
 
private:
 rwsf::AgentContext context_;
};
 
The init( ) function must call the init( ) function of the parent class.
HeaderHandler is a response handler so it will only add the Version on response messages. The rwsf::MimeHeaders class is used to access the HTTP headers.
bool HeaderHandler::invoke(rwsf::MessageInfo& message)
{
  if ((getType() &
         rwsf::MessageInfoHandler::HANDLER_RESPONSE ? true : false))
   {
     context_.getLogger().info("HeaderHandler::invoke");
     const std::string RESPONSE_HEADERS =
                     RWSF_KEY_RESPONSE + "/" + RWSF_KEY_TRANSPORT_HEADERS;
     rwsf::MimeHeaders respHeaders;
     if (message.contains(RESPONSE_HEADERS))
     {
       respHeaders = message.get<rwsf::MimeHeaders>(RESPONSE_HEADERS);
     }
     else
     {
       message.set<rwsf::MimeHeaders>(RESPONSE_HEADERS, respHeaders);
     }
     respHeaders.set("Version", "1.1");
   }
   return true;
}
 
RWSF_DEFINE_HANDLER(HeaderHandler)
 
Because we positioned the HeaderHandler in the agentChain, it will add the Version to any soap response from the agent. If we wanted to limit the addition to only the HelloWorldService or to only the greeting operation, we would have to use a service-specific handler instead. Service-specific handlers are configured in the service-handlers.xml file. Place this file in the conf directory under the service and deploy it along with the service. Here’s a sample service-specific handler for our service.
<rwsf:service-configuration xmlns:rwsf="http://www.roguewave.com/rwsf">
 <rwsf:handler-chain name="HelloWorldServiceSpecificChain">
    <rwsf:handler name="HeaderHandler"
                  class="HeaderHandler.createHeaderHandler"
                  type="response">
    </rwsf:handler>
 </rwsf:handler-chain>
 
 <rwsf:operation name="greeting" uri="http://localhost:8090/rwsf/HelloWorld/HelloWorld">
    <rwsf:incoming-chain name="HelloWorldServiceSpecificChain"/>
 </rwsf:operation>
</rwsf:service-configuration>
 
 
Running the Example
The example project attached to this article contains a readme.txt file with complete instructions on how to run the example. The Ant build files provide targets for building and deploying the project. While the service libraries are deployed to the agent instance, the handler library, HeaderHandler12d.dll, must be deployed to <Hydra Install>/apps-bin. The ant deploy target was modified to make this distinction.

The output displays our additional header:
HTTP/1.1 200 OK
Version: 1.1
Content-Length: 254
Connection: close
 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<rw:greetingResponse xmlns:rw="http://www.example.org/HelloWorld.wsdl">
<response>Hello World</response>
</rw:greetingResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
References
Hydra Agent Runtime Guide for information on handler chains and Creating a Custom Handler.
Please see the attached file for the complete example.



Article ID: 1448
Last updated: 06 Nov, 2009
Revision: 1
Hydra -> Agent -> Modifying the HTTP Header
https://rwkbp.makekb.com/entry/1448/