Search
Varnish Enterprise

Introduction Installation Upgrading Troubleshooting Changelog Changelog for 6.0.x Changes (Varnish Cache 4.1) Changes (Varnish Cache Plus 4.1) Known Issues Features Backend SSL/TLS Client SSL/TLS termination Cluster In-Process TLS MSE 4 Basic Configuration / Getting Started Configuration Persisted caching Categories Configuration Reference MSE 3.0 Settings mkfs.mse Memory Governor MSE 2.0 NUMA Parallel ESI Backend health counter HTTP/2 Support JSON Logging TCP Only Probes Timeouts Transit Buffer Varnish scoreboard VMODs Accept Accounting ACL (aclplus) ActiveDNS Akamai Connector AWS VCL Body Access & Transformation (xbody) Brotli Cookie Plus (cookieplus) DeviceAtlas DeviceAtlas3 Digest Dynamic backends (goto) Edgestash File Format Geolocation (geoip/mmdb) Header Manipulation (headerplus) HTTP communication (http) Image JSON parsing (json) JWT Key value storage (kvstore) Least connections director (leastconn) Module to control the built-in HTTP2 transport (h2) MSE control (mse) MSE4 control (mse4) Probe Proxy ProxyV2 TLV Attribute Extraction (proxy) Pseudo Random Number Generator Purge (purge/softpurge) Real-time Status (rtstatus) Reverse DNS (resolver) Rewrite S3 VMOD Session Slicer SQLite3 Stale Standard (std) Stat (Prometheus) Strings (str) Synthetic backends (synthbackend) Tag-based invalidation (Ykey/Xkey) TCP configuration (tcp) TLS Total Encryption (crypto) Unified director object (udo) Uniform Resource Identifier (uri) Unix Socket Utilities (unix) URL Plus (urlplus) Utils Vsthrottle

Bodyaccess

Description

vmod_bodyaccess gives vcl some access to the request body. A common use case is to allow caching of POST requests, where the request body needs to be part of the hash.

Example VCL

vcl 4.0;
import std;
import bodyaccess;

backend default { .host = "192.0.2.11"; .port = "8080"; }

sub vcl_recv {
	set req.http.x-method = req.method;
	if (req.method == "POST") {
		if (std.cache_req_body(110KB)) {
			set req.http.x-len = bodyaccess.len_req_body();
			set req.http.x-re = bodyaccess.rematch_req_body("Regex");
			bodyaccess.log_req_body("PREFIX:", 3);
			return(hash);
		}
	}
}

sub vcl_hash {
	bodyaccess.hash_req_body();
}

sub vcl_backend_fetch {
	set bereq.method = bereq.http.x-method;
}

sub vcl_deliver {
	set resp.http.x-len = req.http.x-len;
	set resp.http.x-re = req.http.x-re;
}

API

Not that the request body must be retrieved before doing any operations on it. It can be buffered using the cache_req_body() function from libvmod_std.

Note that, according to RFC 2616, caching should never happen for PUT, DELETE and POST. However, there are good reasons allow POST requests to some resources and still chache the result. Examples include REST methods that are idempotent.

For this reason, it is only adviced to use these functions on POST requests.

Search for a string in the request body

INT rematch_req_body(PRIV_CALL, STRING re)

  • Returns -1 if an error occurrs.
  • Returns 0 if the request body doesn’t contain the string re.
  • Returns 1 if the request body contains the string re.

Note: The comparison is case sensitive and the request body must be buffered. re is static and cannot change between calls. This function can only be called from vcl_recv.

Example

	std.cache_req_body(1KB);

	if (bodyaccess.rematch_req_body("FOO") == 1) {
		std.log("is true");
	}

Adding the request body to the hash

VOID hash_req_body()

This adds the (available) request body bytes to the lookup hash key. Note that this function can only be used in vcl_hash and the request body must be buffered for it to work properly.

Example

sub vcl_recv {
	std.cache_req_body(1KB);
}

sub vcl_hash{
	bodyaccess.hash_req_body();
}

Getting the request body length

INT len_req_body()

This returns the request body length, or -1 if an error occurs. The request body must be buffered.

Note: This function can only be called from vcl_recv.

Example

	std.cache_req_body(1KB);
	set req.http.x-len = bodyaccess.len_req_body();

Logging the request body

VOID log_req_body(STRING prefix = "", INT length = 200)

This logs the request body to the VSL, making it available for other components. When logging, it takes an optional prefix and a max line length, so the body could be split up across multiple lines. This is sometimes necessary, as there is a limit to how large a single line can be.

Example

	std.cache_req_body(1KB);
	bodyaccess.log_req_body("PREFIX:", 40);

®Varnish Software, Wallingatan 12, 111 60 Stockholm, Organization nr. 556805-6203