cancel
Showing results for 
Search instead for 
Did you mean: 

Can I alter the request after node selection but before the request is forwarded?

Highlighted
New Contributor

Can I alter the request after node selection but before the request is forwarded?

I would like to be able to obtain the backend node selected for a particular request in a request rule.

This means the load-balancing and session persistence decisions have been calculated and the result of those to be provided to the request rule as part of the context (i.e. connection.getNode() does not return an empty string).


Someone might want to set an HTTP header to a certain value, based on the node selected. It may also be to conditionally alter something in the request data because some of the nodes may not be able to process the data when it is in a certain state.


A use case is that the STM is fronting other reverse proxies (e.g. nginx) configured with Host header differentiated virtual servers, and the STM is presented to the client using a different host name (providing users some sort of load-balanced aggregator site). If I've used host names (rather than IP addresses) for the backend nodes, I could use connection.getNode() to set a Host header that is different to the Host header in the client request, thus making the request acceptable to the backend reverse proxy.


The recommended solution may be to use multiple pools, but I want to use the load-balancing mechanism between nodes in a single pool. As an aside, I believe connection.getPool() should return the default pool for the virtual server handling the request, rather than an empty string.

If making this context available to all request rules is onerous, it would be fine if selected rules had to be flagged in some way to move them further along the request processing chain (after backend node selection, before data forwarded to backend node).

2 REPLIES
New Contributor

Re: Can I alter the request after node selection but before the request is forwarded?

This is what I have done as an example solution, although I do NOT like it.

I do nothing in Request rules for this, but I set up a Response rule like this:

if (http.getResponseCode() >= 400 && request.isResendable() && request.getRetries() < 1) {

   $redoNodeAddr = string.split(connection.getNode(), ":")[0];

   $redoNodePort = string.split(connection.getNode(), ":")[1];

   log.warn("Resending to node " . $redoNodeAddr . ":" . $redoNodePort);

   http.setHeader("Host", $redoNodeAddr);

   pool.select(connection.getPool(), $redoNodeAddr, $redoNodePort);

   request.retry();

}

I need to set the trafficscript!variable_pool_use global setting.

The effect is that an initial request is sent to the pool with the load-balancing decision made, my backend reverse proxies respond with an error status code, this rule adjusts the request to inject the Host header of the initially selected node and resends to that node using the same pool settings, the request is resent to the backend reverse proxy which is now happy with the request.

It works and might be using load-balancing decisions reasonably, but it obviously sucks because of the duplicate request, and only works with re-sendable requests.

Contributor

Re: Can I alter the request after node selection but before the request is forwarded?

Its possible another Traffic Script solution exists, but another option without scripting option is to use a "loop back" virtual server as each node for the virtual server accepting client requests. Then you could alter the requests on the node virtual servers.

Pictured is an example using yahoo.com for my nodes.

config sum.JPG.jpg