[master] e7414b5 Use the protocol specific info to determine precense of request body.

Poul-Henning Kamp phk at FreeBSD.org
Mon Sep 8 11:12:48 CEST 2014


commit e7414b584f9085f7001730a80e993f84902d445a
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Sep 8 09:12:04 2014 +0000

    Use the protocol specific info to determine precense of request body.

diff --git a/bin/varnishd/cache/cache_http1_fsm.c b/bin/varnishd/cache/cache_http1_fsm.c
index af7442a..b707e55 100644
--- a/bin/varnishd/cache/cache_http1_fsm.c
+++ b/bin/varnishd/cache/cache_http1_fsm.c
@@ -77,7 +77,6 @@
 #include "hash/hash_slinger.h"
 
 #include "vcl.h"
-#include "vct.h"
 #include "vtcp.h"
 #include "vtim.h"
 
@@ -259,43 +258,11 @@ http1_cleanup(struct sess *sp, struct worker *wrk, struct req *req)
 /*----------------------------------------------------------------------
  */
 
-static enum req_body_state_e
-http1_req_body_status(struct req *req)
-{
-	char *ptr, *endp;
-
-	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
-
-	if (http_GetHdr(req->http, H_Content_Length, &ptr)) {
-		AN(ptr);
-		if (*ptr == '\0')
-			return (REQ_BODY_FAIL);
-		req->req_bodybytes = strtoul(ptr, &endp, 10);
-		if (*endp != '\0' && !vct_islws(*endp))
-			return (REQ_BODY_FAIL);
-		if (req->req_bodybytes == 0)
-			return (REQ_BODY_NONE);
-		req->h1.bytes_yet = req->req_bodybytes - req->h1.bytes_done;
-		return (REQ_BODY_PRESENT);
-	}
-	if (http_HdrIs(req->http, H_Transfer_Encoding, "chunked")) {
-		req->h1.chunk_ctr = -1;
-		return (REQ_BODY_CHUNKED);
-	}
-	if (http_GetHdr(req->http, H_Transfer_Encoding, NULL))
-		return (REQ_BODY_FAIL);
-	return (REQ_BODY_NONE);
-}
-
-/*----------------------------------------------------------------------
- */
-
 static enum req_fsm_nxt
 http1_dissect(struct worker *wrk, struct req *req)
 {
 	const char *r_100 = "HTTP/1.1 100 Continue\r\n\r\n";
 	const char *r_400 = "HTTP/1.1 400 Bad Request\r\n\r\n";
-	const char *r_411 = "HTTP/1.1 411 Length Required\r\n\r\n";
 	const char *r_417 = "HTTP/1.1 417 Expectation Failed\r\n\r\n";
 	char *p;
 	ssize_t r;
@@ -335,18 +302,22 @@ http1_dissect(struct worker *wrk, struct req *req)
 		return (REQ_FSM_DONE);
 	}
 
-	if (req->req_body_status == REQ_BODY_INIT)
-		req->req_body_status = http1_req_body_status(req);
-	else
+	if (req->req_body_status != REQ_BODY_INIT) {
 		assert(req->req_body_status == REQ_BODY_NONE);	// ESI
-
-	if (req->req_body_status == REQ_BODY_FAIL) {
-		wrk->stats.client_req_411++;
-		r = write(req->sp->fd, r_411, strlen(r_411));
-		if (r > 0)
-			req->acct.resp_hdrbytes += r;
-		SES_Close(req->sp, SC_RX_JUNK);
-		return (REQ_FSM_DONE);
+	} else if (req->htc->body_status == BS_CHUNKED) {
+		req->h1.chunk_ctr = -1;
+		req->req_body_status = REQ_BODY_CHUNKED;
+	} else if (req->htc->body_status == BS_LENGTH) {
+		req->req_bodybytes = req->htc->content_length;
+		req->h1.bytes_yet = req->req_bodybytes - req->h1.bytes_done;
+		req->req_body_status = REQ_BODY_PRESENT;
+	} else if (req->htc->body_status == BS_NONE) {
+		req->req_body_status = REQ_BODY_NONE;
+	} else if (req->htc->body_status == BS_EOF) {
+		/* XXX: We don't support EOF bodies in requests */
+		req->req_body_status = REQ_BODY_NONE;
+	} else {
+		WRONG("Unknown req.body_length situation");
 	}
 
 	if (http_GetHdr(req->http, H_Expect, &p)) {
@@ -366,6 +337,7 @@ http1_dissect(struct worker *wrk, struct req *req)
 			SES_Close(req->sp, SC_REM_CLOSE);
 			return (REQ_FSM_DONE);
 		}
+		http_Unset(req->http, H_Expect);
 	}
 
 	wrk->stats.client_req++;
@@ -375,8 +347,6 @@ http1_dissect(struct worker *wrk, struct req *req)
 	req->ws_req = WS_Snapshot(req->ws);
 	req->doclose = req->http->doclose;
 
-	http_Unset(req->http, H_Expect);
-
 	assert(req->req_body_status != REQ_BODY_INIT);
 
 	HTTP_Copy(req->http0, req->http);	// For ESI & restart
diff --git a/bin/varnishd/cache/cache_http1_proto.c b/bin/varnishd/cache/cache_http1_proto.c
index 8b872fc..b502fbd 100644
--- a/bin/varnishd/cache/cache_http1_proto.c
+++ b/bin/varnishd/cache/cache_http1_proto.c
@@ -522,9 +522,8 @@ HTTP1_DissectRequest(struct http_conn *htc, struct http *hp)
 	http1_proto_ver(hp);
 
 	retval = http1_request_check_host_hdr(hp);
-	if (retval != 0) {
+	if (retval != 0)
 		return (retval);
-	}
 
 	/* RFC2616, section 5.2, point 1 */
 	if (!strncasecmp(hp->hd[HTTP_HDR_URL].b, "http://", 7)) {
@@ -540,6 +539,9 @@ HTTP1_DissectRequest(struct http_conn *htc, struct http *hp)
 
 	htc->body_status = http1_body_status(hp, htc);
 
+	if (htc->body_status == BS_ERROR)
+		return (400);
+
 	hp->doclose = http1_DoConnection(hp);
 
 	return (retval);
diff --git a/bin/varnishtest/tests/r01356.vtc b/bin/varnishtest/tests/r01356.vtc
index 341f2c8..543ee3e 100644
--- a/bin/varnishtest/tests/r01356.vtc
+++ b/bin/varnishtest/tests/r01356.vtc
@@ -10,13 +10,13 @@ varnish v1 -vcl+backend { } -start
 client c1 {
 	txreq -req POST -nolen -hdr "Transfer-Encoding: carrier-pigeon"
 	rxresp
-	expect resp.status == 411
+	expect resp.status == 400
 } -run
 
 client c1 {
 	txreq -req POST -nolen -hdr "Content-Length: carrier-pigeon"
 	rxresp
-	expect resp.status == 411
+	expect resp.status == 400
 } -run
 
 client c1 {



More information about the varnish-commit mailing list