vmod-dbrw User Manual (split by section):   Section:   Chapter:FastBack: Query   Up: Top   FastForward: Reporting Bugs   Contents: Table of ContentsIndex: Concept Index

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 to config. 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.

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);
    }
}

vmod-dbrw User Manual (split by section):   Section:   Chapter:FastBack: Query   Up: Top   FastForward: Reporting Bugs   Contents: Table of ContentsIndex: Concept Index