![]() |
Vmod-dbrw |
Database-driven rewrites for Varnish Cache |
Sergey Poznyakoff |
vmod-dbrw User Manual (split by chapter): | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
? |
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 with 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. It assumes VCL 4.0:
sub vcl_recv { 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")); } } |
Further handling of the 301 response should be performed in a traditional way, e.g.:
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.
The example below shows the same code for VCL 3.0:
import std; sub vcl_recv { set req.http.X-Redirect-To = dbrw.rewrite("host=" + req.http.Host + ";" + "url=" + req.url); if (req.http.X-Redirect-To != "") { error(750, "Redirect"); } } sub vcl_error { if (obj.status == 750) { set obj.http.Location = req.http.X-Redirect-To; set obj.status = std.integer(req.http.X-VMOD-DBRW-Status, 301); return (deliver); } } |
For VCL 3.0, you can use libvmod_redirect
to simplify the
code:
import std; import dbrw; import redirect; sub vcl_recv { set req.http.X-Redirect-To = dbrw.rewrite("host=" + req.http.Host + ";" + "url=" + req.url); if (req.http.X-Redirect-To != "") { error(redirect.location( std.integer(req.http.X-VMOD-DBRW-Status, 301), req.http.X-Redirect-To), "Redirection"); } } |
The vcl_error
subroutine is not needed in this case.
![]() |
![]() |
![]() |
![]() |
![]() |
? |
Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.