[master] 08d3a70d2 add a trivial VRT function to check if a string is a valid header value
Nils Goroll
nils.goroll at uplex.de
Fri Oct 9 11:43:06 UTC 2020
commit 08d3a70d258108d0dffb8ae208e6e29891565534
Author: Nils Goroll <nils.goroll at uplex.de>
Date: Wed Sep 9 15:34:42 2020 +0200
add a trivial VRT function to check if a string is a valid header value
Ref: https://httpwg.org/specs/rfc7230.html#header.fields
field-value = *( field-content / obs-fold )
field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
field-vchar = VCHAR / obs-text
- we do not accept the obsolete line folding (obs-fold)
- VCHAR is 0x20 to 0x7e
- obs-text is 0x80 to 0xff
So we end up with !VCT_CTL || HTAB (LF)
This change would be the basis for new use cases, like
- a type method .valid_header
- a feature flag +validate_headers which would call VRT_ValidHdr
for all SetHdr calls
diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index aef672e27..f88daaac1 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -590,6 +590,35 @@ VRT_UpperLowerStrands(VRT_CTX, VCL_STRANDS s, int up)
return (r);
}
+// RFC7232, 3.2 without obsolete line folding:
+// ASCII VCHAR + TAB + obs-text (0x80-ff)
+static inline VCL_BOOL
+validhdr(const char *p)
+{
+ AN(p);
+ for(;*p != '\0'; p++)
+ if (vct_isctl(*p) && !vct_issp(*p))
+ return (0);
+ return (1);
+}
+
+/*--------------------------------------------------------------------*/
+VCL_BOOL
+VRT_ValidHdr(VRT_CTX, VCL_STRANDS s)
+{
+ int i;
+
+ (void) ctx;
+
+ for (i = 0; i < s->n; i++) {
+ if (s->p[i] == NULL || s->p[i][0] == '\0')
+ continue;
+ if (! validhdr(s->p[i]))
+ return (0);
+ }
+
+ return (1);
+}
/*--------------------------------------------------------------------*/
VCL_VOID
diff --git a/include/vrt.h b/include/vrt.h
index 5e5b032f9..7e31480a4 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -496,6 +496,7 @@ VCL_INT VRT_purge(VRT_CTX, VCL_DURATION, VCL_DURATION, VCL_DURATION);
VCL_VOID VRT_synth(VRT_CTX, VCL_INT, VCL_STRING);
VCL_VOID VRT_hit_for_pass(VRT_CTX, VCL_DURATION);
+VCL_BOOL VRT_ValidHdr(VRT_CTX, VCL_STRANDS);
VCL_VOID VRT_SetHdr(VRT_CTX, VCL_HEADER, const char *, ...);
VCL_VOID VRT_handling(VRT_CTX, unsigned hand);
VCL_VOID VRT_fail(VRT_CTX, const char *fmt, ...) v_printflike_(2,3);
More information about the varnish-commit
mailing list