[4.1] b9946b4 Fail HTTP/1.0 POST and PUT requests without C-L

Lasse Karstensen lkarsten at varnish-software.com
Thu Feb 11 17:14:32 CET 2016


commit b9946b4b0bc65b935580fe7db999b1b6c5558e19
Author: Federico G. Schwindt <fgsch at lodoss.net>
Date:   Tue Feb 2 08:17:13 2016 +0000

    Fail HTTP/1.0 POST and PUT requests without C-L
    
    It is not allowed by the spec and we incorrectly assumed chunked
    and eventually timed out.  OK'd by phk at .
    Fixes #1843.

diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c
index 2bca363..0ae476e 100644
--- a/bin/varnishd/http1/cache_http1_proto.c
+++ b/bin/varnishd/http1/cache_http1_proto.c
@@ -288,6 +288,8 @@ http1_body_status(const struct http *hp, struct http_conn *htc)
 	htc->content_length = -1;
 
 	cl = http_GetContentLength(hp);
+	if (cl == -2)
+		return (BS_ERROR);
 	if (http_GetHdr(hp, H_Transfer_Encoding, &b)) {
 		if (strcasecmp(b, "chunked"))
 			return (BS_ERROR);
@@ -300,8 +302,6 @@ http1_body_status(const struct http *hp, struct http_conn *htc)
 		}
 		return (BS_CHUNKED);
 	}
-	if (cl == -2)
-		return (BS_ERROR);
 	if (cl >= 0) {
 		htc->content_length = cl;
 		return (cl == 0 ? BS_NONE : BS_LENGTH);
@@ -381,10 +381,13 @@ HTTP1_DissectRequest(struct http_conn *htc, struct http *hp)
 	p = http_GetMethod(hp);
 	AN(p);
 
-	/* We handle EOF bodies only for PUT and POST */
-	if (htc->body_status == BS_EOF &&
-	    strcasecmp(p, "put") && strcasecmp(p, "post"))
+	if (htc->body_status == BS_EOF) {
+		assert(hp->protover == 10);
+		/* RFC1945 8.3 p32 and D.1.1 p58 */
+		if (!strcasecmp(p, "post") || !strcasecmp(p, "put"))
+			return (400);
 		htc->body_status = BS_NONE;
+	}
 
 	/* HEAD with a body is a hard error */
 	if (htc->body_status != BS_NONE && !strcasecmp(p, "head"))
diff --git a/bin/varnishtest/tests/r01843.vtc b/bin/varnishtest/tests/r01843.vtc
new file mode 100644
index 0000000..20d37c9
--- /dev/null
+++ b/bin/varnishtest/tests/r01843.vtc
@@ -0,0 +1,17 @@
+varnishtest "HTTP/1.0 POST and PUT need a valid Content-Length"
+
+server s1 { } -start
+
+varnish v1 -vcl+backend {} -start
+
+client c1 {
+	txreq -proto HTTP/1.0 -req "POST" -nolen
+	rxresp
+	expect resp.status == 400
+} -run
+
+client c1 {
+	txreq -proto HTTP/1.0 -req "PUT" -nolen
+	rxresp
+	expect resp.status == 400
+} -run



More information about the varnish-commit mailing list