With this change, http_RemoveHdrToken also removes any values of an element token seperated by equals (like foo=bar)
phk, does this work for you? Thanks, Nils
>From ed60be21f4a4af6bb69d05c810aa2adf5c4ecbd5 Mon Sep 17 00:00:00 2001 From: Nils Goroll <[email protected]> Date: Wed, 17 Sep 2014 18:39:09 +0200 Subject: [PATCH 1/2] Add a function to remove an element/token from a header value (like Accept-Encoding from Vary) --- bin/varnishd/cache/cache.h | 2 + bin/varnishd/cache/cache_http.c | 96 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index b4e79c4..7b28418 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -884,6 +884,8 @@ void http_Teardown(struct http *ht); int http_GetHdr(const struct http *hp, const char *hdr, char **ptr); int http_GetHdrToken(const struct http *hp, const char *hdr, const char *token, char **ptr); +int http_RemoveHdrToken(struct http *hp, const char *hdr, + const char *token); int http_GetHdrField(const struct http *hp, const char *hdr, const char *field, char **ptr); double http_GetHdrQ(const struct http *hp, const char *hdr, const char *field); diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index 031b7dd..fd42914 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -460,6 +460,102 @@ http_GetHdrToken(const struct http *hp, const char *hdr, return (0); } +/*----------------------------------------------------------------------------- + * Remove a given data element (token) from a header + * + * return 1 if header was changed, 0 otherwise + */ + +int +http_RemoveHdrToken(struct http *hp, const char *hdr, + const char *token) +{ + char *bp, *tp, *ep, *n, *w; + unsigned bl, tl, el, hdrl, l; + + if (! (http_GetHdr(hp, hdr, &bp) && + http_GetHdrToken(hp, hdr, token, &tp))) + return (0); + + /* GetHdrToken returns a pointer to the next char after the token */ + tl = strlen(token); + tp -= tl; + + /* skip initial whitespace and commas */ + while (vct_islws(*bp) || *bp == ',') + bp++; + + assert(tp >= bp); + + ep = &tp[tl]; + + /* if the token contains a value, skip it */ + if (*ep == '=') + while (*ep && (! (vct_islws(*ep) || *ep == ','))) + ep++; + + /* move ep to the next token after the token to be removed */ + while (vct_islws(*ep) || *ep == ',') + ep++; + + bl = (tp - bp); + el = strlen(ep); + + if (bl == 0 && el == 0) { + /* nothing but the token to be removed */ + http_Unset(hp, hdr); + return (1); + } + + if (el == 0) { + /* nothing at the end - remove separating whitespace/comma */ + while (vct_islws(bp[bl - 1]) || bp[bl - 1] == ',') + bl--; + assert(bl > 0); + } + + hdrl = strlen(hdr) - 1; + l = hdrl + 1 + bl + el + 1; + + if (WS_Reserve(hp->ws, l) < l) { + http_fail(hp); + VSLb(hp->vsl, SLT_LostHeader, hdr); + WS_Release(hp->ws, 0); + return (0); + } + + n = w = hp->ws->f; + + memcpy(w, hdr + 1, hdrl); + w += hdrl; + *w++ = ' '; + + if (bl) { + memcpy(w, bp, bl); + w += bl; + } + + if (el) { + memcpy(w, ep, el); + w += el; + } + + *w++ = '\0'; + + assert((w - hp->ws->f) == l); + WS_Release(hp->ws, l); + + http_Unset(hp, hdr); + http_SetHeader(hp, n); + + /* + * strictly speaking we could still loose the header in SetHeader, but + * this is unlikely and we cannot check + */ + return (1); +} + + /*-------------------------------------------------------------------- * Find a given headerfields Q value. */ -- 2.0.1
_______________________________________________ varnish-dev mailing list [email protected] https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev
