[master] 12085db Pulling in the request body, is a protocol specific operation, so move the guts of it from cache_fetch.c to cache_http1_fsm.c.

Poul-Henning Kamp phk at varnish-cache.org
Tue Jan 15 15:14:39 CET 2013


commit 12085db88f5842dbe08d9517989415d11514ec24
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Jan 15 14:13:51 2013 +0000

    Pulling in the request body, is a protocol specific operation,
    so move the guts of it from cache_fetch.c to cache_http1_fsm.c.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index d4ddfa8..ba9e482 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -582,6 +582,14 @@ struct object {
 
 /*--------------------------------------------------------------------*/
 
+enum req_body_state_e {
+	REQ_BODY_INIT = 0,
+	REQ_BODY_CL,
+	// REQ_BODY_CHUNKED,
+	REQ_BODY_DONE,
+	REQ_BODY_NONE
+};
+
 struct req {
 	unsigned		magic;
 #define REQ_MAGIC		0x2751aaa1
@@ -612,8 +620,12 @@ struct req {
 	struct exp		exp;
 	unsigned		cur_method;
 	unsigned		handling;
-	unsigned char		reqbodydone;
+
 	unsigned char		wantbody;
+	enum req_body_state_e	req_body_status;
+	uint64_t		req_bodybytes;
+
+	uint64_t		resp_bodybytes;
 
 	uint16_t		err_code;
 	const char		*err_reason;
@@ -621,7 +633,6 @@ struct req {
 	struct director		*director;
 	struct VCL_conf		*vcl;
 
-	uint64_t		req_bodybytes;
 	char			*ws_req;	/* WS above request data */
 
 	double			t_req;
@@ -766,6 +777,7 @@ void VBO_DerefBusyObj(struct worker *wrk, struct busyobj **busyobj);
 void VBO_Free(struct busyobj **vbo);
 
 /* cache_http1_fsm.c [HTTP1] */
+ssize_t HTTP1_GetReqBody(struct req *, void *buf, ssize_t len);
 void HTTP1_Session(struct worker *, struct req *);
 
 /* cache_req_fsm.c [CNT] */
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 1d97c51..50a654c 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -380,43 +380,31 @@ fetch_eof(struct busyobj *bo, struct http_conn *htc)
 int
 FetchReqBody(struct req *req, int sendbody)
 {
-	unsigned long content_length;
 	char buf[8192];
-	char *ptr, *endp;
-	int rdcnt;
+	ssize_t l = 1234;
 
-	if (req->reqbodydone) {
+	if (req->req_body_status == REQ_BODY_DONE) {
 		AZ(sendbody);
 		return (0);
 	}
-
-	if (http_GetHdr(req->http, H_Content_Length, &ptr)) {
-		req->reqbodydone = 1;
-
-		content_length = strtoul(ptr, &endp, 10);
-		/* XXX should check result of conversion */
-		while (content_length) {
-			if (content_length > sizeof buf)
-				rdcnt = sizeof buf;
-			else
-				rdcnt = content_length;
-			rdcnt = HTC_Read(req->htc, buf, rdcnt);
-			if (rdcnt <= 0)
-				return (1);
-			content_length -= rdcnt;
-			if (sendbody) {
-				/* XXX: stats ? */
-				(void)WRW_Write(req->wrk, buf, rdcnt);
-				if (WRW_Flush(req->wrk))
-					return (2);
+	while (req->req_body_status != REQ_BODY_DONE &&
+	    req->req_body_status != REQ_BODY_NONE) {
+		l = HTTP1_GetReqBody(req, buf, sizeof buf);
+		if (l < 0) {
+			return (1);
+		} else if (l == 0) {
+			assert(req->req_body_status == REQ_BODY_DONE ||
+			    req->req_body_status == REQ_BODY_NONE);
+		} else if (sendbody) {
+			/* XXX: stats ? */
+			(void)WRW_Write(req->wrk, buf, l);
+			if (WRW_Flush(req->wrk)) {
+				/* XXX: Try to salvage client-conn ? */
+				req->req_body_status = REQ_BODY_DONE;
+				return (2);
 			}
 		}
 	}
-	if (http_GetHdr(req->http, H_Transfer_Encoding, NULL)) {
-		/* XXX: Handle chunked encoding. */
-		VSLb(req->vsl, SLT_Debug, "Transfer-Encoding in request");
-		return (1);
-	}
 	return (0);
 }
 
@@ -480,7 +468,7 @@ FetchHdr(struct req *req, int need_host_hdr, int sendbody)
 
 	/* Deal with any message-body the request might have */
 	i = FetchReqBody(req, sendbody);
-	if (sendbody && req->reqbodydone)
+	if (sendbody && req->req_body_status == REQ_BODY_DONE)
 		retry = -1;
 	if (WRW_FlushRelease(wrk) || i > 0) {
 		VSLb(req->vsl, SLT_FetchError,
diff --git a/bin/varnishd/cache/cache_http1_fsm.c b/bin/varnishd/cache/cache_http1_fsm.c
index 87771d5..c9b8d8f 100644
--- a/bin/varnishd/cache/cache_http1_fsm.c
+++ b/bin/varnishd/cache/cache_http1_fsm.c
@@ -76,6 +76,7 @@
 #include "cache.h"
 
 #include "vcl.h"
+#include "vct.h"
 #include "vtcp.h"
 #include "vtim.h"
 
@@ -200,7 +201,8 @@ http1_cleanup(struct sess *sp, struct worker *wrk, struct req *req)
 	req->t_req = NAN;
 	req->t_resp = NAN;
 
-	req->req_bodybytes = 0;
+	// req->req_bodybytes = 0;
+	req->resp_bodybytes = 0;
 
 	req->hash_always_miss = 0;
 	req->hash_ignore_busy = 0;
@@ -287,7 +289,7 @@ http1_dissect(struct worker *wrk, struct req *req)
 
 	http_Unset(req->http, H_Expect);
 	/* XXX: pull in req-body and make it available instead. */
-	req->reqbodydone = 0;
+	req->req_body_status = REQ_BODY_INIT;
 
 	HTTP_Copy(req->http0, req->http);	// For ESI & restart
 
@@ -372,3 +374,55 @@ HTTP1_Session(struct worker *wrk, struct req *req)
 		}
 	}
 }
+
+ssize_t
+HTTP1_GetReqBody(struct req *req, void *buf, ssize_t len)
+{
+	char *ptr, *endp;
+
+	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
+
+	if (req->req_body_status == REQ_BODY_INIT) {
+		if (http_GetHdr(req->http, H_Content_Length, &ptr)) {
+			AN(ptr);
+			if (*ptr == '\0') {
+				req->req_body_status = REQ_BODY_DONE;
+				return (-1);
+			}
+			req->req_bodybytes = strtoul(ptr, &endp, 10);
+			if (*endp != '\0' && !vct_islws(*endp)) {
+				req->req_body_status = REQ_BODY_DONE;
+				return (-1);
+			}
+			if (req->req_bodybytes == 0) {
+				req->req_body_status = REQ_BODY_DONE;
+				return (0);
+			}
+			req->req_body_status = REQ_BODY_CL;
+		} else if (http_GetHdr(req->http, H_Transfer_Encoding, NULL)) {
+			VSLb(req->vsl, SLT_Debug,
+			    "Transfer-Encoding in request");
+			req->req_body_status = REQ_BODY_DONE;
+			return (-1);
+		} else {
+			req->req_body_status = REQ_BODY_NONE;
+			return (0);
+		}
+	}
+	if (req->req_body_status == REQ_BODY_CL) {
+		if (req->req_bodybytes == 0) {
+			req->req_body_status = REQ_BODY_DONE;
+			return (0);
+		}
+		if (len > req->req_bodybytes)
+			len = req->req_bodybytes;
+		len = HTC_Read(req->htc, buf, len);
+		if (len <= 0) {
+			req->req_body_status = REQ_BODY_DONE;
+			return (-1);
+		}
+		req->req_bodybytes -= len;
+		return (len);
+	}
+	return (0);
+}
diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index 547755a..fe76777 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -1233,7 +1233,7 @@ CNT_Request(struct worker *wrk, struct req *req)
 		/* XXX: Workaround for pipe */
 		if (req->sp->fd >= 0) {
 			VSLb(req->vsl, SLT_Length, "%ju",
-			    (uintmax_t)req->req_bodybytes);
+			    (uintmax_t)req->resp_bodybytes);
 		}
 		VSLb(req->vsl, SLT_ReqEnd, "%.9f %.9f %.9f %.9f %.9f",
 		    req->t_req,
diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c
index 2873066..2257bab 100644
--- a/bin/varnishd/cache/cache_session.c
+++ b/bin/varnishd/cache/cache_session.c
@@ -78,7 +78,7 @@ SES_Charge(struct worker *wrk, struct req *req)
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 
 	a = &req->acct_req;
-	req->req_bodybytes += a->bodybytes;
+	req->resp_bodybytes += a->bodybytes;
 
 #define ACCT(foo)				\
 	wrk->stats.s_##foo += a->foo;		\



More information about the varnish-commit mailing list