Mailing List Archive

Sticky Sessions for URL based backends
Hi All,

I'm looking for information on what is by all indications an unusual setup.

We are attempting to proxy and cache from a single domain (e.g.,
test.example.com) to individual pages on many backend domains (e.g.,
test.domainone.com/page, test.domaintwo.com/anotherpage, etc.).

The goal is to be able to hit a path on test.example.com and have it
returned the cached page for a backend domain/path. For example:

test.example.com/apple/ -> test.domainone.com/pear/
test.example.com/peach/ -> test.domaintwo.com/strawberry/
... and so on.

The backend pages can be anything (HTML, Wordpress, Joomla, etc.), and are
almost always a "sub-page" of the site rather than the index. We have no
control over the backend servers, so we can't alter their site's code
directly.

We've so far been able to get the general proxy working. The problem is
that for any linked resources that are a level above the backend pages they
either miss the cache (for absolute links) or hit a bad gateway because
they don't match one of the cached paths. For example:

For: test.example.com/apple/ -> test.domainone.com/pear/

(linked) test.domainone.com/wp-content/css/style.css ->
test.example.com/wp-content/css/style.css (returns bad gateway because
test.example.com/wp-content/ doesn't exist)
OR
(linked) test.domainone.com/wp-content/css/style.css -> (rewrite)
test.example.com/apple/wp-content/css/style.css ->
test.domainone.com/pear/wp-content/css/style.css (404 because it doesn't
exist).

So far we've attempted to solve this by using "sticky sessions" to set a
cookie, and then direct traffic to the correct backend if either the path
matches or the cookie is set, but we haven't gotten it quite right yet.
We're also concerned that using a cookie for this may affect caching.

Example config:

import cookie;
import header;

backend domain_one {
.host = "test.domainone.com";
.port = "80";
}

backend domain_two {
.host = "test.domaintwo.com";
.port = "80";
}

sub vcl_recv {
if (req.http.host == "test.example.com") {

cookie.parse(req.http.cookie);
if(cookie.get("sticky")) {
set req.http.sticky = cookie.get("sticky");
}

if(req.http.sticky == "domain_one" || req.url ~ "^/apple/") {
set req.http.sticky = "domain_one";
set req.http.host = "test.domainone.com";
set req.backend_hint = domain_one;
if(req.url == "/apple/") {
set req.url = "/pear/";
}
}
if (req.http.sticky == "domain_two" || req.url ~ "^/peach/") {
set req.http.sticky = "domain_two";
set req.http.host = "test.domaintwo.com";
set req.backend_hint = domain_two;
if(req.url == "/peach/") {
set req.url = "/strawberry/";
}
}
}
}

sub vcl_deliver {
if(req.http.sticky) {
header.append(resp.http.Set-Cookie,"sticky=" + req.http.sticky +
";");
}
}

With this configuration if I go to test.example.com/apple/ it will load the
HTML for test.domainone.com/pear/, and I do get 'Set-Cookie:
sticky=domain_one;' in the initial response. However, all the cookie isn't
passed in subsequent linked requests, so I get 503 errors for all of the
other static content and images (that should be served by
test.domainone.com/wp-content/css/style.css,for example), resulting in a
broken page.

This setup may not be possible, but as I don't have a lot of Varnish
experience I'm trying to make sure I'm not missing something simple.



--

Thank You,

Logan B
NetActuate, Inc.