[Varnish] #682: hash maps

rosenfield.albert at gmail.com rosenfield.albert at gmail.com
Mon Apr 19 22:34:48 CEST 2010


http://www.varnish-cache.org/ticket/682


On Mon, Apr 19, 2010 at 10:30 PM, Varnish
<varnish-bugs at varnish-cache.org> wrote:
> #682: hash maps
> -------------------------+--------------------------------------------------
>  Reporter:  rosenfield   |       Owner:  phk
>     Type:  enhancement  |      Status:  new
>  Priority:  normal       |   Milestone:
> Component:  varnishd     |     Version:  trunk
>  Severity:  normal       |    Keywords:  hash, hashtable, maps
> -------------------------+--------------------------------------------------
>  Hi
>
>  I have a web site where every URL either:
>  1) returns an immutable (cacheable) content page or[[BR]]
>  2) results in an (uncacheable) HTTP redirect to a more-specific URL.
>
>  I'd like to cache everything under bullet 1).
>
>  {{{
>   +-------http-------+                          +------302------+
>   | lots of contents |                          | go here       |
>   | ...              |                          | +------302------+
>   | +-------https------+                        +-| update acc'd  |
>   | | blah blah        |                          | go there      |
>   | | blah             |                          +---------------+
>   | | ....             |
>   +-|                  |
>     |                  |
>     +------------------+
>  }}}
>
>  Many pages are for authorized users only.  Caching them requires a bit of
>  work.  Specifics follow.
>
>  I want an elegant design, meaning:
>  1) No hitting the backend servers to do auth,[[BR]]
>  2) No superfluous per-user backend requests,[[BR]]
>  3) No superfluous per-user copies of the same page.
>
>  {{{
>   +-----------+           +-----------+         +-----------+
>   |           | ---> ---> |           |         |           |
>   |  CLIENT   | blah blah |   CACHE   |  SSSH!  |  BACKEND  |
>   |           | <--- <--- |           |         |           |
>   +-----------+           +-----------+         +-----------+
>  }}}
>
>
>  So far so good.
>
>  At a minimum, I need to keep track of a few details via VCL:
>  1) which security clearance a cached page requires, and[[BR]]
>  2) given the user's authentication cookie, which clearances it grants.
>
>  Bullet 1) is easy to implement.  There are advanced and very flexible
>  solutions where the backend server emits a page's security context via a
>  HTTP header..  But for starters let's just go with something simple and
>  put all pages which require elevated privileges into /admin/, let's call
>  that security context 1.  Even more dangerous stuff goes into /superuser/,
>  aka context 2.  Everything else is context 0.  A snippet of VCL then
>  simply deduces the security context (aka required clearance) by grokking
>  the URL with a regex.
>
>  {{{
>   ^            ^       ^           ^       ^              ^
>   |            |       |           |       |              |
>   | /*         |       | /admin/*  |       | /superuser/* |
>   | /public/*  |       |           |       |              |
>   | /images/*  |       |           |       |              |
>   | /foo/*     |       |           |       |              |
>    \----------/         \---------/         \------------/
>     Context 0            Context 1            Context 2
>  }}}
>
>  Easy peasy.
>
>
>  Bullet 2) comes in two parts.  First, we need to shovel the user's
>  security clearances (or "allowed contexts") to the VCL.  Second, we need
>  to check that against the page's required clearance (or "security
>  context") on subsequent requests.
>
>  For the first part, we just shovel the user's security clearances (or
>  "allowed contexts") to the VCL when the user logs in.  No problem, just
>  add a header, call it "X-Granted-Clearances: 1,2" to the login response.
>  The VCL can now pick out both the user's cookie value from the "Set-
>  Cookie: SESSAUTH=blah" header, and which security contexts this user has
>  access to from the X-Granted-Clearances header.
>
>  For the second part, we hit a brick wall.  When the next request from the
>  user comes in, VCL is in a different state of mind and has forgotten all
>  about that stuff.
>
>  So therein lies my problem.  I need a hash map which is accessible from
>  VCL, in which I can store authentication cookie values plus which security
>  contexts they map to.
>
>  Additionally, the hash map must clean itself up.  The simplest mechanism
>  will do, such as a 5-minute timeout on all entries.
>
>  The required API functions as seen from VCL code are thus:
>  {{{
>    map-define(map-id, timeout)   [ creates the map if it doesn't exist. ]
>    map-set(map-id, key, value)   [ adds or updates entry. NULL value
>  destroys
>                                    entry. internally timestamps new
>  entries. ]
>    map-touch(map-id, key)        [ updates internal timestamp. ]
>    map-get(map-id, key)          [ retrieves an entry. ]
>  }}}
>
>  And the cleanup thread must at least do:
>
>  {{{
>    while (true) {
>       if (no-entries) {
>          wait-for-first-entry;
>       } else {
>          find-entry-with-lowest-timeout;
>          wait-remaining;
>          purge-if-still-exists-and-not-touched;
>       }
>    }
>  }}}
>
>  I think hash maps with timeouts have other use cases as well!
>
>  (For example, the security context could be stored in a {url,context} map
>  rather than being deduced directly from the URL, resulting in a more
>  flexible solution.)
>
> --
> Ticket URL: <http://varnish-cache.org/ticket/682>
> Varnish <http://varnish-cache.org/>
> The Varnish HTTP Accelerator
>




More information about the varnish-bugs mailing list