[master] 972273f Set the protocol-specific body status in http_conn for both req and resp.
Poul-Henning Kamp
phk at FreeBSD.org
Mon Sep 8 10:18:38 CEST 2014
commit 972273fbe4d32e70e1b85e1a43e4c46d2f9188df
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon Sep 8 08:18:15 2014 +0000
Set the protocol-specific body status in http_conn for both req and resp.
diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index b422d9b..1bf2918 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -218,6 +218,7 @@ struct http_conn {
struct ws *ws;
txt rxbuf;
txt pipeline;
+ ssize_t content_length;
enum body_status body_status;
};
@@ -1000,8 +1001,8 @@ enum http1_status_e HTTP1_Reinit(struct http_conn *htc);
enum http1_status_e HTTP1_Rx(struct http_conn *htc);
ssize_t HTTP1_Read(struct http_conn *htc, void *d, size_t len);
enum http1_status_e HTTP1_Complete(struct http_conn *htc);
-uint16_t HTTP1_DissectRequest(struct req *);
-uint16_t HTTP1_DissectResponse(struct http *sp, const struct http_conn *htc);
+uint16_t HTTP1_DissectRequest(struct http_conn *htc, struct http *hp);
+uint16_t HTTP1_DissectResponse(struct http *sp, struct http_conn *htc);
unsigned HTTP1_Write(const struct worker *w, const struct http *hp, const int*);
#define HTTPH(a, b, c) extern char b[];
diff --git a/bin/varnishd/cache/cache_http1_fsm.c b/bin/varnishd/cache/cache_http1_fsm.c
index b0c5299..af7442a 100644
--- a/bin/varnishd/cache/cache_http1_fsm.c
+++ b/bin/varnishd/cache/cache_http1_fsm.c
@@ -322,10 +322,11 @@ http1_dissect(struct worker *wrk, struct req *req)
wrk->vcl = NULL;
HTTP_Setup(req->http, req->ws, req->vsl, SLT_ReqMethod);
- req->err_code = HTTP1_DissectRequest(req);
+ req->err_code = HTTP1_DissectRequest(req->htc, req->http);
/* If we could not even parse the request, just close */
if (req->err_code != 0) {
+ VSLbt(req->vsl, SLT_HttpGarbage, req->htc->rxbuf);
wrk->stats.client_req_400++;
r = write(req->sp->fd, r_400, strlen(r_400));
if (r > 0)
diff --git a/bin/varnishd/cache/cache_http1_proto.c b/bin/varnishd/cache/cache_http1_proto.c
index 03563fd..8b872fc 100644
--- a/bin/varnishd/cache/cache_http1_proto.c
+++ b/bin/varnishd/cache/cache_http1_proto.c
@@ -373,6 +373,61 @@ http1_splitline(struct http *hp, const struct http_conn *htc, const int *hf)
/*--------------------------------------------------------------------*/
+static enum body_status
+http1_body_status(const struct http *hp, struct http_conn *htc)
+{
+ ssize_t cl;
+ char *b;
+
+ CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
+ CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
+
+ htc->content_length = -1;
+
+ if (http_HdrIs(hp, H_Transfer_Encoding, "chunked"))
+ return (BS_CHUNKED);
+
+ if (http_GetHdr(hp, H_Transfer_Encoding, &b))
+ return (BS_ERROR);
+
+ cl = http_GetContentLength(hp);
+ if (cl == -2)
+ return (BS_ERROR);
+ if (cl >= 0) {
+ htc->content_length = cl;
+ return (cl == 0 ? BS_NONE : BS_LENGTH);
+ }
+
+ if (http_HdrIs(hp, H_Connection, "keep-alive")) {
+ /*
+ * Keep alive with neither TE=Chunked or C-Len is impossible.
+ * We assume a zero length body.
+ */
+ return (BS_NONE);
+ }
+
+ if (http_HdrIs(hp, H_Connection, "close")) {
+ /*
+ * In this case, it is safe to just read what comes.
+ */
+ return (BS_EOF);
+ }
+
+ if (hp->protover < 11) {
+ /*
+ * With no Connection header, assume EOF.
+ */
+ return (BS_EOF);
+ }
+
+ /*
+ * Fall back to EOF transfer.
+ */
+ return (BS_EOF);
+}
+
+/*--------------------------------------------------------------------*/
+
static uint16_t
http1_request_check_host_hdr(const struct http *hp)
{
@@ -453,24 +508,17 @@ http1_DoConnection(struct http *hp)
/*--------------------------------------------------------------------*/
uint16_t
-HTTP1_DissectRequest(struct req *req)
+HTTP1_DissectRequest(struct http_conn *htc, struct http *hp)
{
- struct http_conn *htc;
- struct http *hp;
uint16_t retval;
char *b, *e;
- CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
- htc = req->htc;
CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
- hp = req->http;
CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
retval = http1_splitline(hp, htc, HTTP1_Req);
- if (retval != 0) {
- VSLbt(req->vsl, SLT_HttpGarbage, htc->rxbuf);
+ if (retval != 0)
return (retval);
- }
http1_proto_ver(hp);
retval = http1_request_check_host_hdr(hp);
@@ -490,6 +538,8 @@ HTTP1_DissectRequest(struct req *req)
}
}
+ htc->body_status = http1_body_status(hp, htc);
+
hp->doclose = http1_DoConnection(hp);
return (retval);
@@ -498,7 +548,7 @@ HTTP1_DissectRequest(struct req *req)
/*--------------------------------------------------------------------*/
uint16_t
-HTTP1_DissectResponse(struct http *hp, const struct http_conn *htc)
+HTTP1_DissectResponse(struct http *hp, struct http_conn *htc)
{
uint16_t retval = 0;
char *p;
@@ -544,6 +594,8 @@ HTTP1_DissectResponse(struct http *hp, const struct http_conn *htc)
!Tlen(hp->hd[HTTP_HDR_REASON]))
http_SetH(hp, HTTP_HDR_REASON, http_Status2Reason(hp->status));
+ htc->body_status = http1_body_status(hp, htc);
+
hp->doclose = http1_DoConnection(hp);
return (retval);
More information about the varnish-commit
mailing list