Sometimes it is necessary to share data between Lua functions used as
conditions and modifiers in pound configuration file. An
obvious way of doing so is using Lua global variables. This approach,
however, poses one major problem: values stored in globals will
persist not only when processing a single HTTP request, but also
between different HTTP requests, and this can cause undesirable
side effects.
To avoid this, pound provides a special built-in variable
stash. Its value is a table whose contents persist only while
a singe HTTP request is being processed. Applications can
fill it with whatever values they like.
To illustrate its use let’s change the bearer module from
Lua conditionals, so it can be used to select the service to use based
on JWT claims. First, the bearer.ok function should store the
parsed JWT object in stash before returning. Its last lines will then
look like:
stash.bearer = j return true end
Then, we implement a new method, which checks if the hostname given as its argument is listed in one of the JWT claims:
function bearer.urlOK(host)
return stash.bearer ~= nil and
stash.bearer.payload['http://' .. host] == true
end
Now this method can be used as a conditional to select the service to use as shown in the example below:
Service "auth"
Not LuaMatch "bearer.ok" "secret"
Rewrite response
SetHeader "WWW-Authenticate: Bearer realm=\"Restricted access\""
End
Error 401
End
Service "foo"
LuaMatch "bearer.urlOK" "foo.com"
Backend
Address 127.0.0.1
Port 8081
End
End
Service "bar"
LuaMatch "bearer.urlOK" "bar.com"
...
End
The service ‘auth’, same as in the previous example, verifies that the request carries a valid bearer token and, if so, saves off the JWT for further use. Subsequent services make use of this saved value to verify if the corresponding claim is true: the service ‘foo’ is selected if the claim ‘http://foo.com’ is true, and so on.