[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