[master] 4756c13 add http_date_postel feature bit for relaxed http date parsing

Nils Goroll nils.goroll at uplex.de
Wed Jan 31 18:05:10 UTC 2018


commit 4756c13fd6ae0608b2f89c569c6689d8ece9d015
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Wed Jan 31 18:53:39 2018 +0100

    add http_date_postel feature bit for relaxed http date parsing
    
    For now, the only case this adds is a missing leading zero in the
    day of the month of RFC822/RFC1123 - style http dates as in
    
    		Fri, 2 Mar 2018 14:26:02 GMT (bad)
    instead of	Fri, 02 Mar 2018 14:26:02 GMT (correct)
    
    This is clearly invalid according to
    https://tools.ietf.org/html/rfc7231#section-7.1.1.2
    yet accepted by other webserver software.

diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c
index 18f02ca..e2fecec 100644
--- a/bin/varnishd/cache/cache_acceptor.c
+++ b/bin/varnishd/cache/cache_acceptor.c
@@ -130,6 +130,21 @@ static const struct linger linger = {
 static unsigned		need_test;
 
 /*--------------------------------------------------------------------
+ * lacking a better place, we put some generic periodic updates
+ * into the vca_acct() loop which we are running anyway
+ */
+static void
+vca_periodic(double t0)
+{
+	double now;
+
+	now = VTIM_real();
+	VSC_C_main->uptime = (uint64_t)(now - t0);
+
+	VTIM_postel = FEATURE(FEATURE_HTTP_DATE_POSTEL);
+}
+
+/*--------------------------------------------------------------------
  * Some kernels have bugs/limitations with respect to which options are
  * inherited from the accept/listen socket, so we have to keep track of
  * which, if any, sockopts we have to set on the accepted socket.
@@ -522,7 +537,7 @@ static void * v_matchproto_()
 vca_acct(void *arg)
 {
 	struct listen_sock *ls;
-	double t0, now;
+	double t0;
 
 	// XXX Actually a mis-nomer now because the accept happens in a pool
 	// thread. Rename to accept-nanny or so?
@@ -530,6 +545,9 @@ vca_acct(void *arg)
 	THR_Init();
 	(void)arg;
 
+	t0 = VTIM_real();
+
+	vca_periodic(t0);
 	(void)vca_tcp_opt_init();
 
 	AZ(pthread_mutex_lock(&shut_mtx));
@@ -562,7 +580,6 @@ vca_acct(void *arg)
 	need_test = 1;
 	pool_accepting = 1;
 
-	t0 = VTIM_real();
 	while (1) {
 		(void)sleep(1);
 		if (vca_tcp_opt_init()) {
@@ -575,8 +592,7 @@ vca_acct(void *arg)
 			}
 			AZ(pthread_mutex_unlock(&shut_mtx));
 		}
-		now = VTIM_real();
-		VSC_C_main->uptime = (uint64_t)(now - t0);
+		vca_periodic(t0);
 	}
 	NEEDLESS(return NULL);
 }
diff --git a/bin/varnishtest/tests/c00085.vtc b/bin/varnishtest/tests/c00085.vtc
new file mode 100644
index 0000000..ba305f5
--- /dev/null
+++ b/bin/varnishtest/tests/c00085.vtc
@@ -0,0 +1,25 @@
+varnishtest "relaxed date parsing"
+
+server s1 {
+	rxreq
+	txresp \
+	    -hdr "Date: Wed, 31 Jan 2018 14:26:02 GMT" \
+	    -hdr "Last-Modified: Thu, 4 Jan 2018 06:26:29 GMT" \
+	    -hdr "Expires: Fri, 2 Mar 2018 14:26:02 GMT"
+} -start
+
+varnish v1 -arg "-p feature=+http_date_postel" -vcl+backend {
+	import std;
+
+	sub vcl_backend_response {
+		set beresp.http.ttl = beresp.ttl;
+		set beresp.http.lm = std.time(beresp.http.last-modified, now);
+	}
+ } -start
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.http.ttl == "2592000.000"
+	expect resp.http.lm == "Thu, 04 Jan 2018 06:26:29 GMT"
+} -run
diff --git a/include/tbl/feature_bits.h b/include/tbl/feature_bits.h
index 96500da..23f1b01 100644
--- a/include/tbl/feature_bits.h
+++ b/include/tbl/feature_bits.h
@@ -77,6 +77,12 @@ FEATURE_BIT(HTTP2,		http2,
     "Enable HTTP/2 protocol support."
 )
 
+FEATURE_BIT(HTTP_DATE_POSTEL,	http_date_postel,
+    "Relax parsing of timestamps in HTTP headers",
+    "Tolerate non standards conforming variations of timestamp headers"
+    "like Date:, Last-Modified:, Expires: etc."
+)
+
 #undef FEATURE_BIT
 
 /*lint -restore */
diff --git a/include/vtim.h b/include/vtim.h
index 8db4fbe..9c2e6cc 100644
--- a/include/vtim.h
+++ b/include/vtim.h
@@ -29,6 +29,7 @@
  */
 
 /* from libvarnish/vtim.c */
+extern unsigned VTIM_postel;
 #define VTIM_FORMAT_SIZE 30
 void VTIM_format(double t, char *p);
 double VTIM_parse(const char *p);
diff --git a/lib/libvarnish/vtim.c b/lib/libvarnish/vtim.c
index 4ef9058..9772ac8 100644
--- a/lib/libvarnish/vtim.c
+++ b/lib/libvarnish/vtim.c
@@ -70,6 +70,9 @@
 #include "vas.h"
 #include "vtim.h"
 
+/* relax vtim parsing */
+unsigned VTIM_postel = 0;
+
 static const char * const weekday_name[] = {
 	"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
 };
@@ -264,8 +267,12 @@ VTIM_parse(const char *p)
 			/* RFC822 & RFC1123 - "Sun, 06 Nov 1994 08:49:37 GMT" */
 			p++;
 			MUSTBE(' ');
-			DIGIT(10, mday);
-			DIGIT(1, mday);
+			if (VTIM_postel && *p && p[1] == ' ')
+				DIGIT(1, mday);
+			else {
+				DIGIT(10, mday);
+				DIGIT(1, mday);
+			}
 			MUSTBE(' ');
 			MONTH();
 			MUSTBE(' ');


More information about the varnish-commit mailing list