[4.0] e99e8fb Always set the reason headerfield when the status field is set, to keep them in sync. If you want a custom reason field, set status first, then reason.
Poul-Henning Kamp
phk at FreeBSD.org
Tue Jun 24 11:31:55 CEST 2014
commit e99e8fbaa85aafa36abaa0aa9f508e98fd93dfc8
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Tue Jun 10 08:31:16 2014 +0000
Always set the reason headerfield when the status field is set, to
keep them in sync. If you want a custom reason field, set status
first, then reason.
With this in place, HTTP1_Write() doesn't need to worry about them
being OK, and we can polish that code a fair bit.
Turn a couple of boolean arguments into more readable magics.
diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index a79b224..38e597b 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -857,6 +857,8 @@ void HTTP1_Session(struct worker *, struct req *);
int HTTP1_DiscardReqBody(struct req *req);
int HTTP1_CacheReqBody(struct req *req, ssize_t maxsize);
int HTTP1_IterateReqBody(struct req *req, req_body_iter_f *func, void *priv);
+extern const int HTTP1_Req[3];
+extern const int HTTP1_Resp[3];
/* cache_http1_deliver.c */
unsigned V1D_FlushReleaseAcct(struct req *req);
@@ -1030,7 +1032,7 @@ ssize_t HTTP1_Read(struct http_conn *htc, void *d, size_t len);
enum htc_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);
-unsigned HTTP1_Write(const struct worker *w, const struct http *hp, int resp);
+unsigned HTTP1_Write(const struct worker *w, const struct http *hp, const int*);
#define HTTPH(a, b, c) extern char b[];
#include "tbl/http_headers.h"
diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c
index 8313007..159751b 100644
--- a/bin/varnishd/cache/cache_http.c
+++ b/bin/varnishd/cache/cache_http.c
@@ -552,7 +552,9 @@ http_GetStatus(const struct http *hp)
return (hp->status);
}
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * Setting the status will also set the Reason appropriately
+ */
void
http_SetStatus(struct http *to, uint16_t status)
@@ -569,6 +571,7 @@ http_SetStatus(struct http *to, uint16_t status)
assert(status >= 100);
bprintf(buf, "%03d", status);
http_PutField(to, HTTP_HDR_STATUS, buf);
+ http_SetH(to, HTTP_HDR_REASON, http_Status2Reason(status));
}
/*--------------------------------------------------------------------*/
diff --git a/bin/varnishd/cache/cache_http1_deliver.c b/bin/varnishd/cache/cache_http1_deliver.c
index 06b4a32..8778303 100644
--- a/bin/varnishd/cache/cache_http1_deliver.c
+++ b/bin/varnishd/cache/cache_http1_deliver.c
@@ -322,7 +322,8 @@ V1D_Deliver(struct req *req)
* Send HTTP protocol header, unless interior ESI object
*/
if (!(req->res_mode & RES_ESI_CHILD))
- req->resp_hdrbytes += HTTP1_Write(req->wrk, req->resp, 1);
+ req->resp_hdrbytes +=
+ HTTP1_Write(req->wrk, req->resp, HTTP1_Resp);
if (req->res_mode & RES_CHUNKED)
WRW_Chunked(req->wrk);
@@ -429,7 +430,8 @@ V1D_Deliver_Synth(struct req *req)
* Send HTTP protocol header, unless interior ESI object
*/
if (!(req->res_mode & RES_ESI_CHILD))
- req->resp_hdrbytes += HTTP1_Write(req->wrk, req->resp, 1);
+ req->resp_hdrbytes +=
+ HTTP1_Write(req->wrk, req->resp, HTTP1_Resp);
if (req->res_mode & RES_CHUNKED)
WRW_Chunked(req->wrk);
diff --git a/bin/varnishd/cache/cache_http1_fetch.c b/bin/varnishd/cache/cache_http1_fetch.c
index 11c712e..1c3ef53 100644
--- a/bin/varnishd/cache/cache_http1_fetch.c
+++ b/bin/varnishd/cache/cache_http1_fetch.c
@@ -327,7 +327,7 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo, struct req *req)
(void)VTCP_blocking(vc->fd); /* XXX: we should timeout instead */
WRW_Reserve(wrk, &vc->fd, bo->vsl, bo->t_prev);
- hdrbytes = HTTP1_Write(wrk, hp, 0);
+ hdrbytes = HTTP1_Write(wrk, hp, HTTP1_Req);
/* Deal with any message-body the request might (still) have */
i = 0;
diff --git a/bin/varnishd/cache/cache_http1_proto.c b/bin/varnishd/cache/cache_http1_proto.c
index 7316f0b..7f7852c 100644
--- a/bin/varnishd/cache/cache_http1_proto.c
+++ b/bin/varnishd/cache/cache_http1_proto.c
@@ -49,6 +49,14 @@
#include "vct.h"
+const int HTTP1_Req[3] = {
+ HTTP_HDR_METHOD, HTTP_HDR_URL, HTTP_HDR_PROTO
+};
+
+const int HTTP1_Resp[3] = {
+ HTTP_HDR_PROTO, HTTP_HDR_STATUS, HTTP_HDR_REASON
+};
+
/*--------------------------------------------------------------------*/
void
@@ -294,55 +302,46 @@ htc_dissect_hdrs(struct http *hp, char *p, const struct http_conn *htc)
*/
static uint16_t
-htc_splitline(struct http *hp, const struct http_conn *htc, int req)
+htc_splitline(struct http *hp, const struct http_conn *htc, const int *hf)
{
char *p;
- int h1, h2, h3;
+ assert(hf == HTTP1_Req || hf == HTTP1_Resp);
CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
Tcheck(htc->rxbuf);
- if (req) {
- h1 = HTTP_HDR_METHOD;
- h2 = HTTP_HDR_URL;
- h3 = HTTP_HDR_PROTO;
- } else {
- h1 = HTTP_HDR_PROTO;
- h2 = HTTP_HDR_STATUS;
- h3 = HTTP_HDR_REASON;
- }
- AZ(hp->hd[h1].b);
- AZ(hp->hd[h2].b);
- AZ(hp->hd[h3].b);
+ AZ(hp->hd[hf[0]].b);
+ AZ(hp->hd[hf[1]].b);
+ AZ(hp->hd[hf[2]].b);
/* Skip leading LWS */
for (p = htc->rxbuf.b ; vct_islws(*p); p++)
continue;
- hp->hd[h1].b = p;
+ hp->hd[hf[0]].b = p;
/* First field cannot contain SP or CTL */
for (; !vct_issp(*p); p++) {
if (vct_isctl(*p))
return (400);
}
- hp->hd[h1].e = p;
- assert(Tlen(hp->hd[h1]));
+ hp->hd[hf[0]].e = p;
+ assert(Tlen(hp->hd[hf[0]]));
/* Skip SP */
for (; vct_issp(*p); p++) {
if (vct_isctl(*p))
return (400);
}
- hp->hd[h2].b = p;
+ hp->hd[hf[1]].b = p;
/* Second field cannot contain LWS or CTL */
for (; !vct_islws(*p); p++) {
if (vct_isctl(*p))
return (400);
}
- hp->hd[h2].e = p;
- if (!Tlen(hp->hd[h2]))
+ hp->hd[hf[1]].e = p;
+ if (!Tlen(hp->hd[hf[1]]))
return (400);
/* Skip SP */
@@ -350,23 +349,23 @@ htc_splitline(struct http *hp, const struct http_conn *htc, int req)
if (vct_isctl(*p))
return (400);
}
- hp->hd[h3].b = p;
+ hp->hd[hf[2]].b = p;
/* Third field is optional and cannot contain CTL except TAB */
for (; !vct_iscrlf(p); p++) {
if (vct_isctl(*p) && !vct_issp(*p)) {
- hp->hd[h3].b = NULL;
+ hp->hd[hf[2]].b = NULL;
return (400);
}
}
- hp->hd[h3].e = p;
+ hp->hd[hf[2]].e = p;
/* Skip CRLF */
p += vct_skipcrlf(p);
- *hp->hd[h1].e = '\0';
- *hp->hd[h2].e = '\0';
- *hp->hd[h3].e = '\0';
+ *hp->hd[hf[0]].e = '\0';
+ *hp->hd[hf[1]].e = '\0';
+ *hp->hd[hf[2]].e = '\0';
return (htc_dissect_hdrs(hp, p, htc));
}
@@ -426,7 +425,7 @@ HTTP1_DissectRequest(struct req *req)
hp = req->http;
CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
- retval = htc_splitline(hp, htc, 1);
+ retval = htc_splitline(hp, htc, HTTP1_Req);
if (retval != 0) {
VSLbt(req->vsl, SLT_HttpGarbage, htc->rxbuf);
return (retval);
@@ -465,7 +464,7 @@ HTTP1_DissectResponse(struct http *hp, const struct http_conn *htc)
CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
- if (htc_splitline(hp, htc, 0))
+ if (htc_splitline(hp, htc, HTTP1_Resp))
retval = 503;
if (retval == 0) {
@@ -495,6 +494,7 @@ HTTP1_DissectResponse(struct http *hp, const struct http_conn *htc)
assert(retval == 503);
hp->status = retval;
http_SetH(hp, HTTP_HDR_STATUS, "503");
+ http_SetH(hp, HTTP_HDR_REASON, http_Status2Reason(retval));
}
if (hp->hd[HTTP_HDR_REASON].b == NULL ||
@@ -507,36 +507,20 @@ HTTP1_DissectResponse(struct http *hp, const struct http_conn *htc)
/*--------------------------------------------------------------------*/
unsigned
-HTTP1_Write(const struct worker *w, const struct http *hp, int resp)
+HTTP1_Write(const struct worker *w, const struct http *hp, const int *hf)
{
unsigned u, l;
- if (resp) {
- l = WRW_WriteH(w, &hp->hd[HTTP_HDR_PROTO], " ");
-
- hp->hd[HTTP_HDR_STATUS].b = WS_Alloc(hp->ws, 4);
- AN(hp->hd[HTTP_HDR_STATUS].b);
+ assert(hf == HTTP1_Req || hf == HTTP1_Resp);
+ AN(hp->hd[hf[0]].b);
+ AN(hp->hd[hf[1]].b);
+ AN(hp->hd[hf[2]].b);
+ l = WRW_WriteH(w, &hp->hd[hf[0]], " ");
+ l += WRW_WriteH(w, &hp->hd[hf[1]], " ");
+ l += WRW_WriteH(w, &hp->hd[hf[2]], "\r\n");
- assert(hp->status >= 100 && hp->status <= 999);
- sprintf(hp->hd[HTTP_HDR_STATUS].b, "%3d", hp->status);
- hp->hd[HTTP_HDR_STATUS].e = hp->hd[HTTP_HDR_STATUS].b + 3;
-
- l += WRW_WriteH(w, &hp->hd[HTTP_HDR_STATUS], " ");
-
- l += WRW_WriteH(w, &hp->hd[HTTP_HDR_REASON], "\r\n");
- } else {
- AN(hp->hd[HTTP_HDR_URL].b);
- l = WRW_WriteH(w, &hp->hd[HTTP_HDR_METHOD], " ");
- l += WRW_WriteH(w, &hp->hd[HTTP_HDR_URL], " ");
- l += WRW_WriteH(w, &hp->hd[HTTP_HDR_PROTO], "\r\n");
- }
- for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) {
- if (hp->hd[u].b == NULL)
- continue;
- AN(hp->hd[u].b);
- AN(hp->hd[u].e);
+ for (u = HTTP_HDR_FIRST; u < hp->nhd; u++)
l += WRW_WriteH(w, &hp->hd[u], "\r\n");
- }
l += WRW_Write(w, "\r\n", -1);
return (l);
}
diff --git a/bin/varnishd/cache/cache_pipe.c b/bin/varnishd/cache/cache_pipe.c
index bb666a1..27ea964 100644
--- a/bin/varnishd/cache/cache_pipe.c
+++ b/bin/varnishd/cache/cache_pipe.c
@@ -124,7 +124,7 @@ PipeRequest(struct req *req, struct busyobj *bo)
(void)VTCP_blocking(vc->fd);
WRW_Reserve(wrk, &vc->fd, bo->vsl, req->t_req);
- hdrbytes = HTTP1_Write(wrk, bo->bereq, 0);
+ hdrbytes = HTTP1_Write(wrk, bo->bereq, HTTP1_Req);
if (req->htc->pipeline.b != NULL)
(void)WRW_Write(wrk, req->htc->pipeline.b,
More information about the varnish-commit
mailing list