From 1aef6dd4c437180ab1b955f28e8ed9da3b27ff1f Mon Sep 17 00:00:00 2001 From: Guillaume Quintard Date: Wed, 27 Mar 2024 10:41:56 -0700 Subject: [PATCH] add handling --- main.c | 36 ++++++++++++++++++++++-- tests/003.vtc | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 tests/003.vtc diff --git a/main.c b/main.c index 521b44e..e04e52e 100644 --- a/main.c +++ b/main.c @@ -166,6 +166,7 @@ static int process_group(struct VSL_data *vsl, // go through all transaction for (struct VSL_transaction *t = trans[0]; t != NULL; t = *++trans) { char *side; + char *handling = "incomplete"; switch (t->type) { case VSL_t_bereq: @@ -223,16 +224,42 @@ static int process_group(struct VSL_data *vsl, break; case SLT_VCL_call: - if (t->type == VSL_t_req) + if (t->type == VSL_t_req) { req_done = true; - else if (!strcmp(data, "BACKEND_RESPONSE") || !strcmp(data, "BACKEND_ERROR")) + } else if (!strcmp(data, "BACKEND_RESPONSE") || !strcmp(data, "BACKEND_ERROR")) { resp_done = true; + } + + // don't overwrite handling if we're already erroring + if (!strcmp(handling, "fail") || !strcmp(handling, "abandon")) { + break; + } else if (!strcmp(data, "HIT")) { + handling = "hit"; + } else if (!strcmp(data, "MISS")) { + handling = "miss"; + } else if (!strcmp(data, "PASS")) { + handling = "pass"; + } else if (!strcmp(data, "SYNTH")) { + handling = "synth"; + } else if (!strcmp(data, "BACKEND_RESPONSE")) { + handling = "fetched"; + } else if (!strcmp(data, "BACKEND_ERROR")) { + handling = "error"; + } else if (!strcmp(data, "SYNTH")) { + handling = "synth"; + } break; case SLT_VCL_return: if (t->type == VSL_t_bereq && - (!strcmp(data, "fetch") || !strcmp(data, "error"))) + (!strcmp(data, "fetch") || !strcmp(data, "error"))) { req_done = true; + } + if (!strcmp(data, "fail")) { + handling = "fail"; + } else if (!strcmp(data, "abandon")) { + handling = "abandon"; + } break; #define save_data(tag, cond, obj, field) \ @@ -406,6 +433,9 @@ static int process_group(struct VSL_data *vsl, } } + // commit handling + cJSON_AddStringToObject(transaction, "handling", handling); + // we still need to go through the flattened headers // to put them in an object cJSON *h = NULL; diff --git a/tests/003.vtc b/tests/003.vtc new file mode 100644 index 0000000..01f418b --- /dev/null +++ b/tests/003.vtc @@ -0,0 +1,78 @@ +varnishtest "fail/abandon" + +feature cmd jq + +server s1 { + rxreq + txresp +} -start + +varnish v1 -vcl+backend { + import std; + + backend black_hole none; + + sub vcl_recv { + if (req.url == "/recv_fail") { + return (fail); + } else { + return (pass); + } + } + + sub vcl_backend_fetch { + set bereq.backend = s1; + if (bereq.url == "/fetch_fail") { + return (fail); + } else if (bereq.url == "/fetch_abandon" || bereq.url == "/fetch_error") { + set bereq.backend = black_hole; + return (fetch); + } else { + return (fetch); + } + } + + sub vcl_backend_error { + if (bereq.url == "/fetch_abandon") { + return(abandon); + } + } +} -start + +client c1 { + txreq -url "/recv_fail" + rxresp +} -run + +client c1 { + txreq -url "/fetch_fail" + rxresp +} -run + + +client c1 { + txreq -url "/fetch_abandon" + rxresp +} -run + +client c1 { + txreq -url "/fetch_error" + rxresp +} -run + +# give some time for the logs to land (0.1s is overly generous) +delay 0.1 + +shell { + t() { + set -ex + test "$(${varnishlog-json_bin} -$2 -n ${v1_name} -d | jq -r "select(.req.url == \"$1\") | .handling" )" = "$3" + } + + ${varnishlog-json_bin} -bc -n ${v1_name} -d + + t /recv_fail c fail + t /fetch_fail b fail + t /fetch_abandon b abandon + t /fetch_error b error +}