Vmod-dbrw |
|
Database-driven rewrites for Varnish Cache |
Sergey Poznyakoff |
5 The rewrite
Function
- function: string rewrite (string args)
This function is the working horse of the module. It rewrites its argument using the database configured in the previous call to
config
and returns the obtained value.To do so, it performs the following steps:
- Parameter parsing
The args parameter must be a list of
name=value
pairs separated by semicolons. The function parses this string and builds a symbol table. - Variable expansion
Using the symbol table built in the previous stage, each occurrence of
$name
or${name}
is replaced by the actual value of the variable name from the table. Expanding an undefined variable is considered an error. - Establishing the database connection
Unless the connection has already been established by a prior call to
rewrite
, the function establishes it using the parameters supplied earlier in a call toconfig
. If the connection fails, the function returns NULL immediately.Database connections are persisting and thread-specific. This means that each thread keeps its own connection to the database and attempts to re-establish it if it goes down for some reason.
- Query execution
The query is sent to the server and the resulting set collected from it.
- Result interpretation
The resulting set is interpreted as described in result interpretation. This results in a single value being returned to the caller.
- Parameter parsing
Assuming the database structure similar to the one discussed in the
previous chapter, the following example illustrates how to use
rewrite
to redirect the incoming request.
sub vcl_recv { dbrw.config("mysql", "database=rewrite;user=varnish;password=guessme", {"SELECT dest FROM redirects WHERE host='$host' AND url='$url'"}); set req.http.X-Redirect-To = dbrw.rewrite("host=" + req.http.Host + ";" + "url=" + req.url); if (req.http.X-Redirect-To != "") { return(synth(301, "Redirect")); } }
The ‘synth’ sub must be provided in order to construct redirection responses:
import std; sub vcl_synth { if (resp.status == 301) { set resp.http.Location = req.http.X-Redirect-To; if (req.http.X-VMOD-DBRW-Status != "") { set resp.status = std.integer(req.http.X-VMOD-DBRW-Status, 301); } return (deliver); } }
The X-VMOD-DBRW-Status
header, if set, contains the status code to be
returned to the client (see X-VMOD-DBRW-Status). Notice the use
of the vmod_std
module to cast it to integer.
If an error occured during the rewrite, it is recommended to not
cache the response. This way the next request will call rewrite again
and eventually complete the rewriting. This can be achieved using the
following vcl_backend_response
fragment:
sub vcl_backend_response { if (bereq.http.X-VMOD-DBRW-Error == "1") { set beresp.uncacheable = true; return (deliver); } }
This document was generated on April 9, 2020 using makeinfo.
Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.