diff --git a/README.rst b/README.rst index 5ba9a28..912c820 100644 --- a/README.rst +++ b/README.rst @@ -94,6 +94,29 @@ Example | if (bodyaccess.rematch_req_body("FOO") == 1) { | std.log("is true"); | } +req_body +------------- + +Prototype + :: + + req_body() +Return value + STRING +Description + Return available request body to VCL. + Note that this function can only be used in vcl_recv and + the request body must already be in std buffer. + Its intent is for a small body, workspace's storage is used. +Example + :: + + | sub vcl_recv { + | std.cache_req_body(256B); + | + | set req.http.body = regsub(bodyaccess.req_body(), "foo", "bar"); + | } + Find more example in example.vcl. diff --git a/src/tests/test05.vtc b/src/tests/test05.vtc new file mode 100644 index 0000000..53be427 --- /dev/null +++ b/src/tests/test05.vtc @@ -0,0 +1,27 @@ +varnishtest "test regex match on req body" + +server s1 { + rxreq + expect req.body == "BANANE" + expect req.http.foobar == "BANANAS" + txresp +} -start + +varnish v1 -vcl+backend { + import bodyaccess from "${vmod_topbuild}/src/.libs/libvmod_bodyaccess.so"; + import std; + + sub vcl_recv { + std.cache_req_body(100B); + set req.http.req_body = bodyaccess.req_body(); + set req.http.foobar = regsub(req.http.req_body, "NE", "NAS"); + unset req.http.req_body; + } +} + +varnish v1 -start + +client c1 { + txreq -req "POST" -body {BANANE} + rxresp +} -run diff --git a/src/vmod_bodyaccess.c b/src/vmod_bodyaccess.c index ba0682a..5dc061b 100644 --- a/src/vmod_bodyaccess.c +++ b/src/vmod_bodyaccess.c @@ -102,3 +102,37 @@ vmod_rematch_req_body(VRT_CTX, struct vmod_priv *priv_call, VCL_STRING re) return (-1); } + +VCL_STRING +vmod_req_body(VRT_CTX) +{ + struct vsb *vsb; + char *s; + + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + if (ctx->req->req_body_status != REQ_BODY_CACHED) { + VSLb(ctx->vsl, SLT_VCL_Error, + "Unbuffered req.body"); + return (NULL); + } + + if (ctx->method != VCL_MET_RECV) { + VSLb(ctx->vsl, SLT_VCL_Error, + "rematch_req_body can be used only in vcl_recv{}"); + return (NULL); + } + + vsb = VSB_new_auto(); + VRB_Blob(ctx, vsb); + s = WS_Alloc(ctx->ws, VSB_len(vsb) + 1); + if (s == NULL) { + VSLb(ctx->vsl, SLT_VCL_Error, + "workspace can't hold size of req_body (%ld bytes)", VSB_len(vsb)); + VSB_delete(vsb); + return (NULL); + } + memcpy(s, VSB_data(vsb), VSB_len(vsb)); + s[VSB_len(vsb)] = 0; + VSB_delete(vsb); + return (s); +} diff --git a/src/vmod_bodyaccess.vcc b/src/vmod_bodyaccess.vcc index fc89458..692a565 100644 --- a/src/vmod_bodyaccess.vcc +++ b/src/vmod_bodyaccess.vcc @@ -5,3 +5,5 @@ $Function INT rematch_req_body(PRIV_CALL, STRING re) $Function VOID hash_req_body() $Function INT len_req_body() + +$Function STRING req_body()