How to redirect a HTTP Stream on the Request Message

Asked by Kyle Brost on 2012-02-02

I have implement the ability to redirect requests to a single web page. It is not optimal as I would like to redirect as soon as possible.

Currently my adapter is implemented with this work flow:

1) Request is forwarded to ecap adapter
2) Extract the Host header value and store internally as key=>hostName
3) Set the X-Subscriber-Id with the key
4) Allow the request to go unmodified to the destination (useVirgin)
5) Response comes back from destination
6) Extract the X-Subscriber-Id to get the key
7) check to see if the the hostName matches one requiring redirection
8) Create a new message
9) Add the 307 redirect headers
10) Swap out the original response with the adapted on (useAdapted)

This works, but is inefficient as I'm fetching data from the destination that I'm just going to throw away. It also lack the ability to redirect CONNECT requests that don't have responses.

It is possible to intercept the request and satisify the response with out getting the data from the destination server? Something along the lines of?

1) Request is sent to ecap adapter
2) Create a redirect message and set it as the response message.

Where would I start to implement this?

Thanks

Kyle Brost
----

Question information

Language:
English Edit question
Status:
Answered
For:
eCAP Edit question
Assignee:
No assignee Edit question
Last query:
2012-02-02
Last reply:
2012-02-02
Alex Rousskov (rousskov) said : #1

In ICAP terminology, this is called "request satisfaction". There are currently two ways to tell the host application to satisfy a virgin request with an adapted response (instead of forwarding a request to the next hop):

* libecap::Host::Xaction::blockVirgin(): Tells the host to "block" the request. What happens next depends on the host application, but it can be expected that the client will receive some kind of an error message. Usually, such responses are configurable. For example, Squid has deny_info option that can be used to specify what "blocking message" should be served to the client (it has an ability to serve a redirect message as well). Follow Adapter::Xaction::onVirus() in the eCAP ClamAV adapter for an implementation example.

* libecap::Host::Xaction::useAdapted(response): Tells the host to send the provided response headers (possibly followed by response body). The same API is used for regular message adaptation. In request satisfaction mode, you supply a from-scratch built response while receiving a virgin request (REQMOD). To create a response message in REQMOD, use the libecap::Host::newResponse() method. Here is how the eCAP ClamAV adapter used this API to block requests before blockVirgin() was available:

void Adapter::Xaction::useForbiddenMessage(...)
{
        ....
        libecap::shared_ptr<libecap::Message> adapted = MyHost().newResponse();
        Must(adapted != 0);

        StatusLine &statusLine = dynamic_cast<StatusLine&>(adapted->firstLine());
        statusLine.statusCode(403);
        statusLine.reasonPhrase(libecap::Area::FromTempString("Forbidden"));

        adapted->header().add(headerContentType, libecap::Area::FromTempString("text/html"));
        adapted->header().add(headerContentLength, ...);

        hostx->useAdapted(adapted);
}

Please note that request satisfaction is used less often than regular adaptation so the underlying code may be of lower quality. However, I know that the eCAP ClamAV adapter did work with Squid the last time I tested it.

Can you help with this problem?

Provide an answer of your own, or ask Kyle Brost for more information if necessary.

To post a message you must log in.