Preventing respmod adapter from execution based on reqmod status

Asked by Bartłomiej Leszak on 2015-12-21


Lets say we have an reqmod and respmod adapters for squid both working on the same master transaction (request and response) bound to each other by meta header (adaptation_masterx_shared_names squid configuration option). Each of the adapters examine and adapts messages in various states (header and body) - sometime only header is required to pass the message unchanged, sometimes part of the body. But there is a need to honor the decision of "don't adapt and leave it alone" made by reqmod adapter in respmod one.
I thought of removing meta header (say: "X-MASTERX-SHARED-NAME") or better changing its value from unique id to something like "X-MASTERX-SHARED-NAME: PASS", but there seem to be no control over it from ecap adapter (option() querying for masterx shared name is called by host right after "Xaction::start()").
I'm aware of service sets and chains, but from what I've read so far these are valid within either reqmod or respmod (in other words: set or chain cannot group respmod and reqmod services together), so it's no go here.
Variation on the above two options would be having two reqmod adapters: the first one doing real job and returning next service to be the other one only when there is a need to remove the header. The other one would only take care of removing/changing meta header. But I don't know if I like the idea due to its complexity (*if it's possible*)...

Any other option I could look into? Or an idea?

PS1 I would rather avoid "leaking" anything to the "outside" of squid.

Question information

English Edit question
eCAP Edit question
No assignee Edit question
Last query:
Last reply:

This question was reopened

Alex Rousskov (rousskov) said : #1

If your host application supports it, consider using "dynamic adaptation routing". Dynamic adaptation routes are implemented using libecap::metaNextServices meta header. They allow a properly configured REQMOD service to set the RESPMOD service for the same master transaction.

If you are using Squid, look for routing=on option the in ecap_service directive. More info may be available in the similar icap_service section (look for Next-Service).

Alex Rousskov (rousskov) said : #2

Please note that you may still run into "the host application queries the metaheaders too early" issue, even if you do dynamic routing. If you do, I recommend that you ask a separate/dedicated question about it, keeping in mind that adaptation is not a series of completed transactions but a pipeline of concurrent ones. The pipeline may even cross the REQMOD/RESPMOD barrier! The pipelining requirement places a limit on when the meta information, including routing options are queried, but there is some flexibility there that may help you, depending on your specific needs. If you post a separate question, please detail the moments when your adapter needs to make the routing decision, keeping the pipeline in mind.

Bartłomiej Leszak (bartekl) said : #3

I am aware of pipelining, although I'm probably not aware of the gory details... I think there is a possiblity to control it at least a little, I can hold the data in one "step" as long as I need (header, part of the body), but of course I will not have any control of the remote server (it could probably respond to request before I complete request processing in adapter - I guess this is what you meant about crossing REQMOD/RESPMOD barrier*) ... Similarily I can force host to ask options when I'm ready, as hosts asks for it whenever it has a chance to proceed with current message any further in its processing - from my experience with squid and ecap it seems that options are queried once I "release" header (not after start() I wrote earlier) from adapter (after useAdapted() and useVirgin(), probably more).

As of squid, ecap and "dynamic adaptation routing" it seems fine for my needs, although there is one thing I'm not sure is fine or wrong. icap_service manual says that empty X-Next-Services header should result in an empty adaptation plan. I'm not sure if it works fine in icap, but it doesn't in ecap - clearing (setting to libecap::Area::FromTempString(" ") or libecap::Area::FromTempString("")) this header in reqmod adapter has no effect - respmod adapter still gets called. I don't know if reqmod-reqmod chain behaves the same way. Is it potential bug or ecap doesn't support it that way by design?

*) I guess this scenario would include request with body, header already released from adapter and sent to the "wire" (while body under processing) and getting back authorize/redirect/forbidden/... header.

Bartłomiej Leszak (bartekl) said : #4

(I know that "potential bug question" is more appriopriate for squid folks, but as far as I can see you were the one/among ones writing "dynamic adaptation routing" feature for content adaptation :-) )

Bartłomiej Leszak (bartekl) said : #5

Just to clarify: if I do the reverse: set the libecap::metaNextServices option to respmod adapter everything is fine - the adapter gets called, it's just clearing this header that doesn't work.

Alex Rousskov (rousskov) said : #6

> setting [X-Next-Services value] to libecap::Area::FromTempString(" ") or libecap::Area::FromTempString("") in reqmod adapter has no effect - respmod adapter still gets called. I don't know if reqmod-reqmod chain behaves the same way. Is it potential bug or ecap doesn't support it that way by design?

By design, receiving an empty X-Next-Services header by the host application from the adapter should result in the adaptation plan termination. That does not mean that other adaptation plans cannot be created later, via the host application configuration.

I am puzzled at "respmod adapter still gets called" though. Why would your host application call a RESPMOD adapter at all if the RESPMOD adapter ID was not in squid.conf and it was not in any dynamic adaptation plan? Are you using _two_ REQMOD services in a chain, the first of which adds the RESPMOD service ID to the dynamic adaptation plan? If not, perhaps you forgot to remove a squid.conf rule that activates that RESPMOD adapter?

Bartłomiej Leszak (bartekl) said : #7

My understanding was that "dynamic adaptation plan" means that X-Next-Services is the _final_ decision for adaptation if it is set (it will _overwrite_ the adaptation plan). So I used it in a way that by default (in squid.conf) there are two adapters - reqmod and respmod, and the reqmod adapter clears X-Next-Services header when I don't won't to execute respmod one. From what you've written above this doesn't terminate the squid.conf's adapters chain, only the one that was set in X-Next-Services...

Bartłomiej Leszak (bartekl) said : #8

... don't won't ... => ... don't want ...

Can you help with this problem?

Provide an answer of your own, or ask Bartłomiej Leszak for more information if necessary.

To post a message you must log in.