From phk at varnish-cache.org Wed Jan 2 21:45:44 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 02 Jan 2013 22:45:44 +0100 Subject: [master] 0d08727 Spelling fixes. Message-ID: commit 0d0872766deb9a234cc589e74eee269d2114d6ee Author: Poul-Henning Kamp Date: Wed Jan 2 21:45:17 2013 +0000 Spelling fixes. Submitted by: Federico G. Schwindt Thanks! diff --git a/doc/sphinx/reference/varnish-cli.rst b/doc/sphinx/reference/varnish-cli.rst index 88b05fe..c34ae7b 100644 --- a/doc/sphinx/reference/varnish-cli.rst +++ b/doc/sphinx/reference/varnish-cli.rst @@ -81,7 +81,7 @@ backend.list backend.set_health matcher state Sets the health state on a specific backend. This is useful if - you want to take a certain backend out of sirculations. + you want to take a certain backend out of circulation. ban *field operator argument* [&& field operator argument [...]] Immediately invalidate all documents matching the ban diff --git a/doc/sphinx/reference/vcl.rst b/doc/sphinx/reference/vcl.rst index 98c1c47..325470c 100644 --- a/doc/sphinx/reference/vcl.rst +++ b/doc/sphinx/reference/vcl.rst @@ -483,7 +483,7 @@ vcl_fetch hit_for_pass Pass in fetch. Passes the object without caching it. This will - create a socalled hit_for_pass object which has the side effect + create a so-called hit_for_pass object which has the side effect that the decision not to cache will be cached. This is to allow would-be uncachable requests to be passed to the backend at the same time. The same logic is not necessary in vcl_recv because @@ -545,7 +545,7 @@ default code. Multiple subroutines ~~~~~~~~~~~~~~~~~~~~ -If multiple subroutines with the the name of one of the builtin +If multiple subroutines with the name of one of the builtin ones are defined, they are concatenated in the order in which they appear in the source. The default versions distributed with Varnish will be implicitly diff --git a/doc/sphinx/reference/vmod.rst b/doc/sphinx/reference/vmod.rst index a76dee1..b9eb22a 100644 --- a/doc/sphinx/reference/vmod.rst +++ b/doc/sphinx/reference/vmod.rst @@ -34,7 +34,7 @@ The vmod.vcc file The interface between your VMOD and the VCL compiler ("VCC") and the VCL runtime ("VRT") is defined in the vmod.vcc file which a python -script called "vmod.py" turns into thaumathurgically challenged C +script called "vmod.py" turns into thaumaturgically challenged C data structures that does all the hard work. The std VMODs vmod.vcc file looks somewhat like this:: From phk at varnish-cache.org Mon Jan 7 12:59:26 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 07 Jan 2013 13:59:26 +0100 Subject: [master] 0e9627d Adopt Lasses proposal to rename [be]req.request [be]req.method. Message-ID: commit 0e9627ddb36292efa3ece4ec977b9d68c9d85cec Author: Poul-Henning Kamp Date: Mon Jan 7 12:58:22 2013 +0000 Adopt Lasses proposal to rename [be]req.request [be]req.method. Keep .request as an alias for at least one release cycle. I have gone a level deeper than Lasses patch, and also carried this rename through the C-code, docs and VTC files. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index f97f8a7..d4ddfa8 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -181,7 +181,7 @@ struct ws { */ enum httpwhence { - HTTP_Req = 1, + HTTP_Method = 1, HTTP_Resp, HTTP_Bereq, HTTP_Beresp, diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index be87d2b..8586090 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -68,7 +68,7 @@ ved_include(struct req *preq, const char *src, const char *host) req->http0->conds = 0; - HTTP_Setup(req->http, req->ws, req->vsl, HTTP_Req); + HTTP_Setup(req->http, req->ws, req->vsl, HTTP_Method); http_SetH(req->http0, HTTP_HDR_URL, src); if (host != NULL && *host != '\0') { diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index 73fb7fc..91ab200 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -42,11 +42,11 @@ #undef HTTPH static const enum VSL_tag_e foo[] = { - [HTTP_Req] = SLT_ReqRequest, - [HTTP_Resp] = SLT_RespRequest, - [HTTP_Bereq] = SLT_BereqRequest, - [HTTP_Beresp] = SLT_BerespRequest, - [HTTP_Obj] = SLT_ObjRequest, + [HTTP_Method] = SLT_ReqMethod, + [HTTP_Resp] = SLT_RespMethod, + [HTTP_Bereq] = SLT_BereqMethod, + [HTTP_Beresp] = SLT_BerespMethod, + [HTTP_Obj] = SLT_ObjMethod, }; static enum VSL_tag_e @@ -56,8 +56,8 @@ http2shmlog(const struct http *hp, int t) CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); if (t > HTTP_HDR_FIRST) t = HTTP_HDR_FIRST; - assert(hp->logtag >= HTTP_Req && hp->logtag <= HTTP_Obj); /*lint !e685*/ - assert(t >= HTTP_HDR_REQ && t <= HTTP_HDR_FIRST); + assert(hp->logtag >= HTTP_Method && hp->logtag <= HTTP_Obj); /*lint !e685*/ + assert(t >= HTTP_HDR_METHOD && t <= HTTP_HDR_FIRST); return ((enum VSL_tag_e)(foo[hp->logtag] + t)); } @@ -473,8 +473,8 @@ const char * http_GetReq(const struct http *hp) { - Tcheck(hp->hd[HTTP_HDR_REQ]); - return (hp->hd[HTTP_HDR_REQ].b); + Tcheck(hp->hd[HTTP_HDR_METHOD]); + return (hp->hd[HTTP_HDR_METHOD].b); } /*-------------------------------------------------------------------- @@ -664,7 +664,7 @@ http_DissectRequest(struct req *req) CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); retval = http_splitline(hp, htc, - HTTP_HDR_REQ, HTTP_HDR_URL, HTTP_HDR_PROTO); + HTTP_HDR_METHOD, HTTP_HDR_URL, HTTP_HDR_PROTO); if (retval != 0) { VSLbt(req->vsl, SLT_HttpGarbage, htc->rxbuf); return (retval); @@ -757,7 +757,7 @@ void http_ForceGet(const struct http *to) { if (strcmp(http_GetReq(to), "GET")) - http_SetH(to, HTTP_HDR_REQ, "GET"); + http_SetH(to, HTTP_HDR_METHOD, "GET"); } void @@ -845,7 +845,7 @@ http_FilterReq(const struct req *req, unsigned how) hp = req->busyobj->bereq; CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); - http_linkh(hp, req->http, HTTP_HDR_REQ); + http_linkh(hp, req->http, HTTP_HDR_METHOD); http_linkh(hp, req->http, HTTP_HDR_URL); if (how == HTTPH_R_FETCH) http_SetH(hp, HTTP_HDR_PROTO, "HTTP/1.1"); @@ -1068,8 +1068,8 @@ http_Write(const struct worker *w, const struct http *hp, int resp) http_VSLH(hp, HTTP_HDR_RESPONSE); } else { AN(hp->hd[HTTP_HDR_URL].b); - l = WRW_WriteH(w, &hp->hd[HTTP_HDR_REQ], " "); - http_VSLH(hp, HTTP_HDR_REQ); + l = WRW_WriteH(w, &hp->hd[HTTP_HDR_METHOD], " "); + http_VSLH(hp, HTTP_HDR_METHOD); l += WRW_WriteH(w, &hp->hd[HTTP_HDR_URL], " "); http_VSLH(hp, HTTP_HDR_URL); l += WRW_WriteH(w, &hp->hd[HTTP_HDR_PROTO], "\r\n"); diff --git a/bin/varnishd/cache/cache_http1_fsm.c b/bin/varnishd/cache/cache_http1_fsm.c index ab870ad..e6b12ee 100644 --- a/bin/varnishd/cache/cache_http1_fsm.c +++ b/bin/varnishd/cache/cache_http1_fsm.c @@ -257,7 +257,7 @@ http1_dissect(struct worker *wrk, struct req *req) req->vcl = wrk->vcl; wrk->vcl = NULL; - HTTP_Setup(req->http, req->ws, req->vsl, HTTP_Req); + HTTP_Setup(req->http, req->ws, req->vsl, HTTP_Method); req->err_code = http_DissectRequest(req); /* If we could not even parse the request, just close */ diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index e50a9a5..547755a 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -1132,7 +1132,7 @@ cnt_recv(const struct worker *wrk, struct req *req) SHA256_Final(req->digest, req->sha256ctx); req->sha256ctx = NULL; - if (!strcmp(req->http->hd[HTTP_HDR_REQ].b, "HEAD")) + if (!strcmp(req->http->hd[HTTP_HDR_METHOD].b, "HEAD")) req->wantbody = 0; else req->wantbody = 1; diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index 76c17d6..f724054 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -81,10 +81,12 @@ VRT_r_##obj##_##hdr(const struct req *req) \ return (http->hd[fld].b); \ } -VRT_DO_HDR(req, request, req->http, HTTP_HDR_REQ) +VRT_DO_HDR(req, method, req->http, HTTP_HDR_METHOD) +VRT_DO_HDR(req, request, req->http, HTTP_HDR_METHOD) VRT_DO_HDR(req, url, req->http, HTTP_HDR_URL) VRT_DO_HDR(req, proto, req->http, HTTP_HDR_PROTO) -VRT_DO_HDR(bereq, request, req->busyobj->bereq, HTTP_HDR_REQ) +VRT_DO_HDR(bereq, method, req->busyobj->bereq, HTTP_HDR_METHOD) +VRT_DO_HDR(bereq, request, req->busyobj->bereq, HTTP_HDR_METHOD) VRT_DO_HDR(bereq, url, req->busyobj->bereq, HTTP_HDR_URL) VRT_DO_HDR(bereq, proto, req->busyobj->bereq, HTTP_HDR_PROTO) VRT_DO_HDR(obj, proto, req->obj->http, HTTP_HDR_PROTO) diff --git a/bin/varnishd/default.vcl b/bin/varnishd/default.vcl index d0d4c2e..bb78074 100644 --- a/bin/varnishd/default.vcl +++ b/bin/varnishd/default.vcl @@ -48,17 +48,17 @@ sub vcl_recv { set req.http.X-Forwarded-For = client.ip; } } - if (req.request != "GET" && - req.request != "HEAD" && - req.request != "PUT" && - req.request != "POST" && - req.request != "TRACE" && - req.request != "OPTIONS" && - req.request != "DELETE") { + if (req.method != "GET" && + req.method != "HEAD" && + req.method != "PUT" && + req.method != "POST" && + req.method != "TRACE" && + req.method != "OPTIONS" && + req.method != "DELETE") { /* Non-RFC2616 or CONNECT which is weird. */ return (pipe); } - if (req.request != "GET" && req.request != "HEAD") { + if (req.method != "GET" && req.method != "HEAD") { /* We only deal with GET and HEAD by default */ return (pass); } diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index 0dbebfe..f885985 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -301,7 +301,7 @@ collect_backend(struct logline *lp, enum VSL_tag_e tag, unsigned spec, trimfield(&lp->df_h, ptr, end); break; - case SLT_BereqRequest: + case SLT_BereqMethod: if (!lp->active) break; if (lp->df_m != NULL) { @@ -420,7 +420,7 @@ collect_client(struct logline *lp, enum VSL_tag_e tag, unsigned spec, trimfield(&lp->df_h, ptr, end); break; - case SLT_ReqRequest: + case SLT_ReqMethod: if (!lp->active) break; if (lp->df_m != NULL) { diff --git a/bin/varnishreplay/varnishreplay.c b/bin/varnishreplay/varnishreplay.c index aec3f5f..d8d19d5 100644 --- a/bin/varnishreplay/varnishreplay.c +++ b/bin/varnishreplay/varnishreplay.c @@ -515,7 +515,7 @@ replay_thread(void *arg) thread_log(2, 0, "%s(%s)", VSL_tags[tag], msg->ptr); switch (tag) { - case SLT_ReqRequest: + case SLT_ReqMethod: if (thr->method != NULL) thr->bogus = 1; else diff --git a/bin/varnishtest/tests/a00001.vtc b/bin/varnishtest/tests/a00001.vtc index 06b8ae5..0fc6de9 100644 --- a/bin/varnishtest/tests/a00001.vtc +++ b/bin/varnishtest/tests/a00001.vtc @@ -2,7 +2,7 @@ varnishtest "basic default HTTP transactions with expect" server s1 { rxreq - expect req.request == GET + expect req.method == GET expect req.proto == HTTP/1.1 expect req.url == "/" txresp diff --git a/bin/varnishtest/tests/a00002.vtc b/bin/varnishtest/tests/a00002.vtc index e0b4759..4d0f3df 100644 --- a/bin/varnishtest/tests/a00002.vtc +++ b/bin/varnishtest/tests/a00002.vtc @@ -2,7 +2,7 @@ varnishtest "basic default HTTP transactions with expect and options" server s1 { rxreq - expect req.request == PUT + expect req.method == PUT expect req.proto == HTTP/1.0 expect req.url == "/foo" txresp -proto HTTP/1.2 -status 201 -msg Foo diff --git a/bin/varnishtest/tests/a00003.vtc b/bin/varnishtest/tests/a00003.vtc index 7462fb1..4982730 100644 --- a/bin/varnishtest/tests/a00003.vtc +++ b/bin/varnishtest/tests/a00003.vtc @@ -2,7 +2,7 @@ varnishtest "dual independent HTTP transactions" server s1 { rxreq - expect req.request == PUT + expect req.method == PUT expect req.proto == HTTP/1.0 expect req.url == "/foo" txresp -proto HTTP/1.2 -status 201 -msg Foo @@ -10,7 +10,7 @@ server s1 { server s2 { rxreq - expect req.request == GET + expect req.method == GET expect req.proto == HTTP/1.1 expect req.url == "/" txresp diff --git a/bin/varnishtest/tests/a00004.vtc b/bin/varnishtest/tests/a00004.vtc index 01cd868..7fbe476 100644 --- a/bin/varnishtest/tests/a00004.vtc +++ b/bin/varnishtest/tests/a00004.vtc @@ -2,7 +2,7 @@ varnishtest "dual shared server HTTP transactions" server s1 -repeat 2 { rxreq - expect req.request == PUT + expect req.method == PUT expect req.proto == HTTP/1.0 expect req.url == "/foo" txresp -proto HTTP/1.2 -status 201 -msg Foo diff --git a/bin/varnishtest/tests/a00005.vtc b/bin/varnishtest/tests/a00005.vtc index e44a7e2..38ae1cf 100644 --- a/bin/varnishtest/tests/a00005.vtc +++ b/bin/varnishtest/tests/a00005.vtc @@ -2,7 +2,7 @@ varnishtest "dual shared client HTTP transactions" server s1 { rxreq - expect req.request == PUT + expect req.method == PUT expect req.proto == HTTP/1.0 expect req.url == "/foo" txresp -proto HTTP/1.2 -status 201 -msg Foo @@ -10,7 +10,7 @@ server s1 { server s2 { rxreq - expect req.request == GET + expect req.method == GET expect req.proto == HTTP/1.1 expect req.url == "/" txresp diff --git a/bin/varnishtest/tests/a00006.vtc b/bin/varnishtest/tests/a00006.vtc index 5db297b..bcd272f 100644 --- a/bin/varnishtest/tests/a00006.vtc +++ b/bin/varnishtest/tests/a00006.vtc @@ -2,7 +2,7 @@ varnishtest "bidirectional message bodies" server s1 { rxreq - expect req.request == PUT + expect req.method == PUT expect req.proto == HTTP/1.0 expect req.url == "/foo" txresp -proto HTTP/1.2 -status 201 -msg Foo \ diff --git a/bin/varnishtest/tests/b00035.vtc b/bin/varnishtest/tests/b00035.vtc new file mode 100644 index 0000000..9d49f4f --- /dev/null +++ b/bin/varnishtest/tests/b00035.vtc @@ -0,0 +1,26 @@ +varnishtest "{be}req.request compat check" + +server s1 { + rxreq + expect req.method == "GETABCD" + txresp +} -start + +varnish v1 -vcl+backend { + + sub vcl_recv { + set req.method = req.request + "A"; + set req.request = req.method + "B"; + return (pass); + } + + sub vcl_pass { + set bereq.method = bereq.request + "C"; + set bereq.request = bereq.method + "D"; + } +} -start + +client c1 { + txreq + rxresp +} -run diff --git a/bin/varnishtest/tests/c00022.vtc b/bin/varnishtest/tests/c00022.vtc index 33e20cc..64511fa 100644 --- a/bin/varnishtest/tests/c00022.vtc +++ b/bin/varnishtest/tests/c00022.vtc @@ -20,11 +20,11 @@ server s1 { varnish v1 -vcl+backend { sub vcl_recv { - if (req.request == "PURGE") { + if (req.method == "PURGE") { ban ("req.url == " + req.url); error 410; } - if (req.request == "PURGESTR") { + if (req.method == "PURGESTR") { ban ("" + req.http.ban); error 410; } diff --git a/bin/varnishtest/tests/c00033.vtc b/bin/varnishtest/tests/c00033.vtc index d4289e3..28b192d 100644 --- a/bin/varnishtest/tests/c00033.vtc +++ b/bin/varnishtest/tests/c00033.vtc @@ -18,19 +18,19 @@ server s1 { varnish v1 -vcl+backend { sub vcl_recv { - if (req.request == "PURGE") { + if (req.method == "PURGE") { return (lookup); } } sub vcl_hit { - if (req.request == "PURGE") { + if (req.method == "PURGE") { C{ VRT_purge(req, 0, 0); }C error 456 "got it"; } } sub vcl_miss { - if (req.request == "PURGE") { + if (req.method == "PURGE") { C{ VRT_purge(req, 0, 0); }C error 456 "got it"; } diff --git a/bin/varnishtest/tests/e00011.vtc b/bin/varnishtest/tests/e00011.vtc index 8f03bd4..062b13a 100644 --- a/bin/varnishtest/tests/e00011.vtc +++ b/bin/varnishtest/tests/e00011.vtc @@ -2,14 +2,14 @@ varnishtest "Make sure that PASS'ed ESI requests use GET for includes" server s1 { rxreq - expect req.request == POST + expect req.method == POST expect req.url == /foobar txresp -body { FOO } rxreq - expect req.request == GET + expect req.method == GET txresp -hdr "Set-Cookie: Foo=bar" -body { BAR } diff --git a/bin/varnishtest/tests/r00102.vtc b/bin/varnishtest/tests/r00102.vtc index 0fa597b..8c0b784 100644 --- a/bin/varnishtest/tests/r00102.vtc +++ b/bin/varnishtest/tests/r00102.vtc @@ -9,8 +9,8 @@ server s1 { varnish v1 -vcl+backend { sub vcl_recv { - if (req.request == "POST") { - set req.request = "GET"; + if (req.method == "POST") { + set req.method = "GET"; } } } -start diff --git a/bin/varnishtest/tests/r00444.vtc b/bin/varnishtest/tests/r00444.vtc index f71f905..ad8e12a 100644 --- a/bin/varnishtest/tests/r00444.vtc +++ b/bin/varnishtest/tests/r00444.vtc @@ -2,38 +2,38 @@ varnishtest "purging on POST" server s1 { rxreq - expect req.request == "GET" + expect req.method == "GET" txresp -body "1" rxreq - expect req.request == "POST" + expect req.method == "POST" txresp -body "22" rxreq - expect req.request == "POST" + expect req.method == "POST" txresp -body "333" rxreq - expect req.request == "GET" + expect req.method == "GET" txresp -body "4444" } -start varnish v1 -vcl+backend { sub vcl_recv { - if (req.request == "POST") { + if (req.method == "POST") { /* Lookup so we find any cached object */ return (lookup); } } sub vcl_hit { - if (req.request == "POST") { + if (req.method == "POST") { /* Get rid of this object */ set obj.ttl = 0s; return (pass); } } sub vcl_miss { - if (req.request == "POST") { + if (req.method == "POST") { /* Make sure we don't cache the POST result */ return (pass); } diff --git a/bin/varnishtest/tests/r00679.vtc b/bin/varnishtest/tests/r00679.vtc index a79b4c9..ba5ca68 100644 --- a/bin/varnishtest/tests/r00679.vtc +++ b/bin/varnishtest/tests/r00679.vtc @@ -2,7 +2,7 @@ varnishtest "pass + HEAD" server s1 { rxreq - expect req.request == "HEAD" + expect req.method == "HEAD" txresp } -start diff --git a/bin/varnishtest/tests/r01030.vtc b/bin/varnishtest/tests/r01030.vtc index 8351d81..830e465 100644 --- a/bin/varnishtest/tests/r01030.vtc +++ b/bin/varnishtest/tests/r01030.vtc @@ -14,7 +14,7 @@ server s1 { varnish v1 -vcl+backend { sub vcl_recv { - if (req.request == "BAN") { + if (req.method == "BAN") { ban("obj.http.url ~ /"); error 201 "banned"; } diff --git a/bin/varnishtest/tests/v00001.vtc b/bin/varnishtest/tests/v00001.vtc index 644e737..922cd15 100644 --- a/bin/varnishtest/tests/v00001.vtc +++ b/bin/varnishtest/tests/v00001.vtc @@ -12,11 +12,11 @@ varnish v1 -vcl+backend { sub vcl_recv { set req.http.foobar = req.url + - req.request + + req.method + req.proto; set req.url = "/"; set req.proto = "HTTP/1.2"; - set req.request = "GET"; + set req.method = "GET"; } sub vcl_miss { set bereq.http.foobar = @@ -24,7 +24,7 @@ varnish v1 -vcl+backend { bereq.proto; set bereq.url = "/"; set bereq.proto = "HTTP/1.2"; - set bereq.request = "GET"; + set bereq.method = "GET"; } sub vcl_fetch { set beresp.http.foobar = diff --git a/bin/varnishtest/tests/v00011.vtc b/bin/varnishtest/tests/v00011.vtc index dc8bd18..89119e4 100644 --- a/bin/varnishtest/tests/v00011.vtc +++ b/bin/varnishtest/tests/v00011.vtc @@ -10,7 +10,7 @@ server s1 { varnish v1 -vcl+backend { sub vcl_recv { - if (req.request == "PURGE") { + if (req.method == "PURGE") { ban("req.url ~ ^/$"); error 209 "foo"; } diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index f867168..4d71ae9 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -175,7 +175,7 @@ cmd_var_resolve(struct http *hp, char *spec) { char **hh, *hdr; - if (!strcmp(spec, "req.request")) + if (!strcmp(spec, "req.method")) return(hp->req[0]); if (!strcmp(spec, "req.url")) return(hp->req[1]); diff --git a/doc/sphinx/reference/vcl.rst b/doc/sphinx/reference/vcl.rst index 325470c..731da16 100644 --- a/doc/sphinx/reference/vcl.rst +++ b/doc/sphinx/reference/vcl.rst @@ -382,8 +382,8 @@ vcl_recv lookup Look up the requested object in the cache. Control will eventually pass to vcl_hit or vcl_miss, depending on whether the - object is in the cache. The ``bereq.request`` value will be set - to ``GET`` regardless of the value of ``req.request``. + object is in the cache. The ``bereq.method`` value will be set + to ``GET`` regardless of the value of ``req.method``. vcl_pipe Called upon entering pipe mode. In this mode, the request is passed @@ -619,9 +619,12 @@ server.ip server.port The port number of the socket on which the client connection was received. -req.request +req.method The request type (e.g. "GET", "HEAD"). +req.request + Outdated way to spell req.method. + req.url The requested URL. @@ -670,9 +673,12 @@ req.xid The following variables are available while preparing a backend request (either for a cache miss or for pass or pipe mode): -bereq.request +bereq.method The request type (e.g. "GET", "HEAD"). +bereq.request + Outdated way to spell bereq.method. + bereq.url The requested URL. @@ -913,7 +919,7 @@ documents even when cookies are present: :: sub vcl_recv { - if (req.request == "GET" && req.http.cookie) { + if (req.method == "GET" && req.http.cookie) { return(lookup); } } @@ -934,7 +940,7 @@ for object invalidation: } sub vcl_recv { - if (req.request == "PURGE") { + if (req.method == "PURGE") { if (!client.ip ~ purge) { error 405 "Not allowed."; } @@ -943,14 +949,14 @@ for object invalidation: } sub vcl_hit { - if (req.request == "PURGE") { + if (req.method == "PURGE") { purge; error 200 "Purged."; } } sub vcl_miss { - if (req.request == "PURGE") { + if (req.method == "PURGE") { purge; error 200 "Purged."; } diff --git a/doc/sphinx/users-guide/devicedetection.rst b/doc/sphinx/users-guide/devicedetection.rst index 13d501a..fc612e7 100644 --- a/doc/sphinx/users-guide/devicedetection.rst +++ b/doc/sphinx/users-guide/devicedetection.rst @@ -169,7 +169,7 @@ VCL:: } sub append_ua { - if ((req.http.X-UA-Device) && (req.request == "GET")) { + if ((req.http.X-UA-Device) && (req.method == "GET")) { # if there are existing GET arguments; if (req.url ~ "\?") { set req.http.X-get-devicetype = "&devicetype=" + req.http.X-UA-Device; diff --git a/doc/sphinx/users-guide/purging.rst b/doc/sphinx/users-guide/purging.rst index 53facd3..2402632 100644 --- a/doc/sphinx/users-guide/purging.rst +++ b/doc/sphinx/users-guide/purging.rst @@ -35,7 +35,7 @@ following VCL in place:: sub vcl_recv { # allow PURGE from localhost and 192.168.55... - if (req.request == "PURGE") { + if (req.method == "PURGE") { if (!client.ip ~ purge) { error 405 "Not allowed."; } @@ -44,14 +44,14 @@ following VCL in place:: } sub vcl_hit { - if (req.request == "PURGE") { + if (req.method == "PURGE") { purge; error 200 "Purged."; } } sub vcl_miss { - if (req.request == "PURGE") { + if (req.method == "PURGE") { purge; error 200 "Purged."; } @@ -110,7 +110,7 @@ impact CPU usage and thereby performance. You can also add bans to Varnish via HTTP. Doing so requires a bit of VCL:: sub vcl_recv { - if (req.request == "BAN") { + if (req.method == "BAN") { # Same ACL check as above: if (!client.ip ~ purge) { error 405 "Not allowed."; @@ -142,7 +142,7 @@ You can use the following template to write ban lurker friendly bans:: } sub vcl_recv { - if (req.request == "PURGE") { + if (req.method == "PURGE") { if (client.ip !~ purge) { error 401 "Not allowed"; } diff --git a/doc/sphinx/users-guide/vcl-examples.rst b/doc/sphinx/users-guide/vcl-examples.rst index ffa730f..ea78b9b 100644 --- a/doc/sphinx/users-guide/vcl-examples.rst +++ b/doc/sphinx/users-guide/vcl-examples.rst @@ -43,7 +43,7 @@ the IP address of the client against an ACL with the match operator.:: } sub vcl_recv { - if (req.request == "PURGE") { + if (req.method == "PURGE") { if (client.ip ~ local) { return(lookup); } @@ -51,14 +51,14 @@ the IP address of the client against an ACL with the match operator.:: } sub vcl_hit { - if (req.request == "PURGE") { + if (req.method == "PURGE") { set obj.ttl = 0s; error 200 "Purged."; } } sub vcl_miss { - if (req.request == "PURGE") { + if (req.method == "PURGE") { error 404 "Not in cache."; } } diff --git a/etc/zope-plone.vcl b/etc/zope-plone.vcl index 263e343..3127f18 100644 --- a/etc/zope-plone.vcl +++ b/etc/zope-plone.vcl @@ -38,15 +38,15 @@ sub vcl_recv { } # Handle special requests - if (req.request != "GET" && req.request != "HEAD") { + if (req.method != "GET" && req.method != "HEAD") { # POST - Logins and edits - if (req.request == "POST") { + if (req.method == "POST") { return(pass); } # PURGE - The CacheFu product can invalidate updated URLs - if (req.request == "PURGE") { + if (req.method == "PURGE") { if (!client.ip ~ purge) { error 405 "Not allowed."; } @@ -75,13 +75,13 @@ sub vcl_recv { # Do the PURGE thing sub vcl_hit { - if (req.request == "PURGE") { + if (req.method == "PURGE") { purge; error 200 "Purged"; } } sub vcl_miss { - if (req.request == "PURGE") { + if (req.method == "PURGE") { purge; error 200 "Purged"; } diff --git a/include/tbl/vsl_tags_http.h b/include/tbl/vsl_tags_http.h index 542af07..f515492 100644 --- a/include/tbl/vsl_tags_http.h +++ b/include/tbl/vsl_tags_http.h @@ -32,7 +32,7 @@ * */ -SLTH(Request, HTTP_HDR_REQ) +SLTH(Method, HTTP_HDR_METHOD) SLTH(URL, HTTP_HDR_URL) SLTH(Protocol, HTTP_HDR_PROTO) SLTH(Status, HTTP_HDR_STATUS) diff --git a/lib/libvcl/generate.py b/lib/libvcl/generate.py index 45f015e..2064b82 100755 --- a/lib/libvcl/generate.py +++ b/lib/libvcl/generate.py @@ -139,6 +139,12 @@ sp_variables = ( ( ), 'struct req *' ), + ('req.method', + 'STRING', + ( 'proc',), + ( 'proc',), + 'const struct req *' + ), ('req.request', 'STRING', ( 'proc',), @@ -235,6 +241,12 @@ sp_variables = ( ( 'recv',), 'struct req *' ), + ('bereq.method', + 'STRING', + ( 'pipe', 'pass', 'miss', 'fetch',), + ( 'pipe', 'pass', 'miss', 'fetch',), + 'const struct req *' + ), ('bereq.request', 'STRING', ( 'pipe', 'pass', 'miss', 'fetch',), From phk at varnish-cache.org Tue Jan 8 11:23:54 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 08 Jan 2013 12:23:54 +0100 Subject: [master] 6def8cf Move the main table of parameters to its own source code before starting surgery on parameter defaults. Message-ID: commit 6def8cf505a4e88c87e2577cda3a08e7f0282a0b Author: Poul-Henning Kamp Date: Tue Jan 8 11:09:05 2013 +0000 Move the main table of parameters to its own source code before starting surgery on parameter defaults. diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 3d35113..7d2077b 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -61,6 +61,7 @@ varnishd_SOURCES = \ mgt/mgt_cli.c \ mgt/mgt_main.c \ mgt/mgt_param.c \ + mgt/mgt_param_tbl.c \ mgt/mgt_param_bits.c \ mgt/mgt_pool.c \ mgt/mgt_sandbox.c \ diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 0e4440d..97e3f4e 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -53,7 +53,6 @@ #include "mgt_cli.h" -#define MAGIC_INIT_STRING "\001" struct params mgt_param; static int nparspec; static struct parspec const ** parspecs; @@ -93,7 +92,7 @@ tweak_generic_timeout(struct cli *cli, volatile unsigned *dst, const char *arg) /*--------------------------------------------------------------------*/ -static void +void tweak_timeout(struct cli *cli, const struct parspec *par, const char *arg) { volatile unsigned *dest; @@ -149,7 +148,7 @@ tweak_timeout_double(struct cli *cli, const struct parspec *par, /*--------------------------------------------------------------------*/ -static void +void tweak_generic_double(struct cli *cli, const struct parspec *par, const char *arg) { @@ -219,7 +218,7 @@ tweak_generic_bool(struct cli *cli, volatile unsigned *dest, const char *arg) /*--------------------------------------------------------------------*/ -static void +void tweak_bool(struct cli *cli, const struct parspec *par, const char *arg) { volatile unsigned *dest; @@ -363,7 +362,7 @@ tweak_bytes(struct cli *cli, const struct parspec *par, const char *arg) /*--------------------------------------------------------------------*/ -static void +void tweak_bytes_u(struct cli *cli, const struct parspec *par, const char *arg) { volatile unsigned *d1; @@ -385,7 +384,7 @@ tweak_bytes_u(struct cli *cli, const struct parspec *par, const char *arg) * XXX: The magic init string is a hack for this. */ -static void +void tweak_user(struct cli *cli, const struct parspec *par, const char *arg) { struct passwd *pw; @@ -426,7 +425,7 @@ tweak_user(struct cli *cli, const struct parspec *par, const char *arg) * XXX: see comment for tweak_user, same thing here. */ -static void +void tweak_group(struct cli *cli, const struct parspec *par, const char *arg) { struct group *gr; @@ -473,7 +472,7 @@ clean_listen_sock_head(struct listen_sock_head *lsh) } } -static void +void tweak_listen_address(struct cli *cli, const struct parspec *par, const char *arg) { @@ -551,7 +550,7 @@ tweak_listen_address(struct cli *cli, const struct parspec *par, /*--------------------------------------------------------------------*/ -static void +void tweak_string(struct cli *cli, const struct parspec *par, const char *arg) { char **p = TRUST_ME(par->priv); @@ -567,7 +566,7 @@ tweak_string(struct cli *cli, const struct parspec *par, const char *arg) /*--------------------------------------------------------------------*/ -static void +void tweak_waiter(struct cli *cli, const struct parspec *par, const char *arg) { @@ -578,7 +577,7 @@ tweak_waiter(struct cli *cli, const struct parspec *par, const char *arg) /*--------------------------------------------------------------------*/ -static void +void tweak_poolparam(struct cli *cli, const struct parspec *par, const char *arg) { volatile struct poolparam *pp, px; @@ -655,563 +654,6 @@ tweak_poolparam(struct cli *cli, const struct parspec *par, const char *arg) #define PROTECTED_TEXT \ "\nNB: This parameter is protected and can not be changed." -#define MEMPOOL_TEXT \ - "The three numbers are:\n" \ - " min_pool -- minimum size of free pool.\n" \ - " max_pool -- maximum size of free pool.\n" \ - " max_age -- max age of free element.\n" - -/* - * Remember to update varnishd.1 whenever you add / remove a parameter or - * change its default value. - * XXX: we should generate the relevant section of varnishd.1 from here. - */ -static const struct parspec input_parspec[] = { - { "user", tweak_user, NULL, 0, 0, - "The unprivileged user to run as. Setting this will " - "also set \"group\" to the specified user's primary group.", - MUST_RESTART, - MAGIC_INIT_STRING }, - { "group", tweak_group, NULL, 0, 0, - "The unprivileged group to run as.", - MUST_RESTART, - MAGIC_INIT_STRING }, - { "default_ttl", tweak_timeout_double, &mgt_param.default_ttl, - 0, UINT_MAX, - "The TTL assigned to objects if neither the backend nor " - "the VCL code assigns one.\n" - "Objects already cached will not be affected by changes " - "made until they are fetched from the backend again.\n" - "To force an immediate effect at the expense of a total " - "flush of the cache use \"ban obj.http.date ~ .\"", - 0, - "120", "seconds" }, - { "workspace_client", - tweak_bytes_u, &mgt_param.workspace_client, 3072, UINT_MAX, - "Bytes of HTTP protocol workspace for clients HTTP req/resp." - " If larger than 4k, use a multiple of 4k for VM efficiency.", - DELAYED_EFFECT, - "64k", "bytes" }, - { "workspace_backend", - tweak_bytes_u, &mgt_param.workspace_backend, 1024, UINT_MAX, - "Bytes of HTTP protocol workspace for backend HTTP req/resp." - " If larger than 4k, use a multiple of 4k for VM efficiency.", - DELAYED_EFFECT, - "64k", "bytes" }, - { "workspace_thread", - tweak_bytes_u, &mgt_param.workspace_thread, 256, 8192, - "Bytes of auxillary workspace per thread.\n" - "This workspace is used for certain temporary data structures" - " during the operation of a worker thread.\n" - "One use is for the io-vectors for writing requests and" - " responses to sockets, having too little space will" - " result in more writev(2) system calls, having too much" - " just wastes the space.\n", - DELAYED_EFFECT, - "2048", "bytes" }, - { "http_req_hdr_len", - tweak_bytes_u, &mgt_param.http_req_hdr_len, - 40, UINT_MAX, - "Maximum length of any HTTP client request header we will " - "allow. The limit is inclusive its continuation lines.\n", - 0, - "8k", "bytes" }, - { "http_req_size", - tweak_bytes_u, &mgt_param.http_req_size, - 256, UINT_MAX, - "Maximum number of bytes of HTTP client request we will deal " - "with. This is a limit on all bytes up to the double blank " - "line which ends the HTTP request.\n" - "The memory for the request is allocated from the client " - "workspace (param: workspace_client) and this parameter limits " - "how much of that the request is allowed to take up.", - 0, - "32k", "bytes" }, - { "http_resp_hdr_len", - tweak_bytes_u, &mgt_param.http_resp_hdr_len, - 40, UINT_MAX, - "Maximum length of any HTTP backend response header we will " - "allow. The limit is inclusive its continuation lines.\n", - 0, - "8k", "bytes" }, - { "http_resp_size", - tweak_bytes_u, &mgt_param.http_resp_size, - 256, UINT_MAX, - "Maximum number of bytes of HTTP backend resonse we will deal " - "with. This is a limit on all bytes up to the double blank " - "line which ends the HTTP request.\n" - "The memory for the request is allocated from the worker " - "workspace (param: thread_pool_workspace) and this parameter " - "limits how much of that the request is allowed to take up.", - 0, - "32k", "bytes" }, - { "http_max_hdr", tweak_uint, &mgt_param.http_max_hdr, 32, 65535, - "Maximum number of HTTP headers we will deal with in " - "client request or backend reponses. " - "Note that the first line occupies five header fields.\n" - "This parameter does not influence storage consumption, " - "objects allocate exact space for the headers they store.\n", - 0, - "64", "header lines" }, - { "vsl_buffer", - tweak_bytes_u, &mgt_param.vsl_buffer, 1024, UINT_MAX, - "Bytes of (req-/backend-)workspace dedicated to buffering" - " VSL records.\n" - "At a bare minimum, this must be longer than" - " the longest HTTP header to be logged.\n" - "Setting this too high costs memory, setting it too low" - " will cause more VSL flushes and likely increase" - " lock-contention on the VSL mutex.\n" - "Minimum is 1k bytes.", - 0, - "4k", "bytes" }, - { "shm_reclen", - tweak_bytes_u, &mgt_param.shm_reclen, 16, 65535, - "Maximum number of bytes in SHM log record.\n" - "Maximum is 65535 bytes.", - 0, - "255", "bytes" }, - { "default_grace", tweak_timeout_double, &mgt_param.default_grace, - 0, UINT_MAX, - "Default grace period. We will deliver an object " - "this long after it has expired, provided another thread " - "is attempting to get a new copy.\n" - "Objects already cached will not be affected by changes " - "made until they are fetched from the backend again.\n", - DELAYED_EFFECT, - "10", "seconds" }, - { "default_keep", tweak_timeout_double, &mgt_param.default_keep, - 0, UINT_MAX, - "Default keep period. We will keep a useless object " - "around this long, making it available for conditional " - "backend fetches. " - "That means that the object will be removed from the " - "cache at the end of ttl+grace+keep.", - DELAYED_EFFECT, - "0", "seconds" }, - { "timeout_idle", tweak_timeout_double, &mgt_param.timeout_idle, - 0, UINT_MAX, - "Idle timeout for client connections.\n" - "A connection is considered idle, until we receive" - " a non-white-space character on it.", - 0, - "5", "seconds" }, - { "timeout_req", tweak_timeout_double, &mgt_param.timeout_req, - 0, UINT_MAX, - "Max time to receive clients request header, measured" - " from first non-white-space character to double CRNL.", - 0, - "2", "seconds" }, - { "expiry_sleep", tweak_timeout_double, &mgt_param.expiry_sleep, 0, 60, - "How long the expiry thread sleeps when there is nothing " - "for it to do.\n", - 0, - "1", "seconds" }, - { "pipe_timeout", tweak_timeout, &mgt_param.pipe_timeout, 0, 0, - "Idle timeout for PIPE sessions. " - "If nothing have been received in either direction for " - "this many seconds, the session is closed.\n", - 0, - "60", "seconds" }, - { "send_timeout", tweak_timeout, &mgt_param.send_timeout, 0, 0, - "Send timeout for client connections. " - "If the HTTP response hasn't been transmitted in this many\n" - "seconds the session is closed. \n" - "See setsockopt(2) under SO_SNDTIMEO for more information.", - DELAYED_EFFECT, - "600", "seconds" }, - { "idle_send_timeout", tweak_timeout, &mgt_param.idle_send_timeout, - 0, 0, - "Time to wait with no data sent. " - "If no data has been transmitted in this many\n" - "seconds the session is closed. \n" - "See setsockopt(2) under SO_SNDTIMEO for more information.", - DELAYED_EFFECT, - "60", "seconds" }, - { "auto_restart", tweak_bool, &mgt_param.auto_restart, 0, 0, - "Restart child process automatically if it dies.\n", - 0, - "on", "bool" }, - { "nuke_limit", - tweak_uint, &mgt_param.nuke_limit, 0, UINT_MAX, - "Maximum number of objects we attempt to nuke in order" - "to make space for a object body.", - EXPERIMENTAL, - "50", "allocations" }, - { "fetch_chunksize", - tweak_bytes, - &mgt_param.fetch_chunksize, 4 * 1024, UINT_MAX, - "The default chunksize used by fetcher. " - "This should be bigger than the majority of objects with " - "short TTLs.\n" - "Internal limits in the storage_file module makes increases " - "above 128kb a dubious idea.", - EXPERIMENTAL, - "128k", "bytes" }, - { "fetch_maxchunksize", - tweak_bytes, - &mgt_param.fetch_maxchunksize, 64 * 1024, UINT_MAX, - "The maximum chunksize we attempt to allocate from storage. " - "Making this too large may cause delays and storage " - "fragmentation.\n", - EXPERIMENTAL, - "256m", "bytes" }, - { "accept_filter", tweak_bool, &mgt_param.accept_filter, 0, 0, - "Enable kernel accept-filters, if supported by the kernel.", - MUST_RESTART, - "on", "bool" }, - { "listen_address", tweak_listen_address, NULL, 0, 0, - "Whitespace separated list of network endpoints where " - "Varnish will accept requests.\n" - "Possible formats: host, host:port, :port", - MUST_RESTART, - ":80" }, - { "listen_depth", tweak_uint, &mgt_param.listen_depth, 0, UINT_MAX, - "Listen queue depth.", - MUST_RESTART, - "1024", "connections" }, - { "cli_buffer", - tweak_bytes_u, &mgt_param.cli_buffer, 4096, UINT_MAX, - "Size of buffer for CLI command input." - "\nYou may need to increase this if you have big VCL files " - "and use the vcl.inline CLI command.\n" - "NB: Must be specified with -p to have effect.\n", - 0, - "8k", "bytes" }, - { "cli_limit", - tweak_bytes_u, &mgt_param.cli_limit, 128, 99999999, - "Maximum size of CLI response. If the response exceeds" - " this limit, the reponse code will be 201 instead of" - " 200 and the last line will indicate the truncation.", - 0, - "48k", "bytes" }, - { "cli_timeout", tweak_timeout, &mgt_param.cli_timeout, 0, 0, - "Timeout for the childs replies to CLI requests from " - "the mgt_param.", - 0, - "10", "seconds" }, - { "ping_interval", tweak_uint, &mgt_param.ping_interval, 0, UINT_MAX, - "Interval between pings from parent to child.\n" - "Zero will disable pinging entirely, which makes " - "it possible to attach a debugger to the child.", - MUST_RESTART, - "3", "seconds" }, - { "lru_interval", tweak_timeout, &mgt_param.lru_timeout, 0, 0, - "Grace period before object moves on LRU list.\n" - "Objects are only moved to the front of the LRU " - "list if they have not been moved there already inside " - "this timeout period. This reduces the amount of lock " - "operations necessary for LRU list access.", - EXPERIMENTAL, - "2", "seconds" }, - { "cc_command", tweak_string, &mgt_cc_cmd, 0, 0, - "Command used for compiling the C source code to a " - "dlopen(3) loadable object. Any occurrence of %s in " - "the string will be replaced with the source file name, " - "and %o will be replaced with the output file name.", - MUST_RELOAD, - VCC_CC , NULL }, - { "max_restarts", tweak_uint, &mgt_param.max_restarts, 0, UINT_MAX, - "Upper limit on how many times a request can restart." - "\nBe aware that restarts are likely to cause a hit against " - "the backend, so don't increase thoughtlessly.\n", - 0, - "4", "restarts" }, - { "esi_syntax", - tweak_uint, &mgt_param.esi_syntax, 0, UINT_MAX, - "Bitmap controlling ESI parsing code:\n" - " 0x00000001 - Don't check if it looks like XML\n" - " 0x00000002 - Ignore non-esi elements\n" - " 0x00000004 - Emit parsing debug records\n" - " 0x00000008 - Force-split parser input (debugging)\n" - "\n" - "Use 0x notation and do the bitor in your head :-)\n", - 0, - "0", "bitmap" }, - { "max_esi_depth", - tweak_uint, &mgt_param.max_esi_depth, 0, UINT_MAX, - "Maximum depth of esi:include processing.\n", - 0, - "5", "levels" }, - { "connect_timeout", tweak_timeout_double, - &mgt_param.connect_timeout,0, UINT_MAX, - "Default connection timeout for backend connections. " - "We only try to connect to the backend for this many " - "seconds before giving up. " - "VCL can override this default value for each backend and " - "backend request.", - 0, - "0.7", "s" }, - { "first_byte_timeout", tweak_timeout_double, - &mgt_param.first_byte_timeout,0, UINT_MAX, - "Default timeout for receiving first byte from backend. " - "We only wait for this many seconds for the first " - "byte before giving up. A value of 0 means it will never time " - "out. " - "VCL can override this default value for each backend and " - "backend request. This parameter does not apply to pipe.", - 0, - "60", "s" }, - { "between_bytes_timeout", tweak_timeout_double, - &mgt_param.between_bytes_timeout,0, UINT_MAX, - "Default timeout between bytes when receiving data from " - "backend. " - "We only wait for this many seconds between bytes " - "before giving up. A value of 0 means it will never time out. " - "VCL can override this default value for each backend request " - "and backend request. This parameter does not apply to pipe.", - 0, - "60", "s" }, - { "acceptor_sleep_max", tweak_timeout_double, - &mgt_param.acceptor_sleep_max, 0, 10, - "If we run out of resources, such as file descriptors or " - "worker threads, the acceptor will sleep between accepts.\n" - "This parameter limits how long it can sleep between " - "attempts to accept new connections.", - EXPERIMENTAL, - "0.050", "s" }, - { "acceptor_sleep_incr", tweak_timeout_double, - &mgt_param.acceptor_sleep_incr, 0, 1, - "If we run out of resources, such as file descriptors or " - "worker threads, the acceptor will sleep between accepts.\n" - "This parameter control how much longer we sleep, each time " - "we fail to accept a new connection.", - EXPERIMENTAL, - "0.001", "s" }, - { "acceptor_sleep_decay", tweak_generic_double, - &mgt_param.acceptor_sleep_decay, 0, 1, - "If we run out of resources, such as file descriptors or " - "worker threads, the acceptor will sleep between accepts.\n" - "This parameter (multiplicatively) reduce the sleep duration " - "for each succesfull accept. (ie: 0.9 = reduce by 10%)", - EXPERIMENTAL, - "0.900", "" }, - { "clock_skew", tweak_uint, &mgt_param.clock_skew, 0, UINT_MAX, - "How much clockskew we are willing to accept between the " - "backend and our own clock.", - 0, - "10", "s" }, - { "prefer_ipv6", tweak_bool, &mgt_param.prefer_ipv6, 0, 0, - "Prefer IPv6 address when connecting to backends which " - "have both IPv4 and IPv6 addresses.", - 0, - "off", "bool" }, - { "session_max", tweak_uint, - &mgt_param.max_sess, 1000, UINT_MAX, - "Maximum number of sessions we will allocate from one pool " - "before just dropping connections.\n" - "This is mostly an anti-DoS measure, and setting it plenty " - "high should not hurt, as long as you have the memory for " - "it.\n", - 0, - "100000", "sessions" }, - { "timeout_linger", tweak_timeout_double, &mgt_param.timeout_linger, - 0, UINT_MAX, - "How long time the workerthread lingers on an idle session " - "before handing it over to the waiter.\n" - "When sessions are reused, as much as half of all reuses " - "happen within the first 100 msec of the previous request " - "completing.\n" - "Setting this too high results in worker threads not doing " - "anything for their keep, setting it too low just means that " - "more sessions take a detour around the waiter.", - EXPERIMENTAL, - "0.050", "seconds" }, - { "log_local_address", tweak_bool, &mgt_param.log_local_addr, 0, 0, - "Log the local address on the TCP connection in the " - "SessionOpen VSL record.\n" - "Disabling this saves a getsockname(2) system call " - "per TCP connection.\n", - 0, - "on", "bool" }, - { "waiter", tweak_waiter, NULL, 0, 0, - "Select the waiter kernel interface.\n", - WIZARD | MUST_RESTART, - WAITER_DEFAULT, NULL }, - { "ban_dups", tweak_bool, &mgt_param.ban_dups, 0, 0, - "Detect and eliminate duplicate bans.\n", - 0, - "on", "bool" }, - { "syslog_cli_traffic", tweak_bool, &mgt_param.syslog_cli_traffic, 0, 0, - "Log all CLI traffic to syslog(LOG_INFO).\n", - 0, - "on", "bool" }, - { "ban_lurker_sleep", tweak_timeout_double, - &mgt_param.ban_lurker_sleep, 0, UINT_MAX, - "How long time does the ban lurker thread sleeps between " - "successful attempts to push the last item up the ban " - " list. It always sleeps a second when nothing can be done.\n" - "A value of zero disables the ban lurker.", - 0, - "0.01", "s" }, - { "saintmode_threshold", tweak_uint, - &mgt_param.saintmode_threshold, 0, UINT_MAX, - "The maximum number of objects held off by saint mode before " - "no further will be made to the backend until one times out. " - "A value of 0 disables saintmode.", - EXPERIMENTAL, - "10", "objects" }, - { "http_range_support", tweak_bool, &mgt_param.http_range_support, 0, 0, - "Enable support for HTTP Range headers.\n", - 0, - "on", "bool" }, - { "http_gzip_support", tweak_bool, &mgt_param.http_gzip_support, 0, 0, - "Enable gzip support. When enabled Varnish will compress " - "uncompressed objects before they are stored in the cache. " - "If a client does not support gzip encoding Varnish will " - "uncompress compressed objects on demand. Varnish will also " - "rewrite the Accept-Encoding header of clients indicating " - "support for gzip to:\n" - " Accept-Encoding: gzip\n\n" - "Clients that do not support gzip will have their " - "Accept-Encoding header removed. For more information on how " - "gzip is implemented please see the chapter on gzip in the " - "Varnish reference.", - EXPERIMENTAL, - "on", "bool" }, - { "gzip_level", tweak_uint, &mgt_param.gzip_level, 0, 9, - "Gzip compression level: 0=debug, 1=fast, 9=best", - 0, - "6", ""}, - { "gzip_memlevel", tweak_uint, &mgt_param.gzip_memlevel, 1, 9, - "Gzip memory level 1=slow/least, 9=fast/most compression.\n" - "Memory impact is 1=1k, 2=2k, ... 9=256k.", - 0, - "8", ""}, - { "gzip_buffer", - tweak_bytes_u, &mgt_param.gzip_buffer, - 2048, UINT_MAX, - "Size of malloc buffer used for gzip processing.\n" - "These buffers are used for in-transit data," - " for instance gunzip'ed data being sent to a client." - "Making this space to small results in more overhead," - " writes to sockets etc, making it too big is probably" - " just a waste of memory.", - EXPERIMENTAL, - "32k", "bytes" }, - { "shortlived", tweak_timeout_double, - &mgt_param.shortlived, 0, UINT_MAX, - "Objects created with TTL shorter than this are always " - "put in transient storage.\n", - 0, - "10.0", "s" }, - { "critbit_cooloff", tweak_timeout_double, - &mgt_param.critbit_cooloff, 60, 254, - "How long time the critbit hasher keeps deleted objheads " - "on the cooloff list.\n", - WIZARD, - "180.0", "s" }, - { "vcl_dir", tweak_string, &mgt_vcl_dir, 0, 0, - "Directory from which relative VCL filenames (vcl.load and " - "include) are opened.", - 0, -#ifdef VARNISH_VCL_DIR - VARNISH_VCL_DIR, -#else - ".", -#endif - NULL }, - { "vmod_dir", tweak_string, &mgt_vmod_dir, 0, 0, - "Directory where VCL modules are to be found.", - 0, -#ifdef VARNISH_VMOD_DIR - VARNISH_VMOD_DIR, -#else - ".", -#endif - NULL }, - - { "vcc_err_unref", tweak_bool, &mgt_vcc_err_unref, 0, 0, - "Unreferenced VCL objects result in error.\n", - 0, - "on", "bool" }, - - { "vcc_allow_inline_c", tweak_bool, &mgt_vcc_allow_inline_c, 0, 0, - "Allow inline C code in VCL.\n", - 0, - "on", "bool" }, - - { "vcc_unsafe_path", tweak_bool, &mgt_vcc_unsafe_path, 0, 0, - "Allow '/' in vmod & include paths.\n" - "Allow 'import ... from ...'.\n", - 0, - "on", "bool" }, - - { "pcre_match_limit", tweak_uint, - &mgt_param.vre_limits.match, - 1, UINT_MAX, - "The limit for the number of internal matching function" - " calls in a pcre_exec() execution.", - 0, - "10000", ""}, - - { "pcre_match_limit_recursion", tweak_uint, - &mgt_param.vre_limits.match_recursion, - 1, UINT_MAX, - "The limit for the number of internal matching function" - " recursions in a pcre_exec() execution.", - 0, - "10000", ""}, - - { "vsl_space", tweak_bytes, - &mgt_param.vsl_space, 1024*1024, 0, - "The amount of space to allocate for the VSL fifo buffer" - " in the VSM memory segment." - " If you make this too small, varnish{ncsa|log} etc will" - " not be able to keep up." - " Making it too large just costs memory resources.", - MUST_RESTART, - "80M", "bytes"}, - - { "vsm_space", tweak_bytes, - &mgt_param.vsm_space, 1024*1024, 0, - "The amount of space to allocate for stats counters" - " in the VSM memory segment." - " If you make this too small, some counters will be" - " invisible." - " Making it too large just costs memory resources.", - MUST_RESTART, - "1M", "bytes"}, - - { "busyobj_worker_cache", tweak_bool, - &mgt_param.bo_cache, 0, 0, - "Cache free busyobj per worker thread." - "Disable this if you have very high hitrates and want" - "to save the memory of one busyobj per worker thread.", - 0, - "false", ""}, - - { "pool_vbc", tweak_poolparam, &mgt_param.vbc_pool, 0, 10000, - "Parameters for backend connection memory pool.\n" - MEMPOOL_TEXT, - 0, - "10,100,10", ""}, - - { "pool_req", tweak_poolparam, &mgt_param.req_pool, 0, 10000, - "Parameters for per worker pool request memory pool.\n" - MEMPOOL_TEXT, - 0, - "10,100,10", ""}, - { "pool_sess", tweak_poolparam, &mgt_param.sess_pool, 0, 10000, - "Parameters for per worker pool session memory pool.\n" - MEMPOOL_TEXT, - 0, - "10,100,10", ""}, - { "pool_vbo", tweak_poolparam, &mgt_param.vbo_pool, 0, 10000, - "Parameters for backend object fetch memory pool.\n" - MEMPOOL_TEXT, - 0, - "10,100,10", ""}, - - { "obj_readonly", tweak_bool, &mgt_param.obj_readonly, 0, 0, - "If set, we do not update obj.hits and obj.lastuse to" - "avoid dirtying VM pages associated with cached objects.", - 0, - "false", ""}, - - { NULL, NULL, NULL } -}; - /*--------------------------------------------------------------------*/ #define WIDTH 76 @@ -1440,7 +882,7 @@ void MCF_ParamInit(struct cli *cli) { - MCF_AddParams(input_parspec); + MCF_AddParams(mgt_parspec); MCF_AddParams(WRK_parspec); MCF_AddParams(VSL_parspec); diff --git a/bin/varnishd/mgt/mgt_param.h b/bin/varnishd/mgt/mgt_param.h index d25411d..04c9c4f 100644 --- a/bin/varnishd/mgt/mgt_param.h +++ b/bin/varnishd/mgt/mgt_param.h @@ -50,6 +50,17 @@ struct parspec { const char *units; }; +tweak_t tweak_user; +tweak_t tweak_group; +tweak_t tweak_string; +tweak_t tweak_bool; +tweak_t tweak_waiter; +tweak_t tweak_bytes_u; +tweak_t tweak_listen_address; +tweak_t tweak_timeout; +tweak_t tweak_generic_double; +tweak_t tweak_poolparam; + int tweak_generic_uint(struct cli *cli, volatile unsigned *dest, const char *arg, unsigned min, unsigned max); void tweak_uint(struct cli *cli, const struct parspec *par, const char *arg); @@ -57,8 +68,20 @@ void tweak_timeout_double(struct cli *cli, const struct parspec *par, const char *arg); void tweak_bytes(struct cli *cli, const struct parspec *par, const char *arg); +/* mgt_param_tbl.c */ +extern const struct parspec mgt_parspec[]; + /* mgt_param_vsl.c */ extern const struct parspec VSL_parspec[]; /* mgt_pool.c */ extern const struct parspec WRK_parspec[]; + +#define MAGIC_INIT_STRING "\001" + +#define MEMPOOL_TEXT \ + "The three numbers are:\n" \ + " min_pool -- minimum size of free pool.\n" \ + " max_pool -- maximum size of free pool.\n" \ + " max_age -- max age of free element.\n" + diff --git a/bin/varnishd/mgt/mgt_param_tbl.c b/bin/varnishd/mgt/mgt_param_tbl.c new file mode 100644 index 0000000..96052c5 --- /dev/null +++ b/bin/varnishd/mgt/mgt_param_tbl.c @@ -0,0 +1,591 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2013 Varnish Software AS + * All rights reserved. + * + * Author: Poul-Henning Kamp + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include + +#include "mgt/mgt.h" +#include "common/params.h" + +#include "mgt/mgt_param.h" +#include "waiter/waiter.h" + +/* + * Remember to update varnishd.1 whenever you add / remove a parameter or + * change its default value. + * XXX: we should generate the relevant section of varnishd.1 from here. + */ + +const struct parspec mgt_parspec[] = { + { "user", tweak_user, NULL, 0, 0, + "The unprivileged user to run as. Setting this will " + "also set \"group\" to the specified user's primary group.", + MUST_RESTART, + MAGIC_INIT_STRING }, + { "group", tweak_group, NULL, 0, 0, + "The unprivileged group to run as.", + MUST_RESTART, + MAGIC_INIT_STRING }, + { "default_ttl", tweak_timeout_double, &mgt_param.default_ttl, + 0, UINT_MAX, + "The TTL assigned to objects if neither the backend nor " + "the VCL code assigns one.\n" + "Objects already cached will not be affected by changes " + "made until they are fetched from the backend again.\n" + "To force an immediate effect at the expense of a total " + "flush of the cache use \"ban obj.http.date ~ .\"", + 0, + "120", "seconds" }, + { "workspace_client", + tweak_bytes_u, &mgt_param.workspace_client, 3072, UINT_MAX, + "Bytes of HTTP protocol workspace for clients HTTP req/resp." + " If larger than 4k, use a multiple of 4k for VM efficiency.", + DELAYED_EFFECT, + "64k", "bytes" }, + { "workspace_backend", + tweak_bytes_u, &mgt_param.workspace_backend, 1024, UINT_MAX, + "Bytes of HTTP protocol workspace for backend HTTP req/resp." + " If larger than 4k, use a multiple of 4k for VM efficiency.", + DELAYED_EFFECT, + "64k", "bytes" }, + { "workspace_thread", + tweak_bytes_u, &mgt_param.workspace_thread, 256, 8192, + "Bytes of auxillary workspace per thread.\n" + "This workspace is used for certain temporary data structures" + " during the operation of a worker thread.\n" + "One use is for the io-vectors for writing requests and" + " responses to sockets, having too little space will" + " result in more writev(2) system calls, having too much" + " just wastes the space.\n", + DELAYED_EFFECT, + "2048", "bytes" }, + { "http_req_hdr_len", + tweak_bytes_u, &mgt_param.http_req_hdr_len, + 40, UINT_MAX, + "Maximum length of any HTTP client request header we will " + "allow. The limit is inclusive its continuation lines.\n", + 0, + "8k", "bytes" }, + { "http_req_size", + tweak_bytes_u, &mgt_param.http_req_size, + 256, UINT_MAX, + "Maximum number of bytes of HTTP client request we will deal " + "with. This is a limit on all bytes up to the double blank " + "line which ends the HTTP request.\n" + "The memory for the request is allocated from the client " + "workspace (param: workspace_client) and this parameter limits " + "how much of that the request is allowed to take up.", + 0, + "32k", "bytes" }, + { "http_resp_hdr_len", + tweak_bytes_u, &mgt_param.http_resp_hdr_len, + 40, UINT_MAX, + "Maximum length of any HTTP backend response header we will " + "allow. The limit is inclusive its continuation lines.\n", + 0, + "8k", "bytes" }, + { "http_resp_size", + tweak_bytes_u, &mgt_param.http_resp_size, + 256, UINT_MAX, + "Maximum number of bytes of HTTP backend resonse we will deal " + "with. This is a limit on all bytes up to the double blank " + "line which ends the HTTP request.\n" + "The memory for the request is allocated from the worker " + "workspace (param: thread_pool_workspace) and this parameter " + "limits how much of that the request is allowed to take up.", + 0, + "32k", "bytes" }, + { "http_max_hdr", tweak_uint, &mgt_param.http_max_hdr, 32, 65535, + "Maximum number of HTTP headers we will deal with in " + "client request or backend reponses. " + "Note that the first line occupies five header fields.\n" + "This parameter does not influence storage consumption, " + "objects allocate exact space for the headers they store.\n", + 0, + "64", "header lines" }, + { "vsl_buffer", + tweak_bytes_u, &mgt_param.vsl_buffer, 1024, UINT_MAX, + "Bytes of (req-/backend-)workspace dedicated to buffering" + " VSL records.\n" + "At a bare minimum, this must be longer than" + " the longest HTTP header to be logged.\n" + "Setting this too high costs memory, setting it too low" + " will cause more VSL flushes and likely increase" + " lock-contention on the VSL mutex.\n" + "Minimum is 1k bytes.", + 0, + "4k", "bytes" }, + { "shm_reclen", + tweak_bytes_u, &mgt_param.shm_reclen, 16, 65535, + "Maximum number of bytes in SHM log record.\n" + "Maximum is 65535 bytes.", + 0, + "255", "bytes" }, + { "default_grace", tweak_timeout_double, &mgt_param.default_grace, + 0, UINT_MAX, + "Default grace period. We will deliver an object " + "this long after it has expired, provided another thread " + "is attempting to get a new copy.\n" + "Objects already cached will not be affected by changes " + "made until they are fetched from the backend again.\n", + DELAYED_EFFECT, + "10", "seconds" }, + { "default_keep", tweak_timeout_double, &mgt_param.default_keep, + 0, UINT_MAX, + "Default keep period. We will keep a useless object " + "around this long, making it available for conditional " + "backend fetches. " + "That means that the object will be removed from the " + "cache at the end of ttl+grace+keep.", + DELAYED_EFFECT, + "0", "seconds" }, + { "timeout_idle", tweak_timeout_double, &mgt_param.timeout_idle, + 0, UINT_MAX, + "Idle timeout for client connections.\n" + "A connection is considered idle, until we receive" + " a non-white-space character on it.", + 0, + "5", "seconds" }, + { "timeout_req", tweak_timeout_double, &mgt_param.timeout_req, + 0, UINT_MAX, + "Max time to receive clients request header, measured" + " from first non-white-space character to double CRNL.", + 0, + "2", "seconds" }, + { "expiry_sleep", tweak_timeout_double, &mgt_param.expiry_sleep, 0, 60, + "How long the expiry thread sleeps when there is nothing " + "for it to do.\n", + 0, + "1", "seconds" }, + { "pipe_timeout", tweak_timeout, &mgt_param.pipe_timeout, 0, 0, + "Idle timeout for PIPE sessions. " + "If nothing have been received in either direction for " + "this many seconds, the session is closed.\n", + 0, + "60", "seconds" }, + { "send_timeout", tweak_timeout, &mgt_param.send_timeout, 0, 0, + "Send timeout for client connections. " + "If the HTTP response hasn't been transmitted in this many\n" + "seconds the session is closed. \n" + "See setsockopt(2) under SO_SNDTIMEO for more information.", + DELAYED_EFFECT, + "600", "seconds" }, + { "idle_send_timeout", tweak_timeout, &mgt_param.idle_send_timeout, + 0, 0, + "Time to wait with no data sent. " + "If no data has been transmitted in this many\n" + "seconds the session is closed. \n" + "See setsockopt(2) under SO_SNDTIMEO for more information.", + DELAYED_EFFECT, + "60", "seconds" }, + { "auto_restart", tweak_bool, &mgt_param.auto_restart, 0, 0, + "Restart child process automatically if it dies.\n", + 0, + "on", "bool" }, + { "nuke_limit", + tweak_uint, &mgt_param.nuke_limit, 0, UINT_MAX, + "Maximum number of objects we attempt to nuke in order" + "to make space for a object body.", + EXPERIMENTAL, + "50", "allocations" }, + { "fetch_chunksize", + tweak_bytes, + &mgt_param.fetch_chunksize, 4 * 1024, UINT_MAX, + "The default chunksize used by fetcher. " + "This should be bigger than the majority of objects with " + "short TTLs.\n" + "Internal limits in the storage_file module makes increases " + "above 128kb a dubious idea.", + EXPERIMENTAL, + "128k", "bytes" }, + { "fetch_maxchunksize", + tweak_bytes, + &mgt_param.fetch_maxchunksize, 64 * 1024, UINT_MAX, + "The maximum chunksize we attempt to allocate from storage. " + "Making this too large may cause delays and storage " + "fragmentation.\n", + EXPERIMENTAL, + "256m", "bytes" }, + { "accept_filter", tweak_bool, &mgt_param.accept_filter, 0, 0, + "Enable kernel accept-filters, if supported by the kernel.", + MUST_RESTART, + "on", "bool" }, + { "listen_address", tweak_listen_address, NULL, 0, 0, + "Whitespace separated list of network endpoints where " + "Varnish will accept requests.\n" + "Possible formats: host, host:port, :port", + MUST_RESTART, + ":80" }, + { "listen_depth", tweak_uint, &mgt_param.listen_depth, 0, UINT_MAX, + "Listen queue depth.", + MUST_RESTART, + "1024", "connections" }, + { "cli_buffer", + tweak_bytes_u, &mgt_param.cli_buffer, 4096, UINT_MAX, + "Size of buffer for CLI command input." + "\nYou may need to increase this if you have big VCL files " + "and use the vcl.inline CLI command.\n" + "NB: Must be specified with -p to have effect.\n", + 0, + "8k", "bytes" }, + { "cli_limit", + tweak_bytes_u, &mgt_param.cli_limit, 128, 99999999, + "Maximum size of CLI response. If the response exceeds" + " this limit, the reponse code will be 201 instead of" + " 200 and the last line will indicate the truncation.", + 0, + "48k", "bytes" }, + { "cli_timeout", tweak_timeout, &mgt_param.cli_timeout, 0, 0, + "Timeout for the childs replies to CLI requests from " + "the mgt_param.", + 0, + "10", "seconds" }, + { "ping_interval", tweak_uint, &mgt_param.ping_interval, 0, UINT_MAX, + "Interval between pings from parent to child.\n" + "Zero will disable pinging entirely, which makes " + "it possible to attach a debugger to the child.", + MUST_RESTART, + "3", "seconds" }, + { "lru_interval", tweak_timeout, &mgt_param.lru_timeout, 0, 0, + "Grace period before object moves on LRU list.\n" + "Objects are only moved to the front of the LRU " + "list if they have not been moved there already inside " + "this timeout period. This reduces the amount of lock " + "operations necessary for LRU list access.", + EXPERIMENTAL, + "2", "seconds" }, + { "cc_command", tweak_string, &mgt_cc_cmd, 0, 0, + "Command used for compiling the C source code to a " + "dlopen(3) loadable object. Any occurrence of %s in " + "the string will be replaced with the source file name, " + "and %o will be replaced with the output file name.", + MUST_RELOAD, + VCC_CC , NULL }, + { "max_restarts", tweak_uint, &mgt_param.max_restarts, 0, UINT_MAX, + "Upper limit on how many times a request can restart." + "\nBe aware that restarts are likely to cause a hit against " + "the backend, so don't increase thoughtlessly.\n", + 0, + "4", "restarts" }, + { "esi_syntax", + tweak_uint, &mgt_param.esi_syntax, 0, UINT_MAX, + "Bitmap controlling ESI parsing code:\n" + " 0x00000001 - Don't check if it looks like XML\n" + " 0x00000002 - Ignore non-esi elements\n" + " 0x00000004 - Emit parsing debug records\n" + " 0x00000008 - Force-split parser input (debugging)\n" + "\n" + "Use 0x notation and do the bitor in your head :-)\n", + 0, + "0", "bitmap" }, + { "max_esi_depth", + tweak_uint, &mgt_param.max_esi_depth, 0, UINT_MAX, + "Maximum depth of esi:include processing.\n", + 0, + "5", "levels" }, + { "connect_timeout", tweak_timeout_double, + &mgt_param.connect_timeout,0, UINT_MAX, + "Default connection timeout for backend connections. " + "We only try to connect to the backend for this many " + "seconds before giving up. " + "VCL can override this default value for each backend and " + "backend request.", + 0, + "0.7", "s" }, + { "first_byte_timeout", tweak_timeout_double, + &mgt_param.first_byte_timeout,0, UINT_MAX, + "Default timeout for receiving first byte from backend. " + "We only wait for this many seconds for the first " + "byte before giving up. A value of 0 means it will never time " + "out. " + "VCL can override this default value for each backend and " + "backend request. This parameter does not apply to pipe.", + 0, + "60", "s" }, + { "between_bytes_timeout", tweak_timeout_double, + &mgt_param.between_bytes_timeout,0, UINT_MAX, + "Default timeout between bytes when receiving data from " + "backend. " + "We only wait for this many seconds between bytes " + "before giving up. A value of 0 means it will never time out. " + "VCL can override this default value for each backend request " + "and backend request. This parameter does not apply to pipe.", + 0, + "60", "s" }, + { "acceptor_sleep_max", tweak_timeout_double, + &mgt_param.acceptor_sleep_max, 0, 10, + "If we run out of resources, such as file descriptors or " + "worker threads, the acceptor will sleep between accepts.\n" + "This parameter limits how long it can sleep between " + "attempts to accept new connections.", + EXPERIMENTAL, + "0.050", "s" }, + { "acceptor_sleep_incr", tweak_timeout_double, + &mgt_param.acceptor_sleep_incr, 0, 1, + "If we run out of resources, such as file descriptors or " + "worker threads, the acceptor will sleep between accepts.\n" + "This parameter control how much longer we sleep, each time " + "we fail to accept a new connection.", + EXPERIMENTAL, + "0.001", "s" }, + { "acceptor_sleep_decay", tweak_generic_double, + &mgt_param.acceptor_sleep_decay, 0, 1, + "If we run out of resources, such as file descriptors or " + "worker threads, the acceptor will sleep between accepts.\n" + "This parameter (multiplicatively) reduce the sleep duration " + "for each succesfull accept. (ie: 0.9 = reduce by 10%)", + EXPERIMENTAL, + "0.900", "" }, + { "clock_skew", tweak_uint, &mgt_param.clock_skew, 0, UINT_MAX, + "How much clockskew we are willing to accept between the " + "backend and our own clock.", + 0, + "10", "s" }, + { "prefer_ipv6", tweak_bool, &mgt_param.prefer_ipv6, 0, 0, + "Prefer IPv6 address when connecting to backends which " + "have both IPv4 and IPv6 addresses.", + 0, + "off", "bool" }, + { "session_max", tweak_uint, + &mgt_param.max_sess, 1000, UINT_MAX, + "Maximum number of sessions we will allocate from one pool " + "before just dropping connections.\n" + "This is mostly an anti-DoS measure, and setting it plenty " + "high should not hurt, as long as you have the memory for " + "it.\n", + 0, + "100000", "sessions" }, + { "timeout_linger", tweak_timeout_double, &mgt_param.timeout_linger, + 0, UINT_MAX, + "How long time the workerthread lingers on an idle session " + "before handing it over to the waiter.\n" + "When sessions are reused, as much as half of all reuses " + "happen within the first 100 msec of the previous request " + "completing.\n" + "Setting this too high results in worker threads not doing " + "anything for their keep, setting it too low just means that " + "more sessions take a detour around the waiter.", + EXPERIMENTAL, + "0.050", "seconds" }, + { "log_local_address", tweak_bool, &mgt_param.log_local_addr, 0, 0, + "Log the local address on the TCP connection in the " + "SessionOpen VSL record.\n" + "Disabling this saves a getsockname(2) system call " + "per TCP connection.\n", + 0, + "on", "bool" }, + { "waiter", tweak_waiter, NULL, 0, 0, + "Select the waiter kernel interface.\n", + WIZARD | MUST_RESTART, + WAITER_DEFAULT, NULL }, + { "ban_dups", tweak_bool, &mgt_param.ban_dups, 0, 0, + "Detect and eliminate duplicate bans.\n", + 0, + "on", "bool" }, + { "syslog_cli_traffic", tweak_bool, &mgt_param.syslog_cli_traffic, 0, 0, + "Log all CLI traffic to syslog(LOG_INFO).\n", + 0, + "on", "bool" }, + { "ban_lurker_sleep", tweak_timeout_double, + &mgt_param.ban_lurker_sleep, 0, UINT_MAX, + "How long time does the ban lurker thread sleeps between " + "successful attempts to push the last item up the ban " + " list. It always sleeps a second when nothing can be done.\n" + "A value of zero disables the ban lurker.", + 0, + "0.01", "s" }, + { "saintmode_threshold", tweak_uint, + &mgt_param.saintmode_threshold, 0, UINT_MAX, + "The maximum number of objects held off by saint mode before " + "no further will be made to the backend until one times out. " + "A value of 0 disables saintmode.", + EXPERIMENTAL, + "10", "objects" }, + { "http_range_support", tweak_bool, &mgt_param.http_range_support, 0, 0, + "Enable support for HTTP Range headers.\n", + 0, + "on", "bool" }, + { "http_gzip_support", tweak_bool, &mgt_param.http_gzip_support, 0, 0, + "Enable gzip support. When enabled Varnish will compress " + "uncompressed objects before they are stored in the cache. " + "If a client does not support gzip encoding Varnish will " + "uncompress compressed objects on demand. Varnish will also " + "rewrite the Accept-Encoding header of clients indicating " + "support for gzip to:\n" + " Accept-Encoding: gzip\n\n" + "Clients that do not support gzip will have their " + "Accept-Encoding header removed. For more information on how " + "gzip is implemented please see the chapter on gzip in the " + "Varnish reference.", + EXPERIMENTAL, + "on", "bool" }, + { "gzip_level", tweak_uint, &mgt_param.gzip_level, 0, 9, + "Gzip compression level: 0=debug, 1=fast, 9=best", + 0, + "6", ""}, + { "gzip_memlevel", tweak_uint, &mgt_param.gzip_memlevel, 1, 9, + "Gzip memory level 1=slow/least, 9=fast/most compression.\n" + "Memory impact is 1=1k, 2=2k, ... 9=256k.", + 0, + "8", ""}, + { "gzip_buffer", + tweak_bytes_u, &mgt_param.gzip_buffer, + 2048, UINT_MAX, + "Size of malloc buffer used for gzip processing.\n" + "These buffers are used for in-transit data," + " for instance gunzip'ed data being sent to a client." + "Making this space to small results in more overhead," + " writes to sockets etc, making it too big is probably" + " just a waste of memory.", + EXPERIMENTAL, + "32k", "bytes" }, + { "shortlived", tweak_timeout_double, + &mgt_param.shortlived, 0, UINT_MAX, + "Objects created with TTL shorter than this are always " + "put in transient storage.\n", + 0, + "10.0", "s" }, + { "critbit_cooloff", tweak_timeout_double, + &mgt_param.critbit_cooloff, 60, 254, + "How long time the critbit hasher keeps deleted objheads " + "on the cooloff list.\n", + WIZARD, + "180.0", "s" }, + { "vcl_dir", tweak_string, &mgt_vcl_dir, 0, 0, + "Directory from which relative VCL filenames (vcl.load and " + "include) are opened.", + 0, +#ifdef VARNISH_VCL_DIR + VARNISH_VCL_DIR, +#else + ".", +#endif + NULL }, + { "vmod_dir", tweak_string, &mgt_vmod_dir, 0, 0, + "Directory where VCL modules are to be found.", + 0, +#ifdef VARNISH_VMOD_DIR + VARNISH_VMOD_DIR, +#else + ".", +#endif + NULL }, + + { "vcc_err_unref", tweak_bool, &mgt_vcc_err_unref, 0, 0, + "Unreferenced VCL objects result in error.\n", + 0, + "on", "bool" }, + + { "vcc_allow_inline_c", tweak_bool, &mgt_vcc_allow_inline_c, 0, 0, + "Allow inline C code in VCL.\n", + 0, + "on", "bool" }, + + { "vcc_unsafe_path", tweak_bool, &mgt_vcc_unsafe_path, 0, 0, + "Allow '/' in vmod & include paths.\n" + "Allow 'import ... from ...'.\n", + 0, + "on", "bool" }, + + { "pcre_match_limit", tweak_uint, + &mgt_param.vre_limits.match, + 1, UINT_MAX, + "The limit for the number of internal matching function" + " calls in a pcre_exec() execution.", + 0, + "10000", ""}, + + { "pcre_match_limit_recursion", tweak_uint, + &mgt_param.vre_limits.match_recursion, + 1, UINT_MAX, + "The limit for the number of internal matching function" + " recursions in a pcre_exec() execution.", + 0, + "10000", ""}, + + { "vsl_space", tweak_bytes, + &mgt_param.vsl_space, 1024*1024, 0, + "The amount of space to allocate for the VSL fifo buffer" + " in the VSM memory segment." + " If you make this too small, varnish{ncsa|log} etc will" + " not be able to keep up." + " Making it too large just costs memory resources.", + MUST_RESTART, + "80M", "bytes"}, + + { "vsm_space", tweak_bytes, + &mgt_param.vsm_space, 1024*1024, 0, + "The amount of space to allocate for stats counters" + " in the VSM memory segment." + " If you make this too small, some counters will be" + " invisible." + " Making it too large just costs memory resources.", + MUST_RESTART, + "1M", "bytes"}, + + { "busyobj_worker_cache", tweak_bool, + &mgt_param.bo_cache, 0, 0, + "Cache free busyobj per worker thread." + "Disable this if you have very high hitrates and want" + "to save the memory of one busyobj per worker thread.", + 0, + "false", ""}, + + { "pool_vbc", tweak_poolparam, &mgt_param.vbc_pool, 0, 10000, + "Parameters for backend connection memory pool.\n" + MEMPOOL_TEXT, + 0, + "10,100,10", ""}, + + { "pool_req", tweak_poolparam, &mgt_param.req_pool, 0, 10000, + "Parameters for per worker pool request memory pool.\n" + MEMPOOL_TEXT, + 0, + "10,100,10", ""}, + { "pool_sess", tweak_poolparam, &mgt_param.sess_pool, 0, 10000, + "Parameters for per worker pool session memory pool.\n" + MEMPOOL_TEXT, + 0, + "10,100,10", ""}, + { "pool_vbo", tweak_poolparam, &mgt_param.vbo_pool, 0, 10000, + "Parameters for backend object fetch memory pool.\n" + MEMPOOL_TEXT, + 0, + "10,100,10", ""}, + + { "obj_readonly", tweak_bool, &mgt_param.obj_readonly, 0, 0, + "If set, we do not update obj.hits and obj.lastuse to" + "avoid dirtying VM pages associated with cached objects.", + 0, + "false", ""}, + + { NULL, NULL, NULL } +}; From phk at varnish-cache.org Tue Jan 8 11:23:54 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 08 Jan 2013 12:23:54 +0100 Subject: [master] 6afc5a4 Make it possible to truly change a parameters default value, rather than hackishly just setting its value to the wanted default. Message-ID: commit 6afc5a44affb38d844fb76df03a803b28c540f23 Author: Poul-Henning Kamp Date: Tue Jan 8 11:23:13 2013 +0000 Make it possible to truly change a parameters default value, rather than hackishly just setting its value to the wanted default. Fixes #1244 diff --git a/bin/varnishd/mgt/mgt.h b/bin/varnishd/mgt/mgt.h index 905fbcc..b66e729 100644 --- a/bin/varnishd/mgt/mgt.h +++ b/bin/varnishd/mgt/mgt.h @@ -67,7 +67,9 @@ struct choice { const void *pick(const struct choice *cp, const char *which, const char *kind); /* mgt_param.c */ -void MCF_ParamInit(struct cli *); +void MCF_InitParams(struct cli *); +void MCF_CollectParams(void); +void MCF_SetDefault(const char *param, const char *def); void MCF_ParamSet(struct cli *, const char *param, const char *val); void MCF_ParamProtect(struct cli *, const char *arg); void MCF_DumpRstParam(void); diff --git a/bin/varnishd/mgt/mgt_main.c b/bin/varnishd/mgt/mgt_main.c index 2b3c709..b5829a9 100644 --- a/bin/varnishd/mgt/mgt_main.c +++ b/bin/varnishd/mgt/mgt_main.c @@ -378,29 +378,22 @@ main(int argc, char * const *argv) VTAILQ_INIT(&heritage.socks); - MCF_ParamInit(cli); + MCF_CollectParams(); if (sizeof(void *) < 8) { /* * Adjust default parameters for 32 bit systems to conserve * VM space. */ - MCF_ParamSet(cli, "workspace_client", "24k"); - cli_check(cli); - - MCF_ParamSet(cli, "workspace_backend", "16k"); - cli_check(cli); - - MCF_ParamSet(cli, "http_resp_size", "8k"); - cli_check(cli); - - MCF_ParamSet(cli, "http_req_size", "12k"); - cli_check(cli); - - MCF_ParamSet(cli, "gzip_buffer", "4k"); - cli_check(cli); + MCF_SetDefault("workspace_client", "24k"); + MCF_SetDefault("workspace_backend", "16k"); + MCF_SetDefault("http_resp_size", "8k"); + MCF_SetDefault("http_req_size", "12k"); + MCF_SetDefault("gzip_buffer", "4k"); } + MCF_InitParams(cli); + cli_check(cli); while ((o = getopt(argc, argv, diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 97e3f4e..b7baafd 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -879,12 +879,19 @@ MCF_SetDefaults(struct cli *cli) /*--------------------------------------------------------------------*/ void -MCF_ParamInit(struct cli *cli) +MCF_CollectParams(void) { MCF_AddParams(mgt_parspec); MCF_AddParams(WRK_parspec); MCF_AddParams(VSL_parspec); +} + +/*--------------------------------------------------------------------*/ + +void +MCF_InitParams(struct cli *cli) +{ /* XXX: We do this twice, to get past any interdependencies */ MCF_SetDefaults(NULL); @@ -894,6 +901,25 @@ MCF_ParamInit(struct cli *cli) /*--------------------------------------------------------------------*/ void +MCF_SetDefault(const char *param, const char *def) +{ + struct parspec *pn; + int i; + + for (i = 0; i < nparspec; i++) + if (!strcmp(parspecs[i]->name, param)) + break; + assert(i < nparspec); + pn = malloc(sizeof *pn); + AN(pn); + *pn = *(parspecs[i]); + pn->def = def; + parspecs[i] = pn; +} + +/*--------------------------------------------------------------------*/ + +void MCF_DumpRstParam(void) { const struct parspec *pp; From phk at varnish-cache.org Tue Jan 8 12:00:04 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 08 Jan 2013 13:00:04 +0100 Subject: [master] dabcce2 Use the new param-default-setting ability, to simplify the magic surrounding the privsep user/group setting code. Message-ID: commit dabcce2cd278dc2a710777b90ada2aeff0cbadaa Author: Poul-Henning Kamp Date: Tue Jan 8 11:59:08 2013 +0000 Use the new param-default-setting ability, to simplify the magic surrounding the privsep user/group setting code. Fixes #1243 diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index b7baafd..6ce53eb 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -388,36 +388,25 @@ void tweak_user(struct cli *cli, const struct parspec *par, const char *arg) { struct passwd *pw; - struct group *gr; (void)par; if (arg != NULL) { - if (!strcmp(arg, MAGIC_INIT_STRING)) { - pw = getpwnam("nobody"); + if (*arg != '\0') { + pw = getpwnam(arg); if (pw == NULL) { - mgt_param.uid = getuid(); + VCLI_Out(cli, "Unknown user"); + VCLI_SetResult(cli, CLIS_PARAM); return; } - } else - pw = getpwnam(arg); - if (pw == NULL) { - VCLI_Out(cli, "Unknown user"); - VCLI_SetResult(cli, CLIS_PARAM); - return; + REPLACE(mgt_param.user, pw->pw_name); + mgt_param.uid = pw->pw_uid; + } else { + mgt_param.uid = getuid(); } - REPLACE(mgt_param.user, pw->pw_name); - mgt_param.uid = pw->pw_uid; - mgt_param.gid = pw->pw_gid; - - /* set group to user's primary group */ - if ((gr = getgrgid(pw->pw_gid)) != NULL && - (gr = getgrnam(gr->gr_name)) != NULL && - gr->gr_gid == pw->pw_gid) - REPLACE(mgt_param.group, gr->gr_name); } else if (mgt_param.user) { VCLI_Out(cli, "%s (%d)", mgt_param.user, (int)mgt_param.uid); } else { - VCLI_Out(cli, "%d", (int)mgt_param.uid); + VCLI_Out(cli, "UID %d", (int)mgt_param.uid); } } @@ -432,27 +421,22 @@ tweak_group(struct cli *cli, const struct parspec *par, const char *arg) (void)par; if (arg != NULL) { - if (!strcmp(arg, MAGIC_INIT_STRING)) { - gr = getgrnam("nogroup"); + if (*arg != '\0') { + gr = getgrnam(arg); if (gr == NULL) { - /* Only replace if tweak_user didn't */ - if (mgt_param.gid == 0) - mgt_param.gid = getgid(); + VCLI_Out(cli, "Unknown group"); + VCLI_SetResult(cli, CLIS_PARAM); return; } - } else - gr = getgrnam(arg); - if (gr == NULL) { - VCLI_Out(cli, "Unknown group"); - VCLI_SetResult(cli, CLIS_PARAM); - return; + REPLACE(mgt_param.group, gr->gr_name); + mgt_param.gid = gr->gr_gid; + } else { + mgt_param.gid = getgid(); } - REPLACE(mgt_param.group, gr->gr_name); - mgt_param.gid = gr->gr_gid; } else if (mgt_param.group) { VCLI_Out(cli, "%s (%d)", mgt_param.group, (int)mgt_param.gid); } else { - VCLI_Out(cli, "%d", (int)mgt_param.gid); + VCLI_Out(cli, "GID %d", (int)mgt_param.gid); } } @@ -885,6 +869,12 @@ MCF_CollectParams(void) MCF_AddParams(mgt_parspec); MCF_AddParams(WRK_parspec); MCF_AddParams(VSL_parspec); + + /* If we have nobody/nogroup, use them as defaults */ + if (getpwnam("nobody") != NULL) + MCF_SetDefault("user", "nobody"); + if (getgrnam("nogroup") != NULL) + MCF_SetDefault("group", "nogroup"); } /*--------------------------------------------------------------------*/ @@ -933,8 +923,7 @@ MCF_DumpRstParam(void) printf("%s\n", pp->name); if (pp->units != NULL && *pp->units != '\0') printf("\t- Units: %s\n", pp->units); - printf("\t- Default: %s\n", - strcmp(pp->def,MAGIC_INIT_STRING) == 0 ? "magic" : pp->def); + printf("\t- Default: %s\n", pp->def); /* * XXX: we should mark the params with one/two flags * XXX: that say if ->min/->max are valid, so we diff --git a/bin/varnishd/mgt/mgt_param.h b/bin/varnishd/mgt/mgt_param.h index 04c9c4f..4026bb9 100644 --- a/bin/varnishd/mgt/mgt_param.h +++ b/bin/varnishd/mgt/mgt_param.h @@ -77,8 +77,6 @@ extern const struct parspec VSL_parspec[]; /* mgt_pool.c */ extern const struct parspec WRK_parspec[]; -#define MAGIC_INIT_STRING "\001" - #define MEMPOOL_TEXT \ "The three numbers are:\n" \ " min_pool -- minimum size of free pool.\n" \ diff --git a/bin/varnishd/mgt/mgt_param_tbl.c b/bin/varnishd/mgt/mgt_param_tbl.c index 96052c5..0e4e561 100644 --- a/bin/varnishd/mgt/mgt_param_tbl.c +++ b/bin/varnishd/mgt/mgt_param_tbl.c @@ -46,14 +46,13 @@ const struct parspec mgt_parspec[] = { { "user", tweak_user, NULL, 0, 0, - "The unprivileged user to run as. Setting this will " - "also set \"group\" to the specified user's primary group.", + "The unprivileged user to run as.", MUST_RESTART, - MAGIC_INIT_STRING }, + "" }, { "group", tweak_group, NULL, 0, 0, "The unprivileged group to run as.", MUST_RESTART, - MAGIC_INIT_STRING }, + "" }, { "default_ttl", tweak_timeout_double, &mgt_param.default_ttl, 0, UINT_MAX, "The TTL assigned to objects if neither the backend nor " From phk at varnish-cache.org Thu Jan 10 09:32:57 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Thu, 10 Jan 2013 10:32:57 +0100 Subject: [master] 703e7e6 Cast thread_t's all over the place in order to be able to printf them. Message-ID: commit 703e7e67e93a7c46f43ca37ff405aacba26990f8 Author: Poul-Henning Kamp Date: Thu Jan 10 09:31:56 2013 +0000 Cast thread_t's all over the place in order to be able to printf them. A more kosher solution might be pthread_getthreadid_np() on the platforms which support it, but I can't be bothered for three debugging printfs :-) Submitted by: Nils Goroll Fixes #932 diff --git a/bin/varnishreplay/varnishreplay.c b/bin/varnishreplay/varnishreplay.c index d8d19d5..d8f2877 100644 --- a/bin/varnishreplay/varnishreplay.c +++ b/bin/varnishreplay/varnishreplay.c @@ -182,7 +182,7 @@ thread_log(int lvl, int errcode, const char *fmt, ...) if (lvl > debug) return; pthread_mutex_lock(&log_mutex); - fprintf(stderr, "%p ", (void *)pthread_self()); + fprintf(stderr, "%p ", (void *)(uintptr_t)pthread_self()); va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); @@ -276,7 +276,7 @@ thread_get(int fd, void *(*thread_main)(void *)) } else { threads[fd]->fd = fd; thread_log(0, 0, "thread %p:%d started", - (void *)threads[fd]->thread_id, fd); + (void *)(uintptr_t)threads[fd]->thread_id, fd); } } if (threads[fd] == THREAD_FAIL) @@ -301,7 +301,7 @@ thread_close(int fd) mailbox_close(&threads[fd]->mbox); pthread_join(threads[fd]->thread_id, NULL); thread_log(0, 0, "thread %p stopped", - (void *)threads[fd]->thread_id); + (void *)(uintptr_t)threads[fd]->thread_id); thread_clear(threads[fd]); mailbox_destroy(&threads[fd]->mbox); freez(threads[fd]); From phk at varnish-cache.org Thu Jan 10 10:35:03 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Thu, 10 Jan 2013 11:35:03 +0100 Subject: [master] a54af58 A quick FlexeLint check to see that there are no major complaints Message-ID: commit a54af587f43251e616b7edc502e6bb08d589711d Author: Poul-Henning Kamp Date: Thu Jan 10 10:12:19 2013 +0000 A quick FlexeLint check to see that there are no major complaints diff --git a/bin/flint.lnt b/bin/flint.lnt index 18a8d27..1f99a4b 100644 --- a/bin/flint.lnt +++ b/bin/flint.lnt @@ -103,3 +103,10 @@ -elib(123) // macro def. with arg at, (just warn) -emacro(702, WEXITSTATUS) // signed shift right + +-e786 // String concatenation within initializer +-e726 // Extraneous comma ignored + +-e825 // control flows into case/default without -fallthrough comment +-e835 // A zero has been given as ___ argument to operator '___' (<<) + diff --git a/bin/varnishd/flint.lnt b/bin/varnishd/flint.lnt index f0dfd9a..0d810d2 100644 --- a/bin/varnishd/flint.lnt +++ b/bin/varnishd/flint.lnt @@ -77,7 +77,6 @@ -e459 // unlocked access from func-ptr -e454 // mutex not released (...ReleaseLocked) -e457 // unprotected access --e835 // A zero has been given as ___ argument to operator '___' (<<) -e777 // float equality comparison -e679 // Suspicious Truncation in arithmetic expression combining with pointer @@ -130,11 +129,9 @@ -e455 // thread lock -e458 // unprotected read -e763 // Redundant declaration for symbol '...' previously declared --e726 // Extraneous comma ignored -e728 // Symbol ... not explicitly initialized -e716 // while(1) ... -e785 // Too few initializers for aggregate --e786 // String concatenation within initializer -esym(765, vcc_ProcAction) // could be made static -esym(759, vcc_ProcAction) // could be moved to module diff --git a/bin/varnishlog/flint.lnt b/bin/varnishlog/flint.lnt index 3a0395c..7669aca 100644 --- a/bin/varnishlog/flint.lnt +++ b/bin/varnishlog/flint.lnt @@ -18,4 +18,4 @@ -e788 // enum constant '___' not used within defaulted switch -e641 // Converting enum '___' to '___' --esym(785,VSL_tags); // Sparse array +-esym(785,VSL_tags) // Sparse array diff --git a/bin/varnishlog/varnishlog.c b/bin/varnishlog/varnishlog.c index bf7d32b..07fef9b 100644 --- a/bin/varnishlog/varnishlog.c +++ b/bin/varnishlog/varnishlog.c @@ -128,7 +128,7 @@ h_order(void *priv, enum VSL_tag_e tag, unsigned fd, unsigned len, * starting on the new one. */ if (last[fd] != SLT_SessClose) - VSB_printf(ob[fd], "%5d %-12s %c %s\n", + VSB_printf(ob[fd], "%5u %-12s %c %s\n", fd, "Interrupted", type, VSL_tags[tag]); h_order_finish(fd, vd); } @@ -141,8 +141,8 @@ h_order(void *priv, enum VSL_tag_e tag, unsigned fd, unsigned len, VSB_cat(ob[fd], "\n"); else flg[fd] |= F_INVCL; - VSB_printf(ob[fd], "%5d %-12s %c %.*s", - fd, VSL_tags[tag], type, len, ptr); + VSB_printf(ob[fd], "%5u %-12s %c %.*s", + fd, VSL_tags[tag], type, (int)len, ptr); return (0); case SLT_VCL_trace: case SLT_VCL_return: @@ -159,8 +159,8 @@ h_order(void *priv, enum VSL_tag_e tag, unsigned fd, unsigned len, VSB_cat(ob[fd], "\n"); flg[fd] &= ~F_INVCL; } - VSB_printf(ob[fd], "%5d %-12s %c %.*s\n", - fd, VSL_tags[tag], type, len, ptr); + VSB_printf(ob[fd], "%5u %-12s %c %.*s\n", + fd, VSL_tags[tag], type, (int)len, ptr); switch (tag) { case SLT_ReqEnd: case SLT_BackendClose: diff --git a/bin/varnishncsa/base64.c b/bin/varnishncsa/base64.c index a631098..1c0979a 100644 --- a/bin/varnishncsa/base64.c +++ b/bin/varnishncsa/base64.c @@ -6,10 +6,6 @@ #include "config.h" -#include - -#include // for test-prog - #include "base64.h" static const char b64[] = @@ -63,6 +59,8 @@ VB64_decode(char *d, unsigned dlen, const char *s) #ifdef TEST_DRIVER +#include // for test-prog + const char *test1 = "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz" "IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg" diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index f885985..2a4bc21 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -77,7 +77,6 @@ #include "vcs.h" #include "vpf.h" #include "vqueue.h" -#include "vre.h" #include "vsb.h" #include "compat/daemon.h" @@ -112,7 +111,7 @@ static struct logline { VTAILQ_HEAD(, hdr) vcl_log; /* VLC_Log entries */ } **ll; -struct VSM_data *vd; +static struct VSM_data *vd; static size_t nll; @@ -210,7 +209,6 @@ req_header(struct logline *l, const char *name) VTAILQ_FOREACH(h, &l->req_headers, list) { if (strcasecmp(h->key, name) == 0) { return (h->value); - break; } } return (NULL); @@ -223,7 +221,6 @@ resp_header(struct logline *l, const char *name) VTAILQ_FOREACH(h, &l->resp_headers, list) { if (strcasecmp(h->key, name) == 0) { return (h->value); - break; } } return (NULL); @@ -236,7 +233,6 @@ vcl_log(struct logline *l, const char *name) VTAILQ_FOREACH(h, &l->vcl_log, list) { if (strcasecmp(h->key, name) == 0) { return (h->value); - break; } } return (NULL); @@ -796,6 +792,7 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, p = tmp; break; } + /* FALLTHROUGH */ default: fprintf(stderr, "Unknown format starting at: %s\n", --p); @@ -923,7 +920,8 @@ main(int argc, char *argv[]) /* XXX: Silently ignored: it's required anyway */ break; case 'm': - m_flag = 1; /* Fall through */ + m_flag = 1; + /* FALLTHOUGH */ default: if (VSL_Arg(vd, c, optarg) > 0) break; From phk at varnish-cache.org Thu Jan 10 10:35:03 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Thu, 10 Jan 2013 11:35:03 +0100 Subject: [master] 8fa24e2 Match output for boolean params to the default value so we can choose to present on/off or true/false, depending on what makes most sense. Message-ID: commit 8fa24e2043d62401ebb8bc22508b6b72613a32c9 Author: Poul-Henning Kamp Date: Thu Jan 10 10:34:13 2013 +0000 Match output for boolean params to the default value so we can choose to present on/off or true/false, depending on what makes most sense. Fixes #1245 diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 6ce53eb..2966d09 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -187,9 +187,16 @@ tweak_generic_double(struct cli *cli, const struct parspec *par, /*--------------------------------------------------------------------*/ -static void -tweak_generic_bool(struct cli *cli, volatile unsigned *dest, const char *arg) +void +tweak_bool(struct cli *cli, const struct parspec *par, const char *arg) { + volatile unsigned *dest; + int mode = 0; + + if (!strcmp(par->def, "off") || !strcmp(par->def, "on")) + mode = 1; + + dest = par->priv; if (arg != NULL) { if (!strcasecmp(arg, "off")) *dest = 0; @@ -208,23 +215,18 @@ tweak_generic_bool(struct cli *cli, volatile unsigned *dest, const char *arg) else if (!strcasecmp(arg, "true")) *dest = 1; else { - VCLI_Out(cli, "use \"on\" or \"off\"\n"); + VCLI_Out(cli, + mode ? + "use \"on\" or \"off\"\n" : + "use \"true\" or \"false\"\n"); VCLI_SetResult(cli, CLIS_PARAM); return; } - } else + } else if (mode) { VCLI_Out(cli, *dest ? "on" : "off"); -} - -/*--------------------------------------------------------------------*/ - -void -tweak_bool(struct cli *cli, const struct parspec *par, const char *arg) -{ - volatile unsigned *dest; - - dest = par->priv; - tweak_generic_bool(cli, dest, arg); + } else { + VCLI_Out(cli, *dest ? "true" : "false"); + } } /*--------------------------------------------------------------------*/ diff --git a/bin/varnishd/mgt/mgt_param_tbl.c b/bin/varnishd/mgt/mgt_param_tbl.c index 0e4e561..cb54111 100644 --- a/bin/varnishd/mgt/mgt_param_tbl.c +++ b/bin/varnishd/mgt/mgt_param_tbl.c @@ -556,7 +556,7 @@ const struct parspec mgt_parspec[] = { "Disable this if you have very high hitrates and want" "to save the memory of one busyobj per worker thread.", 0, - "false", ""}, + "off", "bool"}, { "pool_vbc", tweak_poolparam, &mgt_param.vbc_pool, 0, 10000, "Parameters for backend connection memory pool.\n" @@ -582,9 +582,9 @@ const struct parspec mgt_parspec[] = { { "obj_readonly", tweak_bool, &mgt_param.obj_readonly, 0, 0, "If set, we do not update obj.hits and obj.lastuse to" - "avoid dirtying VM pages associated with cached objects.", + " avoid dirtying VM pages associated with cached objects.", 0, - "false", ""}, + "false", "bool"}, { NULL, NULL, NULL } }; From phk at varnish-cache.org Mon Jan 14 08:55:30 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 14 Jan 2013 09:55:30 +0100 Subject: [master] a5ce998 Split the http_max_hdr parameter into http_resp_max_hdr and http_req_max_hdr. Message-ID: commit a5ce9982d87a4398b45886f74306a0ed4d6b1829 Author: Poul-Henning Kamp Date: Mon Jan 14 08:55:09 2013 +0000 Split the http_max_hdr parameter into http_resp_max_hdr and http_req_max_hdr. diff --git a/bin/varnishd/cache/cache_busyobj.c b/bin/varnishd/cache/cache_busyobj.c index 0691b83..4bf5ad2 100644 --- a/bin/varnishd/cache/cache_busyobj.c +++ b/bin/varnishd/cache/cache_busyobj.c @@ -113,7 +113,7 @@ VBO_GetBusyObj(struct worker *wrk, struct req *req) p = (void*)PRNDUP(p); assert(p < bo->end); - nhttp = (uint16_t)cache_param->http_max_hdr; + nhttp = (uint16_t)cache_param->http_resp_max_hdr; sz = HTTP_estimate(nhttp); bo->bereq = HTTP_create(p, nhttp); diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 547755a..946d867 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -274,7 +274,7 @@ cnt_error(struct worker *wrk, struct req *req) req->objcore = HSH_NewObjCore(wrk); req->obj = STV_NewObject(bo, &req->objcore, TRANSIENT_STORAGE, cache_param->http_resp_size, - (uint16_t)cache_param->http_max_hdr); + (uint16_t)cache_param->http_req_max_hdr); bo->stats = NULL; if (req->obj == NULL) { req->doclose = SC_OVERLOAD; diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index 5fae4dd..40416a0 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -365,7 +365,7 @@ SES_GetReq(struct worker *wrk, struct sess *sp) p = (void*)PRNDUP(p); assert(p < e); - nhttp = (uint16_t)cache_param->http_max_hdr; + nhttp = (uint16_t)cache_param->http_req_max_hdr; hl = HTTP_estimate(nhttp); req->http = HTTP_create(p, nhttp); diff --git a/bin/varnishd/common/params.h b/bin/varnishd/common/params.h index a6e881b..42e169f 100644 --- a/bin/varnishd/common/params.h +++ b/bin/varnishd/common/params.h @@ -98,9 +98,10 @@ struct params { unsigned shm_workspace; unsigned http_req_size; unsigned http_req_hdr_len; + unsigned http_req_max_hdr; unsigned http_resp_size; unsigned http_resp_hdr_len; - unsigned http_max_hdr; + unsigned http_resp_max_hdr; unsigned shm_reclen; diff --git a/bin/varnishd/mgt/mgt_param_tbl.c b/bin/varnishd/mgt/mgt_param_tbl.c index cb54111..e5d709f 100644 --- a/bin/varnishd/mgt/mgt_param_tbl.c +++ b/bin/varnishd/mgt/mgt_param_tbl.c @@ -86,6 +86,7 @@ const struct parspec mgt_parspec[] = { " just wastes the space.\n", DELAYED_EFFECT, "2048", "bytes" }, + { "http_req_hdr_len", tweak_bytes_u, &mgt_param.http_req_hdr_len, 40, UINT_MAX, @@ -104,6 +105,16 @@ const struct parspec mgt_parspec[] = { "how much of that the request is allowed to take up.", 0, "32k", "bytes" }, + { "http_req_max_hdr", tweak_uint, &mgt_param.http_req_max_hdr, + 32, 65535, + "Maximum number of HTTP headers we will deal with in " + "client request. " + "Note that the first line occupies five header fields.\n" + "This parameter does not influence storage consumption, " + "objects allocate exact space for the headers they store.\n", + 0, + "64", "header lines" }, + { "http_resp_hdr_len", tweak_bytes_u, &mgt_param.http_resp_hdr_len, 40, UINT_MAX, @@ -122,14 +133,16 @@ const struct parspec mgt_parspec[] = { "limits how much of that the request is allowed to take up.", 0, "32k", "bytes" }, - { "http_max_hdr", tweak_uint, &mgt_param.http_max_hdr, 32, 65535, + { "http_resp_max_hdr", tweak_uint, &mgt_param.http_resp_max_hdr, + 32, 65535, "Maximum number of HTTP headers we will deal with in " - "client request or backend reponses. " + "backend response. " "Note that the first line occupies five header fields.\n" "This parameter does not influence storage consumption, " "objects allocate exact space for the headers they store.\n", 0, "64", "header lines" }, + { "vsl_buffer", tweak_bytes_u, &mgt_param.vsl_buffer, 1024, UINT_MAX, "Bytes of (req-/backend-)workspace dedicated to buffering" From phk at varnish-cache.org Mon Jan 14 09:14:08 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 14 Jan 2013 10:14:08 +0100 Subject: [master] de16dba Drop counter client_drop_late, it is already counted in sess_drop, and the counter had race issues. Message-ID: commit de16dba24abf2d24678e3d7a438ad0341ad1dde3 Author: Poul-Henning Kamp Date: Mon Jan 14 09:13:12 2013 +0000 Drop counter client_drop_late, it is already counted in sess_drop, and the counter had race issues. Polish vsc_f_main.h a bit while here diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index 40416a0..51d9bc4 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -257,7 +257,6 @@ SES_ScheduleReq(struct req *req) sp->task.priv = req; if (Pool_Task(pp->pool, &sp->task, POOL_QUEUE_FRONT)) { - VSC_C_main->client_drop_late++; AN (req->vcl); VCL_Rel(&req->vcl); SES_Delete(sp, SC_OVERLOAD, NAN); @@ -281,10 +280,8 @@ SES_Handle(struct sess *sp, double now) AN(pp->pool); sp->task.func = ses_sess_pool_task; sp->task.priv = sp; - if (Pool_Task(pp->pool, &sp->task, POOL_QUEUE_FRONT)) { - VSC_C_main->client_drop_late++; + if (Pool_Task(pp->pool, &sp->task, POOL_QUEUE_FRONT)) SES_Delete(sp, SC_OVERLOAD, now); - } } /*-------------------------------------------------------------------- diff --git a/include/tbl/vsc_f_main.h b/include/tbl/vsc_f_main.h index d9c78ce..133025e 100644 --- a/include/tbl/vsc_f_main.h +++ b/include/tbl/vsc_f_main.h @@ -57,19 +57,28 @@ * */ +/*-------------------------------------------------------------------- + * Globals, not related to traffic + */ + +VSC_F(uptime, uint64_t, 0, 'a', + "Child process uptime", + "" +) + + /*--------------------------------------------------------------------- * Sessions - * see: cache_acceptor.c and cache_pool.c */ VSC_F(sess_conn, uint64_t, 1, 'c', "Sessions accepted", "Count of sessions succesfully accepted" ) + VSC_F(sess_drop, uint64_t, 1, 'c', "Sessions dropped", - "Count of sessions silently dropped due to lack of session memory." - " See parameter 'max_sess'." + "Count of sessions silently dropped due to lack of worker thread." ) VSC_F(sess_fail, uint64_t, 1, 'c', @@ -366,6 +375,8 @@ VSC_F(sess_herd, uint64_t, 1, 'a', "" ) +/*--------------------------------------------------------------------*/ + VSC_F(shm_records, uint64_t, 0, 'a', "SHM records", "" @@ -387,6 +398,8 @@ VSC_F(shm_cycles, uint64_t, 0, 'a', "" ) +/*--------------------------------------------------------------------*/ + VSC_F(sms_nreq, uint64_t, 0, 'a', "SMS allocator requests", "" @@ -408,11 +421,15 @@ VSC_F(sms_bfree, uint64_t, 0, 'i', "" ) +/*--------------------------------------------------------------------*/ + VSC_F(backend_req, uint64_t, 0, 'a', "Backend requests made", "" ) +/*--------------------------------------------------------------------*/ + VSC_F(n_vcl, uint64_t, 0, 'a', "N vcl total", "" @@ -426,7 +443,7 @@ VSC_F(n_vcl_discard, uint64_t, 0, 'a', "" ) -/**********************************************************************/ +/*--------------------------------------------------------------------*/ VSC_F(bans, uint64_t, 0, 'g', "Count of bans", @@ -468,7 +485,7 @@ VSC_F(bans_dups, uint64_t, 0, 'c', "Count of bans replaced by later identical bans." ) -/**********************************************************************/ +/*--------------------------------------------------------------------*/ VSC_F(hcb_nolock, uint64_t, 1, 'a', "HCB Lookups without lock", @@ -483,6 +500,8 @@ VSC_F(hcb_insert, uint64_t, 0, 'a', "" ) +/*--------------------------------------------------------------------*/ + VSC_F(esi_errors, uint64_t, 0, 'a', "ESI parse errors (unlock)", "" @@ -491,14 +510,8 @@ VSC_F(esi_warnings, uint64_t, 0, 'a', "ESI parse warnings (unlock)", "" ) -VSC_F(client_drop_late, uint64_t, 0, 'a', - "Connection dropped late", - "" -) -VSC_F(uptime, uint64_t, 0, 'a', - "Client uptime", - "" -) + +/*--------------------------------------------------------------------*/ VSC_F(dir_dns_lookups, uint64_t, 0, 'a', "DNS director lookups", @@ -517,11 +530,15 @@ VSC_F(dir_dns_cache_full, uint64_t, 0, 'a', "" ) +/*--------------------------------------------------------------------*/ + VSC_F(vmods, uint64_t, 0, 'i', "Loaded VMODs", "" ) +/*--------------------------------------------------------------------*/ + VSC_F(n_gzip, uint64_t, 0, 'a', "Gzip operations", "" @@ -531,7 +548,7 @@ VSC_F(n_gunzip, uint64_t, 0, 'a', "" ) -/**********************************************************************/ +/*--------------------------------------------------------------------*/ VSC_F(vsm_free, uint64_t, 0, 'g', "Free VSM space", From phk at varnish-cache.org Mon Jan 14 10:51:14 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 14 Jan 2013 11:51:14 +0100 Subject: [master] 4a1b92b Revert a5ce9982d87a4398b45886f74306a0ed4d6b1829, there is no net benefit from hair-splitting the number of http headers we support. Improve description to bring this point home, in case I ever get that silly idea again. Message-ID: commit 4a1b92bfb275fc4842f5319c4e855572ca25e8fb Author: Poul-Henning Kamp Date: Mon Jan 14 10:50:25 2013 +0000 Revert a5ce9982d87a4398b45886f74306a0ed4d6b1829, there is no net benefit from hair-splitting the number of http headers we support. Improve description to bring this point home, in case I ever get that silly idea again. diff --git a/bin/varnishd/cache/cache_busyobj.c b/bin/varnishd/cache/cache_busyobj.c index 4bf5ad2..0691b83 100644 --- a/bin/varnishd/cache/cache_busyobj.c +++ b/bin/varnishd/cache/cache_busyobj.c @@ -113,7 +113,7 @@ VBO_GetBusyObj(struct worker *wrk, struct req *req) p = (void*)PRNDUP(p); assert(p < bo->end); - nhttp = (uint16_t)cache_param->http_resp_max_hdr; + nhttp = (uint16_t)cache_param->http_max_hdr; sz = HTTP_estimate(nhttp); bo->bereq = HTTP_create(p, nhttp); diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 946d867..547755a 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -274,7 +274,7 @@ cnt_error(struct worker *wrk, struct req *req) req->objcore = HSH_NewObjCore(wrk); req->obj = STV_NewObject(bo, &req->objcore, TRANSIENT_STORAGE, cache_param->http_resp_size, - (uint16_t)cache_param->http_req_max_hdr); + (uint16_t)cache_param->http_max_hdr); bo->stats = NULL; if (req->obj == NULL) { req->doclose = SC_OVERLOAD; diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index 51d9bc4..2873066 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -362,7 +362,7 @@ SES_GetReq(struct worker *wrk, struct sess *sp) p = (void*)PRNDUP(p); assert(p < e); - nhttp = (uint16_t)cache_param->http_req_max_hdr; + nhttp = (uint16_t)cache_param->http_max_hdr; hl = HTTP_estimate(nhttp); req->http = HTTP_create(p, nhttp); diff --git a/bin/varnishd/common/params.h b/bin/varnishd/common/params.h index 42e169f..a6e881b 100644 --- a/bin/varnishd/common/params.h +++ b/bin/varnishd/common/params.h @@ -98,10 +98,9 @@ struct params { unsigned shm_workspace; unsigned http_req_size; unsigned http_req_hdr_len; - unsigned http_req_max_hdr; unsigned http_resp_size; unsigned http_resp_hdr_len; - unsigned http_resp_max_hdr; + unsigned http_max_hdr; unsigned shm_reclen; diff --git a/bin/varnishd/mgt/mgt_param_tbl.c b/bin/varnishd/mgt/mgt_param_tbl.c index e5d709f..8601bae 100644 --- a/bin/varnishd/mgt/mgt_param_tbl.c +++ b/bin/varnishd/mgt/mgt_param_tbl.c @@ -86,7 +86,6 @@ const struct parspec mgt_parspec[] = { " just wastes the space.\n", DELAYED_EFFECT, "2048", "bytes" }, - { "http_req_hdr_len", tweak_bytes_u, &mgt_param.http_req_hdr_len, 40, UINT_MAX, @@ -105,16 +104,6 @@ const struct parspec mgt_parspec[] = { "how much of that the request is allowed to take up.", 0, "32k", "bytes" }, - { "http_req_max_hdr", tweak_uint, &mgt_param.http_req_max_hdr, - 32, 65535, - "Maximum number of HTTP headers we will deal with in " - "client request. " - "Note that the first line occupies five header fields.\n" - "This parameter does not influence storage consumption, " - "objects allocate exact space for the headers they store.\n", - 0, - "64", "header lines" }, - { "http_resp_hdr_len", tweak_bytes_u, &mgt_param.http_resp_hdr_len, 40, UINT_MAX, @@ -133,16 +122,14 @@ const struct parspec mgt_parspec[] = { "limits how much of that the request is allowed to take up.", 0, "32k", "bytes" }, - { "http_resp_max_hdr", tweak_uint, &mgt_param.http_resp_max_hdr, - 32, 65535, - "Maximum number of HTTP headers we will deal with in " - "backend response. " - "Note that the first line occupies five header fields.\n" - "This parameter does not influence storage consumption, " - "objects allocate exact space for the headers they store.\n", + { "http_max_hdr", tweak_uint, &mgt_param.http_max_hdr, 32, 65535, + "Maximum number of HTTP header lines we allow in " + "{req|resp|bereq|beresp}.http " + "(obj.http is autosized to the exact number of headers).\n" + "Cheap, ~20 bytes, in terms of workspace memory.\n" + "Note that the first line occupies five header lines.\n", 0, "64", "header lines" }, - { "vsl_buffer", tweak_bytes_u, &mgt_param.vsl_buffer, 1024, UINT_MAX, "Bytes of (req-/backend-)workspace dedicated to buffering" From phk at varnish-cache.org Mon Jan 14 13:55:41 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 14 Jan 2013 14:55:41 +0100 Subject: [master] fcd46ae Distinguish between headers we receive (VSL_BogoHeader) and headers we generate (VSL_LostHeader). Message-ID: commit fcd46ae397d7cb18b7cad9cb2067b25813a1230a Author: Poul-Henning Kamp Date: Mon Jan 14 13:54:25 2013 +0000 Distinguish between headers we receive (VSL_BogoHeader) and headers we generate (VSL_LostHeader). Add counters for requests received with 400, 413 and 417 errors. Inspired by: patch from Lasse diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index 91ab200..eb5ad7e 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -518,8 +518,7 @@ http_dissect_hdrs(struct http *hp, char *p, const struct http_conn *htc) } if (q - p > htc->maxhdr) { - VSC_C_main->losthdr++; - VSLb(hp->vsl, SLT_LostHeader, "%.*s", + VSLb(hp->vsl, SLT_BogoHeader, "%.*s", (int)(q - p > 20 ? 20 : q - p), p); return (413); } @@ -544,8 +543,7 @@ http_dissect_hdrs(struct http *hp, char *p, const struct http_conn *htc) http_VSLH(hp, hp->nhd); hp->nhd++; } else { - VSC_C_main->losthdr++; - VSLb(hp->vsl, SLT_LostHeader, "%.*s", + VSLb(hp->vsl, SLT_BogoHeader, "%.*s", (int)(q - p > 20 ? 20 : q - p), p); return (413); } @@ -558,10 +556,20 @@ http_dissect_hdrs(struct http *hp, char *p, const struct http_conn *htc) */ static uint16_t -http_splitline(struct http *hp, - const struct http_conn *htc, int h1, int h2, int h3) +http_splitline(struct http *hp, const struct http_conn *htc, int req) { char *p, *q; + int h1, h2, h3; + + 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_RESPONSE; + } CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); @@ -663,8 +671,7 @@ http_DissectRequest(struct req *req) hp = req->http; CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); - retval = http_splitline(hp, htc, - HTTP_HDR_METHOD, HTTP_HDR_URL, HTTP_HDR_PROTO); + retval = http_splitline(hp, htc, 1); if (retval != 0) { VSLbt(req->vsl, SLT_HttpGarbage, htc->rxbuf); return (retval); @@ -686,8 +693,7 @@ http_DissectResponse(struct http *hp, const struct http_conn *htc) CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); - if (http_splitline(hp, htc, - HTTP_HDR_PROTO, HTTP_HDR_STATUS, HTTP_HDR_RESPONSE)) + if (http_splitline(hp, htc, 0)) retval = 503; if (retval == 0 && memcmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.", 7)) diff --git a/bin/varnishd/cache/cache_http1_fsm.c b/bin/varnishd/cache/cache_http1_fsm.c index e6b12ee..87771d5 100644 --- a/bin/varnishd/cache/cache_http1_fsm.c +++ b/bin/varnishd/cache/cache_http1_fsm.c @@ -262,11 +262,10 @@ http1_dissect(struct worker *wrk, struct req *req) /* If we could not even parse the request, just close */ if (req->err_code == 400) { + wrk->stats.client_req_400++; SES_Close(req->sp, SC_RX_JUNK); return (1); } - - wrk->stats.client_req++; req->acct_req.req++; req->ws_req = WS_Snapshot(req->ws); @@ -275,12 +274,17 @@ http1_dissect(struct worker *wrk, struct req *req) /* XXX: Expect headers are a mess */ if (req->err_code == 0 && http_GetHdr(req->http, H_Expect, &p)) { if (strcasecmp(p, "100-continue")) { + wrk->stats.client_req_417++; req->err_code = 417; } else if (strlen(r) != write(req->sp->fd, r, strlen(r))) { SES_Close(req->sp, SC_REM_CLOSE); return (1); } - } + } else if (req->err_code == 413) + wrk->stats.client_req_413++; + else + wrk->stats.client_req++; + http_Unset(req->http, H_Expect); /* XXX: pull in req-body and make it available instead. */ req->reqbodydone = 0; diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 2966d09..ebb784d 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -216,7 +216,7 @@ tweak_bool(struct cli *cli, const struct parspec *par, const char *arg) *dest = 1; else { VCLI_Out(cli, - mode ? + mode ? "use \"on\" or \"off\"\n" : "use \"true\" or \"false\"\n"); VCLI_SetResult(cli, CLIS_PARAM); diff --git a/include/tbl/vsc_f_main.h b/include/tbl/vsc_f_main.h index 133025e..c266f50 100644 --- a/include/tbl/vsc_f_main.h +++ b/include/tbl/vsc_f_main.h @@ -90,11 +90,29 @@ VSC_F(sess_fail, uint64_t, 1, 'c', /*---------------------------------------------------------------------*/ +VSC_F(client_req_400, uint64_t, 1, 'a', + "Client requests received, subject to 400 errors", + "400 means we couldn't make sense of the request, it was" + " malformed in some drastic way." +) + +VSC_F(client_req_413, uint64_t, 1, 'a', + "Client requests received, subject to 413 errors", + "413 means that HTTP headers execeeded length or count limits." +) + +VSC_F(client_req_417, uint64_t, 1, 'a', + "Client requests received, subject to 417 errors", + "417 means that something went wrong with an Expect: header." +) + VSC_F(client_req, uint64_t, 1, 'a', - "Client requests received", + "Good Client requests received", "" ) +/*---------------------------------------------------------------------*/ + VSC_F(cache_hit, uint64_t, 1, 'a', "Cache hits", "Count of cache hits. " @@ -110,6 +128,7 @@ VSC_F(cache_hitpass, uint64_t, 1, 'a', " cached in it self. This counts how many times the cached " " decision is being used." ) + VSC_F(cache_miss, uint64_t, 1, 'a', "Cache misses", "Count of misses" @@ -117,6 +136,8 @@ VSC_F(cache_miss, uint64_t, 1, 'a', " backend before delivering it to the backend." ) +/*---------------------------------------------------------------------*/ + VSC_F(backend_conn, uint64_t, 0, 'a', "Backend conn. success", "" diff --git a/include/tbl/vsl_tags.h b/include/tbl/vsl_tags.h index bdf840d..3f43bc1 100644 --- a/include/tbl/vsl_tags.h +++ b/include/tbl/vsl_tags.h @@ -130,7 +130,11 @@ SLTM(FetchError, "Error while fetching object", "") #include "tbl/vsl_tags_http.h" #undef SLTH -SLTM(LostHeader, "", "") +SLTM(BogoHeader, "Bogus HTTP received", + "Contains the first 20 characters of received HTTP headers we could" + " not make sense of. Applies to both req.http and beres.http." +) +SLTM(LostHeader, "Failed attempt to set HTTP header", "") SLTM(TTL, "TTL set on object", "") SLTM(Fetch_Body, "Body fetched from backend", "") From phk at varnish-cache.org Tue Jan 15 14:14:39 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 15 Jan 2013 15:14:39 +0100 Subject: [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. Message-ID: commit 12085db88f5842dbe08d9517989415d11514ec24 Author: Poul-Henning Kamp 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; \ From phk at varnish-cache.org Tue Jan 15 14:44:02 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 15 Jan 2013 15:44:02 +0100 Subject: [master] b5d0779 Make discarding the request body a dedicated function, since we may be able to orderly terminate/prevent the transmission in future protocols. Message-ID: commit b5d07794ba931d75f98f9c186040bac5db1b158c Author: Poul-Henning Kamp Date: Tue Jan 15 14:43:28 2013 +0000 Make discarding the request body a dedicated function, since we may be able to orderly terminate/prevent the transmission in future protocols. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index ba9e482..a9af09a 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -778,6 +778,7 @@ void VBO_Free(struct busyobj **vbo); /* cache_http1_fsm.c [HTTP1] */ ssize_t HTTP1_GetReqBody(struct req *, void *buf, ssize_t len); +int HTTP1_DiscardReqBody(struct req *req); void HTTP1_Session(struct worker *, struct req *); /* cache_req_fsm.c [CNT] */ @@ -815,7 +816,6 @@ int FetchError(struct busyobj *, const char *error); int FetchError2(struct busyobj *, const char *error, const char *more); int FetchHdr(struct req *req, int need_host_hdr, int sendbody); void FetchBody(struct worker *w, void *bo); -int FetchReqBody(struct req *, int sendbody); void Fetch_Init(void); /* cache_gzip.c */ diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 50a654c..b8ab6ca 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -44,6 +44,8 @@ static unsigned fetchfrag; +static int fetchReqBody(struct req *req, int sendbody); + /*-------------------------------------------------------------------- * We want to issue the first error we encounter on fetching and * supress the rest. This function does that. @@ -377,8 +379,8 @@ fetch_eof(struct busyobj *bo, struct http_conn *htc) * to contain the complexity when we start handling chunked encoding. */ -int -FetchReqBody(struct req *req, int sendbody) +static int +fetchReqBody(struct req *req, int sendbody) { char buf[8192]; ssize_t l = 1234; @@ -467,7 +469,7 @@ FetchHdr(struct req *req, int need_host_hdr, int sendbody) (void)http_Write(wrk, hp, 0); /* XXX: stats ? */ /* Deal with any message-body the request might have */ - i = FetchReqBody(req, sendbody); + i = fetchReqBody(req, sendbody); if (sendbody && req->req_body_status == REQ_BODY_DONE) retry = -1; if (WRW_FlushRelease(wrk) || i > 0) { diff --git a/bin/varnishd/cache/cache_http1_fsm.c b/bin/varnishd/cache/cache_http1_fsm.c index c9b8d8f..3696081 100644 --- a/bin/varnishd/cache/cache_http1_fsm.c +++ b/bin/varnishd/cache/cache_http1_fsm.c @@ -375,6 +375,27 @@ HTTP1_Session(struct worker *wrk, struct req *req) } } +/* + * XXX: DiscardReqBody() is a dedicated function, because we might + * XXX: be able to disuade or terminate its transmission in some protocols. + */ + +int +HTTP1_DiscardReqBody(struct req *req) +{ + char buf[8192]; + ssize_t l; + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + 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); + } + return (0); +} + ssize_t HTTP1_GetReqBody(struct req *req, void *buf, ssize_t len) { diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index fe76777..3d5693d 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -727,7 +727,7 @@ cnt_hit(struct worker *wrk, struct req *req) if (req->handling == VCL_RET_DELIVER) { //AZ(req->busyobj->bereq->ws); //AZ(req->busyobj->beresp->ws); - (void)FetchReqBody(req, 0); + (void)HTTP1_DiscardReqBody(req); // XXX: handle err req->req_step = R_STP_PREPRESP; return (0); } From phk at varnish-cache.org Mon Jan 21 20:29:28 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 21 Jan 2013 21:29:28 +0100 Subject: [master] d175906 A minor code-move, in anticipation of things yet to come. Message-ID: commit d175906ede4d051bf8f644e65bd7840b6fe0b10b Author: Poul-Henning Kamp Date: Mon Jan 21 20:29:13 2013 +0000 A minor code-move, in anticipation of things yet to come. diff --git a/bin/varnishd/storage/stevedore.c b/bin/varnishd/storage/stevedore.c index 63400eb..0416077 100644 --- a/bin/varnishd/storage/stevedore.c +++ b/bin/varnishd/storage/stevedore.c @@ -159,11 +159,42 @@ stv_pick_stevedore(struct vsl_log *vsl, const char **hint) /*-------------------------------------------------------------------*/ static struct storage * -stv_alloc(struct busyobj *bo, size_t size) +stv_alloc(struct stevedore *stv, size_t size) { struct storage *st; + + CHECK_OBJ_NOTNULL(stv, STEVEDORE_MAGIC); + + if (size > cache_param->fetch_maxchunksize) + size = cache_param->fetch_maxchunksize; + + assert(size <= UINT_MAX); /* field limit in struct storage */ + + for (;;) { + /* try to allocate from it */ + AN(stv->alloc); + st = stv->alloc(stv, size); + if (st != NULL) + break; + + if (size <= cache_param->fetch_chunksize) + break; + + size >>= 1; + } + if (st != NULL) + CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC); + return (st); +} + +/*-------------------------------------------------------------------*/ + +static struct storage * +stv_alloc_obj(struct busyobj *bo, size_t size) +{ + struct storage *st = NULL; struct stevedore *stv; - unsigned fail = 0; + unsigned fail; struct object *obj; /* @@ -181,24 +212,16 @@ stv_alloc(struct busyobj *bo, size_t size) assert(size <= UINT_MAX); /* field limit in struct storage */ - for (;;) { + for (fail = 0; fail <= cache_param->nuke_limit; fail++) { /* try to allocate from it */ AN(stv->alloc); - st = stv->alloc(stv, size); + st = stv_alloc(stv, size); if (st != NULL) break; - if (size > cache_param->fetch_chunksize) { - size >>= 1; - continue; - } - /* no luck; try to free some space and keep trying */ - if (EXP_NukeOne(bo, stv->lru) == -1) - break; - - /* Enough is enough: try another if we have one */ - if (++fail >= cache_param->nuke_limit) + if (fail < cache_param->nuke_limit && + EXP_NukeOne(bo, stv->lru) == -1) break; } if (st != NULL) @@ -390,7 +413,7 @@ struct storage * STV_alloc(struct busyobj *bo, size_t size) { - return (stv_alloc(bo, size)); + return (stv_alloc_obj(bo, size)); } void From phk at varnish-cache.org Mon Jan 21 20:50:18 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 21 Jan 2013 21:50:18 +0100 Subject: [master] 4c47a36 Fix a bug discovered by inspection: Message-ID: commit 4c47a36e9f8b7b2dfe7eff60c3fda418dc6effca Author: Poul-Henning Kamp Date: Mon Jan 21 20:49:46 2013 +0000 Fix a bug discovered by inspection: If we fail to allocate storage, try a smaller chunk, not a larger one. diff --git a/bin/varnishd/storage/stevedore.c b/bin/varnishd/storage/stevedore.c index 0416077..b9408cf 100644 --- a/bin/varnishd/storage/stevedore.c +++ b/bin/varnishd/storage/stevedore.c @@ -180,7 +180,7 @@ stv_alloc(struct stevedore *stv, size_t size) if (size <= cache_param->fetch_chunksize) break; - size >>= 1; + size <<= 1; } if (st != NULL) CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC); diff --git a/bin/varnishtest/tests/r01175.vtc b/bin/varnishtest/tests/r01175.vtc index 739c56a..5cac147 100644 --- a/bin/varnishtest/tests/r01175.vtc +++ b/bin/varnishtest/tests/r01175.vtc @@ -17,4 +17,4 @@ client c1 { expect resp.status == 503 } -run -varnish v1 -expect SMA.test.c_fail < 5 +varnish v1 -expect SMA.test.c_fail < 50 From phk at varnish-cache.org Mon Jan 21 20:55:59 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 21 Jan 2013 21:55:59 +0100 Subject: [master] e7025e7 Improve description Message-ID: commit e7025e7c00c232d6025d4271f63da76c2b2b9bc3 Author: Poul-Henning Kamp Date: Mon Jan 21 20:55:49 2013 +0000 Improve description diff --git a/bin/varnishtest/tests/r01175.vtc b/bin/varnishtest/tests/r01175.vtc index 5cac147..67e1354 100644 --- a/bin/varnishtest/tests/r01175.vtc +++ b/bin/varnishtest/tests/r01175.vtc @@ -1,4 +1,4 @@ -varnishtest "#1175 - -smalloc c_fail incremented by bytes" +varnishtest "#1175 - -smalloc c_fail incremented by allocations, not bytes" server s1 { rxreq From phk at varnish-cache.org Tue Jan 22 11:00:19 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 22 Jan 2013 12:00:19 +0100 Subject: [master] 98c23bb A restart in vcl_fetch{} needs to loose the objcore as well. Message-ID: commit 98c23bb1733b02e1d1fad65fd5212ae04ced865d Author: Poul-Henning Kamp Date: Tue Jan 22 11:00:00 2013 +0000 A restart in vcl_fetch{} needs to loose the objcore as well. Fixes #1253 diff --git a/bin/varnishtest/tests/r01253.vtc b/bin/varnishtest/tests/r01253.vtc new file mode 100644 index 0000000..c1d88ff --- /dev/null +++ b/bin/varnishtest/tests/r01253.vtc @@ -0,0 +1,26 @@ +varnishtest "restarting a pass in vcl_fetch should not panic" + +server s1 { + rxreq + txresp -status 304 -body "1234" + accept + rxreq + txresp -status 200 -body "56" +} -start + +varnish v1 -vcl+backend { + sub vcl_recv { + return (pass); + } + sub vcl_fetch { + if (beresp.status != 200) { + return (restart); + } + } +} -start + +client c1 { + txreq + rxresp + expect resp.bodylen == 2 +} -run From phk at varnish-cache.org Tue Jan 22 11:01:06 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 22 Jan 2013 12:01:06 +0100 Subject: [master] 67a7b98 Also include the actual fix for 1253... Message-ID: commit 67a7b98e8ecb5e36fde9918717da8823837ed261 Author: Poul-Henning Kamp Date: Tue Jan 22 11:00:51 2013 +0000 Also include the actual fix for 1253... diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 3d5693d..8925610 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -430,7 +430,9 @@ cnt_fetch(struct worker *wrk, struct req *req) /* Clean up partial fetch */ AZ(bo->vbc); - if (req->objcore->objhead != NULL || req->handling == VCL_RET_ERROR) { + if (req->objcore->objhead != NULL || + req->handling == VCL_RET_RESTART || + req->handling == VCL_RET_ERROR) { CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); AZ(HSH_Deref(&wrk->stats, req->objcore, NULL)); req->objcore = NULL; @@ -1088,6 +1090,7 @@ cnt_recv(const struct worker *wrk, struct req *req) CHECK_OBJ_NOTNULL(req, REQ_MAGIC); CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); AZ(req->obj); + AZ(req->objcore); AZ(req->busyobj); VSLb(req->vsl, SLT_ReqStart, "%s %s", req->sp->addr, req->sp->port); From phk at varnish-cache.org Tue Jan 22 11:12:57 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 22 Jan 2013 12:12:57 +0100 Subject: [master] 2f831e5 Make it possible to expect on the req.bodylen as well. Message-ID: commit 2f831e5570af1e94d427d42d0f413a252e0fcdd4 Author: Poul-Henning Kamp Date: Tue Jan 22 11:12:42 2013 +0000 Make it possible to expect on the req.bodylen as well. diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index 4d71ae9..cc49568 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -189,6 +189,8 @@ cmd_var_resolve(struct http *hp, char *spec) return(hp->resp[2]); if (!strcmp(spec, "resp.chunklen")) return(hp->chunklen); + if (!strcmp(spec, "req.bodylen")) + return(hp->bodylen); if (!strcmp(spec, "resp.bodylen")) return(hp->bodylen); if (!strcmp(spec, "resp.body")) From phk at varnish-cache.org Tue Jan 22 11:36:26 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 22 Jan 2013 12:36:26 +0100 Subject: [master] fc09259 Fix a buglet which prevented req.body from being shown. Message-ID: commit fc0925900dfdd0bfa83d41135679a90ba7661fde Author: Poul-Henning Kamp Date: Tue Jan 22 11:36:09 2013 +0000 Fix a buglet which prevented req.body from being shown. diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index cc49568..a7c128c 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -448,6 +448,7 @@ http_swallow_body(struct http *hp, char * const *hh, int body) ll = 0; p = http_find_header(hh, "content-length"); if (p != NULL) { + hp->body = hp->rxbuf + hp->prxbuf; l = strtoul(p, NULL, 0); (void)http_rxchar(hp, l, 0); vtc_dump(hp->vl, 4, "body", hp->body, l); From phk at varnish-cache.org Tue Jan 22 12:02:37 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 22 Jan 2013 13:02:37 +0100 Subject: [master] daf0e2c Revamp the req.body handling code. Message-ID: commit daf0e2c19a5a9ef5147ef2d82acb94db2381a24f Author: Poul-Henning Kamp Date: Tue Jan 22 12:01:14 2013 +0000 Revamp the req.body handling code. There now is an undocumented facility for buffering the req.body, but I'm not done testing it, and in particular the error handling has not been exercised to any extent. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index a9af09a..f13218e 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -77,6 +77,14 @@ body_status(enum body_status e) /*--------------------------------------------------------------------*/ +enum req_body_state_e { +#define REQ_BODY(U) REQ_BODY_##U, +#include +#undef REQ_BODY +}; + +/*--------------------------------------------------------------------*/ + enum sess_close { SC_NULL = 0, #define SESS_CLOSE(nm, desc) SC_##nm, @@ -582,14 +590,6 @@ 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 @@ -605,6 +605,8 @@ struct req { enum req_step req_step; VTAILQ_ENTRY(req) w_list; + struct storagehead body; + /* The busy objhead we sleep on */ struct objhead *hash_objhead; struct busyobj *busyobj; @@ -777,9 +779,11 @@ 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); -int HTTP1_DiscardReqBody(struct req *req); +typedef int (req_body_iter_f)(struct req *, void *priv, void *ptr, size_t); 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); /* cache_req_fsm.c [CNT] */ int CNT_Request(struct worker *, struct req *); @@ -1074,6 +1078,7 @@ void STV_close(void); void STV_Freestore(struct object *o); int STV_BanInfo(enum baninfo event, const uint8_t *ban, unsigned len); void STV_BanExport(const uint8_t *bans, unsigned len); +struct storage *STV_alloc_transient(size_t size); /* storage_synth.c */ struct vsb *SMS_Makesynth(struct object *obj); diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index b8ab6ca..de66709 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -44,8 +44,6 @@ static unsigned fetchfrag; -static int fetchReqBody(struct req *req, int sendbody); - /*-------------------------------------------------------------------- * We want to issue the first error we encounter on fetching and * supress the rest. This function does that. @@ -373,39 +371,20 @@ fetch_eof(struct busyobj *bo, struct http_conn *htc) } /*-------------------------------------------------------------------- - * Fetch any body attached to the incoming request, and either write it - * to the backend (if we pass) or discard it (anything else). - * This is mainly a separate function to isolate the stack buffer and - * to contain the complexity when we start handling chunked encoding. + * Pass the request body to the backend */ -static int -fetchReqBody(struct req *req, int sendbody) +static int __match_proto__(req_body_iter_f) +fetch_iter_req_body(struct req *req, void *priv, void *ptr, size_t l) { - char buf[8192]; - ssize_t l = 1234; - if (req->req_body_status == REQ_BODY_DONE) { - AZ(sendbody); - return (0); - } - 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); - } - } + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + (void)priv; + + if (l > 0) { + (void)WRW_Write(req->wrk, ptr, l); + if (WRW_Flush(req->wrk)) + return (-1); } return (0); } @@ -468,11 +447,19 @@ FetchHdr(struct req *req, int need_host_hdr, int sendbody) WRW_Reserve(wrk, &vc->fd, bo->vsl, req->t_req); /* XXX t_resp ? */ (void)http_Write(wrk, hp, 0); /* XXX: stats ? */ - /* Deal with any message-body the request might have */ - i = fetchReqBody(req, sendbody); - if (sendbody && req->req_body_status == REQ_BODY_DONE) - retry = -1; - if (WRW_FlushRelease(wrk) || i > 0) { + /* Deal with any message-body the request might (still) have */ + i = 0; + + if (sendbody) { + i = HTTP1_IterateReqBody(req, + fetch_iter_req_body, NULL); + if (req->req_body_status == REQ_BODY_DONE) + retry = -1; + } else { + i = HTTP1_DiscardReqBody(req); + } + + if (WRW_FlushRelease(wrk) || i != 0) { VSLb(req->vsl, SLT_FetchError, "backend write error: %d (%s)", errno, strerror(errno)); diff --git a/bin/varnishd/cache/cache_http1_fsm.c b/bin/varnishd/cache/cache_http1_fsm.c index 3696081..18eb64b 100644 --- a/bin/varnishd/cache/cache_http1_fsm.c +++ b/bin/varnishd/cache/cache_http1_fsm.c @@ -80,7 +80,7 @@ #include "vtcp.h" #include "vtim.h" -/*-------------------------------------------------------------------- +/*---------------------------------------------------------------------- * Collect a request from the client. */ @@ -161,7 +161,7 @@ http1_wait(struct sess *sp, struct worker *wrk, struct req *req) return (1); } -/*-------------------------------------------------------------------- +/*---------------------------------------------------------------------- * This is the final state, figure out if we should close or recycle * the client connection */ @@ -235,7 +235,7 @@ http1_cleanup(struct sess *sp, struct worker *wrk, struct req *req) } } -/*-------------------------------------------------------------------- +/*---------------------------------------------------------------------- */ static int @@ -296,7 +296,7 @@ http1_dissect(struct worker *wrk, struct req *req) return (0); } -/*-------------------------------------------------------------------- +/*---------------------------------------------------------------------- */ void @@ -375,75 +375,225 @@ HTTP1_Session(struct worker *wrk, struct req *req) } } -/* - * XXX: DiscardReqBody() is a dedicated function, because we might - * XXX: be able to disuade or terminate its transmission in some protocols. - */ - -int -HTTP1_DiscardReqBody(struct req *req) -{ - char buf[8192]; - ssize_t l; +/*---------------------------------------------------------------------- + */ - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - 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); - } - return (0); -} +struct http1_r_b_s { + ssize_t bytes_done; + ssize_t yet; + enum {CL, CHUNKED} mode; +}; -ssize_t -HTTP1_GetReqBody(struct req *req, void *buf, ssize_t len) +static int +http1_setup_req_body(struct req *req, struct http1_r_b_s *rbs) { char *ptr, *endp; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + memset(rbs, 0, sizeof *rbs); - 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; + assert(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_FAIL; return (-1); - } else { + } + req->req_bodybytes = strtoul(ptr, &endp, 10); + if (*endp != '\0' && !vct_islws(*endp)) { + req->req_body_status = REQ_BODY_FAIL; + return (-1); + } + if (req->req_bodybytes == 0) { req->req_body_status = REQ_BODY_NONE; return (0); } + rbs->mode = CL; + rbs->yet = req->req_bodybytes - rbs->bytes_done; + return (0); } - if (req->req_body_status == REQ_BODY_CL) { - if (req->req_bodybytes == 0) { + + if (http_GetHdr(req->http, H_Transfer_Encoding, NULL)) { + rbs->mode = CHUNKED; + VSLb(req->vsl, SLT_Debug, + "Transfer-Encoding in request"); + req->req_body_status = REQ_BODY_DONE; + return (-1); + } + + req->req_body_status = REQ_BODY_NONE; + req->req_bodybytes = 0; + return (0); +} + +static ssize_t +http1_iter_req_body(struct req *req, struct http1_r_b_s *rbs, void *buf, + ssize_t len) +{ + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + + if (rbs->mode == CL) { + AN(req->req_bodybytes); + AN(len); + AN(buf); + if (len > req->req_bodybytes - rbs->bytes_done) + len = req->req_bodybytes - rbs->bytes_done; + if (len == 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; + req->req_body_status = REQ_BODY_FAIL; return (-1); } - req->req_bodybytes -= len; + rbs->bytes_done += len; + rbs->yet = req->req_bodybytes - rbs->bytes_done; return (len); } + INCOMPL(); +} + +/*---------------------------------------------------------------------- + * Iterate over the req.body. + * + * This can be done exactly once if uncached, and multiple times if the + * req.body is cached. + */ + +int +HTTP1_IterateReqBody(struct req *req, req_body_iter_f *func, void *priv) +{ + char buf[8192]; + struct storage *st; + ssize_t l; + int i; + struct http1_r_b_s rbs; + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + AN(func); + + if (req->req_body_status == REQ_BODY_CACHED) { + VTAILQ_FOREACH(st, &req->body, list) { + i = func(req, priv, st->ptr, st->len); + if (i) + return (i); + } + return (0); + } + + if (req->req_body_status == REQ_BODY_NONE) + return (0); + + if (req->req_body_status != REQ_BODY_INIT) + return (-1); + + i = http1_setup_req_body(req, &rbs); + if (i < 0) + return (i); + + if (req->req_body_status == REQ_BODY_NONE) + return (0); + + do { + l = http1_iter_req_body(req, &rbs, buf, sizeof buf); + if (l < 0) + return (l); + if (l > 0) { + i = func(req, priv, buf, l); + if (i) + return (i); + } + } while (l > 0); + return(0); +} + +/*---------------------------------------------------------------------- + * DiscardReqBody() is a dedicated function, because we might + * be able to disuade or terminate its transmission in some protocols. + * For HTTP1 we have no such luck, and we just iterate it into oblivion. + */ + +static int __match_proto__(req_body_iter_f) +httpq_req_body_discard(struct req *req, void *priv, void *ptr, size_t len) +{ + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + (void)priv; + (void)ptr; + (void)len; return (0); } + +int +HTTP1_DiscardReqBody(struct req *req) +{ + + return(HTTP1_IterateReqBody(req, httpq_req_body_discard, NULL)); +} + +/*---------------------------------------------------------------------- + * Cache the req.body if it is smaller than the given size + */ + +int +HTTP1_CacheReqBody(struct req *req, ssize_t maxsize) +{ + struct storage *st; + ssize_t l; + int i; + struct http1_r_b_s rbs; + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + + if (req->req_body_status == REQ_BODY_CACHED) + return (0); + + if (req->req_body_status == REQ_BODY_NONE) + return (0); + + if (req->req_body_status != REQ_BODY_INIT) + return (-1); + + i = http1_setup_req_body(req, &rbs); + if (i < 0) + return (i); + + if (req->req_bodybytes > maxsize) { + req->req_body_status = REQ_BODY_FAIL; + return (-1); + } + + if (req->req_body_status == REQ_BODY_NONE) + return (0); + + st = NULL; + do { + if (st == NULL) { + st = STV_alloc_transient( + rbs.yet ? rbs.yet : cache_param->fetch_chunksize); + if (st == NULL) { + req->req_body_status = REQ_BODY_FAIL; + return (-1); + } else { + VTAILQ_INSERT_TAIL(&req->body, st, list); + } + } + + l = st->space - st->len; + l = http1_iter_req_body(req, &rbs, st->ptr + st->len, l); + if (l < 0) + return (l); + if (req->req_bodybytes > maxsize) { + req->req_body_status = REQ_BODY_FAIL; + return (-1); + } + if (l > 0) { + st->len += l; + if (st->space == st->len) + st = NULL; + } + } while (l > 0); + req->req_body_status = REQ_BODY_CACHED; + return(0); +} diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index c93749f..cbb258b 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -232,7 +232,7 @@ pan_busyobj(const struct busyobj *bo) static void pan_req(const struct req *req) { - const char *hand, *stp; + const char *hand, *stp, *body; VSB_printf(pan_vsp, "req = %p {\n", req); @@ -249,6 +249,18 @@ pan_req(const struct req *req) else VSB_printf(pan_vsp, " step = 0x%x,\n", req->req_step); + switch (req->req_body_status) { +#define REQ_BODY(U) case REQ_BODY_##U: body = "R_BODY_" #U; break; +#include "tbl/req_body.h" +#undef REQ_BODY + default: body = NULL; + } + if (body != NULL) + VSB_printf(pan_vsp, " req_body = %s,\n", body); + else + VSB_printf(pan_vsp, " req_body = 0x%x,\n", + req->req_body_status); + hand = VCL_Return_Name(req->handling); if (hand != NULL) VSB_printf(pan_vsp, " handling = %s,\n", hand); diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 8925610..7ff0d41 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -1089,6 +1089,7 @@ cnt_recv(const struct worker *wrk, struct req *req) CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); + AZ(req->objcore); AZ(req->obj); AZ(req->objcore); AZ(req->busyobj); diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index 2257bab..f7a5a39 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -394,6 +394,8 @@ SES_GetReq(struct worker *wrk, struct sess *sp) req->t_req = NAN; req->t_resp = NAN; + VTAILQ_INIT(&req->body); + return (req); } diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c index 914531e..2c61900 100644 --- a/bin/varnishd/cache/cache_vrt.c +++ b/bin/varnishd/cache/cache_vrt.c @@ -512,6 +512,16 @@ VRT_ban_string(const struct req *req, const char *str) } /*-------------------------------------------------------------------- + * + */ + +int +VRT_CacheReqBody(struct req *req, long long maxsize) +{ + return (HTTP1_CacheReqBody(req, maxsize)); +} + +/*-------------------------------------------------------------------- * "real" purges */ diff --git a/bin/varnishd/storage/stevedore.c b/bin/varnishd/storage/stevedore.c index b9408cf..0b84a46 100644 --- a/bin/varnishd/storage/stevedore.c +++ b/bin/varnishd/storage/stevedore.c @@ -177,7 +177,7 @@ stv_alloc(struct stevedore *stv, size_t size) if (st != NULL) break; - if (size <= cache_param->fetch_chunksize) + if (size <= cache_param->fetch_chunksize) break; size <<= 1; @@ -416,6 +416,13 @@ STV_alloc(struct busyobj *bo, size_t size) return (stv_alloc_obj(bo, size)); } +struct storage * +STV_alloc_transient(size_t size) +{ + + return (stv_alloc(stv_transient, size)); +} + void STV_trim(struct storage *st, size_t size, int move_ok) { diff --git a/bin/varnishtest/tests/c00055.vtc b/bin/varnishtest/tests/c00055.vtc new file mode 100644 index 0000000..fb9a575 --- /dev/null +++ b/bin/varnishtest/tests/c00055.vtc @@ -0,0 +1,30 @@ +varnishtest "test caching of req.body" + +server s1 { + rxreq + expect req.bodylen == 3 + txresp -status 200 -hdr "Foo: BAR" -body "1234" + accept + rxreq + expect req.bodylen == 3 + txresp -status 200 -hdr "Foo: Foo" -body "56" +} -start + +varnish v1 -vcl+backend { + sub vcl_recv { + C{ VRT_CacheReqBody(req, 1000); }C + return (pass); + } + sub vcl_fetch { + if (beresp.http.foo == "BAR") { + return (restart); + } + } +} -start + +client c1 { + txreq -body "FOO" + rxresp + expect resp.http.Foo == "Foo" + expect resp.bodylen == 2 +} -run diff --git a/include/tbl/req_body.h b/include/tbl/req_body.h new file mode 100644 index 0000000..59f87fb --- /dev/null +++ b/include/tbl/req_body.h @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2013 Varnish Software AS + * All rights reserved. + * + * Author: Poul-Henning Kamp + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/*lint -save -e525 -e539 */ + +REQ_BODY(INIT) +REQ_BODY(CACHED) +REQ_BODY(DONE) +REQ_BODY(FAIL) +REQ_BODY(NONE) diff --git a/include/vrt.h b/include/vrt.h index c98e085..a2550aa 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -170,6 +170,10 @@ struct vrt_ref { void VRT_acl_log(struct req *, const char *msg); +/* req related */ + +int VRT_CacheReqBody(struct req *, long long maxsize); + /* Regexp related */ void VRT_re_init(void **, const char *); void VRT_re_fini(void *); From martin at varnish-cache.org Tue Jan 22 12:20:35 2013 From: martin at varnish-cache.org (Martin Blix Grydeland) Date: Tue, 22 Jan 2013 13:20:35 +0100 Subject: [master] cd4bb90 Ignore fd's larger than 65536 in varnishncsa Message-ID: commit cd4bb90edbaceef996a028620e7f35d6ecac3aa1 Author: Martin Blix Grydeland Date: Tue Jan 22 13:15:06 2013 +0100 Ignore fd's larger than 65536 in varnishncsa This makes varnishncsa behave the same way as varnishlog, and prevents overly large memory allocations if it should see a bogus fd (shmlog overrun?). XXX: This will not fix varnishncsa for current trunk, as that is using XIDs instead of FDs breaking some functionality in the tools. This will be handled in the API rewrite. diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index 2a4bc21..e9359cd 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -586,6 +586,10 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, const char *p; struct vsb *os; + /* XXX: Ignore fd's outside 65536 */ + if (fd >= 65536) + return (reopen); + if (fd >= nll) { struct logline **newll = ll; size_t newnll = nll; From martin at varnish-cache.org Tue Jan 22 12:35:32 2013 From: martin at varnish-cache.org (Martin Blix Grydeland) Date: Tue, 22 Jan 2013 13:35:32 +0100 Subject: [3.0] 4f58e8a Ignore fd's larger than 65536 in varnishncsa Message-ID: commit 4f58e8a7d8077d605198fde4e33c874737af4b53 Author: Martin Blix Grydeland Date: Tue Jan 22 13:15:06 2013 +0100 Ignore fd's larger than 65536 in varnishncsa This makes varnishncsa behave the same way as varnishlog, and prevents overly large memory allocations if it should see a bogus fd (shmlog overrun?). XXX: This will not fix varnishncsa for current trunk, as that is using XIDs instead of FDs breaking some functionality in the tools. This will be handled in the API rewrite. diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index f66bb18..dc7b4f9 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -584,6 +584,10 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, const char *p; struct vsb *os; + /* XXX: Ignore fd's outside 65536 */ + if (fd >= 65536) + return (reopen); + if (fd >= nll) { struct logline **newll = ll; size_t newnll = nll; From phk at varnish-cache.org Wed Jan 23 11:03:10 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 23 Jan 2013 12:03:10 +0100 Subject: [master] b2930e5 Give the state engine a explanatory enum, rather than magic values of 0, 1 and 2. Message-ID: commit b2930e5d73da0d722447210ef24134b7f6969f33 Author: Poul-Henning Kamp Date: Wed Jan 23 11:02:45 2013 +0000 Give the state engine a explanatory enum, rather than magic values of 0, 1 and 2. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index f13218e..27f2a12 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -57,6 +57,16 @@ #include "common/params.h" +/*--------------------------------------------------------------------*/ + +enum req_fsm_nxt { + REQ_FSM_MORE, + REQ_FSM_DONE, + REQ_FSM_DISEMBARK, +}; + +/*--------------------------------------------------------------------*/ + enum body_status { #define BODYSTATUS(U,l) BS_##U, #include "tbl/body_status.h" @@ -786,7 +796,7 @@ int HTTP1_CacheReqBody(struct req *req, ssize_t maxsize); int HTTP1_IterateReqBody(struct req *req, req_body_iter_f *func, void *priv); /* cache_req_fsm.c [CNT] */ -int CNT_Request(struct worker *, struct req *); +enum req_fsm_nxt CNT_Request(struct worker *, struct req *); /* cache_cli.c [CLI] */ void CLI_Init(void); diff --git a/bin/varnishd/cache/cache_http1_fsm.c b/bin/varnishd/cache/cache_http1_fsm.c index 18eb64b..83b0914 100644 --- a/bin/varnishd/cache/cache_http1_fsm.c +++ b/bin/varnishd/cache/cache_http1_fsm.c @@ -84,7 +84,7 @@ * Collect a request from the client. */ -static int +static enum req_fsm_nxt http1_wait(struct sess *sp, struct worker *wrk, struct req *req) { int j, tmo; @@ -120,7 +120,7 @@ http1_wait(struct sess *sp, struct worker *wrk, struct req *req) if (hs == HTC_COMPLETE) { /* Got it, run with it */ req->t_req = now; - return (0); + return (REQ_FSM_MORE); } else if (hs == HTC_ERROR_EOF) { why = SC_REM_CLOSE; break; @@ -141,7 +141,7 @@ http1_wait(struct sess *sp, struct worker *wrk, struct req *req) wrk->stats.sess_herd++; SES_ReleaseReq(req); WAIT_Enter(sp); - return (1); + return (REQ_FSM_DONE); } } else { /* Working on it */ @@ -158,7 +158,7 @@ http1_wait(struct sess *sp, struct worker *wrk, struct req *req) SES_ReleaseReq(req); assert(why != SC_NULL); SES_Delete(sp, why, now); - return (1); + return (REQ_FSM_DONE); } /*---------------------------------------------------------------------- @@ -238,7 +238,7 @@ http1_cleanup(struct sess *sp, struct worker *wrk, struct req *req) /*---------------------------------------------------------------------- */ -static int +static enum req_fsm_nxt http1_dissect(struct worker *wrk, struct req *req) { const char *r = "HTTP/1.1 100 Continue\r\n\r\n"; @@ -266,7 +266,7 @@ http1_dissect(struct worker *wrk, struct req *req) if (req->err_code == 400) { wrk->stats.client_req_400++; SES_Close(req->sp, SC_RX_JUNK); - return (1); + return (REQ_FSM_DONE); } req->acct_req.req++; @@ -280,7 +280,7 @@ http1_dissect(struct worker *wrk, struct req *req) req->err_code = 417; } else if (strlen(r) != write(req->sp->fd, r, strlen(r))) { SES_Close(req->sp, SC_REM_CLOSE); - return (1); + return (REQ_FSM_DONE); } } else if (req->err_code == 413) wrk->stats.client_req_413++; @@ -293,7 +293,7 @@ http1_dissect(struct worker *wrk, struct req *req) HTTP_Copy(req->http0, req->http); // For ESI & restart - return (0); + return (REQ_FSM_MORE); } /*---------------------------------------------------------------------- @@ -302,7 +302,7 @@ http1_dissect(struct worker *wrk, struct req *req) void HTTP1_Session(struct worker *wrk, struct req *req) { - int done = 0; + enum req_fsm_nxt nxt = REQ_FSM_MORE; struct sess *sp; enum http1_cleanup_ret sdr; @@ -343,12 +343,12 @@ HTTP1_Session(struct worker *wrk, struct req *req) if (sp->sess_step == S_STP_WORKING) { if (req->req_step == R_STP_RECV) - done = http1_dissect(wrk, req); - if (done == 0) - done = CNT_Request(wrk, req); - if (done == 2) + nxt = http1_dissect(wrk, req); + if (nxt == REQ_FSM_MORE) + nxt = CNT_Request(wrk, req); + if (nxt == REQ_FSM_DISEMBARK) return; - assert(done == 1); + assert(nxt == REQ_FSM_DONE); sdr = http1_cleanup(sp, wrk, req); switch (sdr) { case SESS_DONE_RET_GONE: @@ -366,8 +366,8 @@ HTTP1_Session(struct worker *wrk, struct req *req) } if (sp->sess_step == S_STP_NEWREQ) { - done = http1_wait(sp, wrk, req); - if (done) + nxt = http1_wait(sp, wrk, req); + if (nxt != REQ_FSM_MORE) return; sp->sess_step = S_STP_WORKING; req->req_step = R_STP_RECV; diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 7ff0d41..982e9de 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -91,7 +91,7 @@ DOT } * */ -static int +static enum req_fsm_nxt cnt_prepresp(struct worker *wrk, struct req *req) { struct busyobj *bo; @@ -175,12 +175,12 @@ cnt_prepresp(struct worker *wrk, struct req *req) AZ(req->obj); http_Teardown(req->resp); req->req_step = R_STP_RESTART; - return (0); + return (REQ_FSM_MORE); default: WRONG("Illegal action in vcl_deliver{}"); } req->req_step = R_STP_DELIVER; - return (0); + return (REQ_FSM_MORE); } /*-------------------------------------------------------------------- @@ -198,7 +198,7 @@ DOT deliver -> DONE [style=bold,color=blue] * */ -static int +static enum req_fsm_nxt cnt_deliver(struct worker *wrk, struct req *req) { struct busyobj *bo; @@ -219,7 +219,7 @@ cnt_deliver(struct worker *wrk, struct req *req) VBO_DerefBusyObj(wrk, &req->busyobj); req->err_code = 503; req->req_step = R_STP_ERROR; - return (0); + return (REQ_FSM_MORE); } VBO_DerefBusyObj(wrk, &req->busyobj); } @@ -237,7 +237,7 @@ cnt_deliver(struct worker *wrk, struct req *req) assert(WRW_IsReleased(wrk)); (void)HSH_Deref(&wrk->stats, NULL, &req->obj); http_Teardown(req->resp); - return (1); + return (REQ_FSM_DONE); } /*-------------------------------------------------------------------- * Emit an error @@ -254,7 +254,7 @@ DOT vcl_error-> rsterr [label="restart",color=purple] DOT rsterr [label="RESTART",shape=plaintext] */ -static int +static enum req_fsm_nxt cnt_error(struct worker *wrk, struct req *req) { struct http *h; @@ -281,7 +281,7 @@ cnt_error(struct worker *wrk, struct req *req) req->director = NULL; http_Teardown(bo->beresp); http_Teardown(bo->bereq); - return(1); + return (REQ_FSM_DONE); } CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); req->obj->vxid = bo->vsl->wid; @@ -309,7 +309,7 @@ cnt_error(struct worker *wrk, struct req *req) HSH_Drop(wrk, &req->obj); VBO_DerefBusyObj(wrk, &req->busyobj); req->req_step = R_STP_RESTART; - return (0); + return (REQ_FSM_MORE); } else if (req->handling == VCL_RET_RESTART) req->handling = VCL_RET_DELIVER; @@ -324,7 +324,7 @@ cnt_error(struct worker *wrk, struct req *req) http_Teardown(bo->bereq); VBO_DerefBusyObj(wrk, &req->busyobj); req->req_step = R_STP_PREPRESP; - return (0); + return (REQ_FSM_MORE); } /*-------------------------------------------------------------------- @@ -340,7 +340,7 @@ DOT fetch -> fetchbody [style=bold,color=red] DOT fetch -> fetchbody [style=bold,color=blue] */ -static int +static enum req_fsm_nxt cnt_fetch(struct worker *wrk, struct req *req) { int i, need_host_hdr; @@ -418,7 +418,7 @@ cnt_fetch(struct worker *wrk, struct req *req) switch (req->handling) { case VCL_RET_DELIVER: req->req_step = R_STP_FETCHBODY; - return (0); + return (REQ_FSM_MORE); default: break; } @@ -446,10 +446,10 @@ cnt_fetch(struct worker *wrk, struct req *req) switch (req->handling) { case VCL_RET_RESTART: req->req_step = R_STP_RESTART; - return (0); + return (REQ_FSM_MORE); case VCL_RET_ERROR: req->req_step = R_STP_ERROR; - return (0); + return (REQ_FSM_MORE); default: WRONG("Illegal action in vcl_fetch{}"); } @@ -468,7 +468,7 @@ DOT fetchbody:out -> prepresp [style=bold,color=red] DOT fetchbody:out -> prepresp [style=bold,color=blue] */ -static int +static enum req_fsm_nxt cnt_fetchbody(struct worker *wrk, struct req *req) { struct http *hp, *hp2; @@ -606,7 +606,7 @@ cnt_fetchbody(struct worker *wrk, struct req *req) req->req_step = R_STP_ERROR; VDI_CloseFd(&bo->vbc); VBO_DerefBusyObj(wrk, &req->busyobj); - return (0); + return (REQ_FSM_MORE); } CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); @@ -685,12 +685,12 @@ cnt_fetchbody(struct worker *wrk, struct req *req) VBO_DerefBusyObj(wrk, &req->busyobj); req->err_code = 503; req->req_step = R_STP_ERROR; - return (0); + return (REQ_FSM_MORE); } assert(WRW_IsReleased(wrk)); req->req_step = R_STP_PREPRESP; - return (0); + return (REQ_FSM_MORE); } /*-------------------------------------------------------------------- @@ -711,7 +711,7 @@ DOT hit:pass -> pass [label=pass,style=bold,color=red] DOT hit:del -> prepresp [label="deliver",style=bold,color=green] */ -static int +static enum req_fsm_nxt cnt_hit(struct worker *wrk, struct req *req) { CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); @@ -731,7 +731,7 @@ cnt_hit(struct worker *wrk, struct req *req) //AZ(req->busyobj->beresp->ws); (void)HTTP1_DiscardReqBody(req); // XXX: handle err req->req_step = R_STP_PREPRESP; - return (0); + return (REQ_FSM_MORE); } /* Drop our object, we won't need it */ @@ -741,13 +741,13 @@ cnt_hit(struct worker *wrk, struct req *req) switch(req->handling) { case VCL_RET_PASS: req->req_step = R_STP_PASS; - return (0); + return (REQ_FSM_MORE); case VCL_RET_ERROR: req->req_step = R_STP_ERROR; - return (0); + return (REQ_FSM_MORE); case VCL_RET_RESTART: req->req_step = R_STP_RESTART; - return (0); + return (REQ_FSM_MORE); default: WRONG("Illegal action in vcl_hit{}"); } @@ -772,7 +772,7 @@ DOT lookup:no -> hit [style=bold,color=green] DOT lookup:yes -> pass [style=bold,color=red] */ -static int +static enum req_fsm_nxt cnt_lookup(struct worker *wrk, struct req *req) { struct objcore *oc; @@ -798,7 +798,7 @@ cnt_lookup(struct worker *wrk, struct req *req) * object has been unbusied, and still have the objhead * around to restart the lookup with. */ - return (2); + return (REQ_FSM_DISEMBARK); } AZ(req->objcore); @@ -820,7 +820,7 @@ cnt_lookup(struct worker *wrk, struct req *req) req->objcore = oc; req->req_step = R_STP_MISS; - return (0); + return (REQ_FSM_MORE); } /* We are not prepared to do streaming yet */ @@ -838,13 +838,13 @@ cnt_lookup(struct worker *wrk, struct req *req) (void)HSH_Deref(&wrk->stats, NULL, &req->obj); AZ(req->objcore); req->req_step = R_STP_PASS; - return (0); + return (REQ_FSM_MORE); } wrk->stats.cache_hit++; VSLb(req->vsl, SLT_Hit, "%u", req->obj->vxid); req->req_step = R_STP_HIT; - return (0); + return (REQ_FSM_MORE); } /*-------------------------------------------------------------------- @@ -861,7 +861,7 @@ DOT miss:pass -> pass [label="pass",style=bold,color=red] DOT */ -static int +static enum req_fsm_nxt cnt_miss(struct worker *wrk, struct req *req) { struct busyobj *bo; @@ -892,7 +892,7 @@ cnt_miss(struct worker *wrk, struct req *req) if (req->handling == VCL_RET_FETCH) { CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); req->req_step = R_STP_FETCH; - return (0); + return (REQ_FSM_MORE); } AZ(HSH_Deref(&wrk->stats, req->objcore, NULL)); @@ -913,7 +913,7 @@ cnt_miss(struct worker *wrk, struct req *req) default: WRONG("Illegal action in vcl_miss{}"); } - return (0); + return (REQ_FSM_MORE); } /*-------------------------------------------------------------------- @@ -933,7 +933,7 @@ XDOT pass:err -> err_pass [label="error"] XDOT err_pass [label="ERROR",shape=plaintext] */ -static int +static enum req_fsm_nxt cnt_pass(struct worker *wrk, struct req *req) { struct busyobj *bo; @@ -957,7 +957,7 @@ cnt_pass(struct worker *wrk, struct req *req) http_Teardown(bo->bereq); VBO_DerefBusyObj(wrk, &req->busyobj); req->req_step = R_STP_ERROR; - return (0); + return (REQ_FSM_MORE); } assert(req->handling == VCL_RET_PASS); req->acct_req.pass++; @@ -965,7 +965,7 @@ cnt_pass(struct worker *wrk, struct req *req) req->objcore = HSH_NewObjCore(wrk); req->objcore->busyobj = bo; - return (0); + return (REQ_FSM_MORE); } /*-------------------------------------------------------------------- @@ -993,7 +993,7 @@ DOT vcl_pipe -> err_pipe [label="error"] DOT err_pipe [label="ERROR",shape=plaintext] */ -static int +static enum req_fsm_nxt cnt_pipe(struct worker *wrk, struct req *req) { struct busyobj *bo; @@ -1019,7 +1019,7 @@ cnt_pipe(struct worker *wrk, struct req *req) assert(WRW_IsReleased(wrk)); http_Teardown(bo->bereq); VBO_DerefBusyObj(wrk, &req->busyobj); - return (1); + return (REQ_FSM_DONE); } /*-------------------------------------------------------------------- @@ -1036,7 +1036,7 @@ DOT restart -> err_restart DOT err_restart [label="ERROR",shape=plaintext] */ -static int +static enum req_fsm_nxt cnt_restart(const struct worker *wrk, struct req *req) { @@ -1051,7 +1051,7 @@ cnt_restart(const struct worker *wrk, struct req *req) req->err_code = 0; req->req_step = R_STP_RECV; } - return (0); + return (REQ_FSM_MORE); } /*-------------------------------------------------------------------- @@ -1080,7 +1080,7 @@ DOT recv:lookup -> hash [style=bold,color=green] DOT hash -> lookup [label="hash",style=bold,color=green] */ -static int +static enum req_fsm_nxt cnt_recv(const struct worker *wrk, struct req *req) { unsigned recv_handling; @@ -1098,7 +1098,7 @@ cnt_recv(const struct worker *wrk, struct req *req) if (req->err_code) { req->req_step = R_STP_ERROR; - return (0); + return (REQ_FSM_MORE); } /* By default we use the first backend */ @@ -1144,21 +1144,21 @@ cnt_recv(const struct worker *wrk, struct req *req) switch(recv_handling) { case VCL_RET_LOOKUP: req->req_step = R_STP_LOOKUP; - return (0); + return (REQ_FSM_MORE); case VCL_RET_PIPE: if (req->esi_level > 0) { /* XXX: VSL something */ INCOMPL(); - return (1); + return (REQ_FSM_DONE); } req->req_step = R_STP_PIPE; - return (0); + return (REQ_FSM_MORE); case VCL_RET_PASS: req->req_step = R_STP_PASS; - return (0); + return (REQ_FSM_MORE); case VCL_RET_ERROR: req->req_step = R_STP_ERROR; - return (0); + return (REQ_FSM_MORE); default: WRONG("Illegal action in vcl_recv{}"); } @@ -1182,10 +1182,10 @@ cnt_diag(struct req *req, const char *state) VSL_Flush(req->vsl, 0); } -int +enum req_fsm_nxt CNT_Request(struct worker *wrk, struct req *req) { - int done; + enum req_fsm_nxt nxt; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); @@ -1201,7 +1201,7 @@ CNT_Request(struct worker *wrk, struct req *req) req->wrk = wrk; - for (done = 0; !done; ) { + for (nxt = REQ_FSM_MORE; nxt == REQ_FSM_MORE; ) { /* * This is a good place to be paranoid about the various * pointers still pointing to the things we expect. @@ -1223,7 +1223,7 @@ CNT_Request(struct worker *wrk, struct req *req) case R_STP_##u: \ if (DO_DEBUG(DBG_REQ_STATE)) \ cnt_diag(req, #u); \ - done = cnt_##l arg; \ + nxt = cnt_##l arg; \ break; #include "tbl/steps.h" #undef REQ_STEP @@ -1233,7 +1233,7 @@ CNT_Request(struct worker *wrk, struct req *req) WS_Assert(wrk->aws); CHECK_OBJ_ORNULL(wrk->nobjhead, OBJHEAD_MAGIC); } - if (done == 1) { + if (nxt == REQ_FSM_DONE) { /* XXX: Workaround for pipe */ if (req->sp->fd >= 0) { VSLb(req->vsl, SLT_Length, "%ju", @@ -1259,7 +1259,7 @@ CNT_Request(struct worker *wrk, struct req *req) req->wrk = NULL; assert(WRW_IsReleased(wrk)); - return (done); + return (nxt); } /* From phk at varnish-cache.org Wed Jan 23 11:09:19 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 23 Jan 2013 12:09:19 +0100 Subject: [master] 691e883 Release the storage of the cached req.body when the request is done. Message-ID: commit 691e88392986f0d7b783e4217be5e9f3b40d2faa Author: Poul-Henning Kamp Date: Wed Jan 23 11:09:03 2013 +0000 Release the storage of the cached req.body when the request is done. diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 982e9de..2bb15cd 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -1186,6 +1186,7 @@ enum req_fsm_nxt CNT_Request(struct worker *wrk, struct req *req) { enum req_fsm_nxt nxt; + struct storage *st; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); @@ -1246,6 +1247,12 @@ CNT_Request(struct worker *wrk, struct req *req) req->t_resp - req->t_req, req->sp->t_idle - req->t_resp); + while (!VTAILQ_EMPTY(&req->body)) { + st = VTAILQ_FIRST(&req->body); + VTAILQ_REMOVE(&req->body, st, list); + STV_free(st); + } + /* done == 2 was charged by cache_hash.c */ SES_Charge(wrk, req); From phk at varnish-cache.org Wed Jan 23 12:26:52 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 23 Jan 2013 13:26:52 +0100 Subject: [master] 2592b94 VFP_update_length() was misnamed: It is not a VFP function at all, it is a VBO function which extends the busy object with data which streaming clients can access. Message-ID: commit 2592b945c3a44707786993dfc5a3d225ae3a6f2f Author: Poul-Henning Kamp Date: Wed Jan 23 12:25:48 2013 +0000 VFP_update_length() was misnamed: It is not a VFP function at all, it is a VBO function which extends the busy object with data which streaming clients can access. Name it VBO_extend() instead and move it home to the rest of the VBO functions. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 27f2a12..d60d657 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -268,7 +268,7 @@ struct dstat { /* Fetch processors --------------------------------------------------*/ -void VFP_update_length(const struct busyobj *, ssize_t); +void VBO_extend(const struct busyobj *, ssize_t); typedef void vfp_begin_f(struct busyobj *, size_t ); typedef int vfp_bytes_f(struct busyobj *, struct http_conn *, ssize_t); diff --git a/bin/varnishd/cache/cache_busyobj.c b/bin/varnishd/cache/cache_busyobj.c index 0691b83..dfda90f 100644 --- a/bin/varnishd/cache/cache_busyobj.c +++ b/bin/varnishd/cache/cache_busyobj.c @@ -189,3 +189,15 @@ VBO_DerefBusyObj(struct worker *wrk, struct busyobj **pbo) else VBO_Free(&bo); } + +void +VBO_extend(const struct busyobj *bo, ssize_t l) +{ + + CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + CHECK_OBJ_NOTNULL(bo->fetch_obj, OBJECT_MAGIC); + if (l == 0) + return; + assert(l > 0); + bo->fetch_obj->len += l; +} diff --git a/bin/varnishd/cache/cache_esi_fetch.c b/bin/varnishd/cache/cache_esi_fetch.c index 7dc74ae..f98e90c 100644 --- a/bin/varnishd/cache/cache_esi_fetch.c +++ b/bin/varnishd/cache/cache_esi_fetch.c @@ -103,7 +103,7 @@ vfp_esi_bytes_uu(struct busyobj *bo, const struct vef_priv *vef, return (wl); VEP_Parse(bo, (const char *)st->ptr + st->len, wl); st->len += wl; - VFP_update_length(bo, wl); + VBO_extend(bo, wl); bytes -= wl; } return (1); @@ -142,7 +142,7 @@ vfp_esi_bytes_gu(struct busyobj *bo, const struct vef_priv *vef, return (-1); if (dl > 0) { VEP_Parse(bo, dp, dl); - VFP_update_length(bo, dl); + VBO_extend(bo, dl); } } return (1); @@ -220,7 +220,7 @@ vfp_vep_callback(struct busyobj *bo, ssize_t l, enum vgz_flag flg) } i = VGZ_Gzip(vef->vgz, &dp, &dl, flg); vef->tot += dl; - VFP_update_length(bo, dl); + VBO_extend(bo, dl); } while (!VGZ_IbufEmpty(vef->vgz) || (flg != VGZ_NORMAL && VGZ_ObufFull(vef->vgz))); assert(VGZ_IbufEmpty(vef->vgz)); diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index de66709..3ed08d0 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -113,18 +113,6 @@ VFP_End(struct busyobj *bo) assert(bo->state == BOS_FAILED); } -void -VFP_update_length(const struct busyobj *bo, ssize_t l) -{ - - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - CHECK_OBJ_NOTNULL(bo->fetch_obj, OBJECT_MAGIC); - if (l == 0) - return; - assert(l > 0); - bo->fetch_obj->len += l; -} - /*-------------------------------------------------------------------- * VFP_NOP * @@ -176,7 +164,7 @@ vfp_nop_bytes(struct busyobj *bo, struct http_conn *htc, ssize_t bytes) if (wl <= 0) return (wl); st->len += wl; - VFP_update_length(bo, wl); + VBO_extend(bo, wl); bytes -= wl; } return (1); diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index 5a53cd8..28a8937 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -480,7 +480,7 @@ vfp_gunzip_bytes(struct busyobj *bo, struct http_conn *htc, ssize_t bytes) i = VGZ_Gunzip(vg, &dp, &dl); if (i != VGZ_OK && i != VGZ_END) return(FetchError(bo, "Gunzip data error")); - VFP_update_length(bo, dl); + VBO_extend(bo, dl); } assert(i == Z_OK || i == Z_STREAM_END); return (1); @@ -555,7 +555,7 @@ vfp_gzip_bytes(struct busyobj *bo, struct http_conn *htc, ssize_t bytes) return(-1); i = VGZ_Gzip(vg, &dp, &dl, VGZ_NORMAL); assert(i == Z_OK); - VFP_update_length(bo, dl); + VBO_extend(bo, dl); } return (1); } @@ -581,7 +581,7 @@ vfp_gzip_end(struct busyobj *bo) if (VGZ_ObufStorage(bo, vg)) return(-1); i = VGZ_Gzip(vg, &dp, &dl, VGZ_FINISH); - VFP_update_length(bo, dl); + VBO_extend(bo, dl); } while (i != Z_STREAM_END); VGZ_UpdateObj(vg, bo->fetch_obj); if (VGZ_Destroy(&vg) != VGZ_END) @@ -639,7 +639,7 @@ vfp_testgzip_bytes(struct busyobj *bo, struct http_conn *htc, ssize_t bytes) bytes -= wl; VGZ_Ibuf(vg, st->ptr + st->len, wl); st->len += wl; - VFP_update_length(bo, wl); + VBO_extend(bo, wl); while (!VGZ_IbufEmpty(vg)) { VGZ_Obuf(vg, vg->m_buf, vg->m_sz); From phk at varnish-cache.org Wed Jan 23 12:41:10 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 23 Jan 2013 13:41:10 +0100 Subject: [master] 06d0296 Make the VFP_ methods take a "void *priv" rather than a busyobj, to pave the way for sharing some code on client and backend side. Message-ID: commit 06d029674c66c60efa50f32fe25c98eae45efcfd Author: Poul-Henning Kamp Date: Wed Jan 23 12:40:32 2013 +0000 Make the VFP_ methods take a "void *priv" rather than a busyobj, to pave the way for sharing some code on client and backend side. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index d60d657..f77837a 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -268,11 +268,9 @@ struct dstat { /* Fetch processors --------------------------------------------------*/ -void VBO_extend(const struct busyobj *, ssize_t); - -typedef void vfp_begin_f(struct busyobj *, size_t ); -typedef int vfp_bytes_f(struct busyobj *, struct http_conn *, ssize_t); -typedef int vfp_end_f(struct busyobj *); +typedef void vfp_begin_f(void *priv, size_t ); +typedef int vfp_bytes_f(void *priv, struct http_conn *, ssize_t); +typedef int vfp_end_f(void *priv); struct vfp { vfp_begin_f *begin; @@ -787,6 +785,7 @@ void VBO_Init(void); struct busyobj *VBO_GetBusyObj(struct worker *, struct req *); void VBO_DerefBusyObj(struct worker *wrk, struct busyobj **busyobj); void VBO_Free(struct busyobj **vbo); +void VBO_extend(const struct busyobj *, ssize_t); /* cache_http1_fsm.c [HTTP1] */ typedef int (req_body_iter_f)(struct req *, void *priv, void *ptr, size_t); diff --git a/bin/varnishd/cache/cache_esi_fetch.c b/bin/varnishd/cache/cache_esi_fetch.c index f98e90c..0031a3c 100644 --- a/bin/varnishd/cache/cache_esi_fetch.c +++ b/bin/varnishd/cache/cache_esi_fetch.c @@ -296,12 +296,13 @@ vfp_esi_bytes_gg(const struct busyobj *bo, struct vef_priv *vef, /*---------------------------------------------------------------------*/ static void __match_proto__(vfp_begin_f) -vfp_esi_begin(struct busyobj *bo, size_t estimate) +vfp_esi_begin(void *priv, size_t estimate) { + struct busyobj *bo; struct vef_priv *vef; + CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC); (void)estimate; - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); ALLOC_OBJ(vef, VEF_MAGIC); XXXAN(vef); @@ -340,12 +341,13 @@ vfp_esi_begin(struct busyobj *bo, size_t estimate) } static int __match_proto__(vfp_bytes_f) -vfp_esi_bytes(struct busyobj *bo, struct http_conn *htc, ssize_t bytes) +vfp_esi_bytes(void *priv, struct http_conn *htc, ssize_t bytes) { + struct busyobj *bo; struct vef_priv *vef; int i; - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC); vef = bo->vef_priv; CHECK_OBJ_NOTNULL(vef, VEF_MAGIC); @@ -364,14 +366,15 @@ vfp_esi_bytes(struct busyobj *bo, struct http_conn *htc, ssize_t bytes) } static int __match_proto__(vfp_end_f) -vfp_esi_end(struct busyobj *bo) +vfp_esi_end(void *priv) { + struct busyobj *bo; struct vsb *vsb; struct vef_priv *vef; ssize_t l; int retval = 0; - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC); AN(bo->vep); if (bo->state == BOS_FAILED) diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 3ed08d0..0d539f7 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -129,8 +129,11 @@ VFP_End(struct busyobj *bo) * as seen on the socket, or zero if unknown. */ static void __match_proto__(vfp_begin_f) -vfp_nop_begin(struct busyobj *bo, size_t estimate) +vfp_nop_begin(void *priv, size_t estimate) { + struct busyobj *bo; + + CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC); if (estimate > 0) (void)FetchStorage(bo, estimate); @@ -148,10 +151,13 @@ vfp_nop_begin(struct busyobj *bo, size_t estimate) */ static int __match_proto__(vfp_bytes_f) -vfp_nop_bytes(struct busyobj *bo, struct http_conn *htc, ssize_t bytes) +vfp_nop_bytes(void *priv, struct http_conn *htc, ssize_t bytes) { ssize_t l, wl; struct storage *st; + struct busyobj *bo; + + CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC); while (bytes > 0) { st = FetchStorage(bo, 0); @@ -180,10 +186,12 @@ vfp_nop_bytes(struct busyobj *bo, struct http_conn *htc, ssize_t bytes) */ static int __match_proto__(vfp_end_f) -vfp_nop_end(struct busyobj *bo) +vfp_nop_end(void *priv) { struct storage *st; + struct busyobj *bo; + CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC); st = VTAILQ_LAST(&bo->fetch_obj->store, storagehead); if (st == NULL) return (0); diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index 28a8937..9410b26 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -441,25 +441,28 @@ VGZ_Destroy(struct vgz **vgp) */ static void __match_proto__(vfp_begin_f) -vfp_gunzip_begin(struct busyobj *bo, size_t estimate) +vfp_gunzip_begin(void *priv, size_t estimate) { + struct busyobj *bo; + + CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC); (void)estimate; - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); AZ(bo->vgz_rx); bo->vgz_rx = VGZ_NewUngzip(bo->vsl, "U F -"); XXXAZ(vgz_getmbuf(bo->vgz_rx)); } static int __match_proto__(vfp_bytes_f) -vfp_gunzip_bytes(struct busyobj *bo, struct http_conn *htc, ssize_t bytes) +vfp_gunzip_bytes(void *priv, struct http_conn *htc, ssize_t bytes) { struct vgz *vg; + struct busyobj *bo; ssize_t l, wl; int i = -100; size_t dl; const void *dp; - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC); vg = bo->vgz_rx; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); AZ(vg->vz.avail_in); @@ -487,11 +490,12 @@ vfp_gunzip_bytes(struct busyobj *bo, struct http_conn *htc, ssize_t bytes) } static int __match_proto__(vfp_end_f) -vfp_gunzip_end(struct busyobj *bo) +vfp_gunzip_end(void *priv) { struct vgz *vg; + struct busyobj *bo; - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC); vg = bo->vgz_rx; bo->vgz_rx = NULL; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); @@ -517,26 +521,28 @@ struct vfp vfp_gunzip = { */ static void __match_proto__(vfp_begin_f) -vfp_gzip_begin(struct busyobj *bo, size_t estimate) +vfp_gzip_begin(void *priv, size_t estimate) { (void)estimate; + struct busyobj *bo; - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC); AZ(bo->vgz_rx); bo->vgz_rx = VGZ_NewGzip(bo->vsl, "G F -"); XXXAZ(vgz_getmbuf(bo->vgz_rx)); } static int __match_proto__(vfp_bytes_f) -vfp_gzip_bytes(struct busyobj *bo, struct http_conn *htc, ssize_t bytes) +vfp_gzip_bytes(void *priv, struct http_conn *htc, ssize_t bytes) { struct vgz *vg; + struct busyobj *bo; ssize_t l, wl; int i = -100; size_t dl; const void *dp; - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC); vg = bo->vgz_rx; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); AZ(vg->vz.avail_in); @@ -561,14 +567,15 @@ vfp_gzip_bytes(struct busyobj *bo, struct http_conn *htc, ssize_t bytes) } static int __match_proto__(vfp_end_f) -vfp_gzip_end(struct busyobj *bo) +vfp_gzip_end(void *priv) { struct vgz *vg; + struct busyobj *bo; size_t dl; const void *dp; int i; - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC); vg = bo->vgz_rx; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); bo->vgz_rx = NULL; @@ -603,9 +610,11 @@ struct vfp vfp_gzip = { */ static void __match_proto__(vfp_begin_f) -vfp_testgzip_begin(struct busyobj *bo, size_t estimate) +vfp_testgzip_begin(void *priv, size_t estimate) { - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + struct busyobj *bo; + + CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC); (void)estimate; bo->vgz_rx = VGZ_NewUngzip(bo->vsl, "u F -"); CHECK_OBJ_NOTNULL(bo->vgz_rx, VGZ_MAGIC); @@ -613,16 +622,17 @@ vfp_testgzip_begin(struct busyobj *bo, size_t estimate) } static int __match_proto__(vfp_bytes_f) -vfp_testgzip_bytes(struct busyobj *bo, struct http_conn *htc, ssize_t bytes) +vfp_testgzip_bytes(void *priv, struct http_conn *htc, ssize_t bytes) { struct vgz *vg; + struct busyobj *bo; ssize_t l, wl; int i = -100; size_t dl; const void *dp; struct storage *st; - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC); vg = bo->vgz_rx; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); AZ(vg->vz.avail_in); @@ -656,11 +666,12 @@ vfp_testgzip_bytes(struct busyobj *bo, struct http_conn *htc, ssize_t bytes) } static int __match_proto__(vfp_end_f) -vfp_testgzip_end(struct busyobj *bo) +vfp_testgzip_end(void *priv) { struct vgz *vg; + struct busyobj *bo; - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC); vg = bo->vgz_rx; bo->vgz_rx = NULL; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); From phk at varnish-cache.org Wed Jan 23 13:32:57 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 23 Jan 2013 14:32:57 +0100 Subject: [master] 980cce7 Rename httpconn to http1_proto, for increased clarity in a more complex future world. Message-ID: commit 980cce7fa6fc209efec2f5b2f840e212f4ba8c4c Author: Poul-Henning Kamp Date: Wed Jan 23 13:32:32 2013 +0000 Rename httpconn to http1_proto, for increased clarity in a more complex future world. diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 7d2077b..f5ef9ba 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -31,7 +31,7 @@ varnishd_SOURCES = \ cache/cache_hash.c \ cache/cache_http.c \ cache/cache_http1_fsm.c \ - cache/cache_httpconn.c \ + cache/cache_http1_proto.c \ cache/cache_lck.c \ cache/cache_main.c \ cache/cache_mempool.c \ diff --git a/bin/varnishd/cache/cache_http1_proto.c b/bin/varnishd/cache/cache_http1_proto.c new file mode 100644 index 0000000..8b331af --- /dev/null +++ b/bin/varnishd/cache/cache_http1_proto.c @@ -0,0 +1,211 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software AS + * All rights reserved. + * + * Author: Poul-Henning Kamp + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * HTTP protocol requests + * + * The trouble with the "until magic sequence" design of HTTP protocol messages + * is that either you have to read a single character at a time, which is + * inefficient, or you risk reading too much, and pre-read some of the object, + * or even the next pipelined request, which follows the one you want. + * + * HTC reads a HTTP protocol header into a workspace, subject to limits, + * and stops when we see the magic marker (double [CR]NL), and if we overshoot, + * it keeps track of the "pipelined" data. + * + * We use this both for client and backend connections. + */ + +#include "config.h" + +#include "cache.h" + +#include "vct.h" + + +/*--------------------------------------------------------------------*/ + +void +HTC_Init(struct http_conn *htc, struct ws *ws, int fd, struct vsl_log *vsl, + unsigned maxbytes, unsigned maxhdr) +{ + + htc->magic = HTTP_CONN_MAGIC; + htc->ws = ws; + htc->fd = fd; + htc->vsl = vsl; + htc->maxbytes = maxbytes; + htc->maxhdr = maxhdr; + + (void)WS_Reserve(htc->ws, htc->maxbytes); + htc->rxbuf.b = ws->f; + htc->rxbuf.e = ws->f; + *htc->rxbuf.e = '\0'; + htc->pipeline.b = NULL; + htc->pipeline.e = NULL; +} + +/*-------------------------------------------------------------------- + * Start over, and recycle any pipelined input. + * The WS_Reset is safe, even though the pipelined input is stored in + * the ws somewhere, because WS_Reset only fiddles pointers. + */ + +enum htc_status_e +HTC_Reinit(struct http_conn *htc) +{ + unsigned l; + + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + (void)WS_Reserve(htc->ws, htc->maxbytes); + htc->rxbuf.b = htc->ws->f; + htc->rxbuf.e = htc->ws->f; + if (htc->pipeline.b != NULL) { + l = Tlen(htc->pipeline); + memmove(htc->rxbuf.b, htc->pipeline.b, l); + htc->rxbuf.e += l; + htc->pipeline.b = NULL; + htc->pipeline.e = NULL; + } + *htc->rxbuf.e = '\0'; + return (HTC_Complete(htc)); +} + +/*-------------------------------------------------------------------- + * Check if we have a complete HTTP request or response yet + * + */ + +enum htc_status_e +HTC_Complete(struct http_conn *htc) +{ + int i; + const char *p; + txt *t; + + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + + t = &htc->rxbuf; + Tcheck(*t); + assert(*t->e == '\0'); + + /* Skip any leading white space */ + for (p = t->b ; vct_islws(*p); p++) + continue; + if (p == t->e) { + /* All white space */ + t->e = t->b; + *t->e = '\0'; + return (HTC_ALL_WHITESPACE); + } + while (1) { + p = strchr(p, '\n'); + if (p == NULL) + return (HTC_NEED_MORE); + p++; + if (*p == '\r') + p++; + if (*p == '\n') + break; + } + p++; + i = p - t->b; + WS_ReleaseP(htc->ws, htc->rxbuf.e); + AZ(htc->pipeline.b); + AZ(htc->pipeline.e); + if (htc->rxbuf.b + i < htc->rxbuf.e) { + htc->pipeline.b = htc->rxbuf.b + i; + htc->pipeline.e = htc->rxbuf.e; + htc->rxbuf.e = htc->pipeline.b; + } + return (HTC_COMPLETE); +} + +/*-------------------------------------------------------------------- + * Receive more HTTP protocol bytes + */ + +enum htc_status_e +HTC_Rx(struct http_conn *htc) +{ + int i; + + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + AN(htc->ws->r); + i = (htc->ws->r - htc->rxbuf.e) - 1; /* space for NUL */ + if (i <= 0) { + WS_ReleaseP(htc->ws, htc->rxbuf.b); + return (HTC_OVERFLOW); + } + i = read(htc->fd, htc->rxbuf.e, i); + if (i <= 0) { + /* + * We wouldn't come here if we had a complete HTTP header + * so consequently an EOF can not be OK + */ + WS_ReleaseP(htc->ws, htc->rxbuf.b); + return (HTC_ERROR_EOF); + } + htc->rxbuf.e += i; + *htc->rxbuf.e = '\0'; + return (HTC_Complete(htc)); +} + +/*-------------------------------------------------------------------- + * Read up to len bytes, returning pipelined data first. + */ + +ssize_t +HTC_Read(struct http_conn *htc, void *d, size_t len) +{ + size_t l; + unsigned char *p; + ssize_t i; + + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + l = 0; + p = d; + if (htc->pipeline.b) { + l = Tlen(htc->pipeline); + if (l > len) + l = len; + memcpy(p, htc->pipeline.b, l); + p += l; + len -= l; + htc->pipeline.b += l; + if (htc->pipeline.b == htc->pipeline.e) + htc->pipeline.b = htc->pipeline.e = NULL; + } + if (len == 0) + return (l); + i = read(htc->fd, p, len); + if (i < 0) { + VSLb(htc->vsl, SLT_FetchError, "%s", strerror(errno)); + return (i); + } + return (i + l); +} diff --git a/bin/varnishd/cache/cache_httpconn.c b/bin/varnishd/cache/cache_httpconn.c deleted file mode 100644 index 8b331af..0000000 --- a/bin/varnishd/cache/cache_httpconn.c +++ /dev/null @@ -1,211 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software AS - * All rights reserved. - * - * Author: Poul-Henning Kamp - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * HTTP protocol requests - * - * The trouble with the "until magic sequence" design of HTTP protocol messages - * is that either you have to read a single character at a time, which is - * inefficient, or you risk reading too much, and pre-read some of the object, - * or even the next pipelined request, which follows the one you want. - * - * HTC reads a HTTP protocol header into a workspace, subject to limits, - * and stops when we see the magic marker (double [CR]NL), and if we overshoot, - * it keeps track of the "pipelined" data. - * - * We use this both for client and backend connections. - */ - -#include "config.h" - -#include "cache.h" - -#include "vct.h" - - -/*--------------------------------------------------------------------*/ - -void -HTC_Init(struct http_conn *htc, struct ws *ws, int fd, struct vsl_log *vsl, - unsigned maxbytes, unsigned maxhdr) -{ - - htc->magic = HTTP_CONN_MAGIC; - htc->ws = ws; - htc->fd = fd; - htc->vsl = vsl; - htc->maxbytes = maxbytes; - htc->maxhdr = maxhdr; - - (void)WS_Reserve(htc->ws, htc->maxbytes); - htc->rxbuf.b = ws->f; - htc->rxbuf.e = ws->f; - *htc->rxbuf.e = '\0'; - htc->pipeline.b = NULL; - htc->pipeline.e = NULL; -} - -/*-------------------------------------------------------------------- - * Start over, and recycle any pipelined input. - * The WS_Reset is safe, even though the pipelined input is stored in - * the ws somewhere, because WS_Reset only fiddles pointers. - */ - -enum htc_status_e -HTC_Reinit(struct http_conn *htc) -{ - unsigned l; - - CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); - (void)WS_Reserve(htc->ws, htc->maxbytes); - htc->rxbuf.b = htc->ws->f; - htc->rxbuf.e = htc->ws->f; - if (htc->pipeline.b != NULL) { - l = Tlen(htc->pipeline); - memmove(htc->rxbuf.b, htc->pipeline.b, l); - htc->rxbuf.e += l; - htc->pipeline.b = NULL; - htc->pipeline.e = NULL; - } - *htc->rxbuf.e = '\0'; - return (HTC_Complete(htc)); -} - -/*-------------------------------------------------------------------- - * Check if we have a complete HTTP request or response yet - * - */ - -enum htc_status_e -HTC_Complete(struct http_conn *htc) -{ - int i; - const char *p; - txt *t; - - CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); - - t = &htc->rxbuf; - Tcheck(*t); - assert(*t->e == '\0'); - - /* Skip any leading white space */ - for (p = t->b ; vct_islws(*p); p++) - continue; - if (p == t->e) { - /* All white space */ - t->e = t->b; - *t->e = '\0'; - return (HTC_ALL_WHITESPACE); - } - while (1) { - p = strchr(p, '\n'); - if (p == NULL) - return (HTC_NEED_MORE); - p++; - if (*p == '\r') - p++; - if (*p == '\n') - break; - } - p++; - i = p - t->b; - WS_ReleaseP(htc->ws, htc->rxbuf.e); - AZ(htc->pipeline.b); - AZ(htc->pipeline.e); - if (htc->rxbuf.b + i < htc->rxbuf.e) { - htc->pipeline.b = htc->rxbuf.b + i; - htc->pipeline.e = htc->rxbuf.e; - htc->rxbuf.e = htc->pipeline.b; - } - return (HTC_COMPLETE); -} - -/*-------------------------------------------------------------------- - * Receive more HTTP protocol bytes - */ - -enum htc_status_e -HTC_Rx(struct http_conn *htc) -{ - int i; - - CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); - AN(htc->ws->r); - i = (htc->ws->r - htc->rxbuf.e) - 1; /* space for NUL */ - if (i <= 0) { - WS_ReleaseP(htc->ws, htc->rxbuf.b); - return (HTC_OVERFLOW); - } - i = read(htc->fd, htc->rxbuf.e, i); - if (i <= 0) { - /* - * We wouldn't come here if we had a complete HTTP header - * so consequently an EOF can not be OK - */ - WS_ReleaseP(htc->ws, htc->rxbuf.b); - return (HTC_ERROR_EOF); - } - htc->rxbuf.e += i; - *htc->rxbuf.e = '\0'; - return (HTC_Complete(htc)); -} - -/*-------------------------------------------------------------------- - * Read up to len bytes, returning pipelined data first. - */ - -ssize_t -HTC_Read(struct http_conn *htc, void *d, size_t len) -{ - size_t l; - unsigned char *p; - ssize_t i; - - CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); - l = 0; - p = d; - if (htc->pipeline.b) { - l = Tlen(htc->pipeline); - if (l > len) - l = len; - memcpy(p, htc->pipeline.b, l); - p += l; - len -= l; - htc->pipeline.b += l; - if (htc->pipeline.b == htc->pipeline.e) - htc->pipeline.b = htc->pipeline.e = NULL; - } - if (len == 0) - return (l); - i = read(htc->fd, p, len); - if (i < 0) { - VSLb(htc->vsl, SLT_FetchError, "%s", strerror(errno)); - return (i); - } - return (i + l); -} From phk at varnish-cache.org Wed Jan 23 14:21:02 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 23 Jan 2013 15:21:02 +0100 Subject: [master] f07792e Move bodystatus into struct http_conn Message-ID: commit f07792e7cc484effd86df838705435499e583a00 Author: Poul-Henning Kamp Date: Wed Jan 23 14:20:47 2013 +0000 Move bodystatus into struct http_conn diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index f77837a..e75535b 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -244,6 +244,7 @@ struct http_conn { struct ws *ws; txt rxbuf; txt pipeline; + enum body_status body_status; }; /*--------------------------------------------------------------------*/ @@ -532,7 +533,6 @@ struct busyobj { struct exp exp; struct http_conn htc; - enum body_status body_status; struct pool_task fetch_task; struct vef_priv *vef_priv; diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 0d539f7..ea110bb 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -276,7 +276,7 @@ fetch_straight(struct busyobj *bo, struct http_conn *htc, ssize_t cl) { int i; - assert(bo->body_status == BS_LENGTH); + assert(htc->body_status == BS_LENGTH); if (cl < 0) { return (FetchError(bo, "straight length field bogus")); @@ -303,7 +303,7 @@ fetch_chunked(struct busyobj *bo, struct http_conn *htc) unsigned u; ssize_t cl; - assert(bo->body_status == BS_CHUNKED); + assert(htc->body_status == BS_CHUNKED); do { /* Skip leading whitespace */ do { @@ -361,7 +361,7 @@ static void fetch_eof(struct busyobj *bo, struct http_conn *htc) { - assert(bo->body_status == BS_EOF); + assert(htc->body_status == BS_EOF); if (VFP_Bytes(bo, htc, SSIZE_MAX) < 0) (void)FetchError(bo,"eof socket fail"); } @@ -561,7 +561,7 @@ FetchBody(struct worker *wrk, void *priv) /* XXX: pick up estimate from objdr ? */ cl = 0; cls = 0; - switch (bo->body_status) { + switch (htc->body_status) { case BS_NONE: mklen = 0; break; @@ -611,7 +611,7 @@ FetchBody(struct worker *wrk, void *priv) bo->vfp = NULL; VSLb(bo->vsl, SLT_Fetch_Body, "%u(%s) cls %d mklen %d", - bo->body_status, body_status(bo->body_status), + htc->body_status, body_status(htc->body_status), cls, mklen); http_Teardown(bo->bereq); diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index cbb258b..60f30f4 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -216,7 +216,7 @@ pan_busyobj(const struct busyobj *bo) if (bo->do_stream) VSB_printf(pan_vsp, " do_stream\n"); if (bo->should_close) VSB_printf(pan_vsp, " should_close\n"); VSB_printf(pan_vsp, " bodystatus = %d (%s),\n", - bo->body_status, body_status(bo->body_status)); + bo->htc.body_status, body_status(bo->htc.body_status)); VSB_printf(pan_vsp, " },\n"); if (VALID_OBJ(bo->vbc, BACKEND_MAGIC)) pan_vbc(bo->vbc); diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 2bb15cd..3a15f58 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -392,7 +392,7 @@ cnt_fetch(struct worker *wrk, struct req *req) * headers are adultered by VCL * NB: Also sets other wrk variables */ - bo->body_status = RFC2616_Body(bo, &wrk->stats); + bo->htc.body_status = RFC2616_Body(bo, &wrk->stats); req->err_code = http_GetStatus(bo->beresp); @@ -557,7 +557,7 @@ cnt_fetchbody(struct worker *wrk, struct req *req) bo->do_stream = 0; /* No reason to try streaming a non-existing body */ - if (bo->body_status == BS_NONE) + if (bo->htc.body_status == BS_NONE) bo->do_stream = 0; l = http_EstimateWS(bo->beresp, From tfheen at varnish-cache.org Thu Jan 24 10:10:41 2013 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 24 Jan 2013 11:10:41 +0100 Subject: [master] d7b13fc make autocrap(tm_phk) tools happy Message-ID: commit d7b13fc91d1249b1dbbb4e01b716ec4272acaea5 Author: Nils Goroll Date: Wed Jan 9 19:49:20 2013 +0100 make autocrap(tm_phk) tools happy Reduce warning noise from autoconf Make automake happy Pull in current ld-version-script.m4 which fixes the issue documented here: https://lists.gnu.org/archive/html/bug-gnulib/2010-08/msg00198.html From c24a91405479e7e5bd2633173cf5a24eabbd75fc Mon Sep 17 00:00:00 2001 From: Nils Goroll Date: Wed, 9 Jan 2013 19:45:14 +0100 Subject: [PATCH] make autocrap(tm_phk) tools happy Reduce warning noise from autoconf Make automake happy Pull in current ld-version-script.m4 which fixes the issue documented here: https://lists.gnu.org/archive/html/bug-gnulib/2010-08/msg00198.html diff --git a/bin/varnishadm/Makefile.am b/bin/varnishadm/Makefile.am index 201a361..7941eb2 100644 --- a/bin/varnishadm/Makefile.am +++ b/bin/varnishadm/Makefile.am @@ -1,6 +1,6 @@ # -INCLUDES = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include bin_PROGRAMS = varnishadm diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index f5ef9ba..0165696 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -1,6 +1,6 @@ # -INCLUDES = \ +AM_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/lib/libvgz \ -I$(top_builddir)/bin/varnishd \ diff --git a/bin/varnishhist/Makefile.am b/bin/varnishhist/Makefile.am index 8aafa2d..3d849f6 100644 --- a/bin/varnishhist/Makefile.am +++ b/bin/varnishhist/Makefile.am @@ -1,6 +1,6 @@ # -INCLUDES = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include bin_PROGRAMS = varnishhist diff --git a/bin/varnishlog/Makefile.am b/bin/varnishlog/Makefile.am index e21ee35..23e1fe4 100644 --- a/bin/varnishlog/Makefile.am +++ b/bin/varnishlog/Makefile.am @@ -1,6 +1,6 @@ # -INCLUDES = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include bin_PROGRAMS = varnishlog diff --git a/bin/varnishncsa/Makefile.am b/bin/varnishncsa/Makefile.am index 8b3f617..e9c30fa 100644 --- a/bin/varnishncsa/Makefile.am +++ b/bin/varnishncsa/Makefile.am @@ -1,6 +1,6 @@ # -INCLUDES = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include bin_PROGRAMS = varnishncsa diff --git a/bin/varnishreplay/Makefile.am b/bin/varnishreplay/Makefile.am index 2be20f7..df7b2b8 100644 --- a/bin/varnishreplay/Makefile.am +++ b/bin/varnishreplay/Makefile.am @@ -1,6 +1,6 @@ # -INCLUDES = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include bin_PROGRAMS = varnishreplay diff --git a/bin/varnishstat/Makefile.am b/bin/varnishstat/Makefile.am index 83588c9..98ea717 100644 --- a/bin/varnishstat/Makefile.am +++ b/bin/varnishstat/Makefile.am @@ -1,6 +1,6 @@ # -INCLUDES = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include bin_PROGRAMS = varnishstat diff --git a/bin/varnishtest/Makefile.am b/bin/varnishtest/Makefile.am index 9287b3c..b26e3cb 100644 --- a/bin/varnishtest/Makefile.am +++ b/bin/varnishtest/Makefile.am @@ -15,7 +15,7 @@ check-local: DISTCLEANFILES = _.ok -INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/lib/libvgz +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/lib/libvgz bin_PROGRAMS = varnishtest diff --git a/bin/varnishtop/Makefile.am b/bin/varnishtop/Makefile.am index 88def2f..362acf5 100644 --- a/bin/varnishtop/Makefile.am +++ b/bin/varnishtop/Makefile.am @@ -1,6 +1,6 @@ # -INCLUDES = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include bin_PROGRAMS = varnishtop diff --git a/configure.ac b/configure.ac index 003f682..a4cd8e8 100644 --- a/configure.ac +++ b/configure.ac @@ -5,6 +5,8 @@ AC_REVISION([$Id$]) AC_INIT([Varnish], [trunk], [varnish-dev at varnish-cache.org]) AC_CONFIG_SRCDIR(include/miniobj.h) AM_CONFIG_HEADER(config.h) +AC_CONFIG_MACRO_DIR([m4]) +AC_USE_SYSTEM_EXTENSIONS # save command line CFLAGS for use in VCC_CC (to pass through things like -m64) OCFLAGS="$CFLAGS" diff --git a/lib/libvarnish/Makefile.am b/lib/libvarnish/Makefile.am index 740ae16..60f6a25 100644 --- a/lib/libvarnish/Makefile.am +++ b/lib/libvarnish/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I$(top_srcdir)/include @PCRE_CFLAGS@ +AM_CPPFLAGS = -I$(top_srcdir)/include @PCRE_CFLAGS@ AM_LDFLAGS = $(AM_LT_LDFLAGS) diff --git a/lib/libvarnishapi/Makefile.am b/lib/libvarnishapi/Makefile.am index ee86abc..181d1c1 100644 --- a/lib/libvarnishapi/Makefile.am +++ b/lib/libvarnishapi/Makefile.am @@ -2,7 +2,7 @@ AM_LDFLAGS = $(AM_LT_LDFLAGS) -INCLUDES = -I$(top_srcdir)/include @PCRE_CFLAGS@ +AM_CPPFLAGS = -I$(top_srcdir)/include @PCRE_CFLAGS@ lib_LTLIBRARIES = libvarnishapi.la diff --git a/lib/libvarnishcompat/Makefile.am b/lib/libvarnishcompat/Makefile.am index 33aac4a..698531f 100644 --- a/lib/libvarnishcompat/Makefile.am +++ b/lib/libvarnishcompat/Makefile.am @@ -1,6 +1,6 @@ # -INCLUDES = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include AM_LDFLAGS = $(AM_LT_LDFLAGS) pkglib_LTLIBRARIES = libvarnishcompat.la diff --git a/lib/libvcl/Makefile.am b/lib/libvcl/Makefile.am index f07facd..be3efe0 100644 --- a/lib/libvcl/Makefile.am +++ b/lib/libvcl/Makefile.am @@ -2,7 +2,7 @@ AM_LDFLAGS = $(AM_LT_LDFLAGS) -INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include pkglib_LTLIBRARIES = libvcl.la diff --git a/lib/libvmod_debug/Makefile.am b/lib/libvmod_debug/Makefile.am index 1705cf9..f199ecf 100644 --- a/lib/libvmod_debug/Makefile.am +++ b/lib/libvmod_debug/Makefile.am @@ -1,7 +1,7 @@ # AM_LDFLAGS = $(AM_LT_LDFLAGS) -INCLUDES = \ +AM_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/bin/varnishd \ -I$(top_builddir)/include diff --git a/lib/libvmod_std/Makefile.am b/lib/libvmod_std/Makefile.am index 0a4736a..b8fa7bb 100644 --- a/lib/libvmod_std/Makefile.am +++ b/lib/libvmod_std/Makefile.am @@ -2,7 +2,7 @@ AM_LDFLAGS = $(AM_LT_LDFLAGS) -INCLUDES = \ +AM_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/bin/varnishd \ -I$(top_builddir)/include diff --git a/m4/ld-version-script.m4 b/m4/ld-version-script.m4 index a97888f..63386f1 100644 --- a/m4/ld-version-script.m4 +++ b/m4/ld-version-script.m4 @@ -1,5 +1,5 @@ -# ld-version-script.m4 serial 1 -dnl Copyright (C) 2008, 2009 Free Software Foundation, Inc. +# ld-version-script.m4 serial 3 +dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -26,16 +26,25 @@ AC_DEFUN([gl_LD_VERSION_SCRIPT], save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map" cat > conftest.map < conftest.map < commit b508fffe2a85cba254a4da3211c7b4121036b52b Author: Tollef Fog Heen Date: Thu Jan 24 11:09:48 2013 +0100 Make sure to distribute req_body.h too diff --git a/include/Makefile.am b/include/Makefile.am index 2d15805..cb10bc4 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -11,6 +11,7 @@ nobase_pkginclude_HEADERS = \ tbl/http_headers.h \ tbl/http_response.h \ tbl/locks.h \ + tbl/req_body.h \ tbl/sess_close.h \ tbl/steps.h \ tbl/symbol_kind.h \ From tfheen at varnish-cache.org Thu Jan 24 10:10:41 2013 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 24 Jan 2013 11:10:41 +0100 Subject: [master] b54c7f6 proper dependencies for vmod automake Message-ID: commit b54c7f6d2bc0f1bda7d61fafccdb412cbfa1a18d Author: Nils Goroll Date: Wed Jan 9 20:49:41 2013 +0100 proper dependencies for vmod automake parallel builds (make -jX) failed sporadically for the first compilation (before dependency tracking information was available) due to the race with python building vcc_if.h From 8e2751a28b7cb6331b386fbf6e1a7b1bdeafb4b7 Mon Sep 17 00:00:00 2001 From: Nils Goroll Date: Wed, 9 Jan 2013 20:46:13 +0100 Subject: [PATCH] proper dependencies for vmod automake parallel builds (make -jX) failed sporadically for the first compilation (before dependency tracking information was available) due to the race with python building vcc_if.h diff --git a/lib/libvmod_debug/Makefile.am b/lib/libvmod_debug/Makefile.am index f199ecf..c77a9da 100644 --- a/lib/libvmod_debug/Makefile.am +++ b/lib/libvmod_debug/Makefile.am @@ -14,10 +14,15 @@ noinst_LTLIBRARIES = libvmod_debug.la libvmod_debug_la_LDFLAGS = $(AM_LDFLAGS) -module -export-dynamic -avoid-version -rpath /nowhere libvmod_debug_la_SOURCES = \ - vcc_if.c \ - vcc_if.h \ vmod_debug.c +nodist_libvmod_debug_la_SOURCES = \ + vcc_if.c \ + vcc_if.h + +# BUILT_SOURCES is only a hack and dependency tracking does not help for the first build +vmod_debug.lo: vcc_if.h + vcc_if.c vcc_if.h: $(vmodtool) $(vmod_srcdir)/vmod.vcc @PYTHON@ $(vmodtool) $(vmod_srcdir)/vmod.vcc diff --git a/lib/libvmod_std/Makefile.am b/lib/libvmod_std/Makefile.am index b8fa7bb..59648e8 100644 --- a/lib/libvmod_std/Makefile.am +++ b/lib/libvmod_std/Makefile.am @@ -17,12 +17,17 @@ vmod_LTLIBRARIES = libvmod_std.la libvmod_std_la_LDFLAGS = $(AM_LDFLAGS) -module -export-dynamic -avoid-version libvmod_std_la_SOURCES = \ - vcc_if.c \ - vcc_if.h \ vmod_std.c \ vmod_std_fileread.c \ vmod_std_conversions.c +nodist_libvmod_std_la_SOURCES = \ + vcc_if.c \ + vcc_if.h + +# BUILT_SOURCES is only a hack and dependency tracking does not help for the first build +vmod_std.lo vmod_std_fileread.lo vmod_std_conversions.lo: vcc_if.h + vcc_if.c vcc_if.h: $(vmodtool) $(vmod_srcdir)/vmod.vcc @PYTHON@ $(vmodtool) $(vmod_srcdir)/vmod.vcc From tfheen at varnish-cache.org Thu Jan 24 10:10:41 2013 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 24 Jan 2013 11:10:41 +0100 Subject: [master] f394d25 Build vmods as shared objects only Message-ID: commit f394d25d75975cc1bf25a1612bf821cb294e0da7 Author: Tollef Fog Heen Date: Thu Jan 24 10:53:13 2013 +0100 Build vmods as shared objects only It does not make any kind of sense to build a vmod as a static library, so tell libtool to only build a shared one. diff --git a/lib/libvmod_debug/Makefile.am b/lib/libvmod_debug/Makefile.am index c77a9da..25b3f3f 100644 --- a/lib/libvmod_debug/Makefile.am +++ b/lib/libvmod_debug/Makefile.am @@ -11,7 +11,7 @@ vmod_srcdir = $(top_srcdir)/lib/libvmod_debug vmodtool = $(top_srcdir)/lib/libvcl/vmodtool.py noinst_LTLIBRARIES = libvmod_debug.la -libvmod_debug_la_LDFLAGS = $(AM_LDFLAGS) -module -export-dynamic -avoid-version -rpath /nowhere +libvmod_debug_la_LDFLAGS = $(AM_LDFLAGS) -module -export-dynamic -avoid-version -shared -rpath /nowhere libvmod_debug_la_SOURCES = \ vmod_debug.c diff --git a/lib/libvmod_std/Makefile.am b/lib/libvmod_std/Makefile.am index 59648e8..acc0842 100644 --- a/lib/libvmod_std/Makefile.am +++ b/lib/libvmod_std/Makefile.am @@ -14,7 +14,7 @@ vmod_srcdir = $(top_srcdir)/lib/libvmod_std vmodtool = $(top_srcdir)/lib/libvcl/vmodtool.py vmod_LTLIBRARIES = libvmod_std.la -libvmod_std_la_LDFLAGS = $(AM_LDFLAGS) -module -export-dynamic -avoid-version +libvmod_std_la_LDFLAGS = $(AM_LDFLAGS) -module -export-dynamic -avoid-version -shared libvmod_std_la_SOURCES = \ vmod_std.c \ From phk at varnish-cache.org Thu Jan 24 12:18:04 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Thu, 24 Jan 2013 13:18:04 +0100 Subject: [master] 1ba1185 From @slink: Message-ID: commit 1ba1185618adfea71733dade045e870d5792e1e2 Author: Poul-Henning Kamp Date: Thu Jan 24 12:16:19 2013 +0000 From @slink: tmo can become negative if timeout_idle gets changed on the fly or when the rtc jumps diff --git a/bin/varnishd/waiter/cache_waiter_ports.c b/bin/varnishd/waiter/cache_waiter_ports.c index aa3d766..3c07b95 100644 --- a/bin/varnishd/waiter/cache_waiter_ports.c +++ b/bin/varnishd/waiter/cache_waiter_ports.c @@ -222,12 +222,6 @@ vws_thread(void *priv) double tmo = (sp->t_idle + cache_param->timeout_idle) - now; - /* - * we should have removed all sps whose timeout - * has passed - */ - assert(tmo > 0.0); - if (tmo < min_t) { timeout = &min_ts; } else if (tmo > max_t) { From phk at varnish-cache.org Fri Jan 25 08:47:08 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Fri, 25 Jan 2013 09:47:08 +0100 Subject: [master] 095d05d Generalize the transmit code, so it can be used for both req.* and resp.* Message-ID: commit 095d05d94cf0b62e87d105acb28f8b44aca1a31a Author: Poul-Henning Kamp Date: Fri Jan 25 08:46:32 2013 +0000 Generalize the transmit code, so it can be used for both req.* and resp.* Submitted by: jonathan.huot at thomsonreuters.com diff --git a/bin/varnishtest/tests/a00011.vtc b/bin/varnishtest/tests/a00011.vtc index 9e07f83..7b71d0d 100644 --- a/bin/varnishtest/tests/a00011.vtc +++ b/bin/varnishtest/tests/a00011.vtc @@ -2,12 +2,18 @@ varnishtest "test vtc gzip support" server s1 { rxreq + expect req.http.content-length == "26" + expect req.bodylen == "26" + gunzip + expect req.bodylen == "3" + expect req.http.content-encoding == "gzip" txresp -gzipbody FOO } -start client c1 -connect ${s1_sock} { - txreq + txreq -gzipbody FOO rxresp + expect resp.http.content-length == "26" expect resp.bodylen == "26" gunzip expect resp.bodylen == "3" diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index a7c128c..6a204dc 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -562,13 +562,14 @@ cmd_http_gunzip_body(CMD_ARGS) char *p; unsigned l; + (void)av; (void)cmd; (void)vl; CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC); - ONLY_CLIENT(hp, av); memset(&vz, 0, sizeof vz); + AN(hp->body); if (hp->body[0] != (char)0x1f || hp->body[1] != (char)0x8b) vtc_log(hp->vl, hp->fatal, "Gunzip error: Body lacks gzip magics"); @@ -650,53 +651,22 @@ gzip_body(const struct http *hp, const char *txt, char **body, int *bodylen) } /********************************************************************** - * Transmit a response + * Handle common arguments of a transmited request or response */ -static void -cmd_http_txresp(CMD_ARGS) +static char* const * +http_tx_parse_args(char * const *av, struct vtclog *vl, struct http *hp, + char* body) { - struct http *hp; - const char *proto = "HTTP/1.1"; - const char *status = "200"; - const char *msg = "Ok"; int bodylen = 0; char *b, *c; - char *body = NULL, *nullbody; + char *nullbody = NULL; int nolen = 0; - - (void)cmd; (void)vl; - CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC); - ONLY_SERVER(hp, av); - assert(!strcmp(av[0], "txresp")); - av++; - - VSB_clear(hp->vsb); - - /* send a "Content-Length: 0" header unless something else happens */ - REPLACE(body, ""); nullbody = body; for(; *av != NULL; av++) { - if (!strcmp(*av, "-proto")) { - proto = av[1]; - av++; - } else if (!strcmp(*av, "-status")) { - status = av[1]; - av++; - } else if (!strcmp(*av, "-msg")) { - msg = av[1]; - av++; - continue; - } else - break; - } - - VSB_printf(hp->vsb, "%s %s %s%s", proto, status, msg, nl); - - for(; *av != NULL; av++) { if (!strcmp(*av, "-nolen")) { nolen = 1; } else if (!strcmp(*av, "-hdr")) { @@ -750,13 +720,60 @@ cmd_http_txresp(CMD_ARGS) } else break; } - if (*av != NULL) - vtc_log(hp->vl, 0, "Unknown http txresp spec: %s\n", *av); if (body != NULL && !nolen) VSB_printf(hp->vsb, "Content-Length: %d%s", bodylen, nl); VSB_cat(hp->vsb, nl); if (body != NULL) VSB_bcat(hp->vsb, body, bodylen); + return av; +} + +/********************************************************************** + * Transmit a response + */ + +static void +cmd_http_txresp(CMD_ARGS) +{ + struct http *hp; + const char *proto = "HTTP/1.1"; + const char *status = "200"; + const char *msg = "Ok"; + char* body = NULL; + + (void)cmd; + (void)vl; + CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC); + ONLY_SERVER(hp, av); + assert(!strcmp(av[0], "txresp")); + av++; + + VSB_clear(hp->vsb); + + for(; *av != NULL; av++) { + if (!strcmp(*av, "-proto")) { + proto = av[1]; + av++; + } else if (!strcmp(*av, "-status")) { + status = av[1]; + av++; + } else if (!strcmp(*av, "-msg")) { + msg = av[1]; + av++; + continue; + } else + break; + } + + VSB_printf(hp->vsb, "%s %s %s%s", proto, status, msg, nl); + + /* send a "Content-Length: 0" header unless something else happens */ + REPLACE(body, ""); + + av = http_tx_parse_args(av, vl, hp, body); + if (*av != NULL) + vtc_log(hp->vl, 0, "Unknown http txresp spec: %s\n", *av); + http_write(hp, 4, "txresp"); } @@ -780,6 +797,7 @@ cmd_http_rxreq(CMD_ARGS) vtc_log(hp->vl, 0, "Unknown http rxreq spec: %s\n", *av); http_rxhdr(hp); http_splitheader(hp, 1); + hp->body = hp->rxbuf + hp->prxbuf; http_swallow_body(hp, hp->req, 0); vtc_log(hp->vl, 4, "bodylen = %s", hp->bodylen); } @@ -851,7 +869,6 @@ cmd_http_txreq(CMD_ARGS) const char *req = "GET"; const char *url = "/"; const char *proto = "HTTP/1.1"; - const char *body = NULL; (void)cmd; (void)vl; @@ -876,35 +893,10 @@ cmd_http_txreq(CMD_ARGS) break; } VSB_printf(hp->vsb, "%s %s %s%s", req, url, proto, nl); - for(; *av != NULL; av++) { - if (!strcmp(*av, "-hdr")) { - VSB_printf(hp->vsb, "%s%s", av[1], nl); - av++; - } else - break; - } - for(; *av != NULL; av++) { - if (!strcmp(*av, "-body")) { - AZ(body); - body = av[1]; - av++; - } else if (!strcmp(*av, "-bodylen")) { - AZ(body); - body = synth_body(av[1], 0); - av++; - } else - break; - } + + av = http_tx_parse_args(av, vl, hp, NULL); if (*av != NULL) vtc_log(hp->vl, 0, "Unknown http txreq spec: %s\n", *av); - if (body != NULL) - VSB_printf(hp->vsb, "Content-Length: %ju%s", - (uintmax_t)strlen(body), nl); - VSB_cat(hp->vsb, nl); - if (body != NULL) { - VSB_cat(hp->vsb, body); - VSB_cat(hp->vsb, nl); - } http_write(hp, 4, "txreq"); } From phk at varnish-cache.org Fri Jan 25 09:04:48 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Fri, 25 Jan 2013 10:04:48 +0100 Subject: [master] 09939bc Check return from pthread_mutex_trylock() Message-ID: commit 09939bc49fabaaedb40506eb994a35169d72086d Author: Poul-Henning Kamp Date: Fri Jan 25 09:04:31 2013 +0000 Check return from pthread_mutex_trylock() diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c index 060773b..198e225 100644 --- a/bin/varnishd/cache/cache_shmlog.c +++ b/bin/varnishd/cache/cache_shmlog.c @@ -115,10 +115,14 @@ static uint32_t * vsl_get(unsigned len, unsigned records, unsigned flushes) { uint32_t *p; + int err; - if (pthread_mutex_trylock(&vsl_mtx)) { + err = pthread_mutex_trylock(&vsl_mtx); + if (err == EBUSY) { AZ(pthread_mutex_lock(&vsl_mtx)); VSC_C_main->shm_cont++; + } else { + AZ(err); } assert(vsl_ptr < vsl_end); assert(((uintptr_t)vsl_ptr & 0x3) == 0); From phk at varnish-cache.org Mon Jan 28 08:00:18 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 28 Jan 2013 09:00:18 +0100 Subject: [master] d5a8bac un-inline a couple of enum-to-string functions Message-ID: commit d5a8bac12896dbfc4dc30b61c3351d4904c0bfee Author: Poul-Henning Kamp Date: Mon Jan 28 08:00:02 2013 +0000 un-inline a couple of enum-to-string functions diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index e75535b..cb5b24f 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -54,7 +54,6 @@ #include #endif - #include "common/params.h" /*--------------------------------------------------------------------*/ @@ -73,18 +72,6 @@ enum body_status { #undef BODYSTATUS }; -static inline const char * -body_status(enum body_status e) -{ - switch(e) { -#define BODYSTATUS(U,l) case BS_##U: return (#l); -#include "tbl/body_status.h" -#undef BODYSTATUS - default: - return ("?"); - } -} - /*--------------------------------------------------------------------*/ enum req_body_state_e { @@ -102,19 +89,6 @@ enum sess_close { #undef SESS_CLOSE }; -static inline const char * -sess_close_str(enum sess_close sc, int want_desc) -{ - switch (sc) { - case SC_NULL: return(want_desc ? "(null)": "NULL"); -#define SESS_CLOSE(nm, desc) case SC_##nm: return(want_desc ? desc : #nm); -#include "tbl/sess_close.h" -#undef SESS_CLOSE - - default: return(want_desc ? "(invalid)" : "INVALID"); - } -} - /*--------------------------------------------------------------------*/ /* @@ -129,6 +103,8 @@ enum { #undef SLTH }; +/*--------------------------------------------------------------------*/ + struct SHA256Context; struct VSC_C_lck; struct ban; @@ -960,6 +936,8 @@ void MPL_Free(struct mempool *mpl, void *item); /* cache_panic.c */ void PAN_Init(void); +const char *body_status_2str(enum body_status e); +const char *sess_close_2str(enum sess_close sc, int want_desc); /* cache_pipe.c */ void PipeRequest(struct req *req); diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index ea110bb..c2ebbea 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -611,7 +611,7 @@ FetchBody(struct worker *wrk, void *priv) bo->vfp = NULL; VSLb(bo->vsl, SLT_Fetch_Body, "%u(%s) cls %d mklen %d", - htc->body_status, body_status(htc->body_status), + htc->body_status, body_status_2str(htc->body_status), cls, mklen); http_Teardown(bo->bereq); diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index 60f30f4..dd9b2d7 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -61,6 +61,35 @@ static void pan_sess(const struct sess *sp); /*--------------------------------------------------------------------*/ +const char * +body_status_2str(enum body_status e) +{ + switch(e) { +#define BODYSTATUS(U,l) case BS_##U: return (#l); +#include "tbl/body_status.h" +#undef BODYSTATUS + default: + return ("?"); + } +} + +/*--------------------------------------------------------------------*/ + +const char * +sess_close_2str(enum sess_close sc, int want_desc) +{ + switch (sc) { + case SC_NULL: return(want_desc ? "(null)": "NULL"); +#define SESS_CLOSE(nm, desc) case SC_##nm: return(want_desc ? desc : #nm); +#include "tbl/sess_close.h" +#undef SESS_CLOSE + + default: return(want_desc ? "(invalid)" : "INVALID"); + } +} + +/*--------------------------------------------------------------------*/ + static void pan_ws(const struct ws *ws, int indent) { @@ -216,7 +245,7 @@ pan_busyobj(const struct busyobj *bo) if (bo->do_stream) VSB_printf(pan_vsp, " do_stream\n"); if (bo->should_close) VSB_printf(pan_vsp, " should_close\n"); VSB_printf(pan_vsp, " bodystatus = %d (%s),\n", - bo->htc.body_status, body_status(bo->htc.body_status)); + bo->htc.body_status, body_status_2str(bo->htc.body_status)); VSB_printf(pan_vsp, " },\n"); if (VALID_OBJ(bo->vbc, BACKEND_MAGIC)) pan_vbc(bo->vbc); diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index f7a5a39..1630007 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -327,7 +327,7 @@ SES_Delete(struct sess *sp, enum sess_close reason, double now) b = &sp->acct_ses; VSL(SLT_SessClose, sp->vxid, "%s %.3f %ju %ju %ju %ju %ju %ju", - sess_close_str(sp->reason, 0), now - sp->t_open, b->req, + sess_close_2str(sp->reason, 0), now - sp->t_open, b->req, b->pipe, b->pass, b->fetch, b->hdrbytes, b->bodybytes); MPL_Free(pp->mpl_sess, sp); From phk at varnish-cache.org Mon Jan 28 08:14:18 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 28 Jan 2013 09:14:18 +0100 Subject: [master] 6cdf30e Start splitting "generic HTTP", whatever that might be or become, from HTTP1 specific functionality. Message-ID: commit 6cdf30ed9f69dce360385d77c0b20ffba49e864a Author: Poul-Henning Kamp Date: Mon Jan 28 08:13:49 2013 +0000 Start splitting "generic HTTP", whatever that might be or become, from HTTP1 specific functionality. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index cb5b24f..5237991 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -867,14 +867,14 @@ double http_GetHdrQ(const struct http *hp, const char *hdr, const char *field); uint16_t http_GetStatus(const struct http *hp); const char *http_GetReq(const struct http *hp); int http_HdrIs(const struct http *hp, const char *hdr, const char *val); -uint16_t http_DissectRequest(struct req *); -uint16_t http_DissectResponse(struct http *sp, const struct http_conn *htc); enum sess_close http_DoConnection(const struct http *); void http_CopyHome(const struct http *hp); void http_Unset(struct http *hp, const char *hdr); void http_CollectHdr(struct http *hp, const char *hdr); +void http_VSLH(const struct http *hp, unsigned hdr); + +/* cache_http1_proto.c */ -/* cache_httpconn.c */ enum htc_status_e { HTC_ALL_WHITESPACE = -3, HTC_OVERFLOW = -2, @@ -889,6 +889,8 @@ enum htc_status_e HTC_Reinit(struct http_conn *htc); enum htc_status_e HTC_Rx(struct http_conn *htc); ssize_t HTC_Read(struct http_conn *htc, void *d, size_t len); enum htc_status_e HTC_Complete(struct http_conn *htc); +uint16_t HTC_DissectRequest(struct req *); +uint16_t HTC_DissectResponse(struct http *sp, const struct http_conn *htc); #define HTTPH(a, b, c) extern char b[]; #include "tbl/http_headers.h" diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index c2ebbea..2713571 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -504,7 +504,7 @@ FetchHdr(struct req *req, int need_host_hdr, int sendbody) hp = bo->beresp; - if (http_DissectResponse(hp, htc)) { + if (HTC_DissectResponse(hp, htc)) { VSLb(req->vsl, SLT_FetchError, "http format error"); VDI_CloseFd(&bo->vbc); /* XXX: other cleanup ? */ diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index eb5ad7e..c46cb15 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -61,7 +61,7 @@ http2shmlog(const struct http *hp, int t) return ((enum VSL_tag_e)(foo[hp->logtag] + t)); } -static void +void http_VSLH(const struct http *hp, unsigned hdr) { @@ -477,265 +477,6 @@ http_GetReq(const struct http *hp) return (hp->hd[HTTP_HDR_METHOD].b); } -/*-------------------------------------------------------------------- - * Dissect the headers of the HTTP protocol message. - * Detect conditionals (headers which start with '^[Ii][Ff]-') - */ - -static uint16_t -http_dissect_hdrs(struct http *hp, char *p, const struct http_conn *htc) -{ - char *q, *r; - txt t = htc->rxbuf; - - if (*p == '\r') - p++; - - hp->nhd = HTTP_HDR_FIRST; - hp->conds = 0; - r = NULL; /* For FlexeLint */ - for (; p < t.e; p = r) { - - /* Find end of next header */ - q = r = p; - while (r < t.e) { - if (!vct_iscrlf(*r)) { - r++; - continue; - } - q = r; - assert(r < t.e); - r += vct_skipcrlf(r); - if (r >= t.e) - break; - /* If line does not continue: got it. */ - if (!vct_issp(*r)) - break; - - /* Clear line continuation LWS to spaces */ - while (vct_islws(*q)) - *q++ = ' '; - } - - if (q - p > htc->maxhdr) { - VSLb(hp->vsl, SLT_BogoHeader, "%.*s", - (int)(q - p > 20 ? 20 : q - p), p); - return (413); - } - - /* Empty header = end of headers */ - if (p == q) - break; - - if ((p[0] == 'i' || p[0] == 'I') && - (p[1] == 'f' || p[1] == 'F') && - p[2] == '-') - hp->conds = 1; - - while (q > p && vct_issp(q[-1])) - q--; - *q = '\0'; - - if (hp->nhd < hp->shd) { - hp->hdf[hp->nhd] = 0; - hp->hd[hp->nhd].b = p; - hp->hd[hp->nhd].e = q; - http_VSLH(hp, hp->nhd); - hp->nhd++; - } else { - VSLb(hp->vsl, SLT_BogoHeader, "%.*s", - (int)(q - p > 20 ? 20 : q - p), p); - return (413); - } - } - return (0); -} - -/*-------------------------------------------------------------------- - * Deal with first line of HTTP protocol message. - */ - -static uint16_t -http_splitline(struct http *hp, const struct http_conn *htc, int req) -{ - char *p, *q; - int h1, h2, h3; - - 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_RESPONSE; - } - - CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); - CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); - - /* XXX: Assert a NUL at rx.e ? */ - Tcheck(htc->rxbuf); - - /* Skip leading LWS */ - for (p = htc->rxbuf.b ; vct_islws(*p); p++) - continue; - - /* First field cannot contain SP, CRLF or CTL */ - q = p; - for (; !vct_issp(*p); p++) { - if (vct_isctl(*p)) - return (400); - } - hp->hd[h1].b = q; - hp->hd[h1].e = p; - - /* Skip SP */ - for (; vct_issp(*p); p++) { - if (vct_isctl(*p)) - return (400); - } - - /* Second field cannot contain LWS or CTL */ - q = p; - for (; !vct_islws(*p); p++) { - if (vct_isctl(*p)) - return (400); - } - hp->hd[h2].b = q; - hp->hd[h2].e = p; - - if (!Tlen(hp->hd[h2])) - return (413); - - /* Skip SP */ - for (; vct_issp(*p); p++) { - if (vct_isctl(*p)) - return (400); - } - - /* Third field is optional and cannot contain CTL */ - q = p; - if (!vct_iscrlf(*p)) { - for (; !vct_iscrlf(*p); p++) - if (!vct_issep(*p) && vct_isctl(*p)) - return (400); - } - hp->hd[h3].b = q; - hp->hd[h3].e = p; - - /* Skip CRLF */ - p += vct_skipcrlf(p); - - *hp->hd[h1].e = '\0'; - http_VSLH(hp, h1); - - *hp->hd[h2].e = '\0'; - http_VSLH(hp, h2); - - if (hp->hd[h3].e != NULL) { - *hp->hd[h3].e = '\0'; - http_VSLH(hp, h3); - } - - return (http_dissect_hdrs(hp, p, htc)); -} - -/*--------------------------------------------------------------------*/ - -static void -http_ProtoVer(struct http *hp) -{ - - if (!strcasecmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.0")) - hp->protover = 10; - else if (!strcasecmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.1")) - hp->protover = 11; - else - hp->protover = 9; -} - - -/*--------------------------------------------------------------------*/ - -uint16_t -http_DissectRequest(struct req *req) -{ - struct http_conn *htc; - struct http *hp; - uint16_t retval; - - 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 = http_splitline(hp, htc, 1); - if (retval != 0) { - VSLbt(req->vsl, SLT_HttpGarbage, htc->rxbuf); - return (retval); - } - http_ProtoVer(hp); - return (retval); -} - -/*--------------------------------------------------------------------*/ - -uint16_t -http_DissectResponse(struct http *hp, const struct http_conn *htc) -{ - int j; - uint16_t retval = 0; - char *p; - - - CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); - CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); - - if (http_splitline(hp, htc, 0)) - retval = 503; - - if (retval == 0 && memcmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.", 7)) - retval = 503; - - if (retval == 0 && Tlen(hp->hd[HTTP_HDR_STATUS]) != 3) - retval = 503; - - if (retval == 0) { - hp->status = 0; - p = hp->hd[HTTP_HDR_STATUS].b; - for (j = 100; j != 0; j /= 10) { - if (!vct_isdigit(*p)) { - retval = 503; - break; - } - hp->status += (uint16_t)(j * (*p - '0')); - p++; - } - if (*p != '\0') - retval = 503; - } - - if (retval != 0) { - VSLbt(hp->vsl, SLT_HttpGarbage, htc->rxbuf); - assert(retval >= 100 && retval <= 999); - hp->status = retval; - } else { - http_ProtoVer(hp); - } - - if (hp->hd[HTTP_HDR_RESPONSE].b == NULL || - !Tlen(hp->hd[HTTP_HDR_RESPONSE])) { - /* Backend didn't send a response string, use the standard */ - hp->hd[HTTP_HDR_RESPONSE].b = - TRUST_ME(http_StatusMessage(hp->status)); - hp->hd[HTTP_HDR_RESPONSE].e = - strchr(hp->hd[HTTP_HDR_RESPONSE].b, '\0'); - } - return (retval); -} - /*--------------------------------------------------------------------*/ void diff --git a/bin/varnishd/cache/cache_http1_fsm.c b/bin/varnishd/cache/cache_http1_fsm.c index 83b0914..07fd810 100644 --- a/bin/varnishd/cache/cache_http1_fsm.c +++ b/bin/varnishd/cache/cache_http1_fsm.c @@ -260,7 +260,7 @@ http1_dissect(struct worker *wrk, struct req *req) wrk->vcl = NULL; HTTP_Setup(req->http, req->ws, req->vsl, HTTP_Method); - req->err_code = http_DissectRequest(req); + req->err_code = HTC_DissectRequest(req); /* If we could not even parse the request, just close */ if (req->err_code == 400) { diff --git a/bin/varnishd/cache/cache_http1_proto.c b/bin/varnishd/cache/cache_http1_proto.c index 8b331af..42c2269 100644 --- a/bin/varnishd/cache/cache_http1_proto.c +++ b/bin/varnishd/cache/cache_http1_proto.c @@ -209,3 +209,259 @@ HTC_Read(struct http_conn *htc, void *d, size_t len) } return (i + l); } + +/*-------------------------------------------------------------------- + * Dissect the headers of the HTTP protocol message. + * Detect conditionals (headers which start with '^[Ii][Ff]-') + */ + +static uint16_t +htc_dissect_hdrs(struct http *hp, char *p, const struct http_conn *htc) +{ + char *q, *r; + txt t = htc->rxbuf; + + if (*p == '\r') + p++; + + hp->nhd = HTTP_HDR_FIRST; + hp->conds = 0; + r = NULL; /* For FlexeLint */ + for (; p < t.e; p = r) { + + /* Find end of next header */ + q = r = p; + while (r < t.e) { + if (!vct_iscrlf(*r)) { + r++; + continue; + } + q = r; + assert(r < t.e); + r += vct_skipcrlf(r); + if (r >= t.e) + break; + /* If line does not continue: got it. */ + if (!vct_issp(*r)) + break; + + /* Clear line continuation LWS to spaces */ + while (vct_islws(*q)) + *q++ = ' '; + } + + if (q - p > htc->maxhdr) { + VSLb(hp->vsl, SLT_BogoHeader, "%.*s", + (int)(q - p > 20 ? 20 : q - p), p); + return (413); + } + + /* Empty header = end of headers */ + if (p == q) + break; + + if ((p[0] == 'i' || p[0] == 'I') && + (p[1] == 'f' || p[1] == 'F') && + p[2] == '-') + hp->conds = 1; + + while (q > p && vct_issp(q[-1])) + q--; + *q = '\0'; + + if (hp->nhd < hp->shd) { + hp->hdf[hp->nhd] = 0; + hp->hd[hp->nhd].b = p; + hp->hd[hp->nhd].e = q; + http_VSLH(hp, hp->nhd); + hp->nhd++; + } else { + VSLb(hp->vsl, SLT_BogoHeader, "%.*s", + (int)(q - p > 20 ? 20 : q - p), p); + return (413); + } + } + return (0); +} + +/*-------------------------------------------------------------------- + * Deal with first line of HTTP protocol message. + */ + +static uint16_t +htc_splitline(struct http *hp, const struct http_conn *htc, int req) +{ + char *p, *q; + int h1, h2, h3; + + 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_RESPONSE; + } + + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); + + /* XXX: Assert a NUL at rx.e ? */ + Tcheck(htc->rxbuf); + + /* Skip leading LWS */ + for (p = htc->rxbuf.b ; vct_islws(*p); p++) + continue; + + /* First field cannot contain SP, CRLF or CTL */ + q = p; + for (; !vct_issp(*p); p++) { + if (vct_isctl(*p)) + return (400); + } + hp->hd[h1].b = q; + hp->hd[h1].e = p; + + /* Skip SP */ + for (; vct_issp(*p); p++) { + if (vct_isctl(*p)) + return (400); + } + + /* Second field cannot contain LWS or CTL */ + q = p; + for (; !vct_islws(*p); p++) { + if (vct_isctl(*p)) + return (400); + } + hp->hd[h2].b = q; + hp->hd[h2].e = p; + + if (!Tlen(hp->hd[h2])) + return (413); + + /* Skip SP */ + for (; vct_issp(*p); p++) { + if (vct_isctl(*p)) + return (400); + } + + /* Third field is optional and cannot contain CTL */ + q = p; + if (!vct_iscrlf(*p)) { + for (; !vct_iscrlf(*p); p++) + if (!vct_issep(*p) && vct_isctl(*p)) + return (400); + } + hp->hd[h3].b = q; + hp->hd[h3].e = p; + + /* Skip CRLF */ + p += vct_skipcrlf(p); + + *hp->hd[h1].e = '\0'; + http_VSLH(hp, h1); + + *hp->hd[h2].e = '\0'; + http_VSLH(hp, h2); + + if (hp->hd[h3].e != NULL) { + *hp->hd[h3].e = '\0'; + http_VSLH(hp, h3); + } + + return (htc_dissect_hdrs(hp, p, htc)); +} + +/*--------------------------------------------------------------------*/ + +static void +htc_proto_ver(struct http *hp) +{ + if (!strcasecmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.0")) + hp->protover = 10; + else if (!strcasecmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.1")) + hp->protover = 11; + else + hp->protover = 9; +} + +/*--------------------------------------------------------------------*/ + +uint16_t +HTC_DissectRequest(struct req *req) +{ + struct http_conn *htc; + struct http *hp; + uint16_t retval; + + 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 = htc_splitline(hp, htc, 1); + if (retval != 0) { + VSLbt(req->vsl, SLT_HttpGarbage, htc->rxbuf); + return (retval); + } + htc_proto_ver(hp); + return (retval); +} +/*--------------------------------------------------------------------*/ + +uint16_t +HTC_DissectResponse(struct http *hp, const struct http_conn *htc) +{ + int j; + uint16_t retval = 0; + char *p; + + + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); + + if (htc_splitline(hp, htc, 0)) + retval = 503; + + if (retval == 0 && memcmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.", 7)) + retval = 503; + + if (retval == 0 && Tlen(hp->hd[HTTP_HDR_STATUS]) != 3) + retval = 503; + + if (retval == 0) { + hp->status = 0; + p = hp->hd[HTTP_HDR_STATUS].b; + for (j = 100; j != 0; j /= 10) { + if (!vct_isdigit(*p)) { + retval = 503; + break; + } + hp->status += (uint16_t)(j * (*p - '0')); + p++; + } + if (*p != '\0') + retval = 503; + } + + if (retval != 0) { + VSLbt(hp->vsl, SLT_HttpGarbage, htc->rxbuf); + assert(retval >= 100 && retval <= 999); + hp->status = retval; + } else + htc_proto_ver(hp); + + if (hp->hd[HTTP_HDR_RESPONSE].b == NULL || + !Tlen(hp->hd[HTTP_HDR_RESPONSE])) { + /* Backend didn't send a response string, use the standard */ + hp->hd[HTTP_HDR_RESPONSE].b = + TRUST_ME(http_StatusMessage(hp->status)); + hp->hd[HTTP_HDR_RESPONSE].e = + strchr(hp->hd[HTTP_HDR_RESPONSE].b, '\0'); + } + return (retval); +} + From phk at varnish-cache.org Mon Jan 28 09:59:49 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 28 Jan 2013 10:59:49 +0100 Subject: [master] 16c934f Rename HTC_* to HTTP1_* Message-ID: commit 16c934f5b881954b840a05161c6f008504eeec66 Author: Poul-Henning Kamp Date: Mon Jan 28 09:59:16 2013 +0000 Rename HTC_* to HTTP1_* Add a read-method to http_conn, and use it from all VFPs, which should be protocol agnostic. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 5237991..f5ebf7a 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -112,6 +112,7 @@ struct busyobj; struct cli; struct cli_proto; struct director; +struct http_conn; struct iovec; struct mempool; struct objcore; @@ -207,11 +208,18 @@ struct http { /*-------------------------------------------------------------------- * HTTP Protocol connection structure + * + * This is the protocol independent object for a HTTP connection, used + * both for backend and client sides. + * */ +typedef ssize_t htc_read(struct http_conn *, void *, size_t); + struct http_conn { unsigned magic; #define HTTP_CONN_MAGIC 0x3e19edd1 + htc_read *read; int fd; struct vsl_log *vsl; @@ -876,21 +884,21 @@ void http_VSLH(const struct http *hp, unsigned hdr); /* cache_http1_proto.c */ enum htc_status_e { - HTC_ALL_WHITESPACE = -3, - HTC_OVERFLOW = -2, - HTC_ERROR_EOF = -1, - HTC_NEED_MORE = 0, - HTC_COMPLETE = 1 + HTTP1_ALL_WHITESPACE = -3, + HTTP1_OVERFLOW = -2, + HTTP1_ERROR_EOF = -1, + HTTP1_NEED_MORE = 0, + HTTP1_COMPLETE = 1 }; -void HTC_Init(struct http_conn *htc, struct ws *ws, int fd, struct vsl_log *, +void HTTP1_Init(struct http_conn *htc, struct ws *ws, int fd, struct vsl_log *, unsigned maxbytes, unsigned maxhdr); -enum htc_status_e HTC_Reinit(struct http_conn *htc); -enum htc_status_e HTC_Rx(struct http_conn *htc); -ssize_t HTC_Read(struct http_conn *htc, void *d, size_t len); -enum htc_status_e HTC_Complete(struct http_conn *htc); -uint16_t HTC_DissectRequest(struct req *); -uint16_t HTC_DissectResponse(struct http *sp, const struct http_conn *htc); +enum htc_status_e HTTP1_Reinit(struct http_conn *htc); +enum htc_status_e HTTP1_Rx(struct http_conn *htc); +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); #define HTTPH(a, b, c) extern char b[]; #include "tbl/http_headers.h" diff --git a/bin/varnishd/cache/cache_esi_fetch.c b/bin/varnishd/cache/cache_esi_fetch.c index 0031a3c..d46d7c1 100644 --- a/bin/varnishd/cache/cache_esi_fetch.c +++ b/bin/varnishd/cache/cache_esi_fetch.c @@ -64,8 +64,7 @@ struct vef_priv { */ static ssize_t -vef_read(struct http_conn *htc, void *buf, ssize_t buflen, - ssize_t bytes) +vef_read(struct http_conn *htc, void *buf, ssize_t buflen, ssize_t bytes) { ssize_t d; @@ -76,7 +75,7 @@ vef_read(struct http_conn *htc, void *buf, ssize_t buflen, if (d < bytes) bytes = d; } - return (HTC_Read(htc, buf, bytes)); + return (htc->read(htc, buf, bytes)); } /*--------------------------------------------------------------------- diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 2713571..27c97c0 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -166,7 +166,7 @@ vfp_nop_bytes(void *priv, struct http_conn *htc, ssize_t bytes) l = st->space - st->len; if (l > bytes) l = bytes; - wl = HTC_Read(htc, st->ptr + st->len, l); + wl = HTTP1_Read(htc, st->ptr + st->len, l); if (wl <= 0) return (wl); st->len += wl; @@ -307,7 +307,7 @@ fetch_chunked(struct busyobj *bo, struct http_conn *htc) do { /* Skip leading whitespace */ do { - if (HTC_Read(htc, buf, 1) <= 0) + if (HTTP1_Read(htc, buf, 1) <= 0) return (FetchError(bo, "chunked read err")); } while (vct_islws(buf[0])); @@ -317,7 +317,7 @@ fetch_chunked(struct busyobj *bo, struct http_conn *htc) /* Collect hex digits, skipping leading zeros */ for (u = 1; u < sizeof buf; u++) { do { - if (HTC_Read(htc, buf + u, 1) <= 0) + if (HTTP1_Read(htc, buf + u, 1) <= 0) return (FetchError(bo, "chunked read err")); } while (u == 1 && buf[0] == '0' && buf[u] == '0'); @@ -330,7 +330,7 @@ fetch_chunked(struct busyobj *bo, struct http_conn *htc) /* Skip trailing white space */ while(vct_islws(buf[u]) && buf[u] != '\n') - if (HTC_Read(htc, buf + u, 1) <= 0) + if (HTTP1_Read(htc, buf + u, 1) <= 0) return (FetchError(bo, "chunked read err")); if (buf[u] != '\n') @@ -344,10 +344,10 @@ fetch_chunked(struct busyobj *bo, struct http_conn *htc) if (cl > 0 && VFP_Bytes(bo, htc, cl) <= 0) return (FetchError(bo, "chunked read err")); - i = HTC_Read(htc, buf, 1); + i = HTTP1_Read(htc, buf, 1); if (i <= 0) return (FetchError(bo, "chunked read err")); - if (buf[0] == '\r' && HTC_Read( htc, buf, 1) <= 0) + if (buf[0] == '\r' && HTTP1_Read( htc, buf, 1) <= 0) return (FetchError(bo, "chunked read err")); if (buf[0] != '\n') return (FetchError(bo,"chunked tail no NL")); @@ -469,7 +469,7 @@ FetchHdr(struct req *req, int need_host_hdr, int sendbody) /* Receive response */ - HTC_Init(htc, bo->ws, vc->fd, vc->vsl, + HTTP1_Init(htc, bo->ws, vc->fd, vc->vsl, cache_param->http_resp_size, cache_param->http_resp_hdr_len); @@ -477,8 +477,8 @@ FetchHdr(struct req *req, int need_host_hdr, int sendbody) first = 1; do { - hs = HTC_Rx(htc); - if (hs == HTC_OVERFLOW) { + hs = HTTP1_Rx(htc); + if (hs == HTTP1_OVERFLOW) { VSLb(req->vsl, SLT_FetchError, "http %sread error: overflow", first ? "first " : ""); @@ -486,7 +486,7 @@ FetchHdr(struct req *req, int need_host_hdr, int sendbody) /* XXX: other cleanup ? */ return (-1); } - if (hs == HTC_ERROR_EOF) { + if (hs == HTTP1_ERROR_EOF) { VSLb(req->vsl, SLT_FetchError, "http %sread error: EOF", first ? "first " : ""); @@ -500,11 +500,11 @@ FetchHdr(struct req *req, int need_host_hdr, int sendbody) VTCP_set_read_timeout(vc->fd, vc->between_bytes_timeout); } - } while (hs != HTC_COMPLETE); + } while (hs != HTTP1_COMPLETE); hp = bo->beresp; - if (HTC_DissectResponse(hp, htc)) { + if (HTTP1_DissectResponse(hp, htc)) { VSLb(req->vsl, SLT_FetchError, "http format error"); VDI_CloseFd(&bo->vbc); /* XXX: other cleanup ? */ diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index 9410b26..425e344 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -471,7 +471,7 @@ vfp_gunzip_bytes(void *priv, struct http_conn *htc, ssize_t bytes) l = vg->m_sz; if (l > bytes) l = bytes; - wl = HTC_Read(htc, vg->m_buf, l); + wl = htc->read(htc, vg->m_buf, l); if (wl <= 0) return (wl); VGZ_Ibuf(vg, vg->m_buf, wl); @@ -551,7 +551,7 @@ vfp_gzip_bytes(void *priv, struct http_conn *htc, ssize_t bytes) l = vg->m_sz; if (l > bytes) l = bytes; - wl = HTC_Read(htc, vg->m_buf, l); + wl = htc->read(htc, vg->m_buf, l); if (wl <= 0) return (wl); VGZ_Ibuf(vg, vg->m_buf, wl); @@ -643,7 +643,7 @@ vfp_testgzip_bytes(void *priv, struct http_conn *htc, ssize_t bytes) l = st->space - st->len; if (l > bytes) l = bytes; - wl = HTC_Read(htc, st->ptr + st->len, l); + wl = htc->read(htc, st->ptr + st->len, l); if (wl <= 0) return (wl); bytes -= wl; diff --git a/bin/varnishd/cache/cache_http1_fsm.c b/bin/varnishd/cache/cache_http1_fsm.c index 07fd810..2f99c6e 100644 --- a/bin/varnishd/cache/cache_http1_fsm.c +++ b/bin/varnishd/cache/cache_http1_fsm.c @@ -114,20 +114,20 @@ http1_wait(struct sess *sp, struct worker *wrk, struct req *req) assert(j >= 0); now = VTIM_real(); if (j != 0) - hs = HTC_Rx(req->htc); + hs = HTTP1_Rx(req->htc); else - hs = HTC_Complete(req->htc); - if (hs == HTC_COMPLETE) { + hs = HTTP1_Complete(req->htc); + if (hs == HTTP1_COMPLETE) { /* Got it, run with it */ req->t_req = now; return (REQ_FSM_MORE); - } else if (hs == HTC_ERROR_EOF) { + } else if (hs == HTTP1_ERROR_EOF) { why = SC_REM_CLOSE; break; - } else if (hs == HTC_OVERFLOW) { + } else if (hs == HTTP1_OVERFLOW) { why = SC_RX_OVERFLOW; break; - } else if (hs == HTC_ALL_WHITESPACE) { + } else if (hs == HTTP1_ALL_WHITESPACE) { /* Nothing but whitespace */ when = sp->t_idle + cache_param->timeout_idle; if (when < now) { @@ -224,7 +224,7 @@ http1_cleanup(struct sess *sp, struct worker *wrk, struct req *req) WS_Reset(req->ws, NULL); WS_Reset(wrk->aws, NULL); - if (HTC_Reinit(req->htc) == HTC_COMPLETE) { + if (HTTP1_Reinit(req->htc) == HTTP1_COMPLETE) { req->t_req = sp->t_idle; wrk->stats.sess_pipeline++; return (SESS_DONE_RET_START); @@ -260,7 +260,7 @@ http1_dissect(struct worker *wrk, struct req *req) wrk->vcl = NULL; HTTP_Setup(req->http, req->ws, req->vsl, HTTP_Method); - req->err_code = HTC_DissectRequest(req); + req->err_code = HTTP1_DissectRequest(req); /* If we could not even parse the request, just close */ if (req->err_code == 400) { @@ -330,7 +330,7 @@ HTTP1_Session(struct worker *wrk, struct req *req) } if (sp->sess_step == S_STP_NEWREQ) { - HTC_Init(req->htc, req->ws, sp->fd, req->vsl, + HTTP1_Init(req->htc, req->ws, sp->fd, req->vsl, cache_param->http_req_size, cache_param->http_req_hdr_len); } @@ -442,7 +442,7 @@ http1_iter_req_body(struct req *req, struct http1_r_b_s *rbs, void *buf, req->req_body_status = REQ_BODY_DONE; return (0); } - len = HTC_Read(req->htc, buf, len); + len = HTTP1_Read(req->htc, buf, len); if (len <= 0) { req->req_body_status = REQ_BODY_FAIL; return (-1); diff --git a/bin/varnishd/cache/cache_http1_proto.c b/bin/varnishd/cache/cache_http1_proto.c index 42c2269..8caa135 100644 --- a/bin/varnishd/cache/cache_http1_proto.c +++ b/bin/varnishd/cache/cache_http1_proto.c @@ -46,11 +46,10 @@ #include "vct.h" - /*--------------------------------------------------------------------*/ void -HTC_Init(struct http_conn *htc, struct ws *ws, int fd, struct vsl_log *vsl, +HTTP1_Init(struct http_conn *htc, struct ws *ws, int fd, struct vsl_log *vsl, unsigned maxbytes, unsigned maxhdr) { @@ -60,6 +59,7 @@ HTC_Init(struct http_conn *htc, struct ws *ws, int fd, struct vsl_log *vsl, htc->vsl = vsl; htc->maxbytes = maxbytes; htc->maxhdr = maxhdr; + htc->read = HTTP1_Read; (void)WS_Reserve(htc->ws, htc->maxbytes); htc->rxbuf.b = ws->f; @@ -76,7 +76,7 @@ HTC_Init(struct http_conn *htc, struct ws *ws, int fd, struct vsl_log *vsl, */ enum htc_status_e -HTC_Reinit(struct http_conn *htc) +HTTP1_Reinit(struct http_conn *htc) { unsigned l; @@ -92,7 +92,7 @@ HTC_Reinit(struct http_conn *htc) htc->pipeline.e = NULL; } *htc->rxbuf.e = '\0'; - return (HTC_Complete(htc)); + return (HTTP1_Complete(htc)); } /*-------------------------------------------------------------------- @@ -101,7 +101,7 @@ HTC_Reinit(struct http_conn *htc) */ enum htc_status_e -HTC_Complete(struct http_conn *htc) +HTTP1_Complete(struct http_conn *htc) { int i; const char *p; @@ -120,12 +120,12 @@ HTC_Complete(struct http_conn *htc) /* All white space */ t->e = t->b; *t->e = '\0'; - return (HTC_ALL_WHITESPACE); + return (HTTP1_ALL_WHITESPACE); } while (1) { p = strchr(p, '\n'); if (p == NULL) - return (HTC_NEED_MORE); + return (HTTP1_NEED_MORE); p++; if (*p == '\r') p++; @@ -142,7 +142,7 @@ HTC_Complete(struct http_conn *htc) htc->pipeline.e = htc->rxbuf.e; htc->rxbuf.e = htc->pipeline.b; } - return (HTC_COMPLETE); + return (HTTP1_COMPLETE); } /*-------------------------------------------------------------------- @@ -150,7 +150,7 @@ HTC_Complete(struct http_conn *htc) */ enum htc_status_e -HTC_Rx(struct http_conn *htc) +HTTP1_Rx(struct http_conn *htc) { int i; @@ -159,7 +159,7 @@ HTC_Rx(struct http_conn *htc) i = (htc->ws->r - htc->rxbuf.e) - 1; /* space for NUL */ if (i <= 0) { WS_ReleaseP(htc->ws, htc->rxbuf.b); - return (HTC_OVERFLOW); + return (HTTP1_OVERFLOW); } i = read(htc->fd, htc->rxbuf.e, i); if (i <= 0) { @@ -168,11 +168,11 @@ HTC_Rx(struct http_conn *htc) * so consequently an EOF can not be OK */ WS_ReleaseP(htc->ws, htc->rxbuf.b); - return (HTC_ERROR_EOF); + return (HTTP1_ERROR_EOF); } htc->rxbuf.e += i; *htc->rxbuf.e = '\0'; - return (HTC_Complete(htc)); + return (HTTP1_Complete(htc)); } /*-------------------------------------------------------------------- @@ -180,7 +180,7 @@ HTC_Rx(struct http_conn *htc) */ ssize_t -HTC_Read(struct http_conn *htc, void *d, size_t len) +HTTP1_Read(struct http_conn *htc, void *d, size_t len) { size_t l; unsigned char *p; @@ -390,7 +390,7 @@ htc_proto_ver(struct http *hp) /*--------------------------------------------------------------------*/ uint16_t -HTC_DissectRequest(struct req *req) +HTTP1_DissectRequest(struct req *req) { struct http_conn *htc; struct http *hp; @@ -413,7 +413,7 @@ HTC_DissectRequest(struct req *req) /*--------------------------------------------------------------------*/ uint16_t -HTC_DissectResponse(struct http *hp, const struct http_conn *htc) +HTTP1_DissectResponse(struct http *hp, const struct http_conn *htc) { int j; uint16_t retval = 0; From phk at varnish-cache.org Mon Jan 28 10:37:48 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 28 Jan 2013 11:37:48 +0100 Subject: [master] 4f8456c Inline three small functions of less generality than expected. Message-ID: commit 4f8456c7897475ee9ea5ae05046f12b9a5530b34 Author: Poul-Henning Kamp Date: Mon Jan 28 10:37:20 2013 +0000 Inline three small functions of less generality than expected. diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 27c97c0..e64730b 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -75,45 +75,6 @@ FetchError(struct busyobj *bo, const char *error) } /*-------------------------------------------------------------------- - * VFP method functions - */ - -static void -VFP_Begin(struct busyobj *bo, size_t estimate) -{ - - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - AN(bo->vfp); - - bo->vfp->begin(bo, estimate); -} - -static int -VFP_Bytes(struct busyobj *bo, struct http_conn *htc, ssize_t sz) -{ - - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - AN(bo->vfp); - CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); - assert(bo->state == BOS_FETCHING); - - return (bo->vfp->bytes(bo, htc, sz)); -} - -static void -VFP_End(struct busyobj *bo) -{ - int i; - - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - AN(bo->vfp); - - i = bo->vfp->end(bo); - if (i) - assert(bo->state == BOS_FAILED); -} - -/*-------------------------------------------------------------------- * VFP_NOP * * This fetch-processor does nothing but store the object. @@ -283,7 +244,7 @@ fetch_straight(struct busyobj *bo, struct http_conn *htc, ssize_t cl) } else if (cl == 0) return (0); - i = VFP_Bytes(bo, htc, cl); + i = bo->vfp->bytes(bo, htc, cl); if (i <= 0) return (FetchError(bo, "straight insufficient bytes")); return (0); @@ -341,7 +302,7 @@ fetch_chunked(struct busyobj *bo, struct http_conn *htc) if (cl < 0) return (FetchError(bo,"chunked header number syntax")); - if (cl > 0 && VFP_Bytes(bo, htc, cl) <= 0) + if (cl > 0 && bo->vfp->bytes(bo, htc, cl) <= 0) return (FetchError(bo, "chunked read err")); i = HTTP1_Read(htc, buf, 1); @@ -362,7 +323,7 @@ fetch_eof(struct busyobj *bo, struct http_conn *htc) { assert(htc->body_status == BS_EOF); - if (VFP_Bytes(bo, htc, SSIZE_MAX) < 0) + if (bo->vfp->bytes(bo, htc, SSIZE_MAX) < 0) (void)FetchError(bo,"eof socket fail"); } @@ -553,6 +514,7 @@ FetchBody(struct worker *wrk, void *priv) if (bo->vfp == NULL) bo->vfp = &vfp_nop; + AN(bo->vfp); AZ(bo->vgz_rx); AZ(VTAILQ_FIRST(&obj->store)); @@ -570,26 +532,30 @@ FetchBody(struct worker *wrk, void *priv) break; case BS_LENGTH: cl = fetch_number(bo->h_content_length, 10); - VFP_Begin(bo, cl > 0 ? cl : 0); + + bo->vfp->begin(bo, cl > 0 ? cl : 0); if (bo->state == BOS_FETCHING) cls = fetch_straight(bo, htc, cl); mklen = 1; - VFP_End(bo); + if (bo->vfp->end(bo)) + assert(bo->state == BOS_FAILED); break; case BS_CHUNKED: - VFP_Begin(bo, cl); + bo->vfp->begin(bo, cl > 0 ? cl : 0); if (bo->state == BOS_FETCHING) cls = fetch_chunked(bo, htc); mklen = 1; - VFP_End(bo); + if (bo->vfp->end(bo)) + assert(bo->state == BOS_FAILED); break; case BS_EOF: - VFP_Begin(bo, cl); + bo->vfp->begin(bo, cl > 0 ? cl : 0); if (bo->state == BOS_FETCHING) fetch_eof(bo, htc); mklen = 1; cls = 1; - VFP_End(bo); + if (bo->vfp->end(bo)) + assert(bo->state == BOS_FAILED); break; case BS_ERROR: cls = FetchError(bo, "error incompatible Transfer-Encoding"); From phk at varnish-cache.org Tue Jan 29 14:27:53 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 29 Jan 2013 15:27:53 +0100 Subject: [master] 054fd6a Revisit the managers code to start and stop the child. Message-ID: commit 054fd6a6d3a79fd26d5136b0a486413bce55ff24 Author: Poul-Henning Kamp Date: Tue Jan 29 14:25:39 2013 +0000 Revisit the managers code to start and stop the child. Eliminate SIGCHLD usage, it's icky, at best, when we have other child processes (See #1256) Instead of reaping the child on SIGCHLD, we do it explicitly, and there is now a 10 second wait to give the child a chance to shut down gracefully, before we take a bat to the kneecaps. More work may be warranted, but I want to get some feedback on this bit first. Fixes #1256 diff --git a/bin/varnishd/mgt/mgt_child.c b/bin/varnishd/mgt/mgt_child.c index e6f8700..3def397 100644 --- a/bin/varnishd/mgt/mgt_child.c +++ b/bin/varnishd/mgt/mgt_child.c @@ -57,13 +57,12 @@ #include "mgt_cli.h" -pid_t child_pid = -1; - +pid_t child_pid = -1; static struct vbitmap *fd_map; static int child_cli_in = -1; -static int child_VCLI_Out = -1; +static int child_cli_out = -1; static int child_output = -1; static enum { @@ -84,10 +83,11 @@ static const char * const ch_state[] = { static struct vev *ev_poker; static struct vev *ev_listen; -static struct vlu *vlu; +static struct vlu *child_std_vlu; static struct vsb *child_panic = NULL; +/* XXX: Doesn't really belong here, but only place we use it */ static inline int MGT_FEATURE(enum feature_bits x) { @@ -95,8 +95,82 @@ MGT_FEATURE(enum feature_bits x) (0x80U >> ((unsigned)x & 7))); } +static void mgt_reap_child(void); -/*-------------------------------------------------------------------- +/*--------------------------------------------------------------------- + * A handy little function + */ + +static inline void +closex(int *fd) +{ + + assert(*fd >= 0); + AZ(close(*fd)); + *fd = -1; +} + +/*===================================================================== + * Panic string evacuation and handling + */ + +static void +mgt_panic_record(pid_t r) +{ + char time_str[30]; + + AN(heritage.panic_str[0]); + REPORT(LOG_ERR, "Child (%jd) Panic message: %s", + (intmax_t)r, heritage.panic_str); + + if (child_panic != NULL) + VSB_delete(child_panic); + child_panic = VSB_new_auto(); + AN(child_panic); + VTIM_format(VTIM_real(), time_str); + VSB_printf(child_panic, "Last panic at: %s\n", time_str); + VSB_cat(child_panic, heritage.panic_str); + AZ(VSB_finish(child_panic)); +} + +static void +mgt_panic_clear(void) +{ + VSB_delete(child_panic); + child_panic = NULL; +} + +void __match_proto__(cli_func_t) +mcf_panic_show(struct cli *cli, const char * const *av, void *priv) +{ + (void)av; + (void)priv; + + if (!child_panic) { + VCLI_SetResult(cli, CLIS_CANT); + VCLI_Out(cli, + "Child has not panicked or panic has been cleared"); + return; + } + + VCLI_Out(cli, "%s\n", VSB_data(child_panic)); +} + +void __match_proto__(cli_func_t) +mcf_panic_clear(struct cli *cli, const char * const *av, void *priv) +{ + (void)av; + (void)priv; + + if (child_panic == NULL) { + VCLI_SetResult(cli, CLIS_CANT); + VCLI_Out(cli, "No panic to clear"); + return; + } + mgt_panic_clear(); +} + +/*===================================================================== * Track the highest file descriptor the parent knows is being used. * * This allows the child process to clean/close only a small fraction @@ -124,19 +198,6 @@ mgt_got_fd(int fd) } /*-------------------------------------------------------------------- - * A handy little function - */ - -static inline void -closex(int *fd) -{ - - assert(*fd >= 0); - AZ(close(*fd)); - *fd = -1; -} - -/*-------------------------------------------------------------------- * Keep track of which filedescriptors the child should inherit and * which should be closed after fork() */ @@ -155,80 +216,12 @@ mgt_child_inherit(int fd, const char *what) vbit_clr(fd_map, fd); } -/*--------------------------------------------------------------------*/ - -static int -child_line(void *priv, const char *p) -{ - (void)priv; - - REPORT(LOG_NOTICE, "Child (%jd) said %s", (intmax_t)child_pid, p); - return (0); -} - -/*--------------------------------------------------------------------*/ - -static int -child_listener(const struct vev *e, int what) -{ - - (void)e; - if ((what & ~EV_RD)) { - ev_listen = NULL; - return (1); - } - if (VLU_Fd(child_output, vlu)) { - ev_listen = NULL; - return (1); - } - return (0); -} - -/*--------------------------------------------------------------------*/ - -static int -child_poker(const struct vev *e, int what) -{ - - (void)e; - (void)what; - if (child_state != CH_RUNNING) - return (1); - if (child_pid < 0) - return (0); - if (!mgt_cli_askchild(NULL, NULL, "ping\n")) - return (0); - return (0); -} - -/*-------------------------------------------------------------------- - * If CLI communications with the child process fails, there is nothing - * for us to do but to drag it behind the barn and get it over with. +/*===================================================================== + * Open and close the accept sockets. * - * The typical case is where the child process fails to return a reply - * before the cli_timeout expires. This invalidates the CLI pipes for - * all future use, as we don't know if the child was just slow and the - * result gets piped later on, or if the child is catatonic. + * (The child is priv-sep'ed, so it can't do it.) */ -void -MGT_Child_Cli_Fail(void) -{ - - if (child_state != CH_RUNNING) - return; - if (child_pid < 0) - return; - REPORT(LOG_ERR, "Child (%jd) not responding to CLI, killing it.", - (intmax_t)child_pid); - if (MGT_FEATURE(FEATURE_NO_COREDUMP)) - (void)kill(child_pid, SIGKILL); - else - (void)kill(child_pid, SIGQUIT); -} - -/*--------------------------------------------------------------------*/ - static int open_sockets(void) { @@ -268,10 +261,61 @@ close_sockets(void) } } -/*--------------------------------------------------------------------*/ +/*===================================================================== + * Listen to stdout+stderr from the child + */ + +static int +child_line(void *priv, const char *p) +{ + (void)priv; + + REPORT(LOG_NOTICE, "Child (%jd) said %s", (intmax_t)child_pid, p); + return (0); +} + +/*-------------------------------------------------------------------- + * NB: Notice cleanup call from mgt_reap_child() + */ + +static int __match_proto__(vev_cb_f) +child_listener(const struct vev *e, int what) +{ + + if ((what & ~EV_RD) || VLU_Fd(child_output, child_std_vlu)) { + ev_listen = NULL; + if (e != NULL) + mgt_reap_child(); + return (1); + } + return (0); +} + +/*===================================================================== + * Periodically poke the child, to see that it still lives + */ + +static int __match_proto__(vev_cb_f) +child_poker(const struct vev *e, int what) +{ + + (void)e; + (void)what; + if (child_state != CH_RUNNING) + return (1); + if (child_pid < 0) + return (0); + if (!mgt_cli_askchild(NULL, NULL, "ping\n")) + return (0); + return (0); +} + +/*===================================================================== + * Launch the child process + */ static void -start_child(struct cli *cli) +mgt_launch_child(struct cli *cli) { pid_t pid; unsigned u; @@ -300,7 +344,7 @@ start_child(struct cli *cli) AZ(pipe(cp)); heritage.cli_in = cp[0]; mgt_child_inherit(heritage.cli_in, "cli_in"); - child_VCLI_Out = cp[1]; + child_cli_out = cp[1]; /* Open pipe for child->mgr CLI */ AZ(pipe(cp)); @@ -321,6 +365,7 @@ start_child(struct cli *cli) AN(heritage.vsm); AN(heritage.param); if ((pid = fork()) < 0) { + /* XXX */ perror("Could not fork child"); exit(1); } @@ -334,6 +379,7 @@ start_child(struct cli *cli) /* Close anything we shouldn't know about */ closelog(); + for (i = STDERR_FILENO + 1; i < CLOSE_FD_UP_TO; i++) { if (vbit_test(fd_map, i)) continue; @@ -352,6 +398,7 @@ start_child(struct cli *cli) exit(1); } + assert(pid > 1); REPORT(LOG_NOTICE, "child (%jd) Started", (intmax_t)pid); /* Close stuff the child got */ @@ -365,8 +412,8 @@ start_child(struct cli *cli) close_sockets(); - vlu = VLU_New(NULL, child_line, 0); - AN(vlu); + child_std_vlu = VLU_New(NULL, child_line, 0); + AN(child_std_vlu); AZ(ev_listen); e = vev_new(); @@ -388,7 +435,7 @@ start_child(struct cli *cli) ev_poker = e; } - mgt_cli_start_child(child_cli_in, child_VCLI_Out); + mgt_cli_start_child(child_cli_in, child_cli_out); child_pid = pid; if (mgt_push_vcls_and_start(&u, &p)) { REPORT(LOG_ERR, "Pushing vcls failed:\n%s", p); @@ -399,81 +446,64 @@ start_child(struct cli *cli) child_state = CH_RUNNING; } -/*--------------------------------------------------------------------*/ - -void -mgt_stop_child(void) -{ - - if (child_state != CH_RUNNING) - return; - - child_state = CH_STOPPING; - - REPORT0(LOG_DEBUG, "Stopping Child"); - if (ev_poker != NULL) { - vev_del(mgt_evb, ev_poker); - free(ev_poker); - } - ev_poker = NULL; - - mgt_cli_stop_child(); - - /* We tell the child to die gracefully by closing the CLI */ - closex(&child_VCLI_Out); - closex(&child_cli_in); -} - -/*--------------------------------------------------------------------*/ - -static void -mgt_handle_panicstr(pid_t r) -{ - char time_str[30]; - - AN(heritage.panic_str[0]); - REPORT(LOG_ERR, "Child (%jd) Panic message: %s", - (intmax_t)r, heritage.panic_str); - - if (child_panic) - VSB_delete(child_panic); - child_panic = VSB_new_auto(); - XXXAN(child_panic); - VTIM_format(VTIM_real(), time_str); - VSB_printf(child_panic, "Last panic at: %s\n", time_str); - VSB_cat(child_panic, heritage.panic_str); - AZ(VSB_finish(child_panic)); -} +/*===================================================================== + * Cleanup when child dies. + */ static void -mgt_clear_panic(void) -{ - VSB_delete(child_panic); - child_panic = NULL; -} - -/*--------------------------------------------------------------------*/ - -static int -mgt_sigchld(const struct vev *e, int what) +mgt_reap_child(void) { + int i; int status; struct vsb *vsb; pid_t r; - (void)e; - (void)what; + assert(child_pid != -1); + + /* + * Close the CLI connections + * This signals orderly shut down to child + */ + mgt_cli_stop_child(); + if (child_cli_out >= 0) + closex(&child_cli_out); + if (child_cli_in >= 0) + closex(&child_cli_in); + /* Stop the poker */ if (ev_poker != NULL) { vev_del(mgt_evb, ev_poker); free(ev_poker); } ev_poker = NULL; - r = waitpid(child_pid, &status, WNOHANG); - if (r == 0 || (r == -1 && errno == ECHILD)) - return (0); + /* Stop the listener */ + if (ev_listen != NULL) { + vev_del(mgt_evb, ev_listen); + free(ev_listen); + ev_listen = NULL; + } + + /* Wait 10 seconds for child to die */ + for (i = 0; i < 10; i++) { + r = waitpid(child_pid, &status, WNOHANG); + if (r == child_pid) + break; + (void)sleep(1); + } + if (r == 0) { + /* Kick it Jim... */ + if (MGT_FEATURE(FEATURE_NO_COREDUMP)) + (void)kill(child_pid, SIGKILL); + else + (void)kill(child_pid, SIGQUIT); + r = waitpid(child_pid, &status, 0); + } + if (r != child_pid) + fprintf(stderr, "WAIT 0x%x\n", r); assert(r == child_pid); + + /* Compose obituary */ vsb = VSB_new_auto(); XXXAN(vsb); VSB_printf(vsb, "Child (%ld) %s", (long)r, status ? "died" : "ended"); @@ -495,47 +525,118 @@ mgt_sigchld(const struct vev *e, int what) REPORT(LOG_INFO, "%s", VSB_data(vsb)); VSB_delete(vsb); + /* Dispose of shared memory but evacuate panic messages first */ if (heritage.panic_str[0] != '\0') { - mgt_handle_panicstr(r); + mgt_panic_record(r); mgt_SHM_Destroy(1); } else { mgt_SHM_Destroy(0); } mgt_SHM_Create(); - child_pid = -1; - - if (child_state == CH_RUNNING) { + if (child_state == CH_RUNNING) child_state = CH_DIED; - mgt_cli_stop_child(); - closex(&child_VCLI_Out); - closex(&child_cli_in); - } - if (ev_listen != NULL) { - vev_del(mgt_evb, ev_listen); - free(ev_listen); - ev_listen = NULL; - } /* Pick up any stuff lingering on stdout/stderr */ (void)child_listener(NULL, EV_RD); closex(&child_output); + VLU_Destroy(child_std_vlu); + + child_pid = -1; REPORT0(LOG_DEBUG, "Child cleanup complete"); if (child_state == CH_DIED && mgt_param.auto_restart) - start_child(NULL); - else if (child_state == CH_DIED) { + mgt_launch_child(NULL); + else if (child_state == CH_DIED) child_state = CH_STOPPED; - } else if (child_state == CH_STOPPING) + else if (child_state == CH_STOPPING) child_state = CH_STOPPED; +} - return (0); +/*===================================================================== + * If CLI communications with the child process fails, there is nothing + * for us to do but to drag it behind the barn and get it over with. + * + * The typical case is where the child process fails to return a reply + * before the cli_timeout expires. This invalidates the CLI pipes for + * all future use, as we don't know if the child was just slow and the + * result gets piped later on, or if the child is catatonic. + */ + +void +MGT_Child_Cli_Fail(void) +{ + + if (child_state != CH_RUNNING) + return; + if (child_pid < 0) + return; + REPORT(LOG_ERR, "Child (%jd) not responding to CLI, killing it.", + (intmax_t)child_pid); + if (MGT_FEATURE(FEATURE_NO_COREDUMP)) + (void)kill(child_pid, SIGKILL); + else + (void)kill(child_pid, SIGQUIT); +} + +/*===================================================================== + * Controlled stop of child process + * + * Reaping the child asks for orderly shutdown + */ + +void +mgt_stop_child(void) +{ + + if (child_state != CH_RUNNING) + return; + + child_state = CH_STOPPING; + + REPORT0(LOG_DEBUG, "Stopping Child"); + + mgt_reap_child(); +} + +/*===================================================================== + * CLI command to start/stop child + */ + +void __match_proto__(cli_func_t) +mcf_server_startstop(struct cli *cli, const char * const *av, void *priv) +{ + + (void)av; + if (priv != NULL && child_state == CH_RUNNING) + mgt_stop_child(); + else if (priv == NULL && child_state == CH_STOPPED) { + if (mgt_has_vcl()) { + mgt_launch_child(cli); + } else { + VCLI_SetResult(cli, CLIS_CANT); + VCLI_Out(cli, "No VCL available"); + } + } else { + VCLI_SetResult(cli, CLIS_CANT); + VCLI_Out(cli, "Child in state %s", ch_state[child_state]); + } } /*--------------------------------------------------------------------*/ -static int +void +mcf_server_status(struct cli *cli, const char * const *av, void *priv) +{ + (void)av; + (void)priv; + VCLI_Out(cli, "Child in state %s", ch_state[child_state]); +} + +/*--------------------------------------------------------------------*/ + +static int __match_proto__(vev_cb_f) mgt_sigint(const struct vev *e, int what) { @@ -548,7 +649,7 @@ mgt_sigint(const struct vev *e, int what) exit (2); } -/*-------------------------------------------------------------------- +/*===================================================================== * This thread is the master thread in the management process. * The relatively simple task is to start and stop the child process * and to reincarnate it in case of trouble. @@ -575,14 +676,6 @@ MGT_Run(void) e->name = "mgt_sigint"; AZ(vev_add(mgt_evb, e)); - e = vev_new(); - XXXAN(e); - e->sig = SIGCHLD; - e->sig_flags = SA_NOCLDSTOP; - e->callback = mgt_sigchld; - e->name = "mgt_sigchild"; - AZ(vev_add(mgt_evb, e)); - #ifdef HAVE_SETPROCTITLE setproctitle("Varnish-Mgr %s", heritage.name); #endif @@ -597,7 +690,7 @@ MGT_Run(void) if (!d_flag && !mgt_has_vcl()) REPORT0(LOG_ERR, "No VCL loaded yet"); else if (!d_flag) { - start_child(NULL); + mgt_launch_child(NULL); if (child_state == CH_STOPPED) { exit_status = 2; return; @@ -610,65 +703,3 @@ MGT_Run(void) REPORT0(LOG_ERR, "manager dies"); } - -/*--------------------------------------------------------------------*/ - -void __match_proto__(cli_func_t) -mcf_server_startstop(struct cli *cli, const char * const *av, void *priv) -{ - - (void)av; - if (priv != NULL && child_state == CH_RUNNING) - mgt_stop_child(); - else if (priv == NULL && child_state == CH_STOPPED) { - if (mgt_has_vcl()) { - start_child(cli); - } else { - VCLI_SetResult(cli, CLIS_CANT); - VCLI_Out(cli, "No VCL available"); - } - } else { - VCLI_SetResult(cli, CLIS_CANT); - VCLI_Out(cli, "Child in state %s", ch_state[child_state]); - } -} - -/*--------------------------------------------------------------------*/ - -void -mcf_server_status(struct cli *cli, const char * const *av, void *priv) -{ - (void)av; - (void)priv; - VCLI_Out(cli, "Child in state %s", ch_state[child_state]); -} - -void -mcf_panic_show(struct cli *cli, const char * const *av, void *priv) -{ - (void)av; - (void)priv; - - if (!child_panic) { - VCLI_SetResult(cli, CLIS_CANT); - VCLI_Out(cli, "Child has not panicked or panic has been cleared"); - return; - } - - VCLI_Out(cli, "%s\n", VSB_data(child_panic)); -} - -void -mcf_panic_clear(struct cli *cli, const char * const *av, void *priv) -{ - (void)av; - (void)priv; - - if (!child_panic) { - VCLI_SetResult(cli, CLIS_CANT); - VCLI_Out(cli, "No panic to clear"); - return; - } - - mgt_clear_panic(); -} From adiedler at tecracer.de Tue Jan 29 22:02:50 2013 From: adiedler at tecracer.de (Alexander Diedler) Date: Tue, 29 Jan 2013 23:02:50 +0100 Subject: VArnish 3.0.3 and Typo3 with ELB Message-ID: <739CCB2D4BF8FD48985D6E158AD327B83A5ED09505@DC01.tecracerde.local> Hello, We have some troube with a Varnish Cache, that is fronted by a Amazon Elatic Loadbalancer. We need to keep the PHPSESSID and if the user is logged into the backend, the cache must be passed. Do anybody have a similar szenario? Best regards Alexander From phk at varnish-cache.org Wed Jan 30 10:14:49 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 30 Jan 2013 11:14:49 +0100 Subject: [master] 2bbb032 Split absolute URIs into URL and Host: as per RFC2616 5.2 Message-ID: commit 2bbb032bf67871d7d5a43a38104d58f747f2e860 Author: Poul-Henning Kamp Date: Wed Jan 30 10:05:54 2013 +0000 Split absolute URIs into URL and Host: as per RFC2616 5.2 Fixes #1255 diff --git a/bin/varnishd/cache/cache_http1_proto.c b/bin/varnishd/cache/cache_http1_proto.c index 8caa135..e0c8b83 100644 --- a/bin/varnishd/cache/cache_http1_proto.c +++ b/bin/varnishd/cache/cache_http1_proto.c @@ -389,12 +389,15 @@ htc_proto_ver(struct http *hp) /*--------------------------------------------------------------------*/ +#include + uint16_t HTTP1_DissectRequest(struct req *req) { struct http_conn *htc; struct http *hp; uint16_t retval; + char *b, *e; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); htc = req->htc; @@ -408,8 +411,22 @@ HTTP1_DissectRequest(struct req *req) return (retval); } htc_proto_ver(hp); + + /* RFC2616, section 5.2, point 1 */ + if (!strncasecmp(hp->hd[HTTP_HDR_URL].b, "http://", 7)) { + b = e = hp->hd[HTTP_HDR_URL].b + 7; + while (*e != '/' && *e != '\0') + e++; + if (*e == '/') { + http_Unset(hp, H_Host); + http_PrintfHeader(hp, "Host: %.*s", (int)(e - b), b); + hp->hd[HTTP_HDR_URL].b = e; + } + } + return (retval); } + /*--------------------------------------------------------------------*/ uint16_t diff --git a/bin/varnishtest/tests/r01255.vtc b/bin/varnishtest/tests/r01255.vtc new file mode 100644 index 0000000..cb53d71 --- /dev/null +++ b/bin/varnishtest/tests/r01255.vtc @@ -0,0 +1,19 @@ +varnishtest "Test RFC2616 5.2 compliance" + +server s1 { + rxreq + txresp -hdr "Foo: 1" +} -start + +varnish v1 -vcl+backend { + + sub vcl_deliver { + set resp.http.rxhost = req.http.host; + } +} -start + +client c1 { + txreq -url http://www.example.com/bar + rxresp + expect resp.http.rxhost == www.example.com +} -run From phk at varnish-cache.org Wed Jan 30 10:14:49 2013 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 30 Jan 2013 11:14:49 +0100 Subject: [master] c94a427 Move http_Write() to HTTP1_Write(). The name is still not really good, but at least it belongs here. Message-ID: commit c94a427138d2d2e45c48589bf137c4a38b46cc61 Author: Poul-Henning Kamp Date: Wed Jan 30 10:14:27 2013 +0000 Move http_Write() to HTTP1_Write(). The name is still not really good, but at least it belongs here. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index f5ebf7a..6be2c73 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -851,7 +851,6 @@ const char *http_StatusMessage(unsigned); unsigned http_EstimateWS(const struct http *fm, unsigned how, uint16_t *nhd); void HTTP_Init(void); void http_ClrHeader(struct http *to); -unsigned http_Write(const struct worker *w, const struct http *hp, int resp); void http_SetResp(struct http *to, const char *proto, uint16_t status, const char *response); void http_FilterReq(const struct req *, unsigned how); @@ -899,6 +898,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); #define HTTPH(a, b, c) extern char b[]; #include "tbl/http_headers.h" diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index e64730b..f4befdf 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -402,7 +402,7 @@ FetchHdr(struct req *req, int need_host_hdr, int sendbody) (void)VTCP_blocking(vc->fd); /* XXX: we should timeout instead */ WRW_Reserve(wrk, &vc->fd, bo->vsl, req->t_req); /* XXX t_resp ? */ - (void)http_Write(wrk, hp, 0); /* XXX: stats ? */ + (void)HTTP1_Write(wrk, hp, 0); /* XXX: stats ? */ /* Deal with any message-body the request might (still) have */ i = 0; diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index c46cb15..e9f9e22 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -793,49 +793,6 @@ HTTP_Copy(struct http *to, const struct http * const fm) /*--------------------------------------------------------------------*/ -unsigned -http_Write(const struct worker *w, const struct http *hp, int resp) -{ - unsigned u, l; - - if (resp) { - l = WRW_WriteH(w, &hp->hd[HTTP_HDR_PROTO], " "); - http_VSLH(hp, HTTP_HDR_PROTO); - - hp->hd[HTTP_HDR_STATUS].b = WS_Alloc(hp->ws, 4); - AN(hp->hd[HTTP_HDR_STATUS].b); - - 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], " "); - http_VSLH(hp, HTTP_HDR_STATUS); - - l += WRW_WriteH(w, &hp->hd[HTTP_HDR_RESPONSE], "\r\n"); - http_VSLH(hp, HTTP_HDR_RESPONSE); - } else { - AN(hp->hd[HTTP_HDR_URL].b); - l = WRW_WriteH(w, &hp->hd[HTTP_HDR_METHOD], " "); - http_VSLH(hp, HTTP_HDR_METHOD); - l += WRW_WriteH(w, &hp->hd[HTTP_HDR_URL], " "); - http_VSLH(hp, HTTP_HDR_URL); - l += WRW_WriteH(w, &hp->hd[HTTP_HDR_PROTO], "\r\n"); - http_VSLH(hp, HTTP_HDR_PROTO); - } - 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); - l += WRW_WriteH(w, &hp->hd[u], "\r\n"); - http_VSLH(hp, u); - } - l += WRW_Write(w, "\r\n", -1); - return (l); -} - -/*--------------------------------------------------------------------*/ - void HTTP_Init(void) { diff --git a/bin/varnishd/cache/cache_http1_proto.c b/bin/varnishd/cache/cache_http1_proto.c index e0c8b83..00ed9bf 100644 --- a/bin/varnishd/cache/cache_http1_proto.c +++ b/bin/varnishd/cache/cache_http1_proto.c @@ -482,3 +482,46 @@ HTTP1_DissectResponse(struct http *hp, const struct http_conn *htc) return (retval); } +/*--------------------------------------------------------------------*/ + +unsigned +HTTP1_Write(const struct worker *w, const struct http *hp, int resp) +{ + unsigned u, l; + + if (resp) { + l = WRW_WriteH(w, &hp->hd[HTTP_HDR_PROTO], " "); + http_VSLH(hp, HTTP_HDR_PROTO); + + hp->hd[HTTP_HDR_STATUS].b = WS_Alloc(hp->ws, 4); + AN(hp->hd[HTTP_HDR_STATUS].b); + + 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], " "); + http_VSLH(hp, HTTP_HDR_STATUS); + + l += WRW_WriteH(w, &hp->hd[HTTP_HDR_RESPONSE], "\r\n"); + http_VSLH(hp, HTTP_HDR_RESPONSE); + } else { + AN(hp->hd[HTTP_HDR_URL].b); + l = WRW_WriteH(w, &hp->hd[HTTP_HDR_METHOD], " "); + http_VSLH(hp, HTTP_HDR_METHOD); + l += WRW_WriteH(w, &hp->hd[HTTP_HDR_URL], " "); + http_VSLH(hp, HTTP_HDR_URL); + l += WRW_WriteH(w, &hp->hd[HTTP_HDR_PROTO], "\r\n"); + http_VSLH(hp, HTTP_HDR_PROTO); + } + 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); + l += WRW_WriteH(w, &hp->hd[u], "\r\n"); + http_VSLH(hp, u); + } + 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 f13bbcc..36c48ad 100644 --- a/bin/varnishd/cache/cache_pipe.c +++ b/bin/varnishd/cache/cache_pipe.c @@ -82,7 +82,7 @@ PipeRequest(struct req *req) (void)VTCP_blocking(vc->fd); WRW_Reserve(wrk, &vc->fd, bo->vsl, req->t_req); - req->acct_req.hdrbytes += http_Write(wrk, bo->bereq, 0); + req->acct_req.hdrbytes += HTTP1_Write(wrk, bo->bereq, 0); if (req->htc->pipeline.b != NULL) req->acct_req.bodybytes += diff --git a/bin/varnishd/cache/cache_response.c b/bin/varnishd/cache/cache_response.c index 3fecd27..b49f405 100644 --- a/bin/varnishd/cache/cache_response.c +++ b/bin/varnishd/cache/cache_response.c @@ -260,7 +260,7 @@ RES_WriteObj(struct req *req) */ if (!(req->res_mode & RES_ESI_CHILD)) req->acct_req.hdrbytes += - http_Write(req->wrk, req->resp, 1); + HTTP1_Write(req->wrk, req->resp, 1); if (!req->wantbody) req->res_mode &= ~RES_CHUNKED;