-
Notifications
You must be signed in to change notification settings - Fork 87
Description
Hi,
Consider the following VTC, testing behavior of unset and empty variables:
varnishtest "Test var.get() truthiness and equality to the empty string"
server s1 {
rxreq
txresp
} -start
varnish v1 -vcl+backend {
import std;
import var from "${vmod_builddir}/.libs/libvmod_var.so";
sub vcl_deliver {
var.set("empty", "");
if (var.get("empty")) {
set resp.http.empty-truthy = "true";
} else {
set resp.http.empty-truthy = "false";
}
if (var.get("empty") == "") {
set resp.http.empty-empty = "true";
} else {
set resp.http.empty-empty = "false";
}
if (var.get("unset")) {
set resp.http.unset-truthy = "true";
} else {
set resp.http.unset-truthy = "false";
}
if (var.get("unset") == "") {
set resp.http.unset-empty = "true";
} else {
set resp.http.unset-empty = "false";
}
}
} -start
client c1 {
txreq -url "/"
rxresp
// Empty is truthy: ("String types will evaluate to false if they are unset.")
expect resp.http.empty-truthy == "true"
// Empty is empty:
expect resp.http.empty-empty == "true"
// Unset is not truthy: ("String types will evaluate to false if they are unset.")
expect resp.http.unset-truthy == "false"
// Unset is empty: ("if (req.http.opthdr == "") {} does not distinguish if the header does not exist or if it is empty.")
expect resp.http.unset-empty == "true"
// The last test above fails, because `resp.http.unset-empty` is actually "false", because `var.get("unset") == ""` returns false.
} -run
var.get("unset") == "" of an unset variable returns false, which is unintuitive given the VCL reference documentation:
String types will evaluate to false if they are unset. This allows checks of the type if (req.http.opthdr) {} to test if a header exists, even if it is empty, whereas if (req.http.opthdr == "") {} does not distinguish if the header does not exist or if it is empty.
The reference suggets that var.get("unset") == "" should return true (does not distinguish if the header does not exist or if it is empty). But it actually returns false.
This means that a user of libvmod-var that wishes to check a variable for "not empty" shouldn't do var.get("foo") != "" but actually var.get("foo") && var.get("foo") != "".
I suppose this cannot easily be fixed without "breaking" the API. Should this be documented?