diff --git a/README.md b/README.md index 9870470..75cf791 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ set req.url = querymodifier.excludparams(url=req.url, params="ts,v"); # Modified URL: example.com/?search=name&id=987654321 ``` -### Remove all +### Remove all valid query parameters Remove all query parameters by passing in an empty string. @@ -57,6 +57,19 @@ set req.url = querymodifier.modifyparams(url=req.url, params="", exclude_params= # Modified URL: example.com/ ``` +### Remove all query string + +Remove all of the query string, i.e. everything after, and including the `?` regardless of if +the are valid `name=value` query string parameters. + +``` +import querymodifier; +set req.url = querymodifier.removeallquerystring(url=req.url); + +# Original URL: example.com/?123456 +# Modified URL: example.com/ +``` + ### Additional See the tests for more parameter edge cases. diff --git a/src/vmod_querymodifier.c b/src/vmod_querymodifier.c index 8300750..a398729 100644 --- a/src/vmod_querymodifier.c +++ b/src/vmod_querymodifier.c @@ -309,3 +309,34 @@ VCL_STRING vmod_excludeallparams(VRT_CTX, VCL_STRING uri) { return vmod_modifyparams(ctx, uri, NULL, 1); } + +/** + * Remove the entire query string from the URL, regardless of its content. + * This function will remove everything after (and including) the '?'. + * @param ctx The Varnish context. + * @param uri The URL to modify. + * @return The URL without any query parameters. + */ +VCL_STRING +vmod_removeallquerystring(VRT_CTX, VCL_STRING uri) { + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + CHECK_OBJ_NOTNULL(ctx->ws, WS_MAGIC); + + if (uri == NULL) { + VRT_fail(ctx, "uri is NULL"); + return NULL; + } + + char *uri_buf = WS_Copy(ctx->ws, uri, strlen(uri) + 1); + if (!uri_buf) { + VRT_fail(ctx, "WS_Copy: uri_buf: out of workspace"); + return NULL; + } + + char *query = strchr(uri_buf, '?'); + if (query != NULL) { + *query = '\0'; + } + + return uri_buf; +} diff --git a/src/vmod_querymodifier.vcc b/src/vmod_querymodifier.vcc index 2abaa18..e67b3c2 100644 --- a/src/vmod_querymodifier.vcc +++ b/src/vmod_querymodifier.vcc @@ -48,3 +48,13 @@ Example :: set req.url = querymodifier.excludeallparams(req.url); + +$Function STRING removeallquerystring(STRING url) + +Description + The function removes the entire query string from the URL, i.e. everything after and including the '?'. + +Example + :: + + set req.url = querymodifier.removeallquerystring(req.url); diff --git a/src/vtc/removeallquerystring.vtc b/src/vtc/removeallquerystring.vtc new file mode 100644 index 0000000..ea00ee1 --- /dev/null +++ b/src/vtc/removeallquerystring.vtc @@ -0,0 +1,38 @@ +varnishtest "Test querymodifier vmod for proper removal of all query parameters" + +server s1 { + rxreq + txresp -body "OK1" + expect req.url == "/feed/" + + rxreq + txresp -body "OK1" + expect req.url == "/feed/" +} -start + +varnish v1 -vcl+backend { + import std; + import querymodifier; + + sub vcl_hash { + std.syslog(180, "querymodifier before: " + req.url); + set req.url = querymodifier.removeallquerystring(url=req.url); + std.syslog(180, "querymodifier after: " + req.url); + } +} -start + +client c1 { + txreq -url "/feed/?1730210988319&ts=1730210988319" + rxresp + expect resp.status == 200 + + # This one will be cached as all of the query params are excluded, even invalid ones. + txreq -url "/feed/?1730210982229" + rxresp + expect resp.status == 200 +} -run + +varnish v1 -expect n_object == 1 +varnish v1 -expect cache_miss == 1 +varnish v1 -expect cache_hit == 1 +