From phk at FreeBSD.org Wed Oct 1 07:23:27 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 01 Oct 2014 09:23:27 +0200 Subject: [master] 3299b79 Ask the director for the suckaddr, rather than groping around inside it's privates for it. Message-ID: commit 3299b7935c4ebfcd41ba92db9a11c7639f885258 Author: Poul-Henning Kamp Date: Wed Oct 1 07:23:07 2014 +0000 Ask the director for the suckaddr, rather than groping around inside it's privates for it. diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 845da6a..2fbb223 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -513,6 +513,18 @@ vdi_simple_finish(const struct director *d, struct worker *wrk, } } +static struct suckaddr * __match_proto__(vdi_suckaddr_f) +vdi_simple_suckaddr(const struct director *d, struct worker *wrk, + struct busyobj *bo) +{ + CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + + if (bo->vbc != NULL) + return(bo->vbc->addr); + return (NULL); +} /*--------------------------------------------------------------------*/ @@ -555,6 +567,7 @@ VRT_init_dir(VRT_CTX, struct director **bp, int idx, vs->dir.gethdrs = vdi_simple_gethdrs; vs->dir.getbody = vdi_simple_getbody; vs->dir.finish = vdi_simple_finish; + vs->dir.suckaddr = vdi_simple_suckaddr; vs->vrt = t; diff --git a/bin/varnishd/cache/cache_backend.h b/bin/varnishd/cache/cache_backend.h index 5c18107..fefb7bd 100644 --- a/bin/varnishd/cache/cache_backend.h +++ b/bin/varnishd/cache/cache_backend.h @@ -63,6 +63,8 @@ typedef int vdi_getbody_f(const struct director *, struct worker *, struct busyobj *); typedef void vdi_finish_f(const struct director *, struct worker *, struct busyobj *); +typedef struct suckaddr *vdi_suckaddr_f(const struct director *, + struct worker *, struct busyobj *); struct director { unsigned magic; @@ -75,6 +77,7 @@ struct director { vdi_gethdrs_f *gethdrs; vdi_getbody_f *getbody; vdi_finish_f *finish; + vdi_suckaddr_f *suckaddr; void *priv; }; @@ -168,6 +171,8 @@ void VDI_Finish(const struct director *d, struct worker *wrk, struct vbc *VDI_GetFd(const struct director *d, struct worker *wrk, struct busyobj *); int VDI_Healthy(const struct director *); +struct suckaddr *VDI_Suckaddr(const struct director *d, struct worker *wrk, + struct busyobj *bo); void VDI_AddHostHeader(struct http *to, const struct vbc *vbc); void VBE_Poll(void); void VDI_Init(void); diff --git a/bin/varnishd/cache/cache_dir.c b/bin/varnishd/cache/cache_dir.c index 9f7ae43..c58d5a9 100644 --- a/bin/varnishd/cache/cache_dir.c +++ b/bin/varnishd/cache/cache_dir.c @@ -155,3 +155,16 @@ VDI_Healthy(const struct director *d) AN(d->healthy); return (d->healthy(d, NULL)); } + +/* Get suckaddr ------------------------------------------------------*/ + +struct suckaddr * +VDI_Suckaddr(const struct director *d, struct worker *wrk, struct busyobj *bo) +{ + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); + + AN(d->suckaddr); + return (d->suckaddr(d, wrk, bo)); +} diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index ff49d3a..489a074 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -324,11 +324,7 @@ VRT_r_beresp_backend_ip(VRT_CTX) CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC); - if (ctx->bo->vbc != NULL) { - CHECK_OBJ_NOTNULL(ctx->bo->vbc, VBC_MAGIC); - return(ctx->bo->vbc->addr); - } else - return (NULL); + return (VDI_Suckaddr(ctx->bo->director_resp, ctx->bo->wrk, ctx->bo)); } /*--------------------------------------------------------------------*/ From phk at FreeBSD.org Wed Oct 1 08:54:06 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 01 Oct 2014 10:54:06 +0200 Subject: [master] db649fe Add some sanity-asserts to vsl buffers Message-ID: commit db649fe6138a146d8396ca69e2d61133d0436f89 Author: Poul-Henning Kamp Date: Wed Oct 1 08:53:47 2014 +0000 Add some sanity-asserts to vsl buffers diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c index 66d7c89..04c24a8 100644 --- a/bin/varnishd/cache/cache_shmlog.c +++ b/bin/varnishd/cache/cache_shmlog.c @@ -53,6 +53,16 @@ static unsigned vsl_seq; struct VSC_C_main *VSC_C_main; + +static void +vsl_sanity(const struct vsl_log *vsl) +{ + AN(vsl); + AN(vsl->wlp); + AN(vsl->wlb); + AN(vsl->wle); +} + /*-------------------------------------------------------------------- * Check if the VSL_tag is masked by parameter bitmap */ @@ -238,6 +248,7 @@ VSL_Flush(struct vsl_log *vsl, int overflow) uint32_t *p; unsigned l; + vsl_sanity(vsl); l = pdiff(vsl->wlb, vsl->wlp); if (l == 0) return; @@ -264,6 +275,7 @@ VSLbt(struct vsl_log *vsl, enum VSL_tag_e tag, txt t) unsigned l, mlen; char *p; + vsl_sanity(vsl); Tcheck(t); if (vsl_tag_is_masked(tag)) return; @@ -303,7 +315,7 @@ VSLbv(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, va_list ap) unsigned n, mlen; txt t; - AN(vsl); + vsl_sanity(vsl); AN(fmt); if (vsl_tag_is_masked(tag)) return; @@ -346,6 +358,7 @@ VSLb(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, ...) { va_list ap; + vsl_sanity(vsl); va_start(ap, fmt); VSLbv(vsl, tag, fmt, ap); va_end(ap); @@ -360,6 +373,7 @@ VSLb_ts(struct vsl_log *vsl, const char *event, double first, double *pprev, logging. This must be done carefully because some functions (e.g. WRW_Reserve) takes the last timestamp as it's inital value for timeout calculation. */ + vsl_sanity(vsl); assert(!isnan(now) && now != 0.); VSLb(vsl, SLT_Timestamp, "%s: %.6f %.6f %.6f", event, now, now - first, now - *pprev); @@ -385,6 +399,7 @@ VSL_Setup(struct vsl_log *vsl, void *ptr, size_t len) vsl->wle += len / sizeof(*vsl->wle); vsl->wlr = 0; vsl->wid = 0; + vsl_sanity(vsl); } /*--------------------------------------------------------------------*/ @@ -394,6 +409,7 @@ VSL_ChgId(struct vsl_log *vsl, const char *typ, const char *why, uint32_t vxid) { uint32_t ovxid; + vsl_sanity(vsl); ovxid = vsl->wid; VSLb(vsl, SLT_Link, "%s %u %s", typ, VXID(vxid), why); VSL_End(vsl); @@ -409,6 +425,7 @@ VSL_End(struct vsl_log *vsl) txt t; char p[] = ""; + vsl_sanity(vsl); AN(vsl->wid); t.b = p; t.e = p; From phk at FreeBSD.org Wed Oct 1 10:28:58 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 01 Oct 2014 12:28:58 +0200 Subject: [master] 4b8bf44 Move the ->getfd() responsibilities a few microns. Message-ID: commit 4b8bf44b59ba66ae534990df3adb27f4629ce7d8 Author: Poul-Henning Kamp Date: Wed Oct 1 10:28:29 2014 +0000 Move the ->getfd() responsibilities a few microns. diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 2fbb223..2032787 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -429,6 +429,10 @@ vdi_simple_getfd(const struct director *d, struct busyobj *bo) FIND_TMO(between_bytes_timeout, vc->between_bytes_timeout, bo, vs->vrt); } + if (vc != NULL) + vc->vsl = bo->vsl; + else + VSLb(bo->vsl, SLT_FetchError, "no backend connection"); return (vc); } @@ -455,7 +459,7 @@ vdi_simple_gethdrs(const struct director *d, struct worker *wrk, CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - bo->vbc = VDI_GetFd(d, wrk, bo); + bo->vbc = vdi_simple_getfd(d, bo); if (bo->vbc == NULL) { VSLb(bo->vsl, SLT_FetchError, "no backend connection"); return (-1); diff --git a/bin/varnishd/cache/cache_dir.c b/bin/varnishd/cache/cache_dir.c index c58d5a9..9d5b31b 100644 --- a/bin/varnishd/cache/cache_dir.c +++ b/bin/varnishd/cache/cache_dir.c @@ -127,7 +127,6 @@ VDI_Finish(const struct director *d, struct worker *wrk, struct busyobj *bo) struct vbc * VDI_GetFd(const struct director *d, struct worker *wrk, struct busyobj *bo) { - struct vbc *vc; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); @@ -138,10 +137,7 @@ VDI_GetFd(const struct director *d, struct worker *wrk, struct busyobj *bo) return (NULL); AN(d->getfd); - vc = d->getfd(d, bo); - if (vc != NULL) - vc->vsl = bo->vsl; - return (vc); + return (d->getfd(d, bo)); } /* Check health ------------------------------------------------------ diff --git a/bin/varnishd/cache/cache_pipe.c b/bin/varnishd/cache/cache_pipe.c index 2e2d57d..3d17735 100644 --- a/bin/varnishd/cache/cache_pipe.c +++ b/bin/varnishd/cache/cache_pipe.c @@ -115,7 +115,6 @@ PipeRequest(struct req *req, struct busyobj *bo) vc = VDI_GetFd(bo->director_req, wrk, bo); if (vc == NULL) { - VSLb(bo->vsl, SLT_FetchError, "no backend connection"); pipecharge(req, &acct_pipe, NULL); SES_Close(req->sp, SC_OVERLOAD); return; From phk at FreeBSD.org Wed Oct 1 19:05:14 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 01 Oct 2014 21:05:14 +0200 Subject: [master] 3e08b8b Minor polish Message-ID: commit 3e08b8bb9b6885694d75ae70e97a10736554df25 Author: Poul-Henning Kamp Date: Wed Oct 1 11:31:57 2014 +0000 Minor polish diff --git a/bin/varnishd/cache/cache_http1_fetch.c b/bin/varnishd/cache/cache_http1_fetch.c index ca369d2..7c61514 100644 --- a/bin/varnishd/cache/cache_http1_fetch.c +++ b/bin/varnishd/cache/cache_http1_fetch.c @@ -153,7 +153,7 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo) /* Receive response */ - HTTP1_Init(htc, bo->ws, vc->fd, vc->vsl, + HTTP1_Init(htc, bo->ws, vc->fd, bo->vsl, cache_param->http_resp_size, cache_param->http_resp_hdr_len); CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); From phk at FreeBSD.org Wed Oct 1 19:05:14 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 01 Oct 2014 21:05:14 +0200 Subject: [master] 025f102 Firmly split "director" from "backend". Message-ID: commit 025f1029abfb75069996b605a6ebf52cea5b4c23 Author: Poul-Henning Kamp Date: Wed Oct 1 18:14:38 2014 +0000 Firmly split "director" from "backend". A director is noe an abstract entity which can fetch something for us, however it decides to do that and using whatever protocol (or none). A backend is a network endpoint designated by a precise triplet of VCL backend name IPv4 address (incl port) IPv6 address (incl port) Backends are _also_ "simple" directors, but have an extra layer of complexity in order to enable connection management, including connection reuse across vcl.use commands. diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 26ad745..64fd313 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -16,7 +16,7 @@ varnishd_SOURCES = \ cache/cache_ban.c \ cache/cache_busyobj.c \ cache/cache_cli.c \ - cache/cache_dir.c \ + cache/cache_director.c \ cache/cache_esi_deliver.c \ cache/cache_esi_fetch.c \ cache/cache_esi_parse.c \ @@ -91,6 +91,7 @@ varnishd_SOURCES = \ noinst_HEADERS = \ cache/cache_backend.h \ + cache/cache_director.h \ cache/cache_esi.h \ common/heritage.h \ builtin_vcl.h \ diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 2032787..0918301 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -40,6 +40,7 @@ #include "cache.h" #include "cache_backend.h" +#include "cache_director.h" #include "vrt.h" #include "vtcp.h" diff --git a/bin/varnishd/cache/cache_backend.h b/bin/varnishd/cache/cache_backend.h index fefb7bd..e809926 100644 --- a/bin/varnishd/cache/cache_backend.h +++ b/bin/varnishd/cache/cache_backend.h @@ -26,14 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Backend and Director APIs - * - * A director ("VDI") is an abstract entity which can either satisfy a - * backend fetch request or select another director for the job. - * - * In theory a director does not have to talk HTTP over TCP, it can satisfy - * the backend request using any means it wants, although this is presently - * not implemented. + * Backend and APIs * * A backend ("VBE") is a director which talks HTTP over TCP. * @@ -49,39 +42,6 @@ struct vbc; struct vrt_backend_probe; /*-------------------------------------------------------------------- - * A director is a piece of code which selects one of possibly multiple - * backends to use. - */ - -typedef struct vbc *vdi_getfd_f(const struct director *, struct busyobj *); -typedef unsigned vdi_healthy_f(const struct director *, double *changed); -typedef const struct director *vdi_resolve_f(const struct director *, - struct worker *, struct busyobj *); -typedef int vdi_gethdrs_f(const struct director *, struct worker *, - struct busyobj *); -typedef int vdi_getbody_f(const struct director *, struct worker *, - struct busyobj *); -typedef void vdi_finish_f(const struct director *, struct worker *, - struct busyobj *); -typedef struct suckaddr *vdi_suckaddr_f(const struct director *, - struct worker *, struct busyobj *); - -struct director { - unsigned magic; -#define DIRECTOR_MAGIC 0x3336351d - const char *name; - char *vcl_name; - vdi_getfd_f *getfd; - vdi_healthy_f *healthy; - vdi_resolve_f *resolve; - vdi_gethdrs_f *gethdrs; - vdi_getbody_f *getbody; - vdi_finish_f *finish; - vdi_suckaddr_f *suckaddr; - void *priv; -}; - -/*-------------------------------------------------------------------- * An instance of a backend from a VCL program. */ @@ -154,6 +114,7 @@ void VBE_DropRefLocked(struct backend *b, const struct acct_bereq *); unsigned VBE_Healthy(const struct backend *b, double *changed); void VBE_InitCfg(void); struct backend *VBE_AddBackend(struct cli *cli, const struct vrt_backend *vb); +void VBE_Poll(void); /* cache_backend_poll.c */ void VBP_Insert(struct backend *b, struct vrt_backend_probe const *p, @@ -162,21 +123,6 @@ void VBP_Remove(struct backend *b, struct vrt_backend_probe const *p); void VBP_Use(const struct backend *b, const struct vrt_backend_probe *p); void VBP_Summary(struct cli *cli, const struct vbp_target *vt); -/* cache_dir.c */ -int VDI_GetHdr(struct worker *wrk, struct busyobj *bo); -int VDI_GetBody(const struct director *d, struct worker *wrk, - struct busyobj *bo); -void VDI_Finish(const struct director *d, struct worker *wrk, - struct busyobj *bo); -struct vbc *VDI_GetFd(const struct director *d, struct worker *wrk, - struct busyobj *); -int VDI_Healthy(const struct director *); -struct suckaddr *VDI_Suckaddr(const struct director *d, struct worker *wrk, - struct busyobj *bo); -void VDI_AddHostHeader(struct http *to, const struct vbc *vbc); -void VBE_Poll(void); -void VDI_Init(void); - /* cache_backend_poll.c */ void VBP_Init(void); diff --git a/bin/varnishd/cache/cache_dir.c b/bin/varnishd/cache/cache_dir.c deleted file mode 100644 index 9d5b31b..0000000 --- a/bin/varnishd/cache/cache_dir.c +++ /dev/null @@ -1,166 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2014 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. - * - * Abstract director API - * - * The abstract director API does not know how we talk to the backend or - * if there even is one in the usual meaning of the word. - * - */ - -#include "config.h" - -#include "cache.h" - -#include "cache_backend.h" - -/* Resolve director --------------------------------------------------*/ - -static const struct director * -vdi_resolve(struct worker *wrk, struct busyobj *bo, const struct director *d) -{ - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - - if (d == NULL) { - VSLb(bo->vsl, SLT_FetchError, "No backend"); - return (NULL); - } - - while (d != NULL && d->resolve != NULL) { - CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); - d = d->resolve(d, wrk, bo); - } - CHECK_OBJ_ORNULL(d, DIRECTOR_MAGIC); - if (d == NULL) - VSLb(bo->vsl, SLT_FetchError, "Backend selection failed"); - bo->director_resp = d; - return (d); -} - -/* Get a set of response headers -------------------------------------*/ - -int -VDI_GetHdr(struct worker *wrk, struct busyobj *bo) -{ - const struct director *d; - int i = -1; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - - d = vdi_resolve(wrk, bo, bo->director_req); - if (d != NULL) { - AN(d->gethdrs); - bo->director_state = DIR_S_HDRS; - i = d->gethdrs(d, wrk, bo); - } - if (i) - bo->director_state = DIR_S_NULL; - return (i); -} - -/* Setup body fetch --------------------------------------------------*/ - -int -VDI_GetBody(const struct director *d, struct worker *wrk, struct busyobj *bo) -{ - - CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - - AZ(d->resolve); - AN(d->getbody); - - bo->director_state = DIR_S_BODY; - return (d->getbody(d, wrk, bo)); -} - -/* Finish fetch ------------------------------------------------------*/ - -void -VDI_Finish(const struct director *d, struct worker *wrk, struct busyobj *bo) -{ - - CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - - AZ(d->resolve); - AN(d->finish); - - assert(bo->director_state != DIR_S_NULL); - bo->director_state = DIR_S_NULL; - - d->finish(d, wrk, bo); -} - -/* Get a connection --------------------------------------------------*/ - -struct vbc * -VDI_GetFd(const struct director *d, struct worker *wrk, struct busyobj *bo) -{ - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); - - d = vdi_resolve(wrk, bo, d); - if (d == NULL) - return (NULL); - - AN(d->getfd); - return (d->getfd(d, bo)); -} - -/* Check health ------------------------------------------------------ - */ - -int -VDI_Healthy(const struct director *d) -{ - - CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); - AN(d->healthy); - return (d->healthy(d, NULL)); -} - -/* Get suckaddr ------------------------------------------------------*/ - -struct suckaddr * -VDI_Suckaddr(const struct director *d, struct worker *wrk, struct busyobj *bo) -{ - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); - - AN(d->suckaddr); - return (d->suckaddr(d, wrk, bo)); -} diff --git a/bin/varnishd/cache/cache_director.c b/bin/varnishd/cache/cache_director.c new file mode 100644 index 0000000..7a961ad --- /dev/null +++ b/bin/varnishd/cache/cache_director.c @@ -0,0 +1,167 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2014 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. + * + * Abstract director API + * + * The abstract director API does not know how we talk to the backend or + * if there even is one in the usual meaning of the word. + * + */ + +#include "config.h" + +#include "cache.h" + +// #include "cache_backend.h" +#include "cache_director.h" + +/* Resolve director --------------------------------------------------*/ + +static const struct director * +vdi_resolve(struct worker *wrk, struct busyobj *bo, const struct director *d) +{ + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + + if (d == NULL) { + VSLb(bo->vsl, SLT_FetchError, "No backend"); + return (NULL); + } + + while (d != NULL && d->resolve != NULL) { + CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); + d = d->resolve(d, wrk, bo); + } + CHECK_OBJ_ORNULL(d, DIRECTOR_MAGIC); + if (d == NULL) + VSLb(bo->vsl, SLT_FetchError, "Backend selection failed"); + bo->director_resp = d; + return (d); +} + +/* Get a set of response headers -------------------------------------*/ + +int +VDI_GetHdr(struct worker *wrk, struct busyobj *bo) +{ + const struct director *d; + int i = -1; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + + d = vdi_resolve(wrk, bo, bo->director_req); + if (d != NULL) { + AN(d->gethdrs); + bo->director_state = DIR_S_HDRS; + i = d->gethdrs(d, wrk, bo); + } + if (i) + bo->director_state = DIR_S_NULL; + return (i); +} + +/* Setup body fetch --------------------------------------------------*/ + +int +VDI_GetBody(const struct director *d, struct worker *wrk, struct busyobj *bo) +{ + + CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + + AZ(d->resolve); + AN(d->getbody); + + bo->director_state = DIR_S_BODY; + return (d->getbody(d, wrk, bo)); +} + +/* Finish fetch ------------------------------------------------------*/ + +void +VDI_Finish(const struct director *d, struct worker *wrk, struct busyobj *bo) +{ + + CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + + AZ(d->resolve); + AN(d->finish); + + assert(bo->director_state != DIR_S_NULL); + bo->director_state = DIR_S_NULL; + + d->finish(d, wrk, bo); +} + +/* Get a connection --------------------------------------------------*/ + +struct vbc * +VDI_GetFd(const struct director *d, struct worker *wrk, struct busyobj *bo) +{ + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); + + d = vdi_resolve(wrk, bo, d); + if (d == NULL) + return (NULL); + + AN(d->getfd); + return (d->getfd(d, bo)); +} + +/* Check health ------------------------------------------------------ + */ + +int +VDI_Healthy(const struct director *d) +{ + + CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); + AN(d->healthy); + return (d->healthy(d, NULL)); +} + +/* Get suckaddr ------------------------------------------------------*/ + +struct suckaddr * +VDI_Suckaddr(const struct director *d, struct worker *wrk, struct busyobj *bo) +{ + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); + + AN(d->suckaddr); + return (d->suckaddr(d, wrk, bo)); +} diff --git a/bin/varnishd/cache/cache_director.h b/bin/varnishd/cache/cache_director.h new file mode 100644 index 0000000..2c5e72f --- /dev/null +++ b/bin/varnishd/cache/cache_director.h @@ -0,0 +1,86 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2014 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. + * + * Director APIs + * + * A director ("VDI") is an abstract entity which can either satisfy a + * backend fetch request or select another director for the job. + * + * In theory a director does not have to talk HTTP over TCP, it can satisfy + * the backend request using any means it wants, although this is presently + * not implemented. + * + */ + +/*-------------------------------------------------------------------- + * A director is a piece of code which selects one of possibly multiple + * backends to use. + */ + +typedef struct vbc *vdi_getfd_f(const struct director *, struct busyobj *); +typedef unsigned vdi_healthy_f(const struct director *, double *changed); +typedef const struct director *vdi_resolve_f(const struct director *, + struct worker *, struct busyobj *); +typedef int vdi_gethdrs_f(const struct director *, struct worker *, + struct busyobj *); +typedef int vdi_getbody_f(const struct director *, struct worker *, + struct busyobj *); +typedef void vdi_finish_f(const struct director *, struct worker *, + struct busyobj *); +typedef struct suckaddr *vdi_suckaddr_f(const struct director *, + struct worker *, struct busyobj *); + +struct director { + unsigned magic; +#define DIRECTOR_MAGIC 0x3336351d + const char *name; + char *vcl_name; + vdi_getfd_f *getfd; + vdi_healthy_f *healthy; + vdi_resolve_f *resolve; + vdi_gethdrs_f *gethdrs; + vdi_getbody_f *getbody; + vdi_finish_f *finish; + vdi_suckaddr_f *suckaddr; + void *priv; +}; + +/* cache_director.c */ +int VDI_GetHdr(struct worker *wrk, struct busyobj *bo); +int VDI_GetBody(const struct director *d, struct worker *wrk, + struct busyobj *bo); +void VDI_Finish(const struct director *d, struct worker *wrk, + struct busyobj *bo); +struct vbc *VDI_GetFd(const struct director *d, struct worker *wrk, + struct busyobj *); +int VDI_Healthy(const struct director *); +struct suckaddr *VDI_Suckaddr(const struct director *d, struct worker *wrk, + struct busyobj *bo); +void VDI_AddHostHeader(struct http *to, const struct vbc *vbc); +void VDI_Init(void); + diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 030c1bb..03e366d 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -35,7 +35,7 @@ #include #include "cache.h" -#include "cache_backend.h" +#include "cache_director.h" #include "vend.h" #include "hash/hash_slinger.h" #include "vcl.h" diff --git a/bin/varnishd/cache/cache_http1_fetch.c b/bin/varnishd/cache/cache_http1_fetch.c index 7c61514..1b3514a 100644 --- a/bin/varnishd/cache/cache_http1_fetch.c +++ b/bin/varnishd/cache/cache_http1_fetch.c @@ -38,6 +38,7 @@ #include "hash/hash_slinger.h" #include "cache_backend.h" +#include "cache_director.h" #include "vcli_priv.h" #include "vtcp.h" #include "vtim.h" diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c index 15b8daa..d949059 100644 --- a/bin/varnishd/cache/cache_main.c +++ b/bin/varnishd/cache/cache_main.c @@ -34,6 +34,7 @@ #include "cache.h" #include "cache_backend.h" +#include "cache_director.h" #include "common/heritage.h" #include "vcli_priv.h" diff --git a/bin/varnishd/cache/cache_pipe.c b/bin/varnishd/cache/cache_pipe.c index 3d17735..a27e3de 100644 --- a/bin/varnishd/cache/cache_pipe.c +++ b/bin/varnishd/cache/cache_pipe.c @@ -37,6 +37,7 @@ #include "cache.h" #include "cache_backend.h" +#include "cache_director.h" #include "vtcp.h" #include "vtim.h" diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c index faae807..a49da52 100644 --- a/bin/varnishd/cache/cache_vrt.c +++ b/bin/varnishd/cache/cache_vrt.c @@ -37,7 +37,7 @@ #include "cache.h" -#include "cache_backend.h" +#include "cache_director.h" #include "hash/hash_slinger.h" #include "vav.h" #include "vcl.h" diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index 489a074..8448317 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -39,6 +39,7 @@ #include "hash/hash_slinger.h" #include "cache_backend.h" +#include "cache_director.h" #include "vrt.h" #include "vrt_obj.h" #include "vsa.h" diff --git a/lib/libvmod_directors/fall_back.c b/lib/libvmod_directors/fall_back.c index a317e46..a3d2a9c 100644 --- a/lib/libvmod_directors/fall_back.c +++ b/lib/libvmod_directors/fall_back.c @@ -31,7 +31,7 @@ #include #include "cache/cache.h" -#include "cache/cache_backend.h" +#include "cache/cache_director.h" #include "vrt.h" #include "vcc_if.h" diff --git a/lib/libvmod_directors/hash.c b/lib/libvmod_directors/hash.c index 6ff2a77..e7b63a0 100644 --- a/lib/libvmod_directors/hash.c +++ b/lib/libvmod_directors/hash.c @@ -32,7 +32,7 @@ #include #include "cache/cache.h" -#include "cache/cache_backend.h" +#include "cache/cache_director.h" #include "vrt.h" #include "vbm.h" diff --git a/lib/libvmod_directors/random.c b/lib/libvmod_directors/random.c index d83b840..a693bc6 100644 --- a/lib/libvmod_directors/random.c +++ b/lib/libvmod_directors/random.c @@ -32,7 +32,7 @@ #include #include "cache/cache.h" -#include "cache/cache_backend.h" +#include "cache/cache_director.h" #include "vrt.h" #include "vbm.h" diff --git a/lib/libvmod_directors/round_robin.c b/lib/libvmod_directors/round_robin.c index 1f7d9e8..39f6b3d 100644 --- a/lib/libvmod_directors/round_robin.c +++ b/lib/libvmod_directors/round_robin.c @@ -31,7 +31,7 @@ #include #include "cache/cache.h" -#include "cache/cache_backend.h" +#include "cache/cache_director.h" #include "vrt.h" #include "vcc_if.h" diff --git a/lib/libvmod_directors/vdir.c b/lib/libvmod_directors/vdir.c index 52cf4c4..3488026 100644 --- a/lib/libvmod_directors/vdir.c +++ b/lib/libvmod_directors/vdir.c @@ -31,7 +31,7 @@ #include #include "cache/cache.h" -#include "cache/cache_backend.h" +#include "cache/cache_director.h" #include "vrt.h" #include "vbm.h" diff --git a/lib/libvmod_std/vmod_std.c b/lib/libvmod_std/vmod_std.c index 0778637..4bba4b7 100644 --- a/lib/libvmod_std/vmod_std.c +++ b/lib/libvmod_std/vmod_std.c @@ -44,7 +44,7 @@ #include "vtim.h" #include "cache/cache.h" -#include "cache/cache_backend.h" +#include "cache/cache_director.h" #include "vcc_if.h" From phk at FreeBSD.org Wed Oct 1 19:05:14 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 01 Oct 2014 21:05:14 +0200 Subject: [master] 1be5d26 Rename "pipe" to "http1 pipe", (VTLA: V1P) Message-ID: commit 1be5d26d9e22f8631aff89a087906c6176cef033 Author: Poul-Henning Kamp Date: Wed Oct 1 18:21:24 2014 +0000 Rename "pipe" to "http1 pipe", (VTLA: V1P) diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 64fd313..ab7705d 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -28,6 +28,7 @@ varnishd_SOURCES = \ cache/cache_http.c \ cache/cache_http1_fetch.c \ cache/cache_http1_fsm.c \ + cache/cache_http1_pipe.c \ cache/cache_http1_proto.c \ cache/cache_http1_vfp.c \ cache/cache_lck.c \ @@ -35,7 +36,6 @@ varnishd_SOURCES = \ cache/cache_mempool.c \ cache/cache_obj.c \ cache/cache_panic.c \ - cache/cache_pipe.c \ cache/cache_pool.c \ cache/cache_req_body.c \ cache/cache_req_fsm.c \ diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 4c9568f..99cb5ca 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -746,6 +746,10 @@ unsigned V1D_FlushReleaseAcct(struct req *req); void V1D_Deliver(struct req *, struct busyobj *); void V1D_Deliver_Synth(struct req *req); +/* cache_http1_pipe.c */ +void V1P_Init(void); +void V1P_Process(struct req *req, struct busyobj *bo); + /* cache_req_body.c */ int VRB_Ignore(struct req *req); int VRB_Cache(struct req *req, ssize_t maxsize); @@ -1010,10 +1014,6 @@ 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 Pipe_Init(void); -void PipeRequest(struct req *req, struct busyobj *bo); - /* cache_pool.c */ void Pool_Init(void); void Pool_Accept(void); diff --git a/bin/varnishd/cache/cache_http1_pipe.c b/bin/varnishd/cache/cache_http1_pipe.c new file mode 100644 index 0000000..6a67566 --- /dev/null +++ b/bin/varnishd/cache/cache_http1_pipe.c @@ -0,0 +1,197 @@ +/*- + * 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. + * + * XXX: charge bytes to srcaddr + */ + +#include "config.h" + +#include +#include + +#include "cache.h" + +#include "cache_backend.h" +#include "cache_director.h" +#include "vtcp.h" +#include "vtim.h" + +static struct lock pipestat_mtx; + +struct acct_pipe { + uint64_t req; + uint64_t bereq; + uint64_t in; + uint64_t out; +}; + +static int +rdf(int fd0, int fd1, uint64_t *pcnt) +{ + int i, j; + char buf[BUFSIZ], *p; + + i = read(fd0, buf, sizeof buf); + if (i <= 0) + return (1); + for (p = buf; i > 0; i -= j, p += j) { + j = write(fd1, p, i); + if (j <= 0) + return (1); + *pcnt += j; + if (i != j) + (void)usleep(100000); /* XXX hack */ + } + return (0); +} + +static void +pipecharge(struct req *req, const struct acct_pipe *a, struct VSC_C_vbe *b) +{ + + VSLb(req->vsl, SLT_PipeAcct, "%ju %ju %ju %ju", + (uintmax_t)a->req, + (uintmax_t)a->bereq, + (uintmax_t)a->in, + (uintmax_t)a->out); + + Lck_Lock(&pipestat_mtx); + VSC_C_main->s_pipe_hdrbytes += a->req; + VSC_C_main->s_pipe_in += a->in; + VSC_C_main->s_pipe_out += a->out; + if (b != NULL) { + b->pipe_hdrbytes += a->bereq; + b->pipe_out += a->in; + b->pipe_in += a->out; + } + Lck_Unlock(&pipestat_mtx); +} + +void +V1P_Process(struct req *req, struct busyobj *bo) +{ + struct vbc *vc; + struct worker *wrk; + struct pollfd fds[2]; + int i; + struct acct_pipe acct_pipe; + ssize_t hdrbytes; + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + CHECK_OBJ_NOTNULL(req->sp, SESS_MAGIC); + wrk = req->wrk; + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + + req->res_mode = RES_PIPE; + + memset(&acct_pipe, 0, sizeof acct_pipe); + acct_pipe.req = req->acct.req_hdrbytes; + req->acct.req_hdrbytes = 0; + + vc = VDI_GetFd(bo->director_req, wrk, bo); + if (vc == NULL) { + pipecharge(req, &acct_pipe, NULL); + SES_Close(req->sp, SC_OVERLOAD); + return; + } + bo->vbc = vc; /* For panic dumping */ + (void)VTCP_blocking(vc->fd); + + WRW_Reserve(wrk, &vc->fd, bo->vsl, req->t_req); + hdrbytes = HTTP1_Write(wrk, bo->bereq, HTTP1_Req); + + if (req->htc->pipeline_b != NULL) + (void)WRW_Write(wrk, req->htc->pipeline_b, + req->htc->pipeline_e - req->htc->pipeline_b); + + i = WRW_FlushRelease(wrk, &acct_pipe.bereq); + if (acct_pipe.bereq > hdrbytes) { + acct_pipe.in = acct_pipe.bereq - hdrbytes; + acct_pipe.bereq = hdrbytes; + } + + VSLb_ts_req(req, "Pipe", W_TIM_real(wrk)); + + if (i) { + pipecharge(req, &acct_pipe, vc->backend->vsc); + SES_Close(req->sp, SC_TX_PIPE); + VBE_CloseFd(&vc, NULL); + return; + } + + memset(fds, 0, sizeof fds); + + // XXX: not yet (void)VTCP_linger(vc->fd, 0); + fds[0].fd = vc->fd; + fds[0].events = POLLIN | POLLERR; + + // XXX: not yet (void)VTCP_linger(req->sp->fd, 0); + fds[1].fd = req->sp->fd; + fds[1].events = POLLIN | POLLERR; + + while (fds[0].fd > -1 || fds[1].fd > -1) { + fds[0].revents = 0; + fds[1].revents = 0; + i = poll(fds, 2, (int)(cache_param->pipe_timeout * 1e3)); + if (i < 1) + break; + if (fds[0].revents && + rdf(vc->fd, req->sp->fd, &acct_pipe.out)) { + if (fds[1].fd == -1) + break; + (void)shutdown(vc->fd, SHUT_RD); + (void)shutdown(req->sp->fd, SHUT_WR); + fds[0].events = 0; + fds[0].fd = -1; + } + if (fds[1].revents && + rdf(req->sp->fd, vc->fd, &acct_pipe.in)) { + if (fds[0].fd == -1) + break; + (void)shutdown(req->sp->fd, SHUT_RD); + (void)shutdown(vc->fd, SHUT_WR); + fds[1].events = 0; + fds[1].fd = -1; + } + } + VSLb_ts_req(req, "PipeSess", W_TIM_real(wrk)); + pipecharge(req, &acct_pipe, vc->backend->vsc); + SES_Close(req->sp, SC_TX_PIPE); + VBE_CloseFd(&vc, NULL); + bo->vbc = NULL; +} + +/*--------------------------------------------------------------------*/ + +void +V1P_Init(void) +{ + + Lck_New(&pipestat_mtx, lck_pipestat); +} diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c index d949059..1406e57 100644 --- a/bin/varnishd/cache/cache_main.c +++ b/bin/varnishd/cache/cache_main.c @@ -225,7 +225,7 @@ child_main(void) VBE_InitCfg(); VBP_Init(); Pool_Init(); - Pipe_Init(); + V1P_Init(); EXP_Init(); HSH_Init(heritage.hash); diff --git a/bin/varnishd/cache/cache_pipe.c b/bin/varnishd/cache/cache_pipe.c deleted file mode 100644 index a27e3de..0000000 --- a/bin/varnishd/cache/cache_pipe.c +++ /dev/null @@ -1,197 +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. - * - * XXX: charge bytes to srcaddr - */ - -#include "config.h" - -#include -#include - -#include "cache.h" - -#include "cache_backend.h" -#include "cache_director.h" -#include "vtcp.h" -#include "vtim.h" - -static struct lock pipestat_mtx; - -struct acct_pipe { - uint64_t req; - uint64_t bereq; - uint64_t in; - uint64_t out; -}; - -static int -rdf(int fd0, int fd1, uint64_t *pcnt) -{ - int i, j; - char buf[BUFSIZ], *p; - - i = read(fd0, buf, sizeof buf); - if (i <= 0) - return (1); - for (p = buf; i > 0; i -= j, p += j) { - j = write(fd1, p, i); - if (j <= 0) - return (1); - *pcnt += j; - if (i != j) - (void)usleep(100000); /* XXX hack */ - } - return (0); -} - -static void -pipecharge(struct req *req, const struct acct_pipe *a, struct VSC_C_vbe *b) -{ - - VSLb(req->vsl, SLT_PipeAcct, "%ju %ju %ju %ju", - (uintmax_t)a->req, - (uintmax_t)a->bereq, - (uintmax_t)a->in, - (uintmax_t)a->out); - - Lck_Lock(&pipestat_mtx); - VSC_C_main->s_pipe_hdrbytes += a->req; - VSC_C_main->s_pipe_in += a->in; - VSC_C_main->s_pipe_out += a->out; - if (b != NULL) { - b->pipe_hdrbytes += a->bereq; - b->pipe_out += a->in; - b->pipe_in += a->out; - } - Lck_Unlock(&pipestat_mtx); -} - -void -PipeRequest(struct req *req, struct busyobj *bo) -{ - struct vbc *vc; - struct worker *wrk; - struct pollfd fds[2]; - int i; - struct acct_pipe acct_pipe; - ssize_t hdrbytes; - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - CHECK_OBJ_NOTNULL(req->sp, SESS_MAGIC); - wrk = req->wrk; - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - - req->res_mode = RES_PIPE; - - memset(&acct_pipe, 0, sizeof acct_pipe); - acct_pipe.req = req->acct.req_hdrbytes; - req->acct.req_hdrbytes = 0; - - vc = VDI_GetFd(bo->director_req, wrk, bo); - if (vc == NULL) { - pipecharge(req, &acct_pipe, NULL); - SES_Close(req->sp, SC_OVERLOAD); - return; - } - bo->vbc = vc; /* For panic dumping */ - (void)VTCP_blocking(vc->fd); - - WRW_Reserve(wrk, &vc->fd, bo->vsl, req->t_req); - hdrbytes = HTTP1_Write(wrk, bo->bereq, HTTP1_Req); - - if (req->htc->pipeline_b != NULL) - (void)WRW_Write(wrk, req->htc->pipeline_b, - req->htc->pipeline_e - req->htc->pipeline_b); - - i = WRW_FlushRelease(wrk, &acct_pipe.bereq); - if (acct_pipe.bereq > hdrbytes) { - acct_pipe.in = acct_pipe.bereq - hdrbytes; - acct_pipe.bereq = hdrbytes; - } - - VSLb_ts_req(req, "Pipe", W_TIM_real(wrk)); - - if (i) { - pipecharge(req, &acct_pipe, vc->backend->vsc); - SES_Close(req->sp, SC_TX_PIPE); - VBE_CloseFd(&vc, NULL); - return; - } - - memset(fds, 0, sizeof fds); - - // XXX: not yet (void)VTCP_linger(vc->fd, 0); - fds[0].fd = vc->fd; - fds[0].events = POLLIN | POLLERR; - - // XXX: not yet (void)VTCP_linger(req->sp->fd, 0); - fds[1].fd = req->sp->fd; - fds[1].events = POLLIN | POLLERR; - - while (fds[0].fd > -1 || fds[1].fd > -1) { - fds[0].revents = 0; - fds[1].revents = 0; - i = poll(fds, 2, (int)(cache_param->pipe_timeout * 1e3)); - if (i < 1) - break; - if (fds[0].revents && - rdf(vc->fd, req->sp->fd, &acct_pipe.out)) { - if (fds[1].fd == -1) - break; - (void)shutdown(vc->fd, SHUT_RD); - (void)shutdown(req->sp->fd, SHUT_WR); - fds[0].events = 0; - fds[0].fd = -1; - } - if (fds[1].revents && - rdf(req->sp->fd, vc->fd, &acct_pipe.in)) { - if (fds[0].fd == -1) - break; - (void)shutdown(req->sp->fd, SHUT_RD); - (void)shutdown(vc->fd, SHUT_WR); - fds[1].events = 0; - fds[1].fd = -1; - } - } - VSLb_ts_req(req, "PipeSess", W_TIM_real(wrk)); - pipecharge(req, &acct_pipe, vc->backend->vsc); - SES_Close(req->sp, SC_TX_PIPE); - VBE_CloseFd(&vc, NULL); - bo->vbc = NULL; -} - -/*--------------------------------------------------------------------*/ - -void -Pipe_Init(void) -{ - - Lck_New(&pipestat_mtx, lck_pipestat); -} diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index c9bdb35..4649231 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -499,7 +499,7 @@ cnt_pipe(struct worker *wrk, struct req *req) INCOMPL(); assert(wrk->handling == VCL_RET_PIPE); - PipeRequest(req, bo); + V1P_Process(req, bo); assert(WRW_IsReleased(wrk)); http_Teardown(bo->bereq); THR_SetBusyobj(NULL); From phk at FreeBSD.org Wed Oct 1 19:05:14 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 01 Oct 2014 21:05:14 +0200 Subject: [master] 24c031d Shift HTTP/1 protocol specific source files into a subdirectory Message-ID: commit 24c031dd8c3a84df30199af67493ad489c85766b Author: Poul-Henning Kamp Date: Wed Oct 1 18:28:58 2014 +0000 Shift HTTP/1 protocol specific source files into a subdirectory diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index ab7705d..fdec53b 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -26,11 +26,6 @@ varnishd_SOURCES = \ cache/cache_gzip.c \ cache/cache_hash.c \ cache/cache_http.c \ - cache/cache_http1_fetch.c \ - cache/cache_http1_fsm.c \ - cache/cache_http1_pipe.c \ - cache/cache_http1_proto.c \ - cache/cache_http1_vfp.c \ cache/cache_lck.c \ cache/cache_main.c \ cache/cache_mempool.c \ @@ -39,7 +34,6 @@ varnishd_SOURCES = \ cache/cache_pool.c \ cache/cache_req_body.c \ cache/cache_req_fsm.c \ - cache/cache_http1_deliver.c \ cache/cache_rfc2616.c \ cache/cache_session.c \ cache/cache_shmlog.c \ @@ -59,6 +53,12 @@ varnishd_SOURCES = \ hash/hash_critbit.c \ hash/hash_mgt.c \ hash/hash_simple_list.c \ + http1/cache_http1_deliver.c \ + http1/cache_http1_fetch.c \ + http1/cache_http1_fsm.c \ + http1/cache_http1_pipe.c \ + http1/cache_http1_proto.c \ + http1/cache_http1_vfp.c \ mgt/mgt_child.c \ mgt/mgt_cli.c \ mgt/mgt_main.c \ diff --git a/bin/varnishd/cache/cache_http1_deliver.c b/bin/varnishd/cache/cache_http1_deliver.c deleted file mode 100644 index 766e493..0000000 --- a/bin/varnishd/cache/cache_http1_deliver.c +++ /dev/null @@ -1,463 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2014 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 "cache.h" - -#include "vct.h" - -/*--------------------------------------------------------------------*/ - -static int __match_proto__(vdp_bytes) -v1d_bytes(struct req *req, enum vdp_action act, const void *ptr, ssize_t len) -{ - ssize_t wl = 0; - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - - assert(req->vdp_nxt == -1); /* always at the bottom of the pile */ - - if (len > 0) - wl = WRW_Write(req->wrk, ptr, len); - req->resp_bodybytes += wl; - if (act > VDP_NULL && WRW_Flush(req->wrk)) - return (-1); - if (len != wl) - return (-1); - return (0); -} - -/*--------------------------------------------------------------------*/ - -static int __match_proto__(vdp_bytes) -v1d_range_bytes(struct req *req, enum vdp_action act, const void *ptr, - ssize_t len) -{ - int retval = 0; - ssize_t l; - const char *p = ptr; - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - l = req->range_low - req->range_off; - if (l > 0) { - if (l > len) - l = len; - req->range_off += l; - p += l; - len -= l; - } - l = req->range_high - req->range_off; - if (l > len) - l = len; - if (l > 0) - retval = VDP_bytes(req, act, p, l); - else if (act > VDP_NULL) - retval = VDP_bytes(req, act, p, 0); - req->range_off += len; - return (retval); -} - -/*--------------------------------------------------------------------*/ - -static void -v1d_dorange(struct req *req, struct busyobj *bo, const char *r) -{ - ssize_t len, low, high, has_low; - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); - assert(http_IsStatus(req->resp, 200)); - - /* We must snapshot the length if we're streaming from the backend */ - if (bo != NULL) - len = VBO_waitlen(req->wrk, bo, -1); - else - len = ObjGetLen(req->wrk, req->objcore); - - if (strncmp(r, "bytes=", 6)) - return; - r += 6; - - /* The low end of range */ - has_low = low = 0; - if (!vct_isdigit(*r) && *r != '-') - return; - while (vct_isdigit(*r)) { - has_low = 1; - low *= 10; - low += *r - '0'; - r++; - } - - if (low >= len) - return; - - if (*r != '-') - return; - r++; - - /* The high end of range */ - if (vct_isdigit(*r)) { - high = 0; - while (vct_isdigit(*r)) { - high *= 10; - high += *r - '0'; - r++; - } - if (!has_low) { - low = len - high; - if (low < 0) - low = 0; - high = len - 1; - } - } else - high = len - 1; - if (*r != '\0') - return; - - if (high >= len) - high = len - 1; - - if (low > high) - return; - - http_PrintfHeader(req->resp, "Content-Range: bytes %jd-%jd/%jd", - (intmax_t)low, (intmax_t)high, (intmax_t)len); - http_Unset(req->resp, H_Content_Length); - if (req->res_mode & RES_LEN) - http_PrintfHeader(req->resp, "Content-Length: %jd", - (intmax_t)(1 + high - low)); - http_PutResponse(req->resp, "HTTP/1.1", 206, NULL); - - req->range_off = 0; - req->range_low = low; - req->range_high = high + 1; - VDP_push(req, v1d_range_bytes); -} - -/*--------------------------------------------------------------------*/ - -static enum objiter_status -v1d_WriteDirObj(struct req *req) -{ - enum objiter_status ois; - ssize_t len; - void *oi; - void *ptr; - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - - oi = ObjIterBegin(req->wrk, req->objcore); - XXXAN(oi); - - do { - ois = ObjIter(req->objcore, oi, &ptr, &len); - switch(ois) { - case OIS_DONE: - AZ(len); - break; - case OIS_ERROR: - break; - case OIS_DATA: - case OIS_STREAM: - if (VDP_bytes(req, - ois == OIS_DATA ? VDP_NULL : VDP_FLUSH, ptr, len)) - ois = OIS_ERROR; - break; - default: - WRONG("Wrong OIS value"); - } - } while (ois == OIS_DATA || ois == OIS_STREAM); - (void)VDP_bytes(req, VDP_FINISH, NULL, 0); - ObjIterEnd(req->objcore, &oi); - return (ois); -} - -/*-------------------------------------------------------------------- - * V1D_FlushReleaseAcct() - * Call WRW_FlushRelease on the worker and update the requests - * byte accounting with the number of bytes transmitted - * - * Returns the return value from WRW_FlushRelease() - */ -unsigned -V1D_FlushReleaseAcct(struct req *req) -{ - unsigned u; - uint64_t txcnt = 0, hdrbytes; - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - CHECK_OBJ_NOTNULL(req->wrk, WORKER_MAGIC); - u = WRW_FlushRelease(req->wrk, &txcnt); - if (req->acct.resp_hdrbytes < req->resp_hdrbytes) { - hdrbytes = req->resp_hdrbytes - req->acct.resp_hdrbytes; - if (hdrbytes > txcnt) - hdrbytes = txcnt; - } else - hdrbytes = 0; - req->acct.resp_hdrbytes += hdrbytes; - req->acct.resp_bodybytes += txcnt - hdrbytes; - return (u); -} - -void -V1D_Deliver(struct req *req, struct busyobj *bo) -{ - const char *r; - enum objiter_status ois; - ssize_t l; - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); - - req->res_mode = 0; - - if (!req->disable_esi && ObjGetattr(req->wrk, req->objcore, - OA_ESIDATA, NULL) != NULL) { - /* In ESI mode, we can't know the aggregate length */ - req->res_mode &= ~RES_LEN; - req->res_mode |= RES_ESI; - } else if (http_IsStatus(req->resp, 304)) { - req->res_mode &= ~RES_LEN; - http_Unset(req->resp, H_Content_Length); - req->wantbody = 0; - } else if (bo == NULL) { - /* XXX: Not happy with this convoluted test */ - req->res_mode |= RES_LEN; - if (!(req->objcore->flags & OC_F_PASS) || - ObjGetLen(req->wrk, req->objcore) != 0) { - http_Unset(req->resp, H_Content_Length); - http_PrintfHeader(req->resp, - "Content-Length: %ju", (uintmax_t)ObjGetLen( - req->wrk, req->objcore)); - } - } - - if (req->esi_level > 0) { - /* Included ESI object, always CHUNKED or EOF */ - req->res_mode &= ~RES_LEN; - req->res_mode |= RES_ESI_CHILD; - } - - if (cache_param->http_gzip_support && - ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED) && - !RFC2616_Req_Gzip(req->http)) { - /* - * We don't know what it uncompresses to - * XXX: we could cache that, but would still deliver - * XXX: with multiple writes because of the gunzip buffer - */ - req->res_mode &= ~RES_LEN; - req->res_mode |= RES_GUNZIP; - } - - if (!(req->res_mode & (RES_LEN|RES_CHUNKED|RES_EOF))) { - /* We havn't chosen yet, do so */ - if (!req->wantbody) { - /* Nothing */ - } else if (req->http->protover >= 11) { - req->res_mode |= RES_CHUNKED; - } else { - req->res_mode |= RES_EOF; - req->doclose = SC_TX_EOF; - } - } - VSLb(req->vsl, SLT_Debug, "RES_MODE %x", req->res_mode); - - if (!(req->res_mode & RES_LEN)) - http_Unset(req->resp, H_Content_Length); - - if (req->res_mode & RES_GUNZIP) - http_Unset(req->resp, H_Content_Encoding); - - if (req->res_mode & RES_CHUNKED) - http_SetHeader(req->resp, "Transfer-Encoding: chunked"); - - http_SetHeader(req->resp, - req->doclose ? "Connection: close" : "Connection: keep-alive"); - - req->vdps[0] = v1d_bytes; - req->vdp_nxt = 0; - - if ( - req->wantbody && - !(req->res_mode & (RES_ESI|RES_ESI_CHILD)) && - cache_param->http_range_support && - http_IsStatus(req->resp, 200)) { - http_SetHeader(req->resp, "Accept-Ranges: bytes"); - if (http_GetHdr(req->http, H_Range, &r)) - v1d_dorange(req, bo, r); - } - - if (req->res_mode & RES_ESI) - RFC2616_Weaken_Etag(req->resp); - - WRW_Reserve(req->wrk, &req->sp->fd, req->vsl, req->t_prev); - - /* - * Send HTTP protocol header, unless interior ESI object - */ - if (!(req->res_mode & RES_ESI_CHILD)) - req->resp_hdrbytes += - HTTP1_Write(req->wrk, req->resp, HTTP1_Resp); - - if (req->res_mode & RES_CHUNKED) - WRW_Chunked(req->wrk); - - ois = OIS_DONE; - if (!req->wantbody) { - /* This was a HEAD or conditional request */ - } else if (req->res_mode & RES_ESI) { - ESI_Deliver(req); - } else if (req->res_mode & RES_ESI_CHILD && req->gzip_resp) { - l = -1; - while (req->objcore->busyobj) { - assert(bo != NULL); - l = VBO_waitlen(req->wrk, bo, l); - } - ESI_DeliverChild(req); - } else if (req->res_mode & RES_GUNZIP || - (req->res_mode & RES_ESI_CHILD && - !req->gzip_resp && - ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED))) { - VDP_push(req, VDP_gunzip); - req->vgz = VGZ_NewUngzip(req->vsl, "U D -"); - AZ(VGZ_WrwInit(req->vgz)); - ois = v1d_WriteDirObj(req); - (void)VGZ_Destroy(&req->vgz); - VDP_pop(req, VDP_gunzip); - } else { - ois = v1d_WriteDirObj(req); - } - - if (ois == OIS_DONE && - (req->res_mode & RES_CHUNKED) && - !(req->res_mode & RES_ESI_CHILD)) - WRW_EndChunk(req->wrk); - - if ((V1D_FlushReleaseAcct(req) || ois != OIS_DONE) && req->sp->fd >= 0) - SES_Close(req->sp, SC_REM_CLOSE); -} - -void -V1D_Deliver_Synth(struct req *req) -{ - const char *r; - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - AN(req->synth_body); - - req->res_mode = 0; - if (http_IsStatus(req->resp, 304)) { - req->res_mode &= ~RES_LEN; - http_Unset(req->resp, H_Content_Length); - req->wantbody = 0; - } else { - req->res_mode |= RES_LEN; - http_Unset(req->resp, H_Content_Length); - http_PrintfHeader(req->resp, "Content-Length: %zd", - VSB_len(req->synth_body)); - } - - if (req->esi_level > 0) { - /* Included ESI object, always CHUNKED or EOF */ - req->res_mode &= ~RES_LEN; - req->res_mode |= RES_ESI_CHILD; - } - - if (!(req->res_mode & (RES_LEN|RES_CHUNKED|RES_EOF))) { - /* We havn't chosen yet, do so */ - if (!req->wantbody) { - /* Nothing */ - } else if (req->http->protover >= 11) { - req->res_mode |= RES_CHUNKED; - } else { - req->res_mode |= RES_EOF; - req->doclose = SC_TX_EOF; - } - } - VSLb(req->vsl, SLT_Debug, "RES_MODE %x", req->res_mode); - - if (!(req->res_mode & RES_LEN)) - http_Unset(req->resp, H_Content_Length); - - if (req->res_mode & RES_GUNZIP) - http_Unset(req->resp, H_Content_Encoding); - - if (req->res_mode & RES_CHUNKED) - http_SetHeader(req->resp, "Transfer-Encoding: chunked"); - - http_SetHeader(req->resp, - req->doclose ? "Connection: close" : "Connection: keep-alive"); - - req->vdps[0] = v1d_bytes; - req->vdp_nxt = 0; - - if ( - req->wantbody && - !(req->res_mode & RES_ESI_CHILD) && - cache_param->http_range_support && - http_IsStatus(req->resp, 200)) { - http_SetHeader(req->resp, "Accept-Ranges: bytes"); - if (http_GetHdr(req->http, H_Range, &r)) - v1d_dorange(req, NULL, r); - } - - WRW_Reserve(req->wrk, &req->sp->fd, req->vsl, req->t_prev); - - /* - * Send HTTP protocol header, unless interior ESI object - */ - if (!(req->res_mode & RES_ESI_CHILD)) - req->resp_hdrbytes += - HTTP1_Write(req->wrk, req->resp, HTTP1_Resp); - - if (req->res_mode & RES_CHUNKED) - WRW_Chunked(req->wrk); - - if (!req->wantbody) { - /* This was a HEAD or conditional request */ -#if 0 - XXX: Missing pretend GZIP for esi-children - } else if (req->res_mode & RES_ESI_CHILD && req->gzip_resp) { - ESI_DeliverChild(req); -#endif - } else { - (void)VDP_bytes(req, VDP_FLUSH, VSB_data(req->synth_body), - VSB_len(req->synth_body)); - (void)VDP_bytes(req, VDP_FINISH, NULL, 0); - } - - if (req->res_mode & RES_CHUNKED && !(req->res_mode & RES_ESI_CHILD)) - WRW_EndChunk(req->wrk); - - if (V1D_FlushReleaseAcct(req) && req->sp->fd >= 0) - SES_Close(req->sp, SC_REM_CLOSE); -} diff --git a/bin/varnishd/cache/cache_http1_fetch.c b/bin/varnishd/cache/cache_http1_fetch.c deleted file mode 100644 index 1b3514a..0000000 --- a/bin/varnishd/cache/cache_http1_fetch.c +++ /dev/null @@ -1,208 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2014 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 - -#include "cache.h" - -#include "hash/hash_slinger.h" - -#include "cache_backend.h" -#include "cache_director.h" -#include "vcli_priv.h" -#include "vtcp.h" -#include "vtim.h" - -/*-------------------------------------------------------------------- - * Pass the request body to the backend - */ - -static int __match_proto__(req_body_iter_f) -vbf_iter_req_body(struct req *req, void *priv, void *ptr, size_t l) -{ - struct worker *wrk; - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - CAST_OBJ_NOTNULL(wrk, priv, WORKER_MAGIC); - - if (l > 0) { - (void)WRW_Write(wrk, ptr, l); - if (WRW_Flush(wrk)) - return (-1); - } - return (0); -} - -/*-------------------------------------------------------------------- - * Send request, and receive the HTTP protocol response, but not the - * response body. - * - * Return value: - * -1 failure, not retryable - * 0 success - * 1 failure which can be retried. - */ - -int -V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo) -{ - struct vbc *vc; - struct http *hp; - enum http1_status_e hs; - int retry = -1; - int i, j, first; - struct http_conn *htc; - ssize_t hdrbytes; - int do_chunked = 0; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - CHECK_OBJ_NOTNULL(bo->vbc, VBC_MAGIC); - CHECK_OBJ_ORNULL(bo->req, REQ_MAGIC); - - htc = bo->htc; - hp = bo->bereq; - vc = bo->vbc; - if (vc->recycled) - retry = 1; - - /* - * Now that we know our backend, we can set a default Host: - * header if one is necessary. This cannot be done in the VCL - * because the backend may be chosen by a director. - */ - if (!http_GetHdr(bo->bereq, H_Host, NULL)) - VDI_AddHostHeader(bo->bereq, vc); - - if (bo->req != NULL && - bo->req->req_body_status == REQ_BODY_WITHOUT_LEN) { - http_PrintfHeader(hp, "Transfer-Encoding: chunked"); - do_chunked = 1; - } - - (void)VTCP_blocking(vc->fd); /* XXX: we should timeout instead */ - WRW_Reserve(wrk, &vc->fd, bo->vsl, bo->t_prev); - hdrbytes = HTTP1_Write(wrk, hp, HTTP1_Req); - - /* Deal with any message-body the request might (still) have */ - i = 0; - - if (bo->req != NULL) { - if (do_chunked) - WRW_Chunked(wrk); - i = VRB_Iterate(bo->req, vbf_iter_req_body, wrk); - - if (bo->req->req_body_status == REQ_BODY_TAKEN) { - retry = -1; - } else if (bo->req->req_body_status == REQ_BODY_FAIL) { - VSLb(bo->vsl, SLT_FetchError, - "req.body read error: %d (%s)", - errno, strerror(errno)); - bo->req->doclose = SC_RX_BODY; - retry = -1; - } - if (do_chunked) - WRW_EndChunk(wrk); - } - - j = WRW_FlushRelease(wrk, &bo->acct.bereq_hdrbytes); - if (bo->acct.bereq_hdrbytes > hdrbytes) { - bo->acct.bereq_bodybytes = bo->acct.bereq_hdrbytes - hdrbytes; - bo->acct.bereq_hdrbytes = hdrbytes; - } - if (j != 0 || i != 0) { - VSLb(bo->vsl, SLT_FetchError, "backend write error: %d (%s)", - errno, strerror(errno)); - VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk)); - VBE_CloseFd(&bo->vbc, &bo->acct); - /* XXX: other cleanup ? */ - return (retry); - } - VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk)); - - VSC_C_main->backend_req++; - - /* Receive response */ - - HTTP1_Init(htc, bo->ws, vc->fd, bo->vsl, - cache_param->http_resp_size, - cache_param->http_resp_hdr_len); - CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); - CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC); - - VTCP_set_read_timeout(vc->fd, vc->first_byte_timeout); - - first = 1; - do { - hs = HTTP1_Rx(htc); - if (hs == HTTP1_OVERFLOW) { - bo->acct.beresp_hdrbytes += - htc->rxbuf_e - htc->rxbuf_b; - VSLb(bo->vsl, SLT_FetchError, - "http %sread error: overflow", - first ? "first " : ""); - VBE_CloseFd(&bo->vbc, &bo->acct); - /* XXX: other cleanup ? */ - return (-1); - } - if (hs == HTTP1_ERROR_EOF) { - bo->acct.beresp_hdrbytes += - htc->rxbuf_e - htc->rxbuf_b; - VSLb(bo->vsl, SLT_FetchError, "http %sread error: EOF", - first ? "first " : ""); - VBE_CloseFd(&bo->vbc, &bo->acct); - /* XXX: other cleanup ? */ - return (retry); - } - if (first) { - retry = -1; - first = 0; - VTCP_set_read_timeout(vc->fd, - vc->between_bytes_timeout); - } - } while (hs != HTTP1_COMPLETE); - bo->acct.beresp_hdrbytes += htc->rxbuf_e - htc->rxbuf_b; - - hp = bo->beresp; - - if (HTTP1_DissectResponse(hp, htc)) { - VSLb(bo->vsl, SLT_FetchError, "http format error"); - VBE_CloseFd(&bo->vbc, &bo->acct); - /* XXX: other cleanup ? */ - return (-1); - } - - bo->doclose = http_DoConnection(hp); - - return (0); -} diff --git a/bin/varnishd/cache/cache_http1_fsm.c b/bin/varnishd/cache/cache_http1_fsm.c deleted file mode 100644 index d3438f8..0000000 --- a/bin/varnishd/cache/cache_http1_fsm.c +++ /dev/null @@ -1,403 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2014 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. - * - * This file contains the two central state machine for pushing HTTP1 - * sessions through their states. - * - */ - -#include "config.h" - -#include -#include -#include -#include - -#include "cache.h" -#include "hash/hash_slinger.h" - -#include "vcl.h" -#include "vtcp.h" -#include "vtim.h" - -/*---------------------------------------------------------------------- - * Collect a request from the client. - */ - -static enum req_fsm_nxt -http1_wait(struct sess *sp, struct worker *wrk, struct req *req) -{ - int j, tmo; - struct pollfd pfd[1]; - double now, when; - enum sess_close why = SC_NULL; - enum http1_status_e hs; - - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - - assert(req->sp == sp); - - AZ(req->vcl); - AZ(req->esi_level); - AZ(isnan(sp->t_idle)); - assert(isnan(req->t_first)); - assert(isnan(req->t_prev)); - assert(isnan(req->t_req)); - - tmo = (int)(1e3 * cache_param->timeout_linger); - while (1) { - pfd[0].fd = sp->fd; - pfd[0].events = POLLIN; - pfd[0].revents = 0; - j = poll(pfd, 1, tmo); - assert(j >= 0); - now = VTIM_real(); - if (j != 0) - hs = HTTP1_Rx(req->htc); - else - hs = HTTP1_Complete(req->htc); - if (hs == HTTP1_COMPLETE) { - /* Got it, run with it */ - if (isnan(req->t_first)) - req->t_first = now; - if (isnan(req->t_req)) - req->t_req = now; - req->acct.req_hdrbytes += - req->htc->rxbuf_e - req->htc->rxbuf_b; - return (REQ_FSM_MORE); - } else if (hs == HTTP1_ERROR_EOF) { - why = SC_REM_CLOSE; - break; - } else if (hs == HTTP1_OVERFLOW) { - why = SC_RX_OVERFLOW; - break; - } else if (hs == HTTP1_ALL_WHITESPACE) { - /* Nothing but whitespace */ - when = sp->t_idle + cache_param->timeout_idle; - if (when < now) { - why = SC_RX_TIMEOUT; - break; - } - when = sp->t_idle + cache_param->timeout_linger; - tmo = (int)(1e3 * (when - now)); - if (when < now || tmo == 0) { - wrk->stats->sess_herd++; - SES_ReleaseReq(req); - WAIT_Enter(sp); - return (REQ_FSM_DONE); - } - } else { - /* Working on it */ - if (isnan(req->t_first)) - /* Record first byte received time stamp */ - req->t_first = now; - when = sp->t_idle + cache_param->timeout_req; - tmo = (int)(1e3 * (when - now)); - if (when < now || tmo == 0) { - why = SC_RX_TIMEOUT; - break; - } - } - } - req->acct.req_hdrbytes += req->htc->rxbuf_e - req->htc->rxbuf_b; - CNT_AcctLogCharge(wrk->stats, req); - SES_ReleaseReq(req); - assert(why != SC_NULL); - SES_Delete(sp, why, now); - return (REQ_FSM_DONE); -} - -/*---------------------------------------------------------------------- - * This is the final state, figure out if we should close or recycle - * the client connection - */ - -enum http1_cleanup_ret { - SESS_DONE_RET_GONE, - SESS_DONE_RET_WAIT, - SESS_DONE_RET_START, -}; - -static enum http1_cleanup_ret -http1_cleanup(struct sess *sp, struct worker *wrk, struct req *req) -{ - - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - CHECK_OBJ_ORNULL(req->vcl, VCL_CONF_MAGIC); - - req->director_hint = NULL; - req->restarts = 0; - - AZ(req->esi_level); - - if (req->vcl != NULL) { - if (wrk->vcl != NULL) - VCL_Rel(&wrk->vcl); - wrk->vcl = req->vcl; - req->vcl = NULL; - } - - VRTPRIV_dynamic_kill(sp, (uintptr_t)req); - /* Charge and log byte counters */ - AN(req->vsl->wid); - CNT_AcctLogCharge(wrk->stats, req); - req->req_bodybytes = 0; - req->resp_hdrbytes = 0; - req->resp_bodybytes = 0; - - VSL_End(req->vsl); - - if (!isnan(req->t_prev) && req->t_prev > 0.) - sp->t_idle = req->t_prev; - else - sp->t_idle = W_TIM_real(wrk); - - req->t_first = NAN; - req->t_prev = NAN; - req->t_req = NAN; - req->req_body_status = REQ_BODY_INIT; - - req->hash_always_miss = 0; - req->hash_ignore_busy = 0; - - if (sp->fd >= 0 && req->doclose != SC_NULL) - SES_Close(sp, req->doclose); - - if (sp->fd < 0) { - wrk->stats->sess_closed++; - AZ(req->vcl); - SES_ReleaseReq(req); - SES_Delete(sp, SC_NULL, NAN); - return (SESS_DONE_RET_GONE); - } - - WS_Reset(req->ws, NULL); - WS_Reset(wrk->aws, NULL); - - if (HTTP1_Reinit(req->htc) == HTTP1_COMPLETE) { - AZ(req->vsl->wid); - req->t_first = req->t_req = sp->t_idle; - wrk->stats->sess_pipeline++; - req->acct.req_hdrbytes += - req->htc->rxbuf_e - req->htc->rxbuf_b; - return (SESS_DONE_RET_START); - } else { - if (req->htc->rxbuf_e != req->htc->rxbuf_b) - wrk->stats->sess_readahead++; - return (SESS_DONE_RET_WAIT); - } -} - -/*---------------------------------------------------------------------- - */ - -static enum req_fsm_nxt -http1_dissect(struct worker *wrk, struct req *req) -{ - const char *r_100 = "HTTP/1.1 100 Continue\r\n\r\n"; - const char *r_400 = "HTTP/1.1 400 Bad Request\r\n\r\n"; - const char *r_417 = "HTTP/1.1 417 Expectation Failed\r\n\r\n"; - const char *p; - ssize_t r; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - - /* Allocate a new vxid now that we know we'll need it. */ - AZ(req->vsl->wid); - req->vsl->wid = VXID_Get(wrk, VSL_CLIENTMARKER); - - VSLb(req->vsl, SLT_Begin, "req %u rxreq", VXID(req->sp->vxid)); - VSL(SLT_Link, req->sp->vxid, "req %u rxreq", VXID(req->vsl->wid)); - AZ(isnan(req->t_first)); /* First byte timestamp set by http1_wait */ - AZ(isnan(req->t_req)); /* Complete req rcvd set by http1_wait */ - req->t_prev = req->t_first; - VSLb_ts_req(req, "Start", req->t_first); - VSLb_ts_req(req, "Req", req->t_req); - - /* Borrow VCL reference from worker thread */ - VCL_Refresh(&wrk->vcl); - req->vcl = wrk->vcl; - wrk->vcl = NULL; - - HTTP_Setup(req->http, req->ws, req->vsl, SLT_ReqMethod); - req->err_code = HTTP1_DissectRequest(req->htc, req->http); - - /* If we could not even parse the request, just close */ - if (req->err_code != 0) { - VSLb(req->vsl, SLT_HttpGarbage, "%.*s", - (int)(req->htc->rxbuf_e - req->htc->rxbuf_b), - req->htc->rxbuf_b); - wrk->stats->client_req_400++; - r = write(req->sp->fd, r_400, strlen(r_400)); - if (r > 0) - req->acct.resp_hdrbytes += r; - SES_Close(req->sp, SC_RX_JUNK); - return (REQ_FSM_DONE); - } - - assert (req->req_body_status == REQ_BODY_INIT); - - if (req->htc->body_status == BS_CHUNKED) { - req->req_body_status = REQ_BODY_WITHOUT_LEN; - } else if (req->htc->body_status == BS_LENGTH) { - req->req_body_status = REQ_BODY_WITH_LEN; - } else if (req->htc->body_status == BS_NONE) { - req->req_body_status = REQ_BODY_NONE; - } else if (req->htc->body_status == BS_EOF) { - req->req_body_status = REQ_BODY_WITHOUT_LEN; - } else { - WRONG("Unknown req.body_length situation"); - } - - if (http_GetHdr(req->http, H_Expect, &p)) { - if (strcasecmp(p, "100-continue")) { - wrk->stats->client_req_417++; - req->err_code = 417; - r = write(req->sp->fd, r_417, strlen(r_417)); - if (r > 0) - req->resp_hdrbytes += r; - SES_Close(req->sp, SC_RX_JUNK); - return (REQ_FSM_DONE); - } - r = write(req->sp->fd, r_100, strlen(r_100)); - if (r > 0) - req->acct.resp_hdrbytes += r; - if (r != strlen(r_100)) { - SES_Close(req->sp, SC_REM_CLOSE); - return (REQ_FSM_DONE); - } - http_Unset(req->http, H_Expect); - } - - wrk->stats->client_req++; - wrk->stats->s_req++; - - AZ(req->err_code); - req->ws_req = WS_Snapshot(req->ws); - - assert(req->req_body_status != REQ_BODY_INIT); - - HTTP_Copy(req->http0, req->http); // For ESI & restart - - return (REQ_FSM_MORE); -} - -/*---------------------------------------------------------------------- - */ - -void -HTTP1_Session(struct worker *wrk, struct req *req) -{ - enum req_fsm_nxt nxt = REQ_FSM_MORE; - struct sess *sp; - enum http1_cleanup_ret sdr; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - sp = req->sp; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - - /* - * Whenever we come in from the acceptor or waiter, we need to set - * blocking mode. It would be simpler to do this in the acceptor - * or waiter, but we'd rather do the syscall in the worker thread. - * On systems which return errors for ioctl, we close early - */ - if (sp->sess_step == S_STP_NEWREQ && VTCP_blocking(sp->fd)) { - if (errno == ECONNRESET) - SES_Close(sp, SC_REM_CLOSE); - else - SES_Close(sp, SC_TX_ERROR); - sdr = http1_cleanup(sp, wrk, req); - assert(sdr == SESS_DONE_RET_GONE); - return; - } - - /* - * Return from waitinglist. Check to see if the remote has left. - */ - if (req->req_step == R_STP_LOOKUP && VTCP_check_hup(sp->fd)) { - AN(req->hash_objhead); - (void)HSH_DerefObjHead(wrk, &req->hash_objhead); - AZ(req->hash_objhead); - SES_Close(sp, SC_REM_CLOSE); - sdr = http1_cleanup(sp, wrk, req); - assert(sdr == SESS_DONE_RET_GONE); - return; - } - - if (sp->sess_step == S_STP_NEWREQ) { - HTTP1_Init(req->htc, req->ws, sp->fd, req->vsl, - cache_param->http_req_size, - cache_param->http_req_hdr_len); - } - - while (1) { - assert( - sp->sess_step == S_STP_NEWREQ || - req->req_step == R_STP_LOOKUP || - req->req_step == R_STP_RECV); - - if (sp->sess_step == S_STP_WORKING) { - if (req->req_step == R_STP_RECV) - nxt = http1_dissect(wrk, req); - if (nxt == REQ_FSM_MORE) - nxt = CNT_Request(wrk, req); - if (nxt == REQ_FSM_DISEMBARK) - return; - assert(nxt == REQ_FSM_DONE); - sdr = http1_cleanup(sp, wrk, req); - switch (sdr) { - case SESS_DONE_RET_GONE: - return; - case SESS_DONE_RET_WAIT: - sp->sess_step = S_STP_NEWREQ; - break; - case SESS_DONE_RET_START: - sp->sess_step = S_STP_WORKING; - req->req_step = R_STP_RECV; - break; - default: - WRONG("Illegal enum http1_cleanup_ret"); - } - } - - if (sp->sess_step == S_STP_NEWREQ) { - 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_http1_pipe.c b/bin/varnishd/cache/cache_http1_pipe.c deleted file mode 100644 index 6a67566..0000000 --- a/bin/varnishd/cache/cache_http1_pipe.c +++ /dev/null @@ -1,197 +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. - * - * XXX: charge bytes to srcaddr - */ - -#include "config.h" - -#include -#include - -#include "cache.h" - -#include "cache_backend.h" -#include "cache_director.h" -#include "vtcp.h" -#include "vtim.h" - -static struct lock pipestat_mtx; - -struct acct_pipe { - uint64_t req; - uint64_t bereq; - uint64_t in; - uint64_t out; -}; - -static int -rdf(int fd0, int fd1, uint64_t *pcnt) -{ - int i, j; - char buf[BUFSIZ], *p; - - i = read(fd0, buf, sizeof buf); - if (i <= 0) - return (1); - for (p = buf; i > 0; i -= j, p += j) { - j = write(fd1, p, i); - if (j <= 0) - return (1); - *pcnt += j; - if (i != j) - (void)usleep(100000); /* XXX hack */ - } - return (0); -} - -static void -pipecharge(struct req *req, const struct acct_pipe *a, struct VSC_C_vbe *b) -{ - - VSLb(req->vsl, SLT_PipeAcct, "%ju %ju %ju %ju", - (uintmax_t)a->req, - (uintmax_t)a->bereq, - (uintmax_t)a->in, - (uintmax_t)a->out); - - Lck_Lock(&pipestat_mtx); - VSC_C_main->s_pipe_hdrbytes += a->req; - VSC_C_main->s_pipe_in += a->in; - VSC_C_main->s_pipe_out += a->out; - if (b != NULL) { - b->pipe_hdrbytes += a->bereq; - b->pipe_out += a->in; - b->pipe_in += a->out; - } - Lck_Unlock(&pipestat_mtx); -} - -void -V1P_Process(struct req *req, struct busyobj *bo) -{ - struct vbc *vc; - struct worker *wrk; - struct pollfd fds[2]; - int i; - struct acct_pipe acct_pipe; - ssize_t hdrbytes; - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - CHECK_OBJ_NOTNULL(req->sp, SESS_MAGIC); - wrk = req->wrk; - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - - req->res_mode = RES_PIPE; - - memset(&acct_pipe, 0, sizeof acct_pipe); - acct_pipe.req = req->acct.req_hdrbytes; - req->acct.req_hdrbytes = 0; - - vc = VDI_GetFd(bo->director_req, wrk, bo); - if (vc == NULL) { - pipecharge(req, &acct_pipe, NULL); - SES_Close(req->sp, SC_OVERLOAD); - return; - } - bo->vbc = vc; /* For panic dumping */ - (void)VTCP_blocking(vc->fd); - - WRW_Reserve(wrk, &vc->fd, bo->vsl, req->t_req); - hdrbytes = HTTP1_Write(wrk, bo->bereq, HTTP1_Req); - - if (req->htc->pipeline_b != NULL) - (void)WRW_Write(wrk, req->htc->pipeline_b, - req->htc->pipeline_e - req->htc->pipeline_b); - - i = WRW_FlushRelease(wrk, &acct_pipe.bereq); - if (acct_pipe.bereq > hdrbytes) { - acct_pipe.in = acct_pipe.bereq - hdrbytes; - acct_pipe.bereq = hdrbytes; - } - - VSLb_ts_req(req, "Pipe", W_TIM_real(wrk)); - - if (i) { - pipecharge(req, &acct_pipe, vc->backend->vsc); - SES_Close(req->sp, SC_TX_PIPE); - VBE_CloseFd(&vc, NULL); - return; - } - - memset(fds, 0, sizeof fds); - - // XXX: not yet (void)VTCP_linger(vc->fd, 0); - fds[0].fd = vc->fd; - fds[0].events = POLLIN | POLLERR; - - // XXX: not yet (void)VTCP_linger(req->sp->fd, 0); - fds[1].fd = req->sp->fd; - fds[1].events = POLLIN | POLLERR; - - while (fds[0].fd > -1 || fds[1].fd > -1) { - fds[0].revents = 0; - fds[1].revents = 0; - i = poll(fds, 2, (int)(cache_param->pipe_timeout * 1e3)); - if (i < 1) - break; - if (fds[0].revents && - rdf(vc->fd, req->sp->fd, &acct_pipe.out)) { - if (fds[1].fd == -1) - break; - (void)shutdown(vc->fd, SHUT_RD); - (void)shutdown(req->sp->fd, SHUT_WR); - fds[0].events = 0; - fds[0].fd = -1; - } - if (fds[1].revents && - rdf(req->sp->fd, vc->fd, &acct_pipe.in)) { - if (fds[0].fd == -1) - break; - (void)shutdown(req->sp->fd, SHUT_RD); - (void)shutdown(vc->fd, SHUT_WR); - fds[1].events = 0; - fds[1].fd = -1; - } - } - VSLb_ts_req(req, "PipeSess", W_TIM_real(wrk)); - pipecharge(req, &acct_pipe, vc->backend->vsc); - SES_Close(req->sp, SC_TX_PIPE); - VBE_CloseFd(&vc, NULL); - bo->vbc = NULL; -} - -/*--------------------------------------------------------------------*/ - -void -V1P_Init(void) -{ - - Lck_New(&pipestat_mtx, lck_pipestat); -} diff --git a/bin/varnishd/cache/cache_http1_proto.c b/bin/varnishd/cache/cache_http1_proto.c deleted file mode 100644 index ca0a4d1..0000000 --- a/bin/varnishd/cache/cache_http1_proto.c +++ /dev/null @@ -1,576 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2014 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. - * - * Until we see the magic marker, we have to keep the rxbuf NUL terminated - * because we use strchr(3) on it. - * - * We use this both for client and backend connections. - */ - -#include "config.h" - -#include "cache.h" - -#include "vct.h" - -const int HTTP1_Req[3] = { - HTTP_HDR_METHOD, HTTP_HDR_URL, HTTP_HDR_PROTO -}; - -const int HTTP1_Resp[3] = { - HTTP_HDR_PROTO, HTTP_HDR_STATUS, HTTP_HDR_REASON -}; - -/*--------------------------------------------------------------------*/ - -void -HTTP1_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 http1_status_e -HTTP1_Reinit(struct http_conn *htc) -{ - ssize_t 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 = htc->pipeline_e - htc->pipeline_b; - assert(l > 0); - 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 (HTTP1_Complete(htc)); -} - -/*-------------------------------------------------------------------- - * Check if we have a complete HTTP request or response yet - */ - -enum http1_status_e -HTTP1_Complete(struct http_conn *htc) -{ - char *p; - - CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); - AZ(htc->pipeline_b); - AZ(htc->pipeline_e); - - assert(htc->rxbuf_e >= htc->rxbuf_b); - assert(*htc->rxbuf_e == '\0'); - - /* Skip any leading white space */ - for (p = htc->rxbuf_b ; vct_islws(*p); p++) - continue; - if (p == htc->rxbuf_e) { - /* All white space */ - htc->rxbuf_e = htc->rxbuf_b; - *htc->rxbuf_e = '\0'; - return (HTTP1_ALL_WHITESPACE); - } - while (1) { - p = strchr(p, '\n'); - if (p == NULL) - return (HTTP1_NEED_MORE); - p++; - if (*p == '\r') - p++; - if (*p == '\n') - break; - } - p++; - WS_ReleaseP(htc->ws, htc->rxbuf_e); - if (p < htc->rxbuf_e) { - htc->pipeline_b = p; - htc->pipeline_e = htc->rxbuf_e; - htc->rxbuf_e = p; - } - return (HTTP1_COMPLETE); -} - -/*-------------------------------------------------------------------- - * Receive more HTTP protocol bytes - */ - -enum http1_status_e -HTTP1_Rx(struct http_conn *htc) -{ - int i; - - CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); - AN(htc->ws->r); - AZ(htc->pipeline_b); - AZ(htc->pipeline_e); - i = (htc->ws->r - htc->rxbuf_e) - 1; /* space for NUL */ - if (i <= 0) { - WS_ReleaseP(htc->ws, htc->rxbuf_b); - return (HTTP1_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 (HTTP1_ERROR_EOF); - } - htc->rxbuf_e += i; - *htc->rxbuf_e = '\0'; - return (HTTP1_Complete(htc)); -} - -/*-------------------------------------------------------------------- - * Read up to len bytes, returning pipelined data first. - */ - -ssize_t -HTTP1_Read(struct http_conn *htc, void *d, size_t len) -{ - ssize_t l; - unsigned char *p; - ssize_t i = 0; - - CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); - l = 0; - p = d; - if (htc->pipeline_b) { - l = htc->pipeline_e - htc->pipeline_b; - assert(l > 0); - 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) { - i = read(htc->fd, p, len); - if (i < 0) { - VSLb(htc->vsl, SLT_FetchError, "%s", strerror(errno)); - return (i); - } - } - return (i + l); -} - -/*-------------------------------------------------------------------- - * Dissect the headers of the HTTP protocol message. - * Detect conditionals (headers which start with '^[Ii][Ff]-') - */ - -static uint16_t -http1_dissect_hdrs(struct http *hp, char *p, const struct http_conn *htc) -{ - char *q, *r; - - assert(p > htc->rxbuf_b); - assert(p <= htc->rxbuf_e); - hp->nhd = HTTP_HDR_FIRST; - hp->conds = 0; - r = NULL; /* For FlexeLint */ - for (; p < htc->rxbuf_e; p = r) { - - /* Find end of next header */ - q = r = p; - while (r < htc->rxbuf_e) { - if (!vct_iscrlf(r)) { - r++; - continue; - } - q = r; - assert(r < htc->rxbuf_e); - r += vct_skipcrlf(r); - if (r >= htc->rxbuf_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, "Header too long: %.*s", - (int)(q - p > 20 ? 20 : q - p), p); - return (400); - } - - /* Empty header = end of headers */ - if (p == q) - break; - - if (vct_islws(*p)) { - VSLb(hp->vsl, SLT_BogoHeader, - "1st header has white space: %.*s", - (int)(q - p > 20 ? 20 : q - p), p); - return (400); - } - - 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 (strchr(p, ':') == NULL) { - VSLb(hp->vsl, SLT_BogoHeader, "Header without ':' %.*s", - (int)(q - p > 20 ? 20 : q - p), p); - return (400); - } - - if (hp->nhd < hp->shd) { - hp->hdf[hp->nhd] = 0; - hp->hd[hp->nhd].b = p; - hp->hd[hp->nhd].e = q; - hp->nhd++; - } else { - VSLb(hp->vsl, SLT_BogoHeader, "Too many headers: %.*s", - (int)(q - p > 20 ? 20 : q - p), p); - return (400); - } - } - return (0); -} - -/*-------------------------------------------------------------------- - * Deal with first line of HTTP protocol message. - */ - -static uint16_t -http1_splitline(struct http *hp, const struct http_conn *htc, const int *hf) -{ - char *p; - int i; - - assert(hf == HTTP1_Req || hf == HTTP1_Resp); - CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); - CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); - assert(htc->rxbuf_e >= htc->rxbuf_b); - - AZ(hp->hd[hf[0]].b); - AZ(hp->hd[hf[1]].b); - AZ(hp->hd[hf[2]].b); - - /* Skip leading LWS */ - for (p = htc->rxbuf_b ; vct_islws(*p); p++) - continue; - hp->hd[hf[0]].b = p; - - /* First field cannot contain SP or CTL */ - for (; !vct_issp(*p); p++) { - if (vct_isctl(*p)) - return (400); - } - hp->hd[hf[0]].e = p; - assert(Tlen(hp->hd[hf[0]])); - *p++ = '\0'; - - /* Skip SP */ - for (; vct_issp(*p); p++) { - if (vct_isctl(*p)) - return (400); - } - hp->hd[hf[1]].b = p; - - /* Second field cannot contain LWS or CTL */ - for (; !vct_islws(*p); p++) { - if (vct_isctl(*p)) - return (400); - } - hp->hd[hf[1]].e = p; - if (!Tlen(hp->hd[hf[1]])) - return (400); - *p++ = '\0'; - - /* Skip SP */ - for (; vct_issp(*p); p++) { - if (vct_isctl(*p)) - return (400); - } - hp->hd[hf[2]].b = p; - - /* Third field is optional and cannot contain CTL except TAB */ - for (; !vct_iscrlf(p); p++) { - if (vct_isctl(*p) && !vct_issp(*p)) { - hp->hd[hf[2]].b = NULL; - return (400); - } - } - hp->hd[hf[2]].e = p; - - /* Skip CRLF */ - i = vct_skipcrlf(p); - *p = '\0'; - p += i; - - return (http1_dissect_hdrs(hp, p, htc)); -} - -/*--------------------------------------------------------------------*/ - -static enum body_status -http1_body_status(const struct http *hp, struct http_conn *htc) -{ - ssize_t cl; - const char *b; - - CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); - CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); - - htc->content_length = -1; - - if (http_HdrIs(hp, H_Transfer_Encoding, "chunked")) - return (BS_CHUNKED); - - if (http_GetHdr(hp, H_Transfer_Encoding, &b)) - return (BS_ERROR); - - cl = http_GetContentLength(hp); - if (cl == -2) - return (BS_ERROR); - if (cl >= 0) { - htc->content_length = cl; - return (cl == 0 ? BS_NONE : BS_LENGTH); - } - - if (http_HdrIs(hp, H_Connection, "keep-alive")) { - /* - * Keep alive with neither TE=Chunked or C-Len is impossible. - * We assume a zero length body. - */ - return (BS_NONE); - } - - if (http_HdrIs(hp, H_Connection, "close")) { - /* - * In this case, it is safe to just read what comes. - */ - return (BS_EOF); - } - - if (hp->protover < 11) { - /* - * With no Connection header, assume EOF. - */ - return (BS_EOF); - } - - /* - * Fall back to EOF transfer. - */ - return (BS_EOF); -} - -/*--------------------------------------------------------------------*/ - -static void -http1_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 -HTTP1_DissectRequest(struct http_conn *htc, struct http *hp) -{ - uint16_t retval; - const char *p; - const char *b, *e; - - CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); - CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); - - retval = http1_splitline(hp, htc, HTTP1_Req); - if (retval != 0) - return (retval); - http1_proto_ver(hp); - - if (http_CountHdr(hp, H_Host) > 1) - return (400); - - if (http_CountHdr(hp, H_Content_Length) > 1) - return (400); - - /* 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; - } - } - - htc->body_status = http1_body_status(hp, htc); - if (htc->body_status == BS_ERROR) - return (400); - - p = http_GetMethod(hp); - AN(p); - - /* We handle EOF bodies only for PUT and POST */ - if (htc->body_status == BS_EOF && - strcasecmp(p, "put") && strcasecmp(p, "post")) - htc->body_status = BS_NONE; - - /* HEAD with a body is a hard error */ - if (htc->body_status != BS_NONE && !strcasecmp(p, "head")) - return (400); - - return (retval); -} - -/*--------------------------------------------------------------------*/ - -uint16_t -HTTP1_DissectResponse(struct http *hp, struct http_conn *htc) -{ - uint16_t retval = 0; - const char *p; - - - CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); - CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); - - if (http1_splitline(hp, htc, HTTP1_Resp)) - retval = 503; - - if (retval == 0) { - http1_proto_ver(hp); - if (hp->protover != 10 && hp->protover != 11) - retval = 503; - } - - if (retval == 0 && Tlen(hp->hd[HTTP_HDR_STATUS]) != 3) - retval = 503; - - if (retval == 0) { - p = hp->hd[HTTP_HDR_STATUS].b; - - if (p[0] >= '1' && p[0] <= '9' && - p[1] >= '0' && p[1] <= '9' && - p[2] >= '0' && p[2] <= '9') - hp->status = - 100 * (p[0] - '0') + 10 * (p[1] - '0') + p[2] - '0'; - else - retval = 503; - } - - if (retval != 0) { - VSLb(hp->vsl, SLT_HttpGarbage, "%.*s", - (int)(htc->rxbuf_e - htc->rxbuf_b), htc->rxbuf_b); - assert(retval >= 100 && retval <= 999); - assert(retval == 503); - hp->status = retval; - http_SetH(hp, HTTP_HDR_STATUS, "503"); - http_SetH(hp, HTTP_HDR_REASON, http_Status2Reason(retval)); - } - - if (hp->hd[HTTP_HDR_REASON].b == NULL || - !Tlen(hp->hd[HTTP_HDR_REASON])) - http_SetH(hp, HTTP_HDR_REASON, http_Status2Reason(hp->status)); - - htc->body_status = http1_body_status(hp, htc); - - return (retval); -} - -/*--------------------------------------------------------------------*/ - -unsigned -HTTP1_Write(const struct worker *w, const struct http *hp, const int *hf) -{ - unsigned u, l; - - assert(hf == HTTP1_Req || hf == HTTP1_Resp); - AN(hp->hd[hf[0]].b); - AN(hp->hd[hf[1]].b); - AN(hp->hd[hf[2]].b); - l = WRW_WriteH(w, &hp->hd[hf[0]], " "); - l += WRW_WriteH(w, &hp->hd[hf[1]], " "); - l += WRW_WriteH(w, &hp->hd[hf[2]], "\r\n"); - - for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) - l += WRW_WriteH(w, &hp->hd[u], "\r\n"); - l += WRW_Write(w, "\r\n", -1); - return (l); -} diff --git a/bin/varnishd/cache/cache_http1_vfp.c b/bin/varnishd/cache/cache_http1_vfp.c deleted file mode 100644 index 33a48c5..0000000 --- a/bin/varnishd/cache/cache_http1_vfp.c +++ /dev/null @@ -1,249 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2014 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. - * - * HTTP1 Fetch Filters - * - * These filters are used for both req.body and beresp.body to handle - * the HTTP/1 aspects (C-L/Chunked/EOF) - * - */ - -#include "config.h" - -#include - -#include "cache.h" - -#include "vct.h" - -/*-------------------------------------------------------------------- - * Read a chunked HTTP object. - * - * XXX: Reading one byte at a time is pretty pessimal. - */ - -static enum vfp_status __match_proto__(vfp_pull_f) -v1f_pull_chunked(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, - ssize_t *lp) -{ - struct http_conn *htc; - int i; - char buf[20]; /* XXX: 20 is arbitrary */ - char *q; - unsigned u; - uintmax_t cll; - ssize_t cl, l, lr; - - CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); - CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC); - CAST_OBJ_NOTNULL(htc, vfe->priv1, HTTP_CONN_MAGIC); - AN(ptr); - AN(lp); - - AN(ptr); - AN(lp); - l = *lp; - *lp = 0; - if (vfe->priv2 == -1) { - /* Skip leading whitespace */ - do { - lr = HTTP1_Read(htc, buf, 1); - if (lr <= 0) - return (VFP_Error(vc, "chunked read err")); - } while (vct_islws(buf[0])); - - if (!vct_ishex(buf[0])) - return (VFP_Error(vc, "chunked header non-hex")); - - /* Collect hex digits, skipping leading zeros */ - for (u = 1; u < sizeof buf; u++) { - do { - lr = HTTP1_Read(htc, buf + u, 1); - if (lr <= 0) - return (VFP_Error(vc, - "chunked read err")); - } while (u == 1 && buf[0] == '0' && buf[u] == '0'); - if (!vct_ishex(buf[u])) - break; - } - - if (u >= sizeof buf) - return (VFP_Error(vc, "chunked header too long")); - - /* Skip trailing white space */ - while(vct_islws(buf[u]) && buf[u] != '\n') { - lr = HTTP1_Read(htc, buf + u, 1); - if (lr <= 0) - return (VFP_Error(vc, "chunked read err")); - } - - if (buf[u] != '\n') - return (VFP_Error(vc, "chunked header no NL")); - - buf[u] = '\0'; - - cll = strtoumax(buf, &q, 16); - if (q == NULL || *q != '\0') - return (VFP_Error(vc, "chunked header number syntax")); - cl = (ssize_t)cll; - if((uintmax_t)cl != cll) - return (VFP_Error(vc, "bogusly large chunk size")); - - vfe->priv2 = cl; - } - if (vfe->priv2 > 0) { - if (vfe->priv2 < l) - l = vfe->priv2; - lr = HTTP1_Read(htc, ptr, l); - if (lr <= 0) - return (VFP_Error(vc, "straight insufficient bytes")); - *lp = lr; - vfe->priv2 -= lr; - if (vfe->priv2 == 0) - vfe->priv2 = -1; - return (VFP_OK); - } - AZ(vfe->priv2); - i = HTTP1_Read(htc, buf, 1); - if (i <= 0) - return (VFP_Error(vc, "chunked read err")); - if (buf[0] == '\r' && HTTP1_Read(htc, buf, 1) <= 0) - return (VFP_Error(vc, "chunked read err")); - if (buf[0] != '\n') - return (VFP_Error(vc, "chunked tail no NL")); - return (VFP_END); -} - -static const struct vfp v1f_chunked = { - .name = "V1F_CHUNKED", - .pull = v1f_pull_chunked, -}; - - -/*--------------------------------------------------------------------*/ - -static enum vfp_status __match_proto__(vfp_pull_f) -v1f_pull_straight(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, - ssize_t *lp) -{ - ssize_t l, lr; - struct http_conn *htc; - - CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); - CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC); - CAST_OBJ_NOTNULL(htc, vfe->priv1, HTTP_CONN_MAGIC); - AN(p); - AN(lp); - - l = *lp; - *lp = 0; - - if (vfe->priv2 == 0) // XXX: Optimize Content-Len: 0 out earlier - return (VFP_END); - if (vfe->priv2 < l) - l = vfe->priv2; - lr = HTTP1_Read(htc, p, l); - if (lr <= 0) - return (VFP_Error(vc, "straight insufficient bytes")); - *lp = lr; - vfe->priv2 -= lr; - if (vfe->priv2 == 0) - return (VFP_END); - return (VFP_OK); -} - -static const struct vfp v1f_straight = { - .name = "V1F_STRAIGHT", - .pull = v1f_pull_straight, -}; - -/*--------------------------------------------------------------------*/ - -static enum vfp_status __match_proto__(vfp_pull_f) -v1f_pull_eof(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, - ssize_t *lp) -{ - ssize_t l, lr; - struct http_conn *htc; - - CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); - CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC); - CAST_OBJ_NOTNULL(htc, vfe->priv1, HTTP_CONN_MAGIC); - AN(p); - - AN(lp); - - l = *lp; - *lp = 0; - lr = HTTP1_Read(htc, p, l); - if (lr < 0) - return (VFP_Error(vc, "eof socket fail")); - if (lr == 0) - return (VFP_END); - *lp = lr; - return (VFP_OK); -} - -static const struct vfp v1f_eof = { - .name = "V1F_EOF", - .pull = v1f_pull_eof, -}; - -/*-------------------------------------------------------------------- - */ - -void -V1F_Setup_Fetch(struct vfp_ctx *vfc, struct http_conn *htc) -{ - struct vfp_entry *vfe; - - CHECK_OBJ_NOTNULL(vfc, VFP_CTX_MAGIC); - CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); - - switch(htc->body_status) { - case BS_EOF: - assert(htc->content_length == -1); - vfe = VFP_Push(vfc, &v1f_eof, 0); - vfe->priv2 = 0; - break; - case BS_LENGTH: - assert(htc->content_length > 0); - vfe = VFP_Push(vfc, &v1f_straight, 0); - vfe->priv2 = htc->content_length; - break; - case BS_CHUNKED: - assert(htc->content_length == -1); - vfe = VFP_Push(vfc, &v1f_chunked, 0); - vfe->priv2 = -1; - break; - default: - WRONG("Wrong body_status"); - break; - } - vfe->priv1 = htc; -} diff --git a/bin/varnishd/flint.sh b/bin/varnishd/flint.sh index 4f471cf..7a44dad 100755 --- a/bin/varnishd/flint.sh +++ b/bin/varnishd/flint.sh @@ -23,6 +23,7 @@ flexelint \ storage/*.c \ waiter/*.c \ hash/*.c \ + http1/*.c \ mgt/*.c \ ../../lib/libvarnish/*.c \ ../../lib/libvarnishcompat/execinfo.c \ diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c new file mode 100644 index 0000000..0e63c41 --- /dev/null +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -0,0 +1,463 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2014 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 "cache/cache.h" + +#include "vct.h" + +/*--------------------------------------------------------------------*/ + +static int __match_proto__(vdp_bytes) +v1d_bytes(struct req *req, enum vdp_action act, const void *ptr, ssize_t len) +{ + ssize_t wl = 0; + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + + assert(req->vdp_nxt == -1); /* always at the bottom of the pile */ + + if (len > 0) + wl = WRW_Write(req->wrk, ptr, len); + req->resp_bodybytes += wl; + if (act > VDP_NULL && WRW_Flush(req->wrk)) + return (-1); + if (len != wl) + return (-1); + return (0); +} + +/*--------------------------------------------------------------------*/ + +static int __match_proto__(vdp_bytes) +v1d_range_bytes(struct req *req, enum vdp_action act, const void *ptr, + ssize_t len) +{ + int retval = 0; + ssize_t l; + const char *p = ptr; + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + l = req->range_low - req->range_off; + if (l > 0) { + if (l > len) + l = len; + req->range_off += l; + p += l; + len -= l; + } + l = req->range_high - req->range_off; + if (l > len) + l = len; + if (l > 0) + retval = VDP_bytes(req, act, p, l); + else if (act > VDP_NULL) + retval = VDP_bytes(req, act, p, 0); + req->range_off += len; + return (retval); +} + +/*--------------------------------------------------------------------*/ + +static void +v1d_dorange(struct req *req, struct busyobj *bo, const char *r) +{ + ssize_t len, low, high, has_low; + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); + assert(http_IsStatus(req->resp, 200)); + + /* We must snapshot the length if we're streaming from the backend */ + if (bo != NULL) + len = VBO_waitlen(req->wrk, bo, -1); + else + len = ObjGetLen(req->wrk, req->objcore); + + if (strncmp(r, "bytes=", 6)) + return; + r += 6; + + /* The low end of range */ + has_low = low = 0; + if (!vct_isdigit(*r) && *r != '-') + return; + while (vct_isdigit(*r)) { + has_low = 1; + low *= 10; + low += *r - '0'; + r++; + } + + if (low >= len) + return; + + if (*r != '-') + return; + r++; + + /* The high end of range */ + if (vct_isdigit(*r)) { + high = 0; + while (vct_isdigit(*r)) { + high *= 10; + high += *r - '0'; + r++; + } + if (!has_low) { + low = len - high; + if (low < 0) + low = 0; + high = len - 1; + } + } else + high = len - 1; + if (*r != '\0') + return; + + if (high >= len) + high = len - 1; + + if (low > high) + return; + + http_PrintfHeader(req->resp, "Content-Range: bytes %jd-%jd/%jd", + (intmax_t)low, (intmax_t)high, (intmax_t)len); + http_Unset(req->resp, H_Content_Length); + if (req->res_mode & RES_LEN) + http_PrintfHeader(req->resp, "Content-Length: %jd", + (intmax_t)(1 + high - low)); + http_PutResponse(req->resp, "HTTP/1.1", 206, NULL); + + req->range_off = 0; + req->range_low = low; + req->range_high = high + 1; + VDP_push(req, v1d_range_bytes); +} + +/*--------------------------------------------------------------------*/ + +static enum objiter_status +v1d_WriteDirObj(struct req *req) +{ + enum objiter_status ois; + ssize_t len; + void *oi; + void *ptr; + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + + oi = ObjIterBegin(req->wrk, req->objcore); + XXXAN(oi); + + do { + ois = ObjIter(req->objcore, oi, &ptr, &len); + switch(ois) { + case OIS_DONE: + AZ(len); + break; + case OIS_ERROR: + break; + case OIS_DATA: + case OIS_STREAM: + if (VDP_bytes(req, + ois == OIS_DATA ? VDP_NULL : VDP_FLUSH, ptr, len)) + ois = OIS_ERROR; + break; + default: + WRONG("Wrong OIS value"); + } + } while (ois == OIS_DATA || ois == OIS_STREAM); + (void)VDP_bytes(req, VDP_FINISH, NULL, 0); + ObjIterEnd(req->objcore, &oi); + return (ois); +} + +/*-------------------------------------------------------------------- + * V1D_FlushReleaseAcct() + * Call WRW_FlushRelease on the worker and update the requests + * byte accounting with the number of bytes transmitted + * + * Returns the return value from WRW_FlushRelease() + */ +unsigned +V1D_FlushReleaseAcct(struct req *req) +{ + unsigned u; + uint64_t txcnt = 0, hdrbytes; + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + CHECK_OBJ_NOTNULL(req->wrk, WORKER_MAGIC); + u = WRW_FlushRelease(req->wrk, &txcnt); + if (req->acct.resp_hdrbytes < req->resp_hdrbytes) { + hdrbytes = req->resp_hdrbytes - req->acct.resp_hdrbytes; + if (hdrbytes > txcnt) + hdrbytes = txcnt; + } else + hdrbytes = 0; + req->acct.resp_hdrbytes += hdrbytes; + req->acct.resp_bodybytes += txcnt - hdrbytes; + return (u); +} + +void +V1D_Deliver(struct req *req, struct busyobj *bo) +{ + const char *r; + enum objiter_status ois; + ssize_t l; + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); + + req->res_mode = 0; + + if (!req->disable_esi && ObjGetattr(req->wrk, req->objcore, + OA_ESIDATA, NULL) != NULL) { + /* In ESI mode, we can't know the aggregate length */ + req->res_mode &= ~RES_LEN; + req->res_mode |= RES_ESI; + } else if (http_IsStatus(req->resp, 304)) { + req->res_mode &= ~RES_LEN; + http_Unset(req->resp, H_Content_Length); + req->wantbody = 0; + } else if (bo == NULL) { + /* XXX: Not happy with this convoluted test */ + req->res_mode |= RES_LEN; + if (!(req->objcore->flags & OC_F_PASS) || + ObjGetLen(req->wrk, req->objcore) != 0) { + http_Unset(req->resp, H_Content_Length); + http_PrintfHeader(req->resp, + "Content-Length: %ju", (uintmax_t)ObjGetLen( + req->wrk, req->objcore)); + } + } + + if (req->esi_level > 0) { + /* Included ESI object, always CHUNKED or EOF */ + req->res_mode &= ~RES_LEN; + req->res_mode |= RES_ESI_CHILD; + } + + if (cache_param->http_gzip_support && + ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED) && + !RFC2616_Req_Gzip(req->http)) { + /* + * We don't know what it uncompresses to + * XXX: we could cache that, but would still deliver + * XXX: with multiple writes because of the gunzip buffer + */ + req->res_mode &= ~RES_LEN; + req->res_mode |= RES_GUNZIP; + } + + if (!(req->res_mode & (RES_LEN|RES_CHUNKED|RES_EOF))) { + /* We havn't chosen yet, do so */ + if (!req->wantbody) { + /* Nothing */ + } else if (req->http->protover >= 11) { + req->res_mode |= RES_CHUNKED; + } else { + req->res_mode |= RES_EOF; + req->doclose = SC_TX_EOF; + } + } + VSLb(req->vsl, SLT_Debug, "RES_MODE %x", req->res_mode); + + if (!(req->res_mode & RES_LEN)) + http_Unset(req->resp, H_Content_Length); + + if (req->res_mode & RES_GUNZIP) + http_Unset(req->resp, H_Content_Encoding); + + if (req->res_mode & RES_CHUNKED) + http_SetHeader(req->resp, "Transfer-Encoding: chunked"); + + http_SetHeader(req->resp, + req->doclose ? "Connection: close" : "Connection: keep-alive"); + + req->vdps[0] = v1d_bytes; + req->vdp_nxt = 0; + + if ( + req->wantbody && + !(req->res_mode & (RES_ESI|RES_ESI_CHILD)) && + cache_param->http_range_support && + http_IsStatus(req->resp, 200)) { + http_SetHeader(req->resp, "Accept-Ranges: bytes"); + if (http_GetHdr(req->http, H_Range, &r)) + v1d_dorange(req, bo, r); + } + + if (req->res_mode & RES_ESI) + RFC2616_Weaken_Etag(req->resp); + + WRW_Reserve(req->wrk, &req->sp->fd, req->vsl, req->t_prev); + + /* + * Send HTTP protocol header, unless interior ESI object + */ + if (!(req->res_mode & RES_ESI_CHILD)) + req->resp_hdrbytes += + HTTP1_Write(req->wrk, req->resp, HTTP1_Resp); + + if (req->res_mode & RES_CHUNKED) + WRW_Chunked(req->wrk); + + ois = OIS_DONE; + if (!req->wantbody) { + /* This was a HEAD or conditional request */ + } else if (req->res_mode & RES_ESI) { + ESI_Deliver(req); + } else if (req->res_mode & RES_ESI_CHILD && req->gzip_resp) { + l = -1; + while (req->objcore->busyobj) { + assert(bo != NULL); + l = VBO_waitlen(req->wrk, bo, l); + } + ESI_DeliverChild(req); + } else if (req->res_mode & RES_GUNZIP || + (req->res_mode & RES_ESI_CHILD && + !req->gzip_resp && + ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED))) { + VDP_push(req, VDP_gunzip); + req->vgz = VGZ_NewUngzip(req->vsl, "U D -"); + AZ(VGZ_WrwInit(req->vgz)); + ois = v1d_WriteDirObj(req); + (void)VGZ_Destroy(&req->vgz); + VDP_pop(req, VDP_gunzip); + } else { + ois = v1d_WriteDirObj(req); + } + + if (ois == OIS_DONE && + (req->res_mode & RES_CHUNKED) && + !(req->res_mode & RES_ESI_CHILD)) + WRW_EndChunk(req->wrk); + + if ((V1D_FlushReleaseAcct(req) || ois != OIS_DONE) && req->sp->fd >= 0) + SES_Close(req->sp, SC_REM_CLOSE); +} + +void +V1D_Deliver_Synth(struct req *req) +{ + const char *r; + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + AN(req->synth_body); + + req->res_mode = 0; + if (http_IsStatus(req->resp, 304)) { + req->res_mode &= ~RES_LEN; + http_Unset(req->resp, H_Content_Length); + req->wantbody = 0; + } else { + req->res_mode |= RES_LEN; + http_Unset(req->resp, H_Content_Length); + http_PrintfHeader(req->resp, "Content-Length: %zd", + VSB_len(req->synth_body)); + } + + if (req->esi_level > 0) { + /* Included ESI object, always CHUNKED or EOF */ + req->res_mode &= ~RES_LEN; + req->res_mode |= RES_ESI_CHILD; + } + + if (!(req->res_mode & (RES_LEN|RES_CHUNKED|RES_EOF))) { + /* We havn't chosen yet, do so */ + if (!req->wantbody) { + /* Nothing */ + } else if (req->http->protover >= 11) { + req->res_mode |= RES_CHUNKED; + } else { + req->res_mode |= RES_EOF; + req->doclose = SC_TX_EOF; + } + } + VSLb(req->vsl, SLT_Debug, "RES_MODE %x", req->res_mode); + + if (!(req->res_mode & RES_LEN)) + http_Unset(req->resp, H_Content_Length); + + if (req->res_mode & RES_GUNZIP) + http_Unset(req->resp, H_Content_Encoding); + + if (req->res_mode & RES_CHUNKED) + http_SetHeader(req->resp, "Transfer-Encoding: chunked"); + + http_SetHeader(req->resp, + req->doclose ? "Connection: close" : "Connection: keep-alive"); + + req->vdps[0] = v1d_bytes; + req->vdp_nxt = 0; + + if ( + req->wantbody && + !(req->res_mode & RES_ESI_CHILD) && + cache_param->http_range_support && + http_IsStatus(req->resp, 200)) { + http_SetHeader(req->resp, "Accept-Ranges: bytes"); + if (http_GetHdr(req->http, H_Range, &r)) + v1d_dorange(req, NULL, r); + } + + WRW_Reserve(req->wrk, &req->sp->fd, req->vsl, req->t_prev); + + /* + * Send HTTP protocol header, unless interior ESI object + */ + if (!(req->res_mode & RES_ESI_CHILD)) + req->resp_hdrbytes += + HTTP1_Write(req->wrk, req->resp, HTTP1_Resp); + + if (req->res_mode & RES_CHUNKED) + WRW_Chunked(req->wrk); + + if (!req->wantbody) { + /* This was a HEAD or conditional request */ +#if 0 + XXX: Missing pretend GZIP for esi-children + } else if (req->res_mode & RES_ESI_CHILD && req->gzip_resp) { + ESI_DeliverChild(req); +#endif + } else { + (void)VDP_bytes(req, VDP_FLUSH, VSB_data(req->synth_body), + VSB_len(req->synth_body)); + (void)VDP_bytes(req, VDP_FINISH, NULL, 0); + } + + if (req->res_mode & RES_CHUNKED && !(req->res_mode & RES_ESI_CHILD)) + WRW_EndChunk(req->wrk); + + if (V1D_FlushReleaseAcct(req) && req->sp->fd >= 0) + SES_Close(req->sp, SC_REM_CLOSE); +} diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c new file mode 100644 index 0000000..6793739 --- /dev/null +++ b/bin/varnishd/http1/cache_http1_fetch.c @@ -0,0 +1,208 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2014 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 + +#include "cache/cache.h" + +#include "hash/hash_slinger.h" + +#include "cache/cache_backend.h" +#include "cache/cache_director.h" +#include "vcli_priv.h" +#include "vtcp.h" +#include "vtim.h" + +/*-------------------------------------------------------------------- + * Pass the request body to the backend + */ + +static int __match_proto__(req_body_iter_f) +vbf_iter_req_body(struct req *req, void *priv, void *ptr, size_t l) +{ + struct worker *wrk; + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + CAST_OBJ_NOTNULL(wrk, priv, WORKER_MAGIC); + + if (l > 0) { + (void)WRW_Write(wrk, ptr, l); + if (WRW_Flush(wrk)) + return (-1); + } + return (0); +} + +/*-------------------------------------------------------------------- + * Send request, and receive the HTTP protocol response, but not the + * response body. + * + * Return value: + * -1 failure, not retryable + * 0 success + * 1 failure which can be retried. + */ + +int +V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo) +{ + struct vbc *vc; + struct http *hp; + enum http1_status_e hs; + int retry = -1; + int i, j, first; + struct http_conn *htc; + ssize_t hdrbytes; + int do_chunked = 0; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + CHECK_OBJ_NOTNULL(bo->vbc, VBC_MAGIC); + CHECK_OBJ_ORNULL(bo->req, REQ_MAGIC); + + htc = bo->htc; + hp = bo->bereq; + vc = bo->vbc; + if (vc->recycled) + retry = 1; + + /* + * Now that we know our backend, we can set a default Host: + * header if one is necessary. This cannot be done in the VCL + * because the backend may be chosen by a director. + */ + if (!http_GetHdr(bo->bereq, H_Host, NULL)) + VDI_AddHostHeader(bo->bereq, vc); + + if (bo->req != NULL && + bo->req->req_body_status == REQ_BODY_WITHOUT_LEN) { + http_PrintfHeader(hp, "Transfer-Encoding: chunked"); + do_chunked = 1; + } + + (void)VTCP_blocking(vc->fd); /* XXX: we should timeout instead */ + WRW_Reserve(wrk, &vc->fd, bo->vsl, bo->t_prev); + hdrbytes = HTTP1_Write(wrk, hp, HTTP1_Req); + + /* Deal with any message-body the request might (still) have */ + i = 0; + + if (bo->req != NULL) { + if (do_chunked) + WRW_Chunked(wrk); + i = VRB_Iterate(bo->req, vbf_iter_req_body, wrk); + + if (bo->req->req_body_status == REQ_BODY_TAKEN) { + retry = -1; + } else if (bo->req->req_body_status == REQ_BODY_FAIL) { + VSLb(bo->vsl, SLT_FetchError, + "req.body read error: %d (%s)", + errno, strerror(errno)); + bo->req->doclose = SC_RX_BODY; + retry = -1; + } + if (do_chunked) + WRW_EndChunk(wrk); + } + + j = WRW_FlushRelease(wrk, &bo->acct.bereq_hdrbytes); + if (bo->acct.bereq_hdrbytes > hdrbytes) { + bo->acct.bereq_bodybytes = bo->acct.bereq_hdrbytes - hdrbytes; + bo->acct.bereq_hdrbytes = hdrbytes; + } + if (j != 0 || i != 0) { + VSLb(bo->vsl, SLT_FetchError, "backend write error: %d (%s)", + errno, strerror(errno)); + VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk)); + VBE_CloseFd(&bo->vbc, &bo->acct); + /* XXX: other cleanup ? */ + return (retry); + } + VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk)); + + VSC_C_main->backend_req++; + + /* Receive response */ + + HTTP1_Init(htc, bo->ws, vc->fd, bo->vsl, + cache_param->http_resp_size, + cache_param->http_resp_hdr_len); + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC); + + VTCP_set_read_timeout(vc->fd, vc->first_byte_timeout); + + first = 1; + do { + hs = HTTP1_Rx(htc); + if (hs == HTTP1_OVERFLOW) { + bo->acct.beresp_hdrbytes += + htc->rxbuf_e - htc->rxbuf_b; + VSLb(bo->vsl, SLT_FetchError, + "http %sread error: overflow", + first ? "first " : ""); + VBE_CloseFd(&bo->vbc, &bo->acct); + /* XXX: other cleanup ? */ + return (-1); + } + if (hs == HTTP1_ERROR_EOF) { + bo->acct.beresp_hdrbytes += + htc->rxbuf_e - htc->rxbuf_b; + VSLb(bo->vsl, SLT_FetchError, "http %sread error: EOF", + first ? "first " : ""); + VBE_CloseFd(&bo->vbc, &bo->acct); + /* XXX: other cleanup ? */ + return (retry); + } + if (first) { + retry = -1; + first = 0; + VTCP_set_read_timeout(vc->fd, + vc->between_bytes_timeout); + } + } while (hs != HTTP1_COMPLETE); + bo->acct.beresp_hdrbytes += htc->rxbuf_e - htc->rxbuf_b; + + hp = bo->beresp; + + if (HTTP1_DissectResponse(hp, htc)) { + VSLb(bo->vsl, SLT_FetchError, "http format error"); + VBE_CloseFd(&bo->vbc, &bo->acct); + /* XXX: other cleanup ? */ + return (-1); + } + + bo->doclose = http_DoConnection(hp); + + return (0); +} diff --git a/bin/varnishd/http1/cache_http1_fsm.c b/bin/varnishd/http1/cache_http1_fsm.c new file mode 100644 index 0000000..dc586cc --- /dev/null +++ b/bin/varnishd/http1/cache_http1_fsm.c @@ -0,0 +1,403 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2014 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. + * + * This file contains the two central state machine for pushing HTTP1 + * sessions through their states. + * + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "cache/cache.h" +#include "hash/hash_slinger.h" + +#include "vcl.h" +#include "vtcp.h" +#include "vtim.h" + +/*---------------------------------------------------------------------- + * Collect a request from the client. + */ + +static enum req_fsm_nxt +http1_wait(struct sess *sp, struct worker *wrk, struct req *req) +{ + int j, tmo; + struct pollfd pfd[1]; + double now, when; + enum sess_close why = SC_NULL; + enum http1_status_e hs; + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + + assert(req->sp == sp); + + AZ(req->vcl); + AZ(req->esi_level); + AZ(isnan(sp->t_idle)); + assert(isnan(req->t_first)); + assert(isnan(req->t_prev)); + assert(isnan(req->t_req)); + + tmo = (int)(1e3 * cache_param->timeout_linger); + while (1) { + pfd[0].fd = sp->fd; + pfd[0].events = POLLIN; + pfd[0].revents = 0; + j = poll(pfd, 1, tmo); + assert(j >= 0); + now = VTIM_real(); + if (j != 0) + hs = HTTP1_Rx(req->htc); + else + hs = HTTP1_Complete(req->htc); + if (hs == HTTP1_COMPLETE) { + /* Got it, run with it */ + if (isnan(req->t_first)) + req->t_first = now; + if (isnan(req->t_req)) + req->t_req = now; + req->acct.req_hdrbytes += + req->htc->rxbuf_e - req->htc->rxbuf_b; + return (REQ_FSM_MORE); + } else if (hs == HTTP1_ERROR_EOF) { + why = SC_REM_CLOSE; + break; + } else if (hs == HTTP1_OVERFLOW) { + why = SC_RX_OVERFLOW; + break; + } else if (hs == HTTP1_ALL_WHITESPACE) { + /* Nothing but whitespace */ + when = sp->t_idle + cache_param->timeout_idle; + if (when < now) { + why = SC_RX_TIMEOUT; + break; + } + when = sp->t_idle + cache_param->timeout_linger; + tmo = (int)(1e3 * (when - now)); + if (when < now || tmo == 0) { + wrk->stats->sess_herd++; + SES_ReleaseReq(req); + WAIT_Enter(sp); + return (REQ_FSM_DONE); + } + } else { + /* Working on it */ + if (isnan(req->t_first)) + /* Record first byte received time stamp */ + req->t_first = now; + when = sp->t_idle + cache_param->timeout_req; + tmo = (int)(1e3 * (when - now)); + if (when < now || tmo == 0) { + why = SC_RX_TIMEOUT; + break; + } + } + } + req->acct.req_hdrbytes += req->htc->rxbuf_e - req->htc->rxbuf_b; + CNT_AcctLogCharge(wrk->stats, req); + SES_ReleaseReq(req); + assert(why != SC_NULL); + SES_Delete(sp, why, now); + return (REQ_FSM_DONE); +} + +/*---------------------------------------------------------------------- + * This is the final state, figure out if we should close or recycle + * the client connection + */ + +enum http1_cleanup_ret { + SESS_DONE_RET_GONE, + SESS_DONE_RET_WAIT, + SESS_DONE_RET_START, +}; + +static enum http1_cleanup_ret +http1_cleanup(struct sess *sp, struct worker *wrk, struct req *req) +{ + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + CHECK_OBJ_ORNULL(req->vcl, VCL_CONF_MAGIC); + + req->director_hint = NULL; + req->restarts = 0; + + AZ(req->esi_level); + + if (req->vcl != NULL) { + if (wrk->vcl != NULL) + VCL_Rel(&wrk->vcl); + wrk->vcl = req->vcl; + req->vcl = NULL; + } + + VRTPRIV_dynamic_kill(sp, (uintptr_t)req); + /* Charge and log byte counters */ + AN(req->vsl->wid); + CNT_AcctLogCharge(wrk->stats, req); + req->req_bodybytes = 0; + req->resp_hdrbytes = 0; + req->resp_bodybytes = 0; + + VSL_End(req->vsl); + + if (!isnan(req->t_prev) && req->t_prev > 0.) + sp->t_idle = req->t_prev; + else + sp->t_idle = W_TIM_real(wrk); + + req->t_first = NAN; + req->t_prev = NAN; + req->t_req = NAN; + req->req_body_status = REQ_BODY_INIT; + + req->hash_always_miss = 0; + req->hash_ignore_busy = 0; + + if (sp->fd >= 0 && req->doclose != SC_NULL) + SES_Close(sp, req->doclose); + + if (sp->fd < 0) { + wrk->stats->sess_closed++; + AZ(req->vcl); + SES_ReleaseReq(req); + SES_Delete(sp, SC_NULL, NAN); + return (SESS_DONE_RET_GONE); + } + + WS_Reset(req->ws, NULL); + WS_Reset(wrk->aws, NULL); + + if (HTTP1_Reinit(req->htc) == HTTP1_COMPLETE) { + AZ(req->vsl->wid); + req->t_first = req->t_req = sp->t_idle; + wrk->stats->sess_pipeline++; + req->acct.req_hdrbytes += + req->htc->rxbuf_e - req->htc->rxbuf_b; + return (SESS_DONE_RET_START); + } else { + if (req->htc->rxbuf_e != req->htc->rxbuf_b) + wrk->stats->sess_readahead++; + return (SESS_DONE_RET_WAIT); + } +} + +/*---------------------------------------------------------------------- + */ + +static enum req_fsm_nxt +http1_dissect(struct worker *wrk, struct req *req) +{ + const char *r_100 = "HTTP/1.1 100 Continue\r\n\r\n"; + const char *r_400 = "HTTP/1.1 400 Bad Request\r\n\r\n"; + const char *r_417 = "HTTP/1.1 417 Expectation Failed\r\n\r\n"; + const char *p; + ssize_t r; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + + /* Allocate a new vxid now that we know we'll need it. */ + AZ(req->vsl->wid); + req->vsl->wid = VXID_Get(wrk, VSL_CLIENTMARKER); + + VSLb(req->vsl, SLT_Begin, "req %u rxreq", VXID(req->sp->vxid)); + VSL(SLT_Link, req->sp->vxid, "req %u rxreq", VXID(req->vsl->wid)); + AZ(isnan(req->t_first)); /* First byte timestamp set by http1_wait */ + AZ(isnan(req->t_req)); /* Complete req rcvd set by http1_wait */ + req->t_prev = req->t_first; + VSLb_ts_req(req, "Start", req->t_first); + VSLb_ts_req(req, "Req", req->t_req); + + /* Borrow VCL reference from worker thread */ + VCL_Refresh(&wrk->vcl); + req->vcl = wrk->vcl; + wrk->vcl = NULL; + + HTTP_Setup(req->http, req->ws, req->vsl, SLT_ReqMethod); + req->err_code = HTTP1_DissectRequest(req->htc, req->http); + + /* If we could not even parse the request, just close */ + if (req->err_code != 0) { + VSLb(req->vsl, SLT_HttpGarbage, "%.*s", + (int)(req->htc->rxbuf_e - req->htc->rxbuf_b), + req->htc->rxbuf_b); + wrk->stats->client_req_400++; + r = write(req->sp->fd, r_400, strlen(r_400)); + if (r > 0) + req->acct.resp_hdrbytes += r; + SES_Close(req->sp, SC_RX_JUNK); + return (REQ_FSM_DONE); + } + + assert (req->req_body_status == REQ_BODY_INIT); + + if (req->htc->body_status == BS_CHUNKED) { + req->req_body_status = REQ_BODY_WITHOUT_LEN; + } else if (req->htc->body_status == BS_LENGTH) { + req->req_body_status = REQ_BODY_WITH_LEN; + } else if (req->htc->body_status == BS_NONE) { + req->req_body_status = REQ_BODY_NONE; + } else if (req->htc->body_status == BS_EOF) { + req->req_body_status = REQ_BODY_WITHOUT_LEN; + } else { + WRONG("Unknown req.body_length situation"); + } + + if (http_GetHdr(req->http, H_Expect, &p)) { + if (strcasecmp(p, "100-continue")) { + wrk->stats->client_req_417++; + req->err_code = 417; + r = write(req->sp->fd, r_417, strlen(r_417)); + if (r > 0) + req->resp_hdrbytes += r; + SES_Close(req->sp, SC_RX_JUNK); + return (REQ_FSM_DONE); + } + r = write(req->sp->fd, r_100, strlen(r_100)); + if (r > 0) + req->acct.resp_hdrbytes += r; + if (r != strlen(r_100)) { + SES_Close(req->sp, SC_REM_CLOSE); + return (REQ_FSM_DONE); + } + http_Unset(req->http, H_Expect); + } + + wrk->stats->client_req++; + wrk->stats->s_req++; + + AZ(req->err_code); + req->ws_req = WS_Snapshot(req->ws); + + assert(req->req_body_status != REQ_BODY_INIT); + + HTTP_Copy(req->http0, req->http); // For ESI & restart + + return (REQ_FSM_MORE); +} + +/*---------------------------------------------------------------------- + */ + +void +HTTP1_Session(struct worker *wrk, struct req *req) +{ + enum req_fsm_nxt nxt = REQ_FSM_MORE; + struct sess *sp; + enum http1_cleanup_ret sdr; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + sp = req->sp; + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + + /* + * Whenever we come in from the acceptor or waiter, we need to set + * blocking mode. It would be simpler to do this in the acceptor + * or waiter, but we'd rather do the syscall in the worker thread. + * On systems which return errors for ioctl, we close early + */ + if (sp->sess_step == S_STP_NEWREQ && VTCP_blocking(sp->fd)) { + if (errno == ECONNRESET) + SES_Close(sp, SC_REM_CLOSE); + else + SES_Close(sp, SC_TX_ERROR); + sdr = http1_cleanup(sp, wrk, req); + assert(sdr == SESS_DONE_RET_GONE); + return; + } + + /* + * Return from waitinglist. Check to see if the remote has left. + */ + if (req->req_step == R_STP_LOOKUP && VTCP_check_hup(sp->fd)) { + AN(req->hash_objhead); + (void)HSH_DerefObjHead(wrk, &req->hash_objhead); + AZ(req->hash_objhead); + SES_Close(sp, SC_REM_CLOSE); + sdr = http1_cleanup(sp, wrk, req); + assert(sdr == SESS_DONE_RET_GONE); + return; + } + + if (sp->sess_step == S_STP_NEWREQ) { + HTTP1_Init(req->htc, req->ws, sp->fd, req->vsl, + cache_param->http_req_size, + cache_param->http_req_hdr_len); + } + + while (1) { + assert( + sp->sess_step == S_STP_NEWREQ || + req->req_step == R_STP_LOOKUP || + req->req_step == R_STP_RECV); + + if (sp->sess_step == S_STP_WORKING) { + if (req->req_step == R_STP_RECV) + nxt = http1_dissect(wrk, req); + if (nxt == REQ_FSM_MORE) + nxt = CNT_Request(wrk, req); + if (nxt == REQ_FSM_DISEMBARK) + return; + assert(nxt == REQ_FSM_DONE); + sdr = http1_cleanup(sp, wrk, req); + switch (sdr) { + case SESS_DONE_RET_GONE: + return; + case SESS_DONE_RET_WAIT: + sp->sess_step = S_STP_NEWREQ; + break; + case SESS_DONE_RET_START: + sp->sess_step = S_STP_WORKING; + req->req_step = R_STP_RECV; + break; + default: + WRONG("Illegal enum http1_cleanup_ret"); + } + } + + if (sp->sess_step == S_STP_NEWREQ) { + 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/http1/cache_http1_pipe.c b/bin/varnishd/http1/cache_http1_pipe.c new file mode 100644 index 0000000..e451f35 --- /dev/null +++ b/bin/varnishd/http1/cache_http1_pipe.c @@ -0,0 +1,197 @@ +/*- + * 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. + * + * XXX: charge bytes to srcaddr + */ + +#include "config.h" + +#include +#include + +#include "cache/cache.h" + +#include "cache/cache_backend.h" +#include "cache/cache_director.h" +#include "vtcp.h" +#include "vtim.h" + +static struct lock pipestat_mtx; + +struct acct_pipe { + uint64_t req; + uint64_t bereq; + uint64_t in; + uint64_t out; +}; + +static int +rdf(int fd0, int fd1, uint64_t *pcnt) +{ + int i, j; + char buf[BUFSIZ], *p; + + i = read(fd0, buf, sizeof buf); + if (i <= 0) + return (1); + for (p = buf; i > 0; i -= j, p += j) { + j = write(fd1, p, i); + if (j <= 0) + return (1); + *pcnt += j; + if (i != j) + (void)usleep(100000); /* XXX hack */ + } + return (0); +} + +static void +pipecharge(struct req *req, const struct acct_pipe *a, struct VSC_C_vbe *b) +{ + + VSLb(req->vsl, SLT_PipeAcct, "%ju %ju %ju %ju", + (uintmax_t)a->req, + (uintmax_t)a->bereq, + (uintmax_t)a->in, + (uintmax_t)a->out); + + Lck_Lock(&pipestat_mtx); + VSC_C_main->s_pipe_hdrbytes += a->req; + VSC_C_main->s_pipe_in += a->in; + VSC_C_main->s_pipe_out += a->out; + if (b != NULL) { + b->pipe_hdrbytes += a->bereq; + b->pipe_out += a->in; + b->pipe_in += a->out; + } + Lck_Unlock(&pipestat_mtx); +} + +void +V1P_Process(struct req *req, struct busyobj *bo) +{ + struct vbc *vc; + struct worker *wrk; + struct pollfd fds[2]; + int i; + struct acct_pipe acct_pipe; + ssize_t hdrbytes; + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + CHECK_OBJ_NOTNULL(req->sp, SESS_MAGIC); + wrk = req->wrk; + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + + req->res_mode = RES_PIPE; + + memset(&acct_pipe, 0, sizeof acct_pipe); + acct_pipe.req = req->acct.req_hdrbytes; + req->acct.req_hdrbytes = 0; + + vc = VDI_GetFd(bo->director_req, wrk, bo); + if (vc == NULL) { + pipecharge(req, &acct_pipe, NULL); + SES_Close(req->sp, SC_OVERLOAD); + return; + } + bo->vbc = vc; /* For panic dumping */ + (void)VTCP_blocking(vc->fd); + + WRW_Reserve(wrk, &vc->fd, bo->vsl, req->t_req); + hdrbytes = HTTP1_Write(wrk, bo->bereq, HTTP1_Req); + + if (req->htc->pipeline_b != NULL) + (void)WRW_Write(wrk, req->htc->pipeline_b, + req->htc->pipeline_e - req->htc->pipeline_b); + + i = WRW_FlushRelease(wrk, &acct_pipe.bereq); + if (acct_pipe.bereq > hdrbytes) { + acct_pipe.in = acct_pipe.bereq - hdrbytes; + acct_pipe.bereq = hdrbytes; + } + + VSLb_ts_req(req, "Pipe", W_TIM_real(wrk)); + + if (i) { + pipecharge(req, &acct_pipe, vc->backend->vsc); + SES_Close(req->sp, SC_TX_PIPE); + VBE_CloseFd(&vc, NULL); + return; + } + + memset(fds, 0, sizeof fds); + + // XXX: not yet (void)VTCP_linger(vc->fd, 0); + fds[0].fd = vc->fd; + fds[0].events = POLLIN | POLLERR; + + // XXX: not yet (void)VTCP_linger(req->sp->fd, 0); + fds[1].fd = req->sp->fd; + fds[1].events = POLLIN | POLLERR; + + while (fds[0].fd > -1 || fds[1].fd > -1) { + fds[0].revents = 0; + fds[1].revents = 0; + i = poll(fds, 2, (int)(cache_param->pipe_timeout * 1e3)); + if (i < 1) + break; + if (fds[0].revents && + rdf(vc->fd, req->sp->fd, &acct_pipe.out)) { + if (fds[1].fd == -1) + break; + (void)shutdown(vc->fd, SHUT_RD); + (void)shutdown(req->sp->fd, SHUT_WR); + fds[0].events = 0; + fds[0].fd = -1; + } + if (fds[1].revents && + rdf(req->sp->fd, vc->fd, &acct_pipe.in)) { + if (fds[0].fd == -1) + break; + (void)shutdown(req->sp->fd, SHUT_RD); + (void)shutdown(vc->fd, SHUT_WR); + fds[1].events = 0; + fds[1].fd = -1; + } + } + VSLb_ts_req(req, "PipeSess", W_TIM_real(wrk)); + pipecharge(req, &acct_pipe, vc->backend->vsc); + SES_Close(req->sp, SC_TX_PIPE); + VBE_CloseFd(&vc, NULL); + bo->vbc = NULL; +} + +/*--------------------------------------------------------------------*/ + +void +V1P_Init(void) +{ + + Lck_New(&pipestat_mtx, lck_pipestat); +} diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c new file mode 100644 index 0000000..4d0e025 --- /dev/null +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -0,0 +1,576 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2014 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. + * + * Until we see the magic marker, we have to keep the rxbuf NUL terminated + * because we use strchr(3) on it. + * + * We use this both for client and backend connections. + */ + +#include "config.h" + +#include "cache/cache.h" + +#include "vct.h" + +const int HTTP1_Req[3] = { + HTTP_HDR_METHOD, HTTP_HDR_URL, HTTP_HDR_PROTO +}; + +const int HTTP1_Resp[3] = { + HTTP_HDR_PROTO, HTTP_HDR_STATUS, HTTP_HDR_REASON +}; + +/*--------------------------------------------------------------------*/ + +void +HTTP1_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 http1_status_e +HTTP1_Reinit(struct http_conn *htc) +{ + ssize_t 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 = htc->pipeline_e - htc->pipeline_b; + assert(l > 0); + 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 (HTTP1_Complete(htc)); +} + +/*-------------------------------------------------------------------- + * Check if we have a complete HTTP request or response yet + */ + +enum http1_status_e +HTTP1_Complete(struct http_conn *htc) +{ + char *p; + + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + AZ(htc->pipeline_b); + AZ(htc->pipeline_e); + + assert(htc->rxbuf_e >= htc->rxbuf_b); + assert(*htc->rxbuf_e == '\0'); + + /* Skip any leading white space */ + for (p = htc->rxbuf_b ; vct_islws(*p); p++) + continue; + if (p == htc->rxbuf_e) { + /* All white space */ + htc->rxbuf_e = htc->rxbuf_b; + *htc->rxbuf_e = '\0'; + return (HTTP1_ALL_WHITESPACE); + } + while (1) { + p = strchr(p, '\n'); + if (p == NULL) + return (HTTP1_NEED_MORE); + p++; + if (*p == '\r') + p++; + if (*p == '\n') + break; + } + p++; + WS_ReleaseP(htc->ws, htc->rxbuf_e); + if (p < htc->rxbuf_e) { + htc->pipeline_b = p; + htc->pipeline_e = htc->rxbuf_e; + htc->rxbuf_e = p; + } + return (HTTP1_COMPLETE); +} + +/*-------------------------------------------------------------------- + * Receive more HTTP protocol bytes + */ + +enum http1_status_e +HTTP1_Rx(struct http_conn *htc) +{ + int i; + + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + AN(htc->ws->r); + AZ(htc->pipeline_b); + AZ(htc->pipeline_e); + i = (htc->ws->r - htc->rxbuf_e) - 1; /* space for NUL */ + if (i <= 0) { + WS_ReleaseP(htc->ws, htc->rxbuf_b); + return (HTTP1_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 (HTTP1_ERROR_EOF); + } + htc->rxbuf_e += i; + *htc->rxbuf_e = '\0'; + return (HTTP1_Complete(htc)); +} + +/*-------------------------------------------------------------------- + * Read up to len bytes, returning pipelined data first. + */ + +ssize_t +HTTP1_Read(struct http_conn *htc, void *d, size_t len) +{ + ssize_t l; + unsigned char *p; + ssize_t i = 0; + + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + l = 0; + p = d; + if (htc->pipeline_b) { + l = htc->pipeline_e - htc->pipeline_b; + assert(l > 0); + 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) { + i = read(htc->fd, p, len); + if (i < 0) { + VSLb(htc->vsl, SLT_FetchError, "%s", strerror(errno)); + return (i); + } + } + return (i + l); +} + +/*-------------------------------------------------------------------- + * Dissect the headers of the HTTP protocol message. + * Detect conditionals (headers which start with '^[Ii][Ff]-') + */ + +static uint16_t +http1_dissect_hdrs(struct http *hp, char *p, const struct http_conn *htc) +{ + char *q, *r; + + assert(p > htc->rxbuf_b); + assert(p <= htc->rxbuf_e); + hp->nhd = HTTP_HDR_FIRST; + hp->conds = 0; + r = NULL; /* For FlexeLint */ + for (; p < htc->rxbuf_e; p = r) { + + /* Find end of next header */ + q = r = p; + while (r < htc->rxbuf_e) { + if (!vct_iscrlf(r)) { + r++; + continue; + } + q = r; + assert(r < htc->rxbuf_e); + r += vct_skipcrlf(r); + if (r >= htc->rxbuf_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, "Header too long: %.*s", + (int)(q - p > 20 ? 20 : q - p), p); + return (400); + } + + /* Empty header = end of headers */ + if (p == q) + break; + + if (vct_islws(*p)) { + VSLb(hp->vsl, SLT_BogoHeader, + "1st header has white space: %.*s", + (int)(q - p > 20 ? 20 : q - p), p); + return (400); + } + + 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 (strchr(p, ':') == NULL) { + VSLb(hp->vsl, SLT_BogoHeader, "Header without ':' %.*s", + (int)(q - p > 20 ? 20 : q - p), p); + return (400); + } + + if (hp->nhd < hp->shd) { + hp->hdf[hp->nhd] = 0; + hp->hd[hp->nhd].b = p; + hp->hd[hp->nhd].e = q; + hp->nhd++; + } else { + VSLb(hp->vsl, SLT_BogoHeader, "Too many headers: %.*s", + (int)(q - p > 20 ? 20 : q - p), p); + return (400); + } + } + return (0); +} + +/*-------------------------------------------------------------------- + * Deal with first line of HTTP protocol message. + */ + +static uint16_t +http1_splitline(struct http *hp, const struct http_conn *htc, const int *hf) +{ + char *p; + int i; + + assert(hf == HTTP1_Req || hf == HTTP1_Resp); + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); + assert(htc->rxbuf_e >= htc->rxbuf_b); + + AZ(hp->hd[hf[0]].b); + AZ(hp->hd[hf[1]].b); + AZ(hp->hd[hf[2]].b); + + /* Skip leading LWS */ + for (p = htc->rxbuf_b ; vct_islws(*p); p++) + continue; + hp->hd[hf[0]].b = p; + + /* First field cannot contain SP or CTL */ + for (; !vct_issp(*p); p++) { + if (vct_isctl(*p)) + return (400); + } + hp->hd[hf[0]].e = p; + assert(Tlen(hp->hd[hf[0]])); + *p++ = '\0'; + + /* Skip SP */ + for (; vct_issp(*p); p++) { + if (vct_isctl(*p)) + return (400); + } + hp->hd[hf[1]].b = p; + + /* Second field cannot contain LWS or CTL */ + for (; !vct_islws(*p); p++) { + if (vct_isctl(*p)) + return (400); + } + hp->hd[hf[1]].e = p; + if (!Tlen(hp->hd[hf[1]])) + return (400); + *p++ = '\0'; + + /* Skip SP */ + for (; vct_issp(*p); p++) { + if (vct_isctl(*p)) + return (400); + } + hp->hd[hf[2]].b = p; + + /* Third field is optional and cannot contain CTL except TAB */ + for (; !vct_iscrlf(p); p++) { + if (vct_isctl(*p) && !vct_issp(*p)) { + hp->hd[hf[2]].b = NULL; + return (400); + } + } + hp->hd[hf[2]].e = p; + + /* Skip CRLF */ + i = vct_skipcrlf(p); + *p = '\0'; + p += i; + + return (http1_dissect_hdrs(hp, p, htc)); +} + +/*--------------------------------------------------------------------*/ + +static enum body_status +http1_body_status(const struct http *hp, struct http_conn *htc) +{ + ssize_t cl; + const char *b; + + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); + + htc->content_length = -1; + + if (http_HdrIs(hp, H_Transfer_Encoding, "chunked")) + return (BS_CHUNKED); + + if (http_GetHdr(hp, H_Transfer_Encoding, &b)) + return (BS_ERROR); + + cl = http_GetContentLength(hp); + if (cl == -2) + return (BS_ERROR); + if (cl >= 0) { + htc->content_length = cl; + return (cl == 0 ? BS_NONE : BS_LENGTH); + } + + if (http_HdrIs(hp, H_Connection, "keep-alive")) { + /* + * Keep alive with neither TE=Chunked or C-Len is impossible. + * We assume a zero length body. + */ + return (BS_NONE); + } + + if (http_HdrIs(hp, H_Connection, "close")) { + /* + * In this case, it is safe to just read what comes. + */ + return (BS_EOF); + } + + if (hp->protover < 11) { + /* + * With no Connection header, assume EOF. + */ + return (BS_EOF); + } + + /* + * Fall back to EOF transfer. + */ + return (BS_EOF); +} + +/*--------------------------------------------------------------------*/ + +static void +http1_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 +HTTP1_DissectRequest(struct http_conn *htc, struct http *hp) +{ + uint16_t retval; + const char *p; + const char *b, *e; + + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); + + retval = http1_splitline(hp, htc, HTTP1_Req); + if (retval != 0) + return (retval); + http1_proto_ver(hp); + + if (http_CountHdr(hp, H_Host) > 1) + return (400); + + if (http_CountHdr(hp, H_Content_Length) > 1) + return (400); + + /* 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; + } + } + + htc->body_status = http1_body_status(hp, htc); + if (htc->body_status == BS_ERROR) + return (400); + + p = http_GetMethod(hp); + AN(p); + + /* We handle EOF bodies only for PUT and POST */ + if (htc->body_status == BS_EOF && + strcasecmp(p, "put") && strcasecmp(p, "post")) + htc->body_status = BS_NONE; + + /* HEAD with a body is a hard error */ + if (htc->body_status != BS_NONE && !strcasecmp(p, "head")) + return (400); + + return (retval); +} + +/*--------------------------------------------------------------------*/ + +uint16_t +HTTP1_DissectResponse(struct http *hp, struct http_conn *htc) +{ + uint16_t retval = 0; + const char *p; + + + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); + + if (http1_splitline(hp, htc, HTTP1_Resp)) + retval = 503; + + if (retval == 0) { + http1_proto_ver(hp); + if (hp->protover != 10 && hp->protover != 11) + retval = 503; + } + + if (retval == 0 && Tlen(hp->hd[HTTP_HDR_STATUS]) != 3) + retval = 503; + + if (retval == 0) { + p = hp->hd[HTTP_HDR_STATUS].b; + + if (p[0] >= '1' && p[0] <= '9' && + p[1] >= '0' && p[1] <= '9' && + p[2] >= '0' && p[2] <= '9') + hp->status = + 100 * (p[0] - '0') + 10 * (p[1] - '0') + p[2] - '0'; + else + retval = 503; + } + + if (retval != 0) { + VSLb(hp->vsl, SLT_HttpGarbage, "%.*s", + (int)(htc->rxbuf_e - htc->rxbuf_b), htc->rxbuf_b); + assert(retval >= 100 && retval <= 999); + assert(retval == 503); + hp->status = retval; + http_SetH(hp, HTTP_HDR_STATUS, "503"); + http_SetH(hp, HTTP_HDR_REASON, http_Status2Reason(retval)); + } + + if (hp->hd[HTTP_HDR_REASON].b == NULL || + !Tlen(hp->hd[HTTP_HDR_REASON])) + http_SetH(hp, HTTP_HDR_REASON, http_Status2Reason(hp->status)); + + htc->body_status = http1_body_status(hp, htc); + + return (retval); +} + +/*--------------------------------------------------------------------*/ + +unsigned +HTTP1_Write(const struct worker *w, const struct http *hp, const int *hf) +{ + unsigned u, l; + + assert(hf == HTTP1_Req || hf == HTTP1_Resp); + AN(hp->hd[hf[0]].b); + AN(hp->hd[hf[1]].b); + AN(hp->hd[hf[2]].b); + l = WRW_WriteH(w, &hp->hd[hf[0]], " "); + l += WRW_WriteH(w, &hp->hd[hf[1]], " "); + l += WRW_WriteH(w, &hp->hd[hf[2]], "\r\n"); + + for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) + l += WRW_WriteH(w, &hp->hd[u], "\r\n"); + l += WRW_Write(w, "\r\n", -1); + return (l); +} diff --git a/bin/varnishd/http1/cache_http1_vfp.c b/bin/varnishd/http1/cache_http1_vfp.c new file mode 100644 index 0000000..404a2f5 --- /dev/null +++ b/bin/varnishd/http1/cache_http1_vfp.c @@ -0,0 +1,249 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2014 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. + * + * HTTP1 Fetch Filters + * + * These filters are used for both req.body and beresp.body to handle + * the HTTP/1 aspects (C-L/Chunked/EOF) + * + */ + +#include "config.h" + +#include + +#include "cache/cache.h" + +#include "vct.h" + +/*-------------------------------------------------------------------- + * Read a chunked HTTP object. + * + * XXX: Reading one byte at a time is pretty pessimal. + */ + +static enum vfp_status __match_proto__(vfp_pull_f) +v1f_pull_chunked(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, + ssize_t *lp) +{ + struct http_conn *htc; + int i; + char buf[20]; /* XXX: 20 is arbitrary */ + char *q; + unsigned u; + uintmax_t cll; + ssize_t cl, l, lr; + + CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); + CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC); + CAST_OBJ_NOTNULL(htc, vfe->priv1, HTTP_CONN_MAGIC); + AN(ptr); + AN(lp); + + AN(ptr); + AN(lp); + l = *lp; + *lp = 0; + if (vfe->priv2 == -1) { + /* Skip leading whitespace */ + do { + lr = HTTP1_Read(htc, buf, 1); + if (lr <= 0) + return (VFP_Error(vc, "chunked read err")); + } while (vct_islws(buf[0])); + + if (!vct_ishex(buf[0])) + return (VFP_Error(vc, "chunked header non-hex")); + + /* Collect hex digits, skipping leading zeros */ + for (u = 1; u < sizeof buf; u++) { + do { + lr = HTTP1_Read(htc, buf + u, 1); + if (lr <= 0) + return (VFP_Error(vc, + "chunked read err")); + } while (u == 1 && buf[0] == '0' && buf[u] == '0'); + if (!vct_ishex(buf[u])) + break; + } + + if (u >= sizeof buf) + return (VFP_Error(vc, "chunked header too long")); + + /* Skip trailing white space */ + while(vct_islws(buf[u]) && buf[u] != '\n') { + lr = HTTP1_Read(htc, buf + u, 1); + if (lr <= 0) + return (VFP_Error(vc, "chunked read err")); + } + + if (buf[u] != '\n') + return (VFP_Error(vc, "chunked header no NL")); + + buf[u] = '\0'; + + cll = strtoumax(buf, &q, 16); + if (q == NULL || *q != '\0') + return (VFP_Error(vc, "chunked header number syntax")); + cl = (ssize_t)cll; + if((uintmax_t)cl != cll) + return (VFP_Error(vc, "bogusly large chunk size")); + + vfe->priv2 = cl; + } + if (vfe->priv2 > 0) { + if (vfe->priv2 < l) + l = vfe->priv2; + lr = HTTP1_Read(htc, ptr, l); + if (lr <= 0) + return (VFP_Error(vc, "straight insufficient bytes")); + *lp = lr; + vfe->priv2 -= lr; + if (vfe->priv2 == 0) + vfe->priv2 = -1; + return (VFP_OK); + } + AZ(vfe->priv2); + i = HTTP1_Read(htc, buf, 1); + if (i <= 0) + return (VFP_Error(vc, "chunked read err")); + if (buf[0] == '\r' && HTTP1_Read(htc, buf, 1) <= 0) + return (VFP_Error(vc, "chunked read err")); + if (buf[0] != '\n') + return (VFP_Error(vc, "chunked tail no NL")); + return (VFP_END); +} + +static const struct vfp v1f_chunked = { + .name = "V1F_CHUNKED", + .pull = v1f_pull_chunked, +}; + + +/*--------------------------------------------------------------------*/ + +static enum vfp_status __match_proto__(vfp_pull_f) +v1f_pull_straight(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, + ssize_t *lp) +{ + ssize_t l, lr; + struct http_conn *htc; + + CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); + CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC); + CAST_OBJ_NOTNULL(htc, vfe->priv1, HTTP_CONN_MAGIC); + AN(p); + AN(lp); + + l = *lp; + *lp = 0; + + if (vfe->priv2 == 0) // XXX: Optimize Content-Len: 0 out earlier + return (VFP_END); + if (vfe->priv2 < l) + l = vfe->priv2; + lr = HTTP1_Read(htc, p, l); + if (lr <= 0) + return (VFP_Error(vc, "straight insufficient bytes")); + *lp = lr; + vfe->priv2 -= lr; + if (vfe->priv2 == 0) + return (VFP_END); + return (VFP_OK); +} + +static const struct vfp v1f_straight = { + .name = "V1F_STRAIGHT", + .pull = v1f_pull_straight, +}; + +/*--------------------------------------------------------------------*/ + +static enum vfp_status __match_proto__(vfp_pull_f) +v1f_pull_eof(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, + ssize_t *lp) +{ + ssize_t l, lr; + struct http_conn *htc; + + CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); + CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC); + CAST_OBJ_NOTNULL(htc, vfe->priv1, HTTP_CONN_MAGIC); + AN(p); + + AN(lp); + + l = *lp; + *lp = 0; + lr = HTTP1_Read(htc, p, l); + if (lr < 0) + return (VFP_Error(vc, "eof socket fail")); + if (lr == 0) + return (VFP_END); + *lp = lr; + return (VFP_OK); +} + +static const struct vfp v1f_eof = { + .name = "V1F_EOF", + .pull = v1f_pull_eof, +}; + +/*-------------------------------------------------------------------- + */ + +void +V1F_Setup_Fetch(struct vfp_ctx *vfc, struct http_conn *htc) +{ + struct vfp_entry *vfe; + + CHECK_OBJ_NOTNULL(vfc, VFP_CTX_MAGIC); + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + + switch(htc->body_status) { + case BS_EOF: + assert(htc->content_length == -1); + vfe = VFP_Push(vfc, &v1f_eof, 0); + vfe->priv2 = 0; + break; + case BS_LENGTH: + assert(htc->content_length > 0); + vfe = VFP_Push(vfc, &v1f_straight, 0); + vfe->priv2 = htc->content_length; + break; + case BS_CHUNKED: + assert(htc->content_length == -1); + vfe = VFP_Push(vfc, &v1f_chunked, 0); + vfe->priv2 = -1; + break; + default: + WRONG("Wrong body_status"); + break; + } + vfe->priv1 = htc; +} From phk at FreeBSD.org Wed Oct 1 19:05:14 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 01 Oct 2014 21:05:14 +0200 Subject: [master] 0107b32 More vbe/{v}dir name cleanup Message-ID: commit 0107b32f6b283fb339b9c1b7859e0adcf22fd2bf Author: Poul-Henning Kamp Date: Wed Oct 1 18:34:54 2014 +0000 More vbe/{v}dir name cleanup diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 0918301..51e9cb7 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -54,7 +54,7 @@ static unsigned vbcps = sizeof(struct vbc); * the directoricity of it under this line. */ -struct vdi_simple { +struct vbe_dir { unsigned magic; #define VDI_SIMPLE_MAGIC 0x476d25b7 struct director dir; @@ -109,7 +109,7 @@ VBE_ReleaseConn(struct vbc *vc) static int vbe_TryConnect(const struct busyobj *bo, int pf, - const struct suckaddr *sa, const struct vdi_simple *vs) + const struct suckaddr *sa, const struct vbe_dir *vs) { int s, i, tmo; double tmod; @@ -138,7 +138,7 @@ vbe_TryConnect(const struct busyobj *bo, int pf, /*--------------------------------------------------------------------*/ static void -bes_conn_try(struct busyobj *bo, struct vbc *vc, const struct vdi_simple *vs) +bes_conn_try(struct busyobj *bo, struct vbc *vc, const struct vbe_dir *vs) { int s; struct backend *bp = vs->backend; @@ -246,7 +246,7 @@ VBE_Healthy(const struct backend *backend, double *changed) */ static struct vbc * -vbe_GetVbe(struct busyobj *bo, struct vdi_simple *vs) +vbe_GetVbe(struct busyobj *bo, struct vbe_dir *vs) { struct vbc *vc; struct backend *bp; @@ -325,7 +325,7 @@ vbe_GetVbe(struct busyobj *bo, struct vdi_simple *vs) void VBE_UseHealth(const struct director *vdi) { - struct vdi_simple *vs; + struct vbe_dir *vs; ASSERT_CLI(); @@ -344,7 +344,7 @@ VBE_UseHealth(const struct director *vdi) void VBE_DiscardHealth(const struct director *vdi) { - struct vdi_simple *vs; + struct vbe_dir *vs; ASSERT_CLI(); @@ -415,9 +415,9 @@ vbe_RecycleFd(struct vbc **vbp, const struct acct_bereq *acct_bereq) */ static struct vbc * __match_proto__(vdi_getfd_f) -vdi_simple_getfd(const struct director *d, struct busyobj *bo) +vbe_dir_getfd(const struct director *d, struct busyobj *bo) { - struct vdi_simple *vs; + struct vbe_dir *vs; struct vbc *vc; CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); @@ -438,9 +438,9 @@ vdi_simple_getfd(const struct director *d, struct busyobj *bo) } static unsigned __match_proto__(vdi_healthy_f) -vdi_simple_healthy(const struct director *d, double *changed) +vbe_dir_healthy(const struct director *d, double *changed) { - struct vdi_simple *vs; + struct vbe_dir *vs; struct backend *be; CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); @@ -451,7 +451,7 @@ vdi_simple_healthy(const struct director *d, double *changed) } static int __match_proto__(vdi_gethdrs_f) -vdi_simple_gethdrs(const struct director *d, struct worker *wrk, +vbe_dir_gethdrs(const struct director *d, struct worker *wrk, struct busyobj *bo) { int i; @@ -460,7 +460,7 @@ vdi_simple_gethdrs(const struct director *d, struct worker *wrk, CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - bo->vbc = vdi_simple_getfd(d, bo); + bo->vbc = vbe_dir_getfd(d, bo); if (bo->vbc == NULL) { VSLb(bo->vsl, SLT_FetchError, "no backend connection"); return (-1); @@ -490,7 +490,7 @@ vdi_simple_gethdrs(const struct director *d, struct worker *wrk, } static int __match_proto__(vdi_getbody_f) -vdi_simple_getbody(const struct director *d, struct worker *wrk, +vbe_dir_getbody(const struct director *d, struct worker *wrk, struct busyobj *bo) { @@ -503,7 +503,7 @@ vdi_simple_getbody(const struct director *d, struct worker *wrk, } static void __match_proto__(vdi_finish_f) -vdi_simple_finish(const struct director *d, struct worker *wrk, +vbe_dir_finish(const struct director *d, struct worker *wrk, struct busyobj *bo) { CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); @@ -519,7 +519,7 @@ vdi_simple_finish(const struct director *d, struct worker *wrk, } static struct suckaddr * __match_proto__(vdi_suckaddr_f) -vdi_simple_suckaddr(const struct director *d, struct worker *wrk, +vbe_dir_suckaddr(const struct director *d, struct worker *wrk, struct busyobj *bo) { CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); @@ -534,9 +534,9 @@ vdi_simple_suckaddr(const struct director *d, struct worker *wrk, /*--------------------------------------------------------------------*/ void -VRT_fini_dir(VRT_CTX, struct director *d) +VRT_fini_vbe(VRT_CTX, struct director *d) { - struct vdi_simple *vs; + struct vbe_dir *vs; ASSERT_CLI(); CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); @@ -551,11 +551,11 @@ VRT_fini_dir(VRT_CTX, struct director *d) } void -VRT_init_dir(VRT_CTX, struct director **bp, int idx, +VRT_init_vbe(VRT_CTX, struct director **bp, int idx, const void *priv) { const struct vrt_backend *t; - struct vdi_simple *vs; + struct vbe_dir *vs; ASSERT_CLI(); CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); @@ -567,12 +567,12 @@ VRT_init_dir(VRT_CTX, struct director **bp, int idx, vs->dir.priv = vs; vs->dir.name = "simple"; REPLACE(vs->dir.vcl_name, t->vcl_name); - vs->dir.getfd = vdi_simple_getfd; - vs->dir.healthy = vdi_simple_healthy; - vs->dir.gethdrs = vdi_simple_gethdrs; - vs->dir.getbody = vdi_simple_getbody; - vs->dir.finish = vdi_simple_finish; - vs->dir.suckaddr = vdi_simple_suckaddr; + vs->dir.getfd = vbe_dir_getfd; + vs->dir.healthy = vbe_dir_healthy; + vs->dir.gethdrs = vbe_dir_gethdrs; + vs->dir.getbody = vbe_dir_getbody; + vs->dir.finish = vbe_dir_finish; + vs->dir.suckaddr = vbe_dir_suckaddr; vs->vrt = t; @@ -584,7 +584,7 @@ VRT_init_dir(VRT_CTX, struct director **bp, int idx, } void -VDI_Init(void) +VBE_Init(void) { vbcpool = MPL_New("vbc", &cache_param->vbc_pool, &vbcps); diff --git a/bin/varnishd/cache/cache_backend.h b/bin/varnishd/cache/cache_backend.h index e809926..ec24380 100644 --- a/bin/varnishd/cache/cache_backend.h +++ b/bin/varnishd/cache/cache_backend.h @@ -88,7 +88,7 @@ struct vbc { #define VBC_MAGIC 0x0c5e6592 VTAILQ_ENTRY(vbc) list; struct backend *backend; - struct vdi_simple *vdis; + struct vbe_dir *vdis; struct vsl_log *vsl; int fd; diff --git a/bin/varnishd/cache/cache_director.h b/bin/varnishd/cache/cache_director.h index 2c5e72f..f717aa4 100644 --- a/bin/varnishd/cache/cache_director.h +++ b/bin/varnishd/cache/cache_director.h @@ -82,5 +82,5 @@ int VDI_Healthy(const struct director *); struct suckaddr *VDI_Suckaddr(const struct director *d, struct worker *wrk, struct busyobj *bo); void VDI_AddHostHeader(struct http *to, const struct vbc *vbc); -void VDI_Init(void); +void VBE_Init(void); diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c index 1406e57..880f7cf 100644 --- a/bin/varnishd/cache/cache_main.c +++ b/bin/varnishd/cache/cache_main.c @@ -220,7 +220,7 @@ child_main(void) HTTP_Init(); - VDI_Init(); + VBE_Init(); VBO_Init(); VBE_InitCfg(); VBP_Init(); diff --git a/include/vrt.h b/include/vrt.h index 5b7ab7a..92dc040 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -224,8 +224,8 @@ void VRT_Rollback(VRT_CTX, const struct http *); void VRT_synth_page(VRT_CTX, const char *, ...); /* Backend related */ -void VRT_init_dir(VRT_CTX, struct director **, int idx, const void *priv); -void VRT_fini_dir(VRT_CTX, struct director *); +void VRT_init_vbe(VRT_CTX, struct director **, int idx, const void *priv); +void VRT_fini_vbe(VRT_CTX, struct director *); /* Suckaddr related */ int VRT_VSA_GetPtr(const struct suckaddr *sua, const unsigned char ** dst); diff --git a/lib/libvcc/vcc_backend.c b/lib/libvcc/vcc_backend.c index b9114f6..25b13da 100644 --- a/lib/libvcc/vcc_backend.c +++ b/lib/libvcc/vcc_backend.c @@ -423,9 +423,9 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be) ifp = New_IniFin(tl); VSB_printf(ifp->ini, - "\tVRT_init_dir(ctx, VCL_conf.director,\n" + "\tVRT_init_vbe(ctx, VCL_conf.director,\n" "\t VGC_backend_%s, &vgc_dir_priv_%s);", vgcname, vgcname); - VSB_printf(ifp->fin, "\tVRT_fini_dir(ctx, VGCDIR(%s));", vgcname); + VSB_printf(ifp->fin, "\tVRT_fini_vbe(ctx, VGCDIR(%s));", vgcname); tl->ndirector++; } From phk at FreeBSD.org Thu Oct 2 07:01:37 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 02 Oct 2014 09:01:37 +0200 Subject: [master] a1cb651 Fix my brainfart in PRIV_SESS and PRIV_REQ: We want one variable for each VMOD which asks. Message-ID: commit a1cb65112c717d0de3d6f3bd03da2f07d4dbe6ba Author: Poul-Henning Kamp Date: Thu Oct 2 07:00:53 2014 +0000 Fix my brainfart in PRIV_SESS and PRIV_REQ: We want one variable for each VMOD which asks. Patch by: mithrandir Fixes #1600 diff --git a/bin/varnishd/cache/cache_vrt_priv.c b/bin/varnishd/cache/cache_vrt_priv.c index 0893b4c..4998e74 100644 --- a/bin/varnishd/cache/cache_vrt_priv.c +++ b/bin/varnishd/cache/cache_vrt_priv.c @@ -47,26 +47,29 @@ struct vrt_privs { struct vmod_priv priv[1]; const struct VCL_conf *vcl; uintptr_t id; + uintptr_t vmod_id; }; /*-------------------------------------------------------------------- */ static struct vmod_priv * -VRT_priv_dynamic(VRT_CTX, uintptr_t id) +VRT_priv_dynamic(VRT_CTX, uintptr_t id, uintptr_t vmod_id) { struct vrt_privs *vps; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); VTAILQ_FOREACH(vps, &ctx->req->sp->privs, list) { CHECK_OBJ_NOTNULL(vps, VRT_PRIVS_MAGIC); - if (vps->vcl == ctx->vcl && vps->id == id) + if (vps->vcl == ctx->vcl && vps->id == id + && vps->vmod_id == vmod_id) return (vps->priv); } ALLOC_OBJ(vps, VRT_PRIVS_MAGIC); AN(vps); vps->vcl = ctx->vcl; vps->id = id; + vps->vmod_id = vmod_id; VTAILQ_INSERT_TAIL(&ctx->req->sp->privs, vps, list); return (vps->priv); } @@ -91,15 +94,15 @@ VRTPRIV_dynamic_kill(struct sess *sp, uintptr_t id) } struct vmod_priv * -VRT_priv_req(VRT_CTX) +VRT_priv_req(VRT_CTX, void *vmod_id) { - return (VRT_priv_dynamic(ctx, (uintptr_t)ctx->req)); + return (VRT_priv_dynamic(ctx, (uintptr_t)ctx->req, (uintptr_t)vmod_id)); } struct vmod_priv * -VRT_priv_sess(VRT_CTX) +VRT_priv_sess(VRT_CTX, void *vmod_id) { - return (VRT_priv_dynamic(ctx, (uintptr_t)NULL)); + return (VRT_priv_dynamic(ctx, (uintptr_t)NULL, (uintptr_t)vmod_id)); } /*-------------------------------------------------------------------- diff --git a/include/vrt.h b/include/vrt.h index 92dc040..f9624a6 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -246,8 +246,8 @@ struct vmod_priv { typedef int vmod_init_f(struct vmod_priv *, const struct VCL_conf *); void VRT_priv_fini(const struct vmod_priv *p); -struct vmod_priv *VRT_priv_sess(VRT_CTX); -struct vmod_priv *VRT_priv_req(VRT_CTX); +struct vmod_priv *VRT_priv_sess(VRT_CTX, void *vmod_id); +struct vmod_priv *VRT_priv_req(VRT_CTX, void *vmod_id); /* Stevedore related functions */ int VRT_Stv(const char *nm); diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index acc7b51..32e544c 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -567,10 +567,18 @@ vcc_func(struct vcc *tl, struct expr **e, const char *cfunc, e2 = vcc_mk_expr(VOID, "&%s", buf); p += strlen(p) + 1; } else if (fmt == VOID && !strcmp(p, "PRIV_REQ")) { - e2 = vcc_mk_expr(VOID, "VRT_priv_req(ctx)"); + r = strchr(name, '.'); + AN(r); + e2 = vcc_mk_expr(VOID, + "VRT_priv_req(ctx, &VGC_vmod_%.*s)", + (int) (r - name), name); p += strlen(p) + 1; } else if (fmt == VOID && !strcmp(p, "PRIV_SESS")) { - e2 = vcc_mk_expr(VOID, "VRT_priv_sess(ctx)"); + r = strchr(name, '.'); + AN(r); + e2 = vcc_mk_expr(VOID, + "VRT_priv_sess(ctx, &VGC_vmod_%.*s)", + (int) (r - name), name); p += strlen(p) + 1; } else if (fmt == ENUM) { ExpectErr(tl, ID); From phk at FreeBSD.org Thu Oct 2 20:41:27 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 02 Oct 2014 22:41:27 +0200 Subject: [master] 7b00bfa Unhide vcl.show from 'help' output, it was hidden due to overzealous copy&paste. Message-ID: commit 7b00bfa7eabb7c6fc0f7229eb39274073e043b1a Author: Poul-Henning Kamp Date: Thu Oct 2 20:40:51 2014 +0000 Unhide vcl.show from 'help' output, it was hidden due to overzealous copy&paste. Spotted by: scn diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c index 0aa40fe..72dc303 100644 --- a/bin/varnishd/cache/cache_vcl.c +++ b/bin/varnishd/cache/cache_vcl.c @@ -503,7 +503,7 @@ static struct cli_proto vcl_cmds[] = { { CLI_VCL_LIST, "i", ccf_config_list }, { CLI_VCL_DISCARD, "i", ccf_config_discard }, { CLI_VCL_USE, "i", ccf_config_use }, - { CLI_VCL_SHOW, "i", ccf_config_show }, + { CLI_VCL_SHOW, "", ccf_config_show }, { NULL } }; From phk at FreeBSD.org Fri Oct 3 07:29:15 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Fri, 03 Oct 2014 09:29:15 +0200 Subject: [master] f8be8b0 Fix a printf-format mismatch for OS/X Message-ID: commit f8be8b035a73b76849e93eac333738b4619f485a Author: Poul-Henning Kamp Date: Fri Oct 3 07:28:48 2014 +0000 Fix a printf-format mismatch for OS/X diff --git a/bin/varnishd/cache/cache_fetch_proc.c b/bin/varnishd/cache/cache_fetch_proc.c index 331efce..e2d9796 100644 --- a/bin/varnishd/cache/cache_fetch_proc.c +++ b/bin/varnishd/cache/cache_fetch_proc.c @@ -121,8 +121,8 @@ VFP_Close(struct vfp_ctx *vc) VTAILQ_FOREACH(vfe, &vc->vfp, list) { if(vfe->vfp->fini != NULL) vfe->vfp->fini(vc, vfe); - VSLb(vc->wrk->vsl, SLT_VfpAcct, "%s %ju %ju", - vfe->vfp->name, vfe->calls, vfe->bytes_out); + VSLb(vc->wrk->vsl, SLT_VfpAcct, "%s %ju %ju", vfe->vfp->name, + (uintmax_t)vfe->calls, (uintmax_t)vfe->bytes_out); } } From phk at FreeBSD.org Mon Oct 6 06:36:34 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 06 Oct 2014 08:36:34 +0200 Subject: [master] 086fd76 Minor simplification Message-ID: commit 086fd762ff168ddc5490d1df1eef1b532c10698d Author: Poul-Henning Kamp Date: Mon Oct 6 06:36:25 2014 +0000 Minor simplification diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 51e9cb7..bfce9cc 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -203,24 +203,6 @@ vbe_CheckFd(int fd) } /*-------------------------------------------------------------------- - * Manage a pool of vbc structures. - * XXX: as an experiment, make this caching controlled by a parameter - * XXX: so we can see if it has any effect. - */ - -static struct vbc * -vbe_NewConn(void) -{ - struct vbc *vc; - - vc = MPL_Get(vbcpool, NULL); - XXXAN(vc); - vc->magic = VBC_MAGIC; - vc->fd = -1; - return (vc); -} - -/*-------------------------------------------------------------------- * Test if backend is healthy and report when it last changed */ @@ -301,9 +283,10 @@ vbe_GetVbe(struct busyobj *bo, struct vbe_dir *vs) return (NULL); } - vc = vbe_NewConn(); - assert(vc->fd == -1); - AZ(vc->backend); + vc = MPL_Get(vbcpool, NULL); + XXXAN(vc); + vc->magic = VBC_MAGIC; + vc->fd = -1; bes_conn_try(bo, vc, vs); if (vc->fd < 0) { VBE_ReleaseConn(vc); From phk at FreeBSD.org Mon Oct 6 07:39:04 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 06 Oct 2014 09:39:04 +0200 Subject: [master] bd069ef Make pipe-mode close the director/backend through the VDI api. Message-ID: commit bd069ef4eb5a00aa10f0681b0c7f704b6ad24357 Author: Poul-Henning Kamp Date: Mon Oct 6 07:38:45 2014 +0000 Make pipe-mode close the director/backend through the VDI api. diff --git a/bin/varnishd/http1/cache_http1_pipe.c b/bin/varnishd/http1/cache_http1_pipe.c index e451f35..5620d0d 100644 --- a/bin/varnishd/http1/cache_http1_pipe.c +++ b/bin/varnishd/http1/cache_http1_pipe.c @@ -121,6 +121,8 @@ V1P_Process(struct req *req, struct busyobj *bo) return; } bo->vbc = vc; /* For panic dumping */ + bo->wrk = req->wrk; + bo->director_state = DIR_S_BODY; (void)VTCP_blocking(vc->fd); WRW_Reserve(wrk, &vc->fd, bo->vsl, req->t_req); @@ -138,53 +140,45 @@ V1P_Process(struct req *req, struct busyobj *bo) VSLb_ts_req(req, "Pipe", W_TIM_real(wrk)); - if (i) { - pipecharge(req, &acct_pipe, vc->backend->vsc); - SES_Close(req->sp, SC_TX_PIPE); - VBE_CloseFd(&vc, NULL); - return; - } - - memset(fds, 0, sizeof fds); - - // XXX: not yet (void)VTCP_linger(vc->fd, 0); - fds[0].fd = vc->fd; - fds[0].events = POLLIN | POLLERR; - - // XXX: not yet (void)VTCP_linger(req->sp->fd, 0); - fds[1].fd = req->sp->fd; - fds[1].events = POLLIN | POLLERR; - - while (fds[0].fd > -1 || fds[1].fd > -1) { - fds[0].revents = 0; - fds[1].revents = 0; - i = poll(fds, 2, (int)(cache_param->pipe_timeout * 1e3)); - if (i < 1) - break; - if (fds[0].revents && - rdf(vc->fd, req->sp->fd, &acct_pipe.out)) { - if (fds[1].fd == -1) - break; - (void)shutdown(vc->fd, SHUT_RD); - (void)shutdown(req->sp->fd, SHUT_WR); - fds[0].events = 0; - fds[0].fd = -1; - } - if (fds[1].revents && - rdf(req->sp->fd, vc->fd, &acct_pipe.in)) { - if (fds[0].fd == -1) + if (i == 0) { + memset(fds, 0, sizeof fds); + fds[0].fd = vc->fd; + fds[0].events = POLLIN | POLLERR; + fds[1].fd = req->sp->fd; + fds[1].events = POLLIN | POLLERR; + + while (fds[0].fd > -1 || fds[1].fd > -1) { + fds[0].revents = 0; + fds[1].revents = 0; + i = poll(fds, 2, + (int)(cache_param->pipe_timeout * 1e3)); + if (i < 1) break; - (void)shutdown(req->sp->fd, SHUT_RD); - (void)shutdown(vc->fd, SHUT_WR); - fds[1].events = 0; - fds[1].fd = -1; + if (fds[0].revents && + rdf(vc->fd, req->sp->fd, &acct_pipe.out)) { + if (fds[1].fd == -1) + break; + (void)shutdown(vc->fd, SHUT_RD); + (void)shutdown(req->sp->fd, SHUT_WR); + fds[0].events = 0; + fds[0].fd = -1; + } + if (fds[1].revents && + rdf(req->sp->fd, vc->fd, &acct_pipe.in)) { + if (fds[0].fd == -1) + break; + (void)shutdown(req->sp->fd, SHUT_RD); + (void)shutdown(vc->fd, SHUT_WR); + fds[1].events = 0; + fds[1].fd = -1; + } } } VSLb_ts_req(req, "PipeSess", W_TIM_real(wrk)); pipecharge(req, &acct_pipe, vc->backend->vsc); SES_Close(req->sp, SC_TX_PIPE); - VBE_CloseFd(&vc, NULL); - bo->vbc = NULL; + bo->doclose = SC_TX_PIPE; + VDI_Finish(bo->director_resp, bo->wrk, bo); } /*--------------------------------------------------------------------*/ From phk at FreeBSD.org Mon Oct 6 08:03:43 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 06 Oct 2014 10:03:43 +0200 Subject: [master] 54b7af9 Always close directors through the VDI api. Message-ID: commit 54b7af96905eb7cd902f00181156e03052901d6b Author: Poul-Henning Kamp Date: Mon Oct 6 08:00:21 2014 +0000 Always close directors through the VDI api. diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index bfce9cc..4e4625c 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -341,8 +341,8 @@ VBE_DiscardHealth(const struct director *vdi) /* Close a connection ------------------------------------------------*/ -void -VBE_CloseFd(struct vbc **vbp, const struct acct_bereq *acct_bereq) +static void +vbe_CloseFd(struct vbc **vbp, const struct acct_bereq *acct_bereq) { struct backend *bp; struct vbc *vc; @@ -356,8 +356,6 @@ VBE_CloseFd(struct vbc **vbp, const struct acct_bereq *acct_bereq) bp = vc->backend; - VSLb(vc->vsl, SLT_BackendClose, "%d %s", vc->fd, bp->display_name); - vc->vsl = NULL; VTCP_close(&vc->fd); VBE_DropRefConn(bp, acct_bereq); @@ -382,8 +380,6 @@ vbe_RecycleFd(struct vbc **vbp, const struct acct_bereq *acct_bereq) bp = vc->backend; - VSLb(vc->vsl, SLT_BackendReuse, "%d %s", vc->fd, bp->display_name); - vc->vsl = NULL; Lck_Lock(&bp->mtx); @@ -458,17 +454,20 @@ vbe_dir_gethdrs(const struct director *d, struct worker *wrk, if (i == 1) { AZ(bo->vbc); VSC_C_main->backend_retry++; - bo->vbc = VDI_GetFd(d, wrk, bo); + bo->doclose = SC_NULL; + bo->vbc = vbe_dir_getfd(d, bo); if (bo->vbc == NULL) { VSLb(bo->vsl, SLT_FetchError, "no backend connection"); return (-1); } i = V1F_fetch_hdr(wrk, bo); } - if (i != 0) + if (i != 0) { + bo->doclose = SC_NULL; AZ(bo->vbc); - else + } else { AN(bo->vbc); + } return (i); } @@ -494,11 +493,20 @@ vbe_dir_finish(const struct director *d, struct worker *wrk, CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); if (bo->vbc != NULL) { - if (bo->doclose != SC_NULL) - VBE_CloseFd(&bo->vbc, &bo->acct); - else + if (bo->doclose != SC_NULL) { + VSLb(bo->vsl, SLT_BackendClose, + "%d %s", bo->vbc->fd, + bo->vbc->backend->display_name); + vbe_CloseFd(&bo->vbc, &bo->acct); + } else { + VSLb(bo->vsl, SLT_BackendReuse, + "%d %s", bo->vbc->fd, + bo->vbc->backend->display_name); vbe_RecycleFd(&bo->vbc, &bo->acct); + } + } + AZ(bo->vbc); } static struct suckaddr * __match_proto__(vdi_suckaddr_f) diff --git a/bin/varnishd/cache/cache_backend.h b/bin/varnishd/cache/cache_backend.h index ec24380..72a4cdf 100644 --- a/bin/varnishd/cache/cache_backend.h +++ b/bin/varnishd/cache/cache_backend.h @@ -105,7 +105,6 @@ struct vbc { void VBE_ReleaseConn(struct vbc *vc); void VBE_UseHealth(const struct director *vdi); void VBE_DiscardHealth(const struct director *vdi); -void VBE_CloseFd(struct vbc **vbp, const struct acct_bereq *); /* cache_backend_cfg.c */ void VBE_DropRefConn(struct backend *, const struct acct_bereq *); diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c index 6793739..974c5b4 100644 --- a/bin/varnishd/http1/cache_http1_fetch.c +++ b/bin/varnishd/http1/cache_http1_fetch.c @@ -144,7 +144,8 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo) VSLb(bo->vsl, SLT_FetchError, "backend write error: %d (%s)", errno, strerror(errno)); VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk)); - VBE_CloseFd(&bo->vbc, &bo->acct); + bo->doclose = SC_TX_ERROR; + VDI_Finish(bo->director_resp, bo->wrk, bo); /* XXX: other cleanup ? */ return (retry); } @@ -171,7 +172,8 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo) VSLb(bo->vsl, SLT_FetchError, "http %sread error: overflow", first ? "first " : ""); - VBE_CloseFd(&bo->vbc, &bo->acct); + bo->doclose = SC_RX_OVERFLOW; + VDI_Finish(bo->director_resp, bo->wrk, bo); /* XXX: other cleanup ? */ return (-1); } @@ -180,7 +182,8 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo) htc->rxbuf_e - htc->rxbuf_b; VSLb(bo->vsl, SLT_FetchError, "http %sread error: EOF", first ? "first " : ""); - VBE_CloseFd(&bo->vbc, &bo->acct); + bo->doclose = SC_RX_TIMEOUT; + VDI_Finish(bo->director_resp, bo->wrk, bo); /* XXX: other cleanup ? */ return (retry); } @@ -197,7 +200,8 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo) if (HTTP1_DissectResponse(hp, htc)) { VSLb(bo->vsl, SLT_FetchError, "http format error"); - VBE_CloseFd(&bo->vbc, &bo->acct); + bo->doclose = SC_RX_JUNK; + VDI_Finish(bo->director_resp, bo->wrk, bo); /* XXX: other cleanup ? */ return (-1); } From phk at FreeBSD.org Mon Oct 6 08:03:43 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 06 Oct 2014 10:03:43 +0200 Subject: [master] e8941f6 We don't need a vsl copy any more. Message-ID: commit e8941f637a46a9fd750a401911e985cf31ba39ff Author: Poul-Henning Kamp Date: Mon Oct 6 08:03:15 2014 +0000 We don't need a vsl copy any more. diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 4e4625c..b6d75a7 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -356,7 +356,6 @@ vbe_CloseFd(struct vbc **vbp, const struct acct_bereq *acct_bereq) bp = vc->backend; - vc->vsl = NULL; VTCP_close(&vc->fd); VBE_DropRefConn(bp, acct_bereq); vc->backend = NULL; @@ -380,8 +379,6 @@ vbe_RecycleFd(struct vbc **vbp, const struct acct_bereq *acct_bereq) bp = vc->backend; - vc->vsl = NULL; - Lck_Lock(&bp->mtx); VSC_C_main->backend_recycle++; VTAILQ_INSERT_HEAD(&bp->connlist, vc, list); @@ -409,9 +406,7 @@ vbe_dir_getfd(const struct director *d, struct busyobj *bo) FIND_TMO(between_bytes_timeout, vc->between_bytes_timeout, bo, vs->vrt); } - if (vc != NULL) - vc->vsl = bo->vsl; - else + if (vc == NULL) VSLb(bo->vsl, SLT_FetchError, "no backend connection"); return (vc); } diff --git a/bin/varnishd/cache/cache_backend.h b/bin/varnishd/cache/cache_backend.h index 72a4cdf..bf3e789 100644 --- a/bin/varnishd/cache/cache_backend.h +++ b/bin/varnishd/cache/cache_backend.h @@ -89,7 +89,6 @@ struct vbc { VTAILQ_ENTRY(vbc) list; struct backend *backend; struct vbe_dir *vdis; - struct vsl_log *vsl; int fd; struct suckaddr *addr; From phk at FreeBSD.org Mon Oct 6 08:42:20 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 06 Oct 2014 10:42:20 +0200 Subject: [master] dbba743 Simplify even more. Message-ID: commit dbba7430b83ff28cae025bc7f6e04bc9c54709c3 Author: Poul-Henning Kamp Date: Mon Oct 6 08:42:05 2014 +0000 Simplify even more. diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index b6d75a7..0f141e2 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -339,53 +339,6 @@ VBE_DiscardHealth(const struct director *vdi) VBP_Remove(vs->backend, vs->vrt->probe); } -/* Close a connection ------------------------------------------------*/ - -static void -vbe_CloseFd(struct vbc **vbp, const struct acct_bereq *acct_bereq) -{ - struct backend *bp; - struct vbc *vc; - - AN(vbp); - vc = *vbp; - *vbp = NULL; - CHECK_OBJ_NOTNULL(vc, VBC_MAGIC); - CHECK_OBJ_NOTNULL(vc->backend, BACKEND_MAGIC); - assert(vc->fd >= 0); - - bp = vc->backend; - - VTCP_close(&vc->fd); - VBE_DropRefConn(bp, acct_bereq); - vc->backend = NULL; - VBE_ReleaseConn(vc); -} - -/* Recycle a connection ----------------------------------------------*/ - -static void -vbe_RecycleFd(struct vbc **vbp, const struct acct_bereq *acct_bereq) -{ - struct backend *bp; - struct vbc *vc; - - AN(vbp); - vc = *vbp; - *vbp = NULL; - CHECK_OBJ_NOTNULL(vc, VBC_MAGIC); - CHECK_OBJ_NOTNULL(vc->backend, BACKEND_MAGIC); - assert(vc->fd >= 0); - - bp = vc->backend; - - Lck_Lock(&bp->mtx); - VSC_C_main->backend_recycle++; - VTAILQ_INSERT_HEAD(&bp->connlist, vc, list); - VBE_DropRefLocked(bp, acct_bereq); -} - - /*-------------------------------------------------------------------- * */ @@ -483,25 +436,31 @@ static void __match_proto__(vdi_finish_f) vbe_dir_finish(const struct director *d, struct worker *wrk, struct busyobj *bo) { + struct backend *bp; + CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - if (bo->vbc != NULL) { - if (bo->doclose != SC_NULL) { - VSLb(bo->vsl, SLT_BackendClose, - "%d %s", bo->vbc->fd, - bo->vbc->backend->display_name); - vbe_CloseFd(&bo->vbc, &bo->acct); - } else { - VSLb(bo->vsl, SLT_BackendReuse, - "%d %s", bo->vbc->fd, - bo->vbc->backend->display_name); - vbe_RecycleFd(&bo->vbc, &bo->acct); - } - + if (bo->vbc == NULL) + return; + bp = bo->vbc->backend; + if (bo->doclose != SC_NULL) { + VSLb(bo->vsl, SLT_BackendClose, "%d %s", bo->vbc->fd, + bp->display_name); + VTCP_close(&bo->vbc->fd); + VBE_DropRefConn(bp, &bo->acct); + bo->vbc->backend = NULL; + VBE_ReleaseConn(bo->vbc); + } else { + VSLb(bo->vsl, SLT_BackendReuse, "%d %s", bo->vbc->fd, + bp->display_name); + Lck_Lock(&bp->mtx); + VSC_C_main->backend_recycle++; + VTAILQ_INSERT_HEAD(&bp->connlist, bo->vbc, list); + VBE_DropRefLocked(bp, &bo->acct); } - AZ(bo->vbc); + bo->vbc = NULL; } static struct suckaddr * __match_proto__(vdi_suckaddr_f) From phk at FreeBSD.org Mon Oct 6 09:12:06 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 06 Oct 2014 11:12:06 +0200 Subject: [master] 9fb3148 Move HTTP1_Read() to http1_vfp, make it static and rename as appropriate. Message-ID: commit 9fb314818a1c4bac3541f3cd3c4ee9a63e1969f5 Author: Poul-Henning Kamp Date: Mon Oct 6 09:11:23 2014 +0000 Move HTTP1_Read() to http1_vfp, make it static and rename as appropriate. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 99cb5ca..f661de3 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -919,7 +919,6 @@ void HTTP1_Init(struct http_conn *htc, struct ws *ws, int fd, struct vsl_log *, unsigned maxbytes, unsigned maxhdr); enum http1_status_e HTTP1_Reinit(struct http_conn *htc); enum http1_status_e HTTP1_Rx(struct http_conn *htc); -ssize_t HTTP1_Read(struct http_conn *htc, void *d, size_t len); enum http1_status_e HTTP1_Complete(struct http_conn *htc); uint16_t HTTP1_DissectRequest(struct http_conn *htc, struct http *hp); uint16_t HTTP1_DissectResponse(struct http *sp, struct http_conn *htc); diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index 4d0e025..9ee962a 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -184,42 +184,6 @@ HTTP1_Rx(struct http_conn *htc) } /*-------------------------------------------------------------------- - * Read up to len bytes, returning pipelined data first. - */ - -ssize_t -HTTP1_Read(struct http_conn *htc, void *d, size_t len) -{ - ssize_t l; - unsigned char *p; - ssize_t i = 0; - - CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); - l = 0; - p = d; - if (htc->pipeline_b) { - l = htc->pipeline_e - htc->pipeline_b; - assert(l > 0); - 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) { - i = read(htc->fd, p, len); - if (i < 0) { - VSLb(htc->vsl, SLT_FetchError, "%s", strerror(errno)); - return (i); - } - } - return (i + l); -} - -/*-------------------------------------------------------------------- * Dissect the headers of the HTTP protocol message. * Detect conditionals (headers which start with '^[Ii][Ff]-') */ diff --git a/bin/varnishd/http1/cache_http1_vfp.c b/bin/varnishd/http1/cache_http1_vfp.c index 404a2f5..18b9995 100644 --- a/bin/varnishd/http1/cache_http1_vfp.c +++ b/bin/varnishd/http1/cache_http1_vfp.c @@ -42,6 +42,44 @@ #include "vct.h" /*-------------------------------------------------------------------- + * Read up to len bytes, returning pipelined data first. + */ + +static ssize_t +v1f_read(struct http_conn *htc, void *d, size_t len) +{ + ssize_t l; + unsigned char *p; + ssize_t i = 0; + + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + l = 0; + p = d; + if (htc->pipeline_b) { + l = htc->pipeline_e - htc->pipeline_b; + assert(l > 0); + 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) { + i = read(htc->fd, p, len); + if (i < 0) { + // XXX: VTCP_Assert(i); // but also: EAGAIN + VSLb(htc->vsl, SLT_FetchError, "%s", strerror(errno)); + return (i); + } + } + return (i + l); +} + + +/*-------------------------------------------------------------------- * Read a chunked HTTP object. * * XXX: Reading one byte at a time is pretty pessimal. @@ -72,7 +110,7 @@ v1f_pull_chunked(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, if (vfe->priv2 == -1) { /* Skip leading whitespace */ do { - lr = HTTP1_Read(htc, buf, 1); + lr = v1f_read(htc, buf, 1); if (lr <= 0) return (VFP_Error(vc, "chunked read err")); } while (vct_islws(buf[0])); @@ -83,7 +121,7 @@ v1f_pull_chunked(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, /* Collect hex digits, skipping leading zeros */ for (u = 1; u < sizeof buf; u++) { do { - lr = HTTP1_Read(htc, buf + u, 1); + lr = v1f_read(htc, buf + u, 1); if (lr <= 0) return (VFP_Error(vc, "chunked read err")); @@ -97,7 +135,7 @@ v1f_pull_chunked(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, /* Skip trailing white space */ while(vct_islws(buf[u]) && buf[u] != '\n') { - lr = HTTP1_Read(htc, buf + u, 1); + lr = v1f_read(htc, buf + u, 1); if (lr <= 0) return (VFP_Error(vc, "chunked read err")); } @@ -119,7 +157,7 @@ v1f_pull_chunked(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, if (vfe->priv2 > 0) { if (vfe->priv2 < l) l = vfe->priv2; - lr = HTTP1_Read(htc, ptr, l); + lr = v1f_read(htc, ptr, l); if (lr <= 0) return (VFP_Error(vc, "straight insufficient bytes")); *lp = lr; @@ -129,10 +167,10 @@ v1f_pull_chunked(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, return (VFP_OK); } AZ(vfe->priv2); - i = HTTP1_Read(htc, buf, 1); + i = v1f_read(htc, buf, 1); if (i <= 0) return (VFP_Error(vc, "chunked read err")); - if (buf[0] == '\r' && HTTP1_Read(htc, buf, 1) <= 0) + if (buf[0] == '\r' && v1f_read(htc, buf, 1) <= 0) return (VFP_Error(vc, "chunked read err")); if (buf[0] != '\n') return (VFP_Error(vc, "chunked tail no NL")); @@ -167,7 +205,7 @@ v1f_pull_straight(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, return (VFP_END); if (vfe->priv2 < l) l = vfe->priv2; - lr = HTTP1_Read(htc, p, l); + lr = v1f_read(htc, p, l); if (lr <= 0) return (VFP_Error(vc, "straight insufficient bytes")); *lp = lr; @@ -185,8 +223,7 @@ static const struct vfp v1f_straight = { /*--------------------------------------------------------------------*/ static enum vfp_status __match_proto__(vfp_pull_f) -v1f_pull_eof(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, - ssize_t *lp) +v1f_pull_eof(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, ssize_t *lp) { ssize_t l, lr; struct http_conn *htc; @@ -200,7 +237,7 @@ v1f_pull_eof(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, l = *lp; *lp = 0; - lr = HTTP1_Read(htc, p, l); + lr = v1f_read(htc, p, l); if (lr < 0) return (VFP_Error(vc, "eof socket fail")); if (lr == 0) From phk at FreeBSD.org Mon Oct 6 09:35:57 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 06 Oct 2014 11:35:57 +0200 Subject: [master] 0929e83 More backend/http_conn cleanup Message-ID: commit 0929e83453578a825a1c88db4b85996720182ffd Author: Poul-Henning Kamp Date: Mon Oct 6 09:35:45 2014 +0000 More backend/http_conn cleanup diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index f661de3..056f61e 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -244,7 +244,6 @@ struct http_conn { #define HTTP_CONN_MAGIC 0x3e19edd1 int fd; - struct vsl_log *vsl; unsigned maxbytes; unsigned maxhdr; struct ws *ws; @@ -915,7 +914,7 @@ enum http1_status_e { HTTP1_COMPLETE = 1 }; -void HTTP1_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, unsigned maxbytes, unsigned maxhdr); enum http1_status_e HTTP1_Reinit(struct http_conn *htc); enum http1_status_e HTTP1_Rx(struct http_conn *htc); diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c index 974c5b4..2d63159 100644 --- a/bin/varnishd/http1/cache_http1_fetch.c +++ b/bin/varnishd/http1/cache_http1_fetch.c @@ -155,8 +155,7 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo) /* Receive response */ - HTTP1_Init(htc, bo->ws, vc->fd, bo->vsl, - cache_param->http_resp_size, + HTTP1_Init(htc, bo->ws, vc->fd, cache_param->http_resp_size, cache_param->http_resp_hdr_len); CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC); diff --git a/bin/varnishd/http1/cache_http1_fsm.c b/bin/varnishd/http1/cache_http1_fsm.c index dc586cc..4850df2 100644 --- a/bin/varnishd/http1/cache_http1_fsm.c +++ b/bin/varnishd/http1/cache_http1_fsm.c @@ -357,9 +357,8 @@ HTTP1_Session(struct worker *wrk, struct req *req) } if (sp->sess_step == S_STP_NEWREQ) { - HTTP1_Init(req->htc, req->ws, sp->fd, req->vsl, - cache_param->http_req_size, - cache_param->http_req_hdr_len); + HTTP1_Init(req->htc, req->ws, sp->fd, + cache_param->http_req_size, cache_param->http_req_hdr_len); } while (1) { diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index 9ee962a..8eac608 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -60,14 +60,13 @@ const int HTTP1_Resp[3] = { /*--------------------------------------------------------------------*/ void -HTTP1_Init(struct http_conn *htc, struct ws *ws, int fd, struct vsl_log *vsl, - unsigned maxbytes, unsigned maxhdr) +HTTP1_Init(struct http_conn *htc, struct ws *ws, int fd, unsigned maxbytes, + unsigned maxhdr) { htc->magic = HTTP_CONN_MAGIC; htc->ws = ws; htc->fd = fd; - htc->vsl = vsl; htc->maxbytes = maxbytes; htc->maxhdr = maxhdr; diff --git a/bin/varnishd/http1/cache_http1_vfp.c b/bin/varnishd/http1/cache_http1_vfp.c index 18b9995..daf81a5 100644 --- a/bin/varnishd/http1/cache_http1_vfp.c +++ b/bin/varnishd/http1/cache_http1_vfp.c @@ -46,12 +46,13 @@ */ static ssize_t -v1f_read(struct http_conn *htc, void *d, size_t len) +v1f_read(const struct vfp_ctx *vc, struct http_conn *htc, void *d, size_t len) { ssize_t l; unsigned char *p; ssize_t i = 0; + CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); l = 0; p = d; @@ -71,7 +72,8 @@ v1f_read(struct http_conn *htc, void *d, size_t len) i = read(htc->fd, p, len); if (i < 0) { // XXX: VTCP_Assert(i); // but also: EAGAIN - VSLb(htc->vsl, SLT_FetchError, "%s", strerror(errno)); + VSLb(vc->wrk->vsl, SLT_FetchError, + "%s", strerror(errno)); return (i); } } @@ -110,7 +112,7 @@ v1f_pull_chunked(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, if (vfe->priv2 == -1) { /* Skip leading whitespace */ do { - lr = v1f_read(htc, buf, 1); + lr = v1f_read(vc, htc, buf, 1); if (lr <= 0) return (VFP_Error(vc, "chunked read err")); } while (vct_islws(buf[0])); @@ -121,7 +123,7 @@ v1f_pull_chunked(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, /* Collect hex digits, skipping leading zeros */ for (u = 1; u < sizeof buf; u++) { do { - lr = v1f_read(htc, buf + u, 1); + lr = v1f_read(vc, htc, buf + u, 1); if (lr <= 0) return (VFP_Error(vc, "chunked read err")); @@ -135,7 +137,7 @@ v1f_pull_chunked(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, /* Skip trailing white space */ while(vct_islws(buf[u]) && buf[u] != '\n') { - lr = v1f_read(htc, buf + u, 1); + lr = v1f_read(vc, htc, buf + u, 1); if (lr <= 0) return (VFP_Error(vc, "chunked read err")); } @@ -157,7 +159,7 @@ v1f_pull_chunked(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, if (vfe->priv2 > 0) { if (vfe->priv2 < l) l = vfe->priv2; - lr = v1f_read(htc, ptr, l); + lr = v1f_read(vc, htc, ptr, l); if (lr <= 0) return (VFP_Error(vc, "straight insufficient bytes")); *lp = lr; @@ -167,10 +169,10 @@ v1f_pull_chunked(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, return (VFP_OK); } AZ(vfe->priv2); - i = v1f_read(htc, buf, 1); + i = v1f_read(vc, htc, buf, 1); if (i <= 0) return (VFP_Error(vc, "chunked read err")); - if (buf[0] == '\r' && v1f_read(htc, buf, 1) <= 0) + if (buf[0] == '\r' && v1f_read(vc, htc, buf, 1) <= 0) return (VFP_Error(vc, "chunked read err")); if (buf[0] != '\n') return (VFP_Error(vc, "chunked tail no NL")); @@ -205,7 +207,7 @@ v1f_pull_straight(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, return (VFP_END); if (vfe->priv2 < l) l = vfe->priv2; - lr = v1f_read(htc, p, l); + lr = v1f_read(vc, htc, p, l); if (lr <= 0) return (VFP_Error(vc, "straight insufficient bytes")); *lp = lr; @@ -237,7 +239,7 @@ v1f_pull_eof(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, ssize_t *lp) l = *lp; *lp = 0; - lr = v1f_read(htc, p, l); + lr = v1f_read(vc, htc, p, l); if (lr < 0) return (VFP_Error(vc, "eof socket fail")); if (lr == 0) From phk at FreeBSD.org Mon Oct 6 10:16:56 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 06 Oct 2014 12:16:56 +0200 Subject: [master] b6071fe If we know an beresp.body is zero bytes long, zap any Content-Encoding: it might have, it doesn't make any sense. Message-ID: commit b6071feb7a94cc2c76b103629c86ea8a5ac42ded Author: Poul-Henning Kamp Date: Mon Oct 6 10:16:19 2014 +0000 If we know an beresp.body is zero bytes long, zap any Content-Encoding: it might have, it doesn't make any sense. Fixes #1602 diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 03e366d..8045cd4 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -526,6 +526,9 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo) if (!cache_param->http_gzip_support) bo->do_gzip = bo->do_gunzip = 0; + if (bo->htc->content_length == 0) + http_Unset(bo->beresp, H_Content_Encoding); + bo->is_gzip = http_HdrIs(bo->beresp, H_Content_Encoding, "gzip"); bo->is_gunzip = !http_GetHdr(bo->beresp, H_Content_Encoding, NULL); From phk at FreeBSD.org Mon Oct 6 10:17:23 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 06 Oct 2014 12:17:23 +0200 Subject: [master] 924d67d Add test case for #1602 Message-ID: commit 924d67d6c0373d8538bf70364928bd073ddb1709 Author: Poul-Henning Kamp Date: Mon Oct 6 10:17:04 2014 +0000 Add test case for #1602 diff --git a/bin/varnishtest/tests/r01602.vtc b/bin/varnishtest/tests/r01602.vtc new file mode 100644 index 0000000..993bdaa --- /dev/null +++ b/bin/varnishtest/tests/r01602.vtc @@ -0,0 +1,22 @@ +varnishtest "Test case for #1602" + +server s1 { + rxreq + expect req.url == "/bar" + txresp -gzipbody {} + rxreq + expect req.url == "/foo" + txresp -hdr "Content-Encoding: gzip" +} -start + +varnish v1 -vcl+backend { + sub vcl_backend_response { + set beresp.do_esi = true; + } +} -start + +client c1 { + txreq -url /bar -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 +} -run From phk at FreeBSD.org Mon Oct 6 12:11:27 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 06 Oct 2014 14:11:27 +0200 Subject: [master] 54fe085 Also neuter do_gzip and do_gunzip if content length is zero Message-ID: commit 54fe085352af60884182739dd53ccd1bbb2adc7a Author: Poul-Henning Kamp Date: Mon Oct 6 12:10:43 2014 +0000 Also neuter do_gzip and do_gunzip if content length is zero diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 8045cd4..674845d 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -536,12 +536,12 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo) /* It can't be both */ assert(bo->is_gzip == 0 || bo->is_gunzip == 0); - /* We won't gunzip unless it is gzip'ed */ - if (bo->do_gunzip && !bo->is_gzip) + /* We won't gunzip unless it is non-empty and gzip'ed */ + if (bo->htc->content_length == 0 || (bo->do_gunzip && !bo->is_gzip)) bo->do_gunzip = 0; - /* We wont gzip unless it is ungziped */ - if (bo->do_gzip && !bo->is_gunzip) + /* We wont gzip unless it is non-empty and ungziped */ + if (bo->htc->content_length == 0 || (bo->do_gzip && !bo->is_gunzip)) bo->do_gzip = 0; /* But we can't do both at the same time */ diff --git a/bin/varnishtest/tests/r01602.vtc b/bin/varnishtest/tests/r01602.vtc index 993bdaa..4411304 100644 --- a/bin/varnishtest/tests/r01602.vtc +++ b/bin/varnishtest/tests/r01602.vtc @@ -12,6 +12,7 @@ server s1 { varnish v1 -vcl+backend { sub vcl_backend_response { set beresp.do_esi = true; + set beresp.do_gzip = true; } } -start From phk at FreeBSD.org Tue Oct 7 09:03:59 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 07 Oct 2014 11:03:59 +0200 Subject: [master] bab1226 Use RFC5861::stale-while-revalidate to initialize beresp.grace Message-ID: commit bab12263b1561c3d45e5bc6a0ab9b66e8b0ed115 Author: Poul-Henning Kamp Date: Tue Oct 7 09:03:28 2014 +0000 Use RFC5861::stale-while-revalidate to initialize beresp.grace Submitted by: fgs diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 056f61e..254c22e 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -1158,6 +1158,7 @@ unsigned RFC2616_Req_Gzip(const struct http *); int RFC2616_Do_Cond(const struct req *sp); void RFC2616_Weaken_Etag(struct http *hp); void RFC2616_Vary_AE(struct http *hp); +void RFC5861_Stale(const struct busyobj *); /* stevedore.c */ int STV_NewObject(struct objcore *, struct worker *, diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 674845d..2f9ab92 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -365,6 +365,8 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo) EXP_Clr(&bo->fetch_objcore->exp); RFC2616_Ttl(bo, now); + RFC5861_Stale(bo); + /* private objects have negative TTL */ if (bo->fetch_objcore->flags & OC_F_PRIVATE) bo->fetch_objcore->exp.ttl = -1.; diff --git a/bin/varnishd/cache/cache_rfc2616.c b/bin/varnishd/cache/cache_rfc2616.c index 20b366b..4733b56 100644 --- a/bin/varnishd/cache/cache_rfc2616.c +++ b/bin/varnishd/cache/cache_rfc2616.c @@ -275,3 +275,35 @@ RFC2616_Vary_AE(struct http *hp) http_SetHeader(hp, "Vary: Accept-Encoding"); } } + +/* + * RFC5861 outlines a way to control the use of stale responses. + * We use this to initialize the grace period. + */ + +void +RFC5861_Stale(const struct busyobj *bo) +{ + const char *p; + const struct http *hp; + struct exp *expp; + + expp = &bo->fetch_objcore->exp; + + /* + * If we are not meant to cache this ignore any potential + * stale-while-revalidate values. + */ + if (expp->ttl < 0.) + return; + + hp = bo->beresp; + + if (http_GetHdrField(hp, H_Cache_Control, + "stale-while-revalidate", &p) && p != NULL) { + if (*p == '-') + expp->grace = 0; + else + expp->grace = strtoul(p, NULL, 0); + } +} diff --git a/bin/varnishtest/tests/b00043.vtc b/bin/varnishtest/tests/b00043.vtc new file mode 100644 index 0000000..1591a03 --- /dev/null +++ b/bin/varnishtest/tests/b00043.vtc @@ -0,0 +1,41 @@ +varnishtest "Test stale-while-revalidate" + +server s1 { + rxreq + txresp -hdr "Cache-Control: max-age=30, stale-while-revalidate=30" + rxreq + txresp -hdr "Cache-Control: max-age=0, stale-while-revalidate=30" + rxreq + txresp -hdr "Cache-Control: max-age=30, stale-while-revalidate=30" -hdr "Age: 40" + rxreq + txresp -status 500 -hdr "Cache-Control: max-age=30, stale-while-revalidate=30" +} -start + +varnish v1 -vcl+backend { + sub vcl_backend_response { + set beresp.http.grace = beresp.grace; + set beresp.http.ttl = beresp.ttl; + } +} -start + +client c1 { + txreq -url /1 + rxresp + expect resp.http.grace == 30.000 + expect resp.http.ttl == 30.000 + + txreq -url /2 + rxresp + expect resp.http.grace == 30.000 + expect resp.http.ttl == 0.000 + + txreq -url /3 + rxresp + expect resp.http.grace == 30.000 + expect resp.http.ttl == -10.000 + + txreq -url /4 + rxresp + expect resp.http.grace == 10.000 + expect resp.http.ttl == 0.000 +} -run From martin at varnish-software.com Tue Oct 7 10:32:38 2014 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 07 Oct 2014 12:32:38 +0200 Subject: [master] 837d1c9 varnishlog -k argument Message-ID: commit 837d1c99b075f109d22f7b53a16064fe8e4e36d6 Author: Martin Blix Grydeland Date: Mon Oct 6 23:30:20 2014 +0200 varnishlog -k argument Implement -k argument in vut for use with varnishlog. This takes as an argument the number of log transactions to be processed before exiting. Useful to stop varnishlog after a given set of log data has been produced. Drop -s from the 'not implemented yet' list as this option has very limited usefullness. diff --git a/bin/varnishlog/varnishlog_options.h b/bin/varnishlog/varnishlog_options.h index aa3bdff..fae84a4 100644 --- a/bin/varnishlog/varnishlog_options.h +++ b/bin/varnishlog/varnishlog_options.h @@ -59,6 +59,7 @@ VUT_OPT_D VUT_OPT_g VUT_OPT_h VSL_OPT_i +VUT_OPT_k VSL_OPT_I VSL_OPT_L VUT_OPT_n diff --git a/doc/sphinx/reference/varnishlog.rst b/doc/sphinx/reference/varnishlog.rst index b916752..54247fd 100644 --- a/doc/sphinx/reference/varnishlog.rst +++ b/doc/sphinx/reference/varnishlog.rst @@ -21,20 +21,6 @@ The following options are available: .. include:: ../include/varnishlog_options.rst --k num - - Only show the first num log transactions (or log records - in -g raw mode) - - XXX: Not yet implemented - --s num - - Skip the first num log transactions (or log records if - in -g raw mode) - - XXX: Not yet implemented - SIGNALS ======= diff --git a/include/vut.h b/include/vut.h index a0b9df2..0dc7482 100644 --- a/include/vut.h +++ b/include/vut.h @@ -41,6 +41,7 @@ struct VUT { int d_opt; int D_opt; int g_arg; + int k_arg; char *P_arg; char *q_arg; char *r_arg; diff --git a/include/vut_options.h b/include/vut_options.h index de3bab2..9f01181 100644 --- a/include/vut_options.h +++ b/include/vut_options.h @@ -51,6 +51,12 @@ "Print program usage and exit" \ ) +#define VUT_OPT_k \ + VOPT("k:", "[-k num]", "Limit transactions", \ + "Process this number of matching log transactions before" \ + " exiting." \ + ) + #define VUT_OPT_n \ VOPT("n:", "[-n name]", "Varnish instance name", \ "Specify the name of the varnishd instance to get logs" \ diff --git a/lib/libvarnishtools/vut.c b/lib/libvarnishtools/vut.c index 50a9f27..1635ffe 100644 --- a/lib/libvarnishtools/vut.c +++ b/lib/libvarnishtools/vut.c @@ -83,6 +83,24 @@ vut_sigusr1(int sig) VUT.sigusr1 = 1; } +static int __match_proto__(VSLQ_dispatch_f) +vut_dispatch(struct VSL_data *vsl, struct VSL_transaction * const trans[], + void *priv) +{ + int i; + + (void)priv; + if (VUT.k_arg == 0) + return (-1); /* End of file */ + AN(VUT.dispatch_f); + i = VUT.dispatch_f(vsl, trans, VUT.dispatch_priv); + if (VUT.k_arg > 0) + VUT.k_arg--; + if (i >= 0 && VUT.k_arg == 0) + return (-1); /* End of file */ + return (i); +} + void VUT_Error(int status, const char *fmt, ...) { @@ -114,6 +132,7 @@ int VUT_Arg(int opt, const char *arg) { int i; + char *p; switch (opt) { case 'd': @@ -127,6 +146,12 @@ VUT_Arg(int opt, const char *arg) case 'g': /* Grouping */ return (VUT_g_Arg(arg)); + case 'k': + /* Log transaction limit */ + VUT.k_arg = (int)strtol(arg, &p, 10); + if (*p != '\0' || VUT.k_arg <= 0) + VUT_Error(1, "-k: Invalid number '%s'", arg); + return (1); case 'n': /* Varnish instance */ if (VUT.vsm == NULL) @@ -178,6 +203,7 @@ VUT_Init(const char *progname) AZ(VUT.vsl); VUT.vsl = VSL_New(); AN(VUT.vsl); + VUT.k_arg = -1; } void @@ -281,8 +307,7 @@ VUT_Main(void) /* Flush and report any incomplete records */ VUT.sigusr1 = 0; if (VUT.vslq != NULL) - VSLQ_Flush(VUT.vslq, VUT.dispatch_f, - VUT.dispatch_priv); + VSLQ_Flush(VUT.vslq, vut_dispatch, NULL); } if (VUT.vslq == NULL) { @@ -307,7 +332,7 @@ VUT_Main(void) VUT_Error(0, "Log reacquired"); } - i = VSLQ_Dispatch(VUT.vslq, VUT.dispatch_f, VUT.dispatch_priv); + i = VSLQ_Dispatch(VUT.vslq, vut_dispatch, NULL); if (i == 1) /* Call again */ continue; @@ -330,7 +355,7 @@ VUT_Main(void) /* XXX: Make continuation optional */ - VSLQ_Flush(VUT.vslq, VUT.dispatch_f, VUT.dispatch_priv); + VSLQ_Flush(VUT.vslq, vut_dispatch, NULL); VSLQ_Delete(&VUT.vslq); AZ(VUT.vslq); From fgsch at lodoss.net Tue Oct 7 11:17:51 2014 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Tue, 07 Oct 2014 13:17:51 +0200 Subject: [master] 11cc8b2 Correct comment Message-ID: commit 11cc8b2fff717d1889a3e51fb320e55c6c4d9e85 Author: Federico G. Schwindt Date: Tue Oct 7 12:15:19 2014 +0100 Correct comment While here drop -w in favour of -p and do some whitespace cleanup. diff --git a/varnish.default b/varnish.default index 152b35e..a9a063e 100644 --- a/varnish.default +++ b/varnish.default @@ -31,17 +31,17 @@ MEMLOCK=82000 # # DAEMON_OPTS="-a :6081 \ # -T localhost:6082 \ -# -b localhost:8080 \ -# -u varnish -g varnish \ -# -S /etc/varnish/secret \ -# -s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G" +# -b localhost:8080 \ +# -u varnish -g varnish \ +# -S /etc/varnish/secret \ +# -s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G" ## Alternative 2, Configuration with VCL # # Listen on port 6081, administration on localhost:6082, and forward to -# one content server selected by the vcl file, based on the request. Use a 1GB -# fixed-size cache file. +# one content server selected by the vcl file, based on the request. +# Use a 256MB memory based cache. # DAEMON_OPTS="-a :6081 \ -T localhost:6082 \ @@ -85,7 +85,7 @@ DAEMON_OPTS="-a :6081 \ # # # File containing administration secret # VARNISH_SECRET_FILE=/etc/varnish/secret -# +# # # Backend storage specification # VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}" # @@ -98,8 +98,10 @@ DAEMON_OPTS="-a :6081 \ # -f ${VARNISH_VCL_CONF} \ # -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \ # -t ${VARNISH_TTL} \ -# -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \ -# -S ${VARNISH_SECRET_FILE} \ +# -p thread_pool_min=${VARNISH_MIN_THREADS} \ +# -p thread_pool_max=${VARNISH_MAX_THREADS} \ +# -p thread_pool_timeout=${VARNISH_THREAD_TIMEOUT} \ +# -S ${VARNISH_SECRET_FILE} \ # -s ${VARNISH_STORAGE}" # From nils.goroll at uplex.de Tue Oct 7 13:09:31 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 07 Oct 2014 15:09:31 +0200 Subject: [master] 44dc73e add back the graphviz sources as removed by commit 4ad0d5bdfe45eb31111fb1d0b1a4aa72942b477d Message-ID: commit 44dc73eec90b04e9f93364c3bfe281eb069bcd3f Author: Nils Goroll Date: Mon Oct 6 16:58:51 2014 +0200 add back the graphviz sources as removed by commit 4ad0d5bdfe45eb31111fb1d0b1a4aa72942b477d diff --git a/doc/graphviz/cache_http1_fsm.dot b/doc/graphviz/cache_http1_fsm.dot new file mode 100644 index 0000000..9ff2f57 --- /dev/null +++ b/doc/graphviz/cache_http1_fsm.dot @@ -0,0 +1,22 @@ + digraph vcl_center { + size="7.2,10.5" + margin="0.5" + center="1" + + acceptor -> http1_wait [label=S_STP_NEWREQ, align=center] + hash -> CNT_Request [label="Busy object\nS_STP_WORKING\nR_STP_LOOKUP" + color=blue] + disembark -> hash [style=dotted, color=blue] + http1_wait -> CNT_Request [label="S_STP_WORKING\nR_STP_RECV"] + http1_wait -> disembark [label="Session close"] + http1_wait -> disembark [label="Timeout" color=green] + disembark -> waiter [style=dotted, color=green] + waiter -> http1_wait [color=green] + CNT_Request -> disembark + [label="Busy object\nS_STP_WORKING\nR_STP_LOOKUP" color=blue] + CNT_Request -> http1_cleanup + http1_cleanup -> disembark [label="Session close"] + http1_cleanup -> CNT_Request [label="S_STP_WORKING\nR_STP_RECV"] + http1_cleanup -> http1_wait [label="S_STP_NEWREQ"] + + } diff --git a/doc/graphviz/cache_req_fsm.dot b/doc/graphviz/cache_req_fsm.dot new file mode 100644 index 0000000..0edea1e --- /dev/null +++ b/doc/graphviz/cache_req_fsm.dot @@ -0,0 +1,111 @@ + digraph vcl_center { + size="7.2,10.5" + margin="0.5" + center="1" + acceptor [ + shape=hexagon + label="Request received" + ] + ESI_REQ [ shape=hexagon ] + ESI_REQ -> recv + SYNTH [shape=plaintext] + RESTART [shape=plaintext] + acceptor -> recv [style=bold,color=green] + deliver [ + shape=record + label="{cnt_deliver:|Filter obj.-\>resp.|{vcl_deliver\{\}|{req.|resp.}}|{restart?|deliver?}}" + ] + deliver:deliver:s -> DONE [style=bold,color=green] + deliver:deliver:s -> DONE [style=bold,color=red] + deliver:deliver:s -> DONE [style=bold,color=blue] + subgraph xcluster_synth { + synth [ + shape=record + label="{cnt_synth:|{vcl_synth\{\}|resp.}|{deliver?|restart?}}" + ] + SYNTH -> synth + synth:del:s -> deliver [label=deliver] + } + subgraph xcluster_body { + fetch [ + shape=record + label="{cnt_fetch:|wait for fetch|{OK|Failed}}" + ] + } + fetch:ok:s -> deliver [style=bold,color=red] + fetch:ok:s -> deliver [style=bold,color=blue] + fetch:err:s -> vcl_error + subgraph xcluster_lookup { + lookup [ + shape=record + label="{cnt_lookup:|hash lookup|{busy?|exp?|exp+busy?|hit?|miss?|hit-for-pass?}}" + ] + lookup2 [ + shape=record + label="{cnt_lookup:|{vcl_hit\{\}|req.*, obj.*}|{deliver?|synth?|restart?|fetch?|pass?}}" + ] + } + lookup:busy:w -> lookup:top:w [label="(waitinglist)"] + lookup:miss:s -> miss [style=bold,color=blue] + lookup:hfp:s -> pass [style=bold,color=red] + lookup:e:s -> lookup2 [style=bold,color=green] + lookup:eb:s -> lookup2 [style=bold,color=green] + lookup:h:s -> lookup2 [style=bold,color=green] + lookup2:pass:s -> pass [style=bold,color=red] + lookup2:fetch:s -> miss [style=bold,color=blue] + lookup2:deliver:s -> deliver:n [style=bold,color=green] + subgraph xcluster_miss { + miss [ + shape=record + label="{cnt_miss:|{vcl_miss\{\}|req.*}|{fetch?|synth?|restart?|pass?}}" + ] + } + miss:fetch:s -> fetch [label="fetch",style=bold,color=blue] + miss:pass:s -> pass [label="pass",style=bold,color=red] + + subgraph xcluster_pass { + pass [ + shape=record + label="{cnt_pass:|{vcl_pass\{\}|req.*}|{fetch?|synth?|restart?}}" + ] + } + pass:fetch:s -> fetch:n [style=bold, color=red] + subgraph xcluster_pipe { + pipe [ + shape=record + label="{cnt_pipe:|filter req.*-\>bereq.*|{vcl_pipe()|req.*, bereq\.*}|{pipe?|synth?}}" + ] + pipe_do [ + shape=ellipse + label="send bereq.\npipe until close" + ] + pipe:pipe -> pipe_do [label="pipe",style=bold,color=orange] + } + pipe_do -> DONE [style=bold,color=orange] + subgraph xcluster_restart { + restart [ + shape=record + label="{cnt_restart}" + ] + } + RESTART -> restart [color=purple] + restart -> recv [color=purple] + restart -> err_restart + err_restart [label="SYNTH",shape=plaintext] + subgraph xcluster_recv { + recv [ + shape=record + label="{cnt_recv:|{vcl_recv\{\}|req.*}|{vcl_hash\{\}|req.*}|{lookup?|pass?|pipe?|synth?|purge?}}" + ] + } + recv:pipe -> pipe [style=bold,color=orange] + recv:pass -> pass [style=bold,color=red] + recv:lookup:s -> lookup [style=bold,color=green] + recv:purge:s -> purge [style=bold,color=purple] + subgraph xcluster_purge { + purge [ + shape=record + label="{cnt_purge:|{vcl_purge\{\}|req.*}|{synth?}}" + ] + } + } From nils.goroll at uplex.de Tue Oct 7 13:09:31 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 07 Oct 2014 15:09:31 +0200 Subject: [master] be2db39 look for the dot tool from the graphviz package and ps2pdf Message-ID: commit be2db3941788fb690af01d9342167620a46359b0 Author: Nils Goroll Date: Mon Oct 6 17:08:11 2014 +0200 look for the dot tool from the graphviz package and ps2pdf diff --git a/configure.ac b/configure.ac index d4f5c5b..7195207 100644 --- a/configure.ac +++ b/configure.ac @@ -70,6 +70,28 @@ AC_ARG_WITH([rst2html], fi]) AM_CONDITIONAL(HAVE_RST2HTML,[test "x$RST2HTML" != "xno"]) +AC_ARG_WITH([dot], + AS_HELP_STRING([--with-dot=PATH], + [Location of the dot tool from graphviz (auto)]), + [DOT="$withval"], + [AC_CHECK_PROGS(DOT, [dot], [no]) + if test "x$DOT" = "xno"; then + AC_MSG_WARN( + [dot not found - can't generate graphviz output for documentation.]) + fi]) +AM_CONDITIONAL(HAVE_DOT,[test "x$DOT" != "xno"]) + +AC_ARG_WITH([ps2pdf], + AS_HELP_STRING([--with-ps2pdf=PATH], + [Location of the ps2pdf tool from ghostscript (auto)]), + [PS2PDF="$withval"], + [AC_CHECK_PROGS(PS2PDF, [ps2pdf], [no]) + if test "x$PS2PDF" = "xno"; then + AC_MSG_WARN( + [ps2pdf not found - can't generate graphviz output for documentation.]) + fi]) +AM_CONDITIONAL(HAVE_PS2PDF,[test "x$PS2PDF" != "xno"]) + # Checks for libraries. save_LIBS="${LIBS}" LIBS="" From nils.goroll at uplex.de Tue Oct 7 13:09:31 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 07 Oct 2014 15:09:31 +0200 Subject: [master] 1e2d4aa basic build infrastructure for graphviz output Message-ID: commit 1e2d4aab8064ee08e4d1a0a730a14be995ea57d4 Author: Nils Goroll Date: Mon Oct 6 17:56:29 2014 +0200 basic build infrastructure for graphviz output diff --git a/.gitignore b/.gitignore index 460e76a..516380e 100644 --- a/.gitignore +++ b/.gitignore @@ -98,6 +98,8 @@ cscope.*out /doc/sphinx/build/ /doc/sphinx/conf.py /doc/sphinx/include/vcl_var.rst +# graphviz-generated +/doc/graphviz/*.pdf # NetBeans insists on this /nbproject/private/ diff --git a/configure.ac b/configure.ac index 7195207..0691424 100644 --- a/configure.ac +++ b/configure.ac @@ -648,6 +648,7 @@ AC_CONFIG_FILES([ bin/varnishtest/Makefile bin/varnishncsa/Makefile doc/Makefile + doc/graphviz/Makefile doc/sphinx/Makefile doc/sphinx/conf.py etc/Makefile diff --git a/doc/Makefile.am b/doc/Makefile.am index 5da0749..927b54a 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -14,4 +14,4 @@ else @false endif -SUBDIRS = sphinx +SUBDIRS = sphinx graphviz diff --git a/doc/graphviz/Makefile.am b/doc/graphviz/Makefile.am new file mode 100644 index 0000000..8d2ca8f --- /dev/null +++ b/doc/graphviz/Makefile.am @@ -0,0 +1,24 @@ +# Makefile for graphviz outputs +# + +# You can set these variables from the command line. +# this is a4, letter is 8.5,11 +SIZE = 8.4,11.7 + +if HAVE_DOT +if HAVE_PS2PDF + +PDFS = \ + cache_http1_fsm.pdf \ + cache_req_fsm.pdf + +pdf: $(PDFS) + +endif +endif + +%.ps: %.dot + @DOT@ -Tps -Gsize=$(SIZE) $< >$@ + +%.pdf: %.ps + @PS2PDF@ $< From nils.goroll at uplex.de Tue Oct 7 13:09:31 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 07 Oct 2014 15:09:31 +0200 Subject: [master] d09cf37 remove size params - they are set in the Makefile now Message-ID: commit d09cf370d88fd3c499b437d51b4b2cfb07f5ea0a Author: Nils Goroll Date: Mon Oct 6 17:59:59 2014 +0200 remove size params - they are set in the Makefile now diff --git a/doc/graphviz/cache_http1_fsm.dot b/doc/graphviz/cache_http1_fsm.dot index 9ff2f57..5021b91 100644 --- a/doc/graphviz/cache_http1_fsm.dot +++ b/doc/graphviz/cache_http1_fsm.dot @@ -1,5 +1,4 @@ digraph vcl_center { - size="7.2,10.5" margin="0.5" center="1" diff --git a/doc/graphviz/cache_req_fsm.dot b/doc/graphviz/cache_req_fsm.dot index 0edea1e..6b526c8 100644 --- a/doc/graphviz/cache_req_fsm.dot +++ b/doc/graphviz/cache_req_fsm.dot @@ -1,5 +1,4 @@ digraph vcl_center { - size="7.2,10.5" margin="0.5" center="1" acceptor [ From nils.goroll at uplex.de Tue Oct 7 13:09:31 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 07 Oct 2014 15:09:31 +0200 Subject: [master] b175cc6 progress on dot graphs - add cache_fetch.dot for backend side Message-ID: commit b175cc68326c0dc1eb69941992ffbe69c478c43e Author: Nils Goroll Date: Mon Oct 6 22:36:47 2014 +0200 progress on dot graphs - add cache_fetch.dot for backend side diff --git a/doc/graphviz/Makefile.am b/doc/graphviz/Makefile.am index 8d2ca8f..51e2b4c 100644 --- a/doc/graphviz/Makefile.am +++ b/doc/graphviz/Makefile.am @@ -10,7 +10,8 @@ if HAVE_PS2PDF PDFS = \ cache_http1_fsm.pdf \ - cache_req_fsm.pdf + cache_req_fsm.pdf \ + cache_fetch.pdf pdf: $(PDFS) diff --git a/doc/graphviz/cache_fetch.dot b/doc/graphviz/cache_fetch.dot new file mode 100644 index 0000000..0a9fdf1 --- /dev/null +++ b/doc/graphviz/cache_fetch.dot @@ -0,0 +1,106 @@ +digraph cache_fetch { + margin="0.5" + center="1" + rotate=90 + + /*** cache_fetch.c ***/ + subgraph cluster_backend { + style=filled + color=aliceblue + RETRY [shape=plaintext] + v_b_f_BGFETCH [label="BGFETCH", + shape=box, + style=filled, + color=turquoise] + v_b_f_FETCH [label="FETCH", + shape=box, + style=filled, + color=turquoise] + v_b_f_BGFETCH -> v_b_f [style=bold,color=green] + v_b_f_FETCH -> v_b_f [style=bold,color=blue] + v_b_f_FETCH -> v_b_f [style=bold,color=red] + RETRY -> v_b_f [color=purple] + /* vbf_stp_startfetch() */ + v_b_f [ + shape=record + label=" + {vbf_stp_startfetch:| + {vcl_backend_fetch\{\}|bereq.*}| + {abandon| + fetch}}" + ] + v_b_f:fetch:s -> v_b_hdrs [style=bold] + v_b_hdrs [ label="send bereq,\nread beresp (headers)"] + v_b_hdrs -> v_b_r [style=bold] + v_b_hdrs -> v_b_e + v_b_r [ + shape=record + label=" + {vbf_stp_startfetch:| + {vcl_backend_response\{\}|{ + bereq.*|beresp.*}}| + {{retry|{max?|ok?}}| + abandon| + {deliver|{304?| + body?}}}}" + ] + v_b_r:retry -> v_b_r_retry [color=purple] + v_b_r:max -> v_b_e + v_b_r:fetch_304:s -> vbf_stp_condfetch + v_b_r:fetch_body:s -> vbf_stp_fetch + + v_b_r_retry [label="RETRY",shape=plaintext] + + vbf_stp_fetch [ + shape=record + fontcolor=grey + color=grey + label=" + {vbf_stp_fetch:| + setup VFPs| + fetch| + {fetch_fail?|error?|ok?}}" + ] + vbf_stp_fetch:ok:s -> FETCH_DONE + + vbf_stp_condfetch [ + shape=record + fontcolor=grey + color=grey + label=" + {vbf_stp_condfetch:| + copy obj attr| + steal body| + {fetch_fail?|ok?}}" + + ] + vbf_stp_condfetch:ok:s -> FETCH_DONE + + /* vbf_stp_error */ + v_b_e [ + shape=record + label=" + {vbf_stp_error:| + {vcl_backend_error\{\}|{ + bereq.*|beresp.*}}| + {{retry|{max?|ok?}}| + deliver}}}" + ] + // v_b_e:deliver aka "backend synth" - goes into cache + v_b_e:deliver -> FETCH_DONE [label="\"backend synth\""] + v_b_e:retry -> v_b_e_retry [color=purple] + v_b_e_retry [label="RETRY",shape=plaintext] + v_b_e:max:s -> FETCH_FAIL + + v_b_e_retry [label="RETRY",shape=plaintext] + + FETCH_DONE [label="FETCH_DONE", + shape=box,style=filled,color=turquoise] + + abandon [shape=plaintext] + abandon -> FETCH_FAIL + // F_STP_FAIL + FETCH_FAIL [label="FETCH_FAIL", + shape=box,style=filled,color=turquoise] + } +} \ No newline at end of file diff --git a/doc/graphviz/cache_req_fsm.dot b/doc/graphviz/cache_req_fsm.dot index 6b526c8..5cea42c 100644 --- a/doc/graphviz/cache_req_fsm.dot +++ b/doc/graphviz/cache_req_fsm.dot @@ -1,110 +1,246 @@ - digraph vcl_center { - margin="0.5" +digraph cache_req_fsm { + margin="0.25" + ranksep="0.5" center="1" - acceptor [ - shape=hexagon - label="Request received" - ] - ESI_REQ [ shape=hexagon ] - ESI_REQ -> recv - SYNTH [shape=plaintext] - RESTART [shape=plaintext] - acceptor -> recv [style=bold,color=green] - deliver [ - shape=record - label="{cnt_deliver:|Filter obj.-\>resp.|{vcl_deliver\{\}|{req.|resp.}}|{restart?|deliver?}}" - ] - deliver:deliver:s -> DONE [style=bold,color=green] - deliver:deliver:s -> DONE [style=bold,color=red] - deliver:deliver:s -> DONE [style=bold,color=blue] - subgraph xcluster_synth { - synth [ - shape=record - label="{cnt_synth:|{vcl_synth\{\}|resp.}|{deliver?|restart?}}" - ] - SYNTH -> synth - synth:del:s -> deliver [label=deliver] - } - subgraph xcluster_body { - fetch [ - shape=record - label="{cnt_fetch:|wait for fetch|{OK|Failed}}" - ] - } - fetch:ok:s -> deliver [style=bold,color=red] - fetch:ok:s -> deliver [style=bold,color=blue] - fetch:err:s -> vcl_error - subgraph xcluster_lookup { - lookup [ - shape=record - label="{cnt_lookup:|hash lookup|{busy?|exp?|exp+busy?|hit?|miss?|hit-for-pass?}}" - ] - lookup2 [ - shape=record - label="{cnt_lookup:|{vcl_hit\{\}|req.*, obj.*}|{deliver?|synth?|restart?|fetch?|pass?}}" - ] - } - lookup:busy:w -> lookup:top:w [label="(waitinglist)"] - lookup:miss:s -> miss [style=bold,color=blue] - lookup:hfp:s -> pass [style=bold,color=red] - lookup:e:s -> lookup2 [style=bold,color=green] - lookup:eb:s -> lookup2 [style=bold,color=green] - lookup:h:s -> lookup2 [style=bold,color=green] - lookup2:pass:s -> pass [style=bold,color=red] - lookup2:fetch:s -> miss [style=bold,color=blue] - lookup2:deliver:s -> deliver:n [style=bold,color=green] - subgraph xcluster_miss { - miss [ - shape=record - label="{cnt_miss:|{vcl_miss\{\}|req.*}|{fetch?|synth?|restart?|pass?}}" - ] - } - miss:fetch:s -> fetch [label="fetch",style=bold,color=blue] - miss:pass:s -> pass [label="pass",style=bold,color=red] - - subgraph xcluster_pass { - pass [ - shape=record - label="{cnt_pass:|{vcl_pass\{\}|req.*}|{fetch?|synth?|restart?}}" - ] - } - pass:fetch:s -> fetch:n [style=bold, color=red] - subgraph xcluster_pipe { - pipe [ - shape=record - label="{cnt_pipe:|filter req.*-\>bereq.*|{vcl_pipe()|req.*, bereq\.*}|{pipe?|synth?}}" - ] - pipe_do [ - shape=ellipse - label="send bereq.\npipe until close" - ] - pipe:pipe -> pipe_do [label="pipe",style=bold,color=orange] - } - pipe_do -> DONE [style=bold,color=orange] - subgraph xcluster_restart { - restart [ - shape=record - label="{cnt_restart}" + + //// XXX does this belong here? -- from cache_vcl.c + /* + vcl_load [label = "vcl.load",shape=plaintext] + vcl_load -> init + init [ + shape=record + label=" + {VCL_Load:| + {vcl_init}| + {ok|fail}}" ] - } - RESTART -> restart [color=purple] - restart -> recv [color=purple] - restart -> err_restart - err_restart [label="SYNTH",shape=plaintext] - subgraph xcluster_recv { - recv [ - shape=record - label="{cnt_recv:|{vcl_recv\{\}|req.*}|{vcl_hash\{\}|req.*}|{lookup?|pass?|pipe?|synth?|purge?}}" + init:ok -> ok + init:fail -> fail + + vcl_discard [label = "vcl.discard",shape=plaintext] + vcl_discard -> fini + fini [ + shape=record + label=" + {VCL_Nuke:| + {vcl_fini}| + {ok}}" ] - } - recv:pipe -> pipe [style=bold,color=orange] - recv:pass -> pass [style=bold,color=red] - recv:lookup:s -> lookup [style=bold,color=green] - recv:purge:s -> purge [style=bold,color=purple] - subgraph xcluster_purge { - purge [ - shape=record - label="{cnt_purge:|{vcl_purge\{\}|req.*}|{synth?}}" + fini:ok -> ok + */ + + acceptor [ + shape=hexagon + label="Request received" ] - } - } + ESI_REQ [ shape=hexagon ] + RESTART [shape=plaintext] + + ESI_REQ -> recv + SYNTH [shape=plaintext] + acceptor -> recv [style=bold] + + subgraph xcluster_deliver { + /* cnt_deliver() */ + deliver [ + shape=record + label=" + {cnt_deliver:| + Filter obj.-\>resp.| + {vcl_deliver\{\}| + {req.*|resp.*}}| + {restart|deliver|synth}}" + ] + + deliver:deliver:s -> V1D_Deliver [style=bold,color=green] + deliver:deliver:s -> V1D_Deliver [style=bold,color=red] + deliver:deliver:s -> V1D_Deliver [style=bold,color=blue] + + stream [label="stream?\nbody",style=filled,color=turquoise] + stream -> V1D_Deliver [style=dotted] + } + + V1D_Deliver -> DONE + + /* cnt_synth() */ + subgraph xcluster_synth { + synth [ + shape=record + label=" + {cnt_synth:| + {vcl_synth\{\}|{req.*|resp.*}}| + {deliver|restart}}" + ] + + SYNTH -> synth [color=purple] + synth:del:s -> V1D_Deliver_Synth [color=purple] + + V1D_Deliver_Synth -> DONE + } + + subgraph cluster_backend { + style=filled + color=aliceblue + + "see backend graph" [shape=plaintext] + + node [shape=box, + style=filled, + color=turquoise] + + BGFETCH + FETCH + FETCH_DONE + FETCH_FAIL + } + + lookup2:deliver:s -> BGFETCH [label="parallel\nif obj expired", + color=green] + FETCH_FAIL -> synth [color=purple] + + FETCH_DONE -> deliver [style=bold,color=red] + FETCH_DONE -> deliver [style=bold,color=blue] + FETCH -> FETCH_DONE [style=dotted] + FETCH -> FETCH_FAIL [style=dotted] + /* cnt_lookup() */ + subgraph xcluster_lookup { + lookup [ + shape=record + color=grey + fontcolor=grey + label=" + {cnt_lookup:| + hash lookup| + {busy?| + hit?| + miss?| + hit-for-pass?}}" + ] + lookup2 [ + shape=record + label=" + {cnt_lookup:| + {vcl_hit\{\}|{req.*|obj.*}}| + {deliver| + fetch| + restart| + synth| + pass}}" + ] + } + lookup:busy:w -> lookup:top:w [label="(waitinglist)", + color=grey, + fontcolor=grey] + lookup:miss:s -> miss [style=bold,color=blue] + lookup:hfp:s -> pass [style=bold,color=red] + lookup:h:s -> lookup2 [style=bold,color=green] + + lookup2:deliver:s -> deliver:n [style=bold,color=green] + lookup2:fetch:s -> miss [style=bold,color=blue] + // XXX should not happen + // lookup2:fetch:s -> pass [style=bold,color=red,label="(no busy obj)"] + lookup2:pass:s -> pass [style=bold,color=red] + + /* cnt_miss */ + subgraph xcluster_miss { + miss [ + shape=record + label=" + {cnt_miss:| + {vcl_miss\{\}|req.*}| + {fetch| + synth| + restart| + pass}}" + ] + } + miss:fetch:s -> FETCH [style=bold,color=blue] + miss:pass:s -> pass [style=bold,color=red] + + /* cnt_pass */ + subgraph xcluster_pass { + pass [ + shape=record + label="{cnt_pass:| + {vcl_pass\{\}|req.*}| + {fetch| + synth| + restart}}" + ] + } + pass:fetch:s -> FETCH [style=bold, color=red] + + /* cnt_pipe */ + subgraph xcluster_pipe { + pipe [ + shape=record + label=" + {cnt_pipe:| + filter req.*-\>bereq.*| + {vcl_pipe\{\}|{req.*|bereq.*}}| + {pipe| + synth}}" + ] + pipe_do [ + shape=ellipse + label="send bereq.\ncopy bytes until close" + ] + pipe:pipe -> pipe_do [style=bold,color=orange] + } + pipe_do -> DONE [style=bold,color=orange] + + /* cnt_restart */ + subgraph xcluster_restart { + restart [ + shape=record + color=grey + fontcolor=grey + label=" + {cnt_restart:| + {ok?| + max_restarts?}}" + ] + } + RESTART -> restart [color=purple] + restart:ok:s -> recv + restart:max:s -> err_restart [color=purple] + err_restart [label="SYNTH",shape=plaintext] + + /* cnt_recv() */ + subgraph xcluster_recv { + recv [ + shape=record + label=" + {cnt_recv:| + {vcl_recv\{\}|req.*}| + {hash| + pass| + pipe| + synth| + purge}}" + ] + recv:hash -> hash [style=bold,color=green] + hash [ + shape=record + label=" + {cnt_recv:| + {vcl_hash\{\}|req.*}| + {lookup}}"] + } + recv:pipe -> pipe [style=bold,color=orange] + recv:pass -> pass [style=bold,color=red] + hash:lookup:s -> lookup [style=bold,color=green] + recv:purge:s -> purge [style=bold,color=purple] + + /* cnt_purge */ + subgraph xcluster_purge { + purge [ + shape=record + label=" + {cnt_purge:| + {vcl_purge\{\}|req.*}| + {synth| + restart}}" + ] + } +} \ No newline at end of file From nils.goroll at uplex.de Tue Oct 7 13:25:13 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 07 Oct 2014 15:25:13 +0200 Subject: [master] 635442d comma instead of fullstop Message-ID: commit 635442db7904447ca336d154899d72d2abe6c7ce Author: Nils Goroll Date: Tue Oct 7 15:24:50 2014 +0200 comma instead of fullstop diff --git a/doc/graphviz/cache_req_fsm.dot b/doc/graphviz/cache_req_fsm.dot index 5cea42c..1949757 100644 --- a/doc/graphviz/cache_req_fsm.dot +++ b/doc/graphviz/cache_req_fsm.dot @@ -183,7 +183,7 @@ digraph cache_req_fsm { ] pipe_do [ shape=ellipse - label="send bereq.\ncopy bytes until close" + label="send bereq,\ncopy bytes until close" ] pipe:pipe -> pipe_do [style=bold,color=orange] } From nils.goroll at uplex.de Tue Oct 7 13:25:13 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 07 Oct 2014 15:25:13 +0200 Subject: [master] c452065 better names, add error node for backend Message-ID: commit c4520659c02d938969ba3d5d37c4be9489b11198 Author: Nils Goroll Date: Tue Oct 7 15:25:00 2014 +0200 better names, add error node for backend diff --git a/doc/graphviz/cache_fetch.dot b/doc/graphviz/cache_fetch.dot index 0a9fdf1..db292f0 100644 --- a/doc/graphviz/cache_fetch.dot +++ b/doc/graphviz/cache_fetch.dot @@ -42,12 +42,12 @@ digraph cache_fetch { {{retry|{max?|ok?}}| abandon| {deliver|{304?| - body?}}}}" + other?}}}}" ] v_b_r:retry -> v_b_r_retry [color=purple] v_b_r:max -> v_b_e v_b_r:fetch_304:s -> vbf_stp_condfetch - v_b_r:fetch_body:s -> vbf_stp_fetch + v_b_r:non_304:s -> vbf_stp_fetch v_b_r_retry [label="RETRY",shape=plaintext] @@ -76,6 +76,9 @@ digraph cache_fetch { ] vbf_stp_condfetch:ok:s -> FETCH_DONE + error [shape=plaintext] + error -> FETCH_FAIL + /* vbf_stp_error */ v_b_e [ shape=record From lkarsten at varnish-software.com Wed Oct 8 07:44:39 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Wed, 08 Oct 2014 09:44:39 +0200 Subject: [4.0] 7923c15 Remove incorrect changelog entry. Message-ID: commit 7923c15dac707de38bef3d327b8a7d8031a2e5dc Author: Lasse Karstensen Date: Mon Oct 6 12:40:35 2014 +0200 Remove incorrect changelog entry. After re-reading the patch, this isn't important enough to warrant a changelog entry. Spotted by: fgsch diff --git a/doc/changes.rst b/doc/changes.rst index e424a20..4f0e27c 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -8,7 +8,6 @@ New since 4.0.1: - [libvmod-std] New function strstr() for matching substrings. - server.(hostname|identity) is now available in all VCL functions. - VCL variable type BYTES was added. -- X-Forwarded-For is now set on return(synth) from vcl_recv. - `workspace_client` default is now 9k. - [varnishstat] Update interval can now be subsecond. - Document that reloading VCL does not reload a VMOD. From lkarsten at varnish-software.com Wed Oct 8 07:44:39 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Wed, 08 Oct 2014 09:44:39 +0200 Subject: [4.0] b68a6ed Update copyright statement. Message-ID: commit b68a6edaa9819c5d5e99ff79e9fb9561cb29e41b Author: Lasse Karstensen Date: Mon Sep 29 15:25:17 2014 +0200 Update copyright statement. diff --git a/LICENSE b/LICENSE index a6cf987..67dc00a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ Copyright (c) 2006 Verdens Gang AS -Copyright (c) 2006-2011 Varnish Software AS +Copyright (c) 2006-2014 Varnish Software AS All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/lib/libvarnish/version.c b/lib/libvarnish/version.c index b7b2edc..284c661 100644 --- a/lib/libvarnish/version.c +++ b/lib/libvarnish/version.c @@ -44,5 +44,5 @@ VCS_Message(const char *progname) { fprintf(stderr, "%s (%s)\n", progname, VCS_version); fprintf(stderr, "Copyright (c) 2006 Verdens Gang AS\n"); - fprintf(stderr, "Copyright (c) 2006-2011 Varnish Software AS\n"); + fprintf(stderr, "Copyright (c) 2006-2014 Varnish Software AS\n"); } From lkarsten at varnish-software.com Wed Oct 8 07:44:39 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Wed, 08 Oct 2014 09:44:39 +0200 Subject: [4.0] 90f6391 Unhide vcl.show from 'help' output, it was hidden due to overzealous copy&paste. Message-ID: commit 90f63914fcd88413a4ccf2d216444cce6f725ccf Author: Poul-Henning Kamp Date: Thu Oct 2 20:40:51 2014 +0000 Unhide vcl.show from 'help' output, it was hidden due to overzealous copy&paste. Spotted by: scn diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c index 43c28c4..2f7c1b9 100644 --- a/bin/varnishd/cache/cache_vcl.c +++ b/bin/varnishd/cache/cache_vcl.c @@ -490,7 +490,7 @@ static struct cli_proto vcl_cmds[] = { { CLI_VCL_LIST, "i", ccf_config_list }, { CLI_VCL_DISCARD, "i", ccf_config_discard }, { CLI_VCL_USE, "i", ccf_config_use }, - { CLI_VCL_SHOW, "i", ccf_config_show }, + { CLI_VCL_SHOW, "", ccf_config_show }, { NULL } }; From lkarsten at varnish-software.com Wed Oct 8 07:44:39 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Wed, 08 Oct 2014 09:44:39 +0200 Subject: [4.0] 8bcefb3 varnishlog -k argument Message-ID: commit 8bcefb3ffdd9c6232eaef758fa8b66a10127baf9 Author: Martin Blix Grydeland Date: Mon Oct 6 23:58:12 2014 +0200 varnishlog -k argument Implement -k argument in vut for use with varnishlog. This takes as an argument the number of log transactions to be processed before exiting. Useful to stop varnishlog after a given set of log data has been produced. Drop -s from the 'not implemented yet' list as this option has very limited usefullness. diff --git a/bin/varnishlog/varnishlog_options.h b/bin/varnishlog/varnishlog_options.h index aa3bdff..fae84a4 100644 --- a/bin/varnishlog/varnishlog_options.h +++ b/bin/varnishlog/varnishlog_options.h @@ -59,6 +59,7 @@ VUT_OPT_D VUT_OPT_g VUT_OPT_h VSL_OPT_i +VUT_OPT_k VSL_OPT_I VSL_OPT_L VUT_OPT_n diff --git a/doc/sphinx/reference/varnishlog.rst b/doc/sphinx/reference/varnishlog.rst index b916752..54247fd 100644 --- a/doc/sphinx/reference/varnishlog.rst +++ b/doc/sphinx/reference/varnishlog.rst @@ -21,20 +21,6 @@ The following options are available: .. include:: ../include/varnishlog_options.rst --k num - - Only show the first num log transactions (or log records - in -g raw mode) - - XXX: Not yet implemented - --s num - - Skip the first num log transactions (or log records if - in -g raw mode) - - XXX: Not yet implemented - SIGNALS ======= diff --git a/include/vut.h b/include/vut.h index a0b9df2..0dc7482 100644 --- a/include/vut.h +++ b/include/vut.h @@ -41,6 +41,7 @@ struct VUT { int d_opt; int D_opt; int g_arg; + int k_arg; char *P_arg; char *q_arg; char *r_arg; diff --git a/include/vut_options.h b/include/vut_options.h index de3bab2..9f01181 100644 --- a/include/vut_options.h +++ b/include/vut_options.h @@ -51,6 +51,12 @@ "Print program usage and exit" \ ) +#define VUT_OPT_k \ + VOPT("k:", "[-k num]", "Limit transactions", \ + "Process this number of matching log transactions before" \ + " exiting." \ + ) + #define VUT_OPT_n \ VOPT("n:", "[-n name]", "Varnish instance name", \ "Specify the name of the varnishd instance to get logs" \ diff --git a/lib/libvarnishtools/vut.c b/lib/libvarnishtools/vut.c index 50a9f27..1635ffe 100644 --- a/lib/libvarnishtools/vut.c +++ b/lib/libvarnishtools/vut.c @@ -83,6 +83,24 @@ vut_sigusr1(int sig) VUT.sigusr1 = 1; } +static int __match_proto__(VSLQ_dispatch_f) +vut_dispatch(struct VSL_data *vsl, struct VSL_transaction * const trans[], + void *priv) +{ + int i; + + (void)priv; + if (VUT.k_arg == 0) + return (-1); /* End of file */ + AN(VUT.dispatch_f); + i = VUT.dispatch_f(vsl, trans, VUT.dispatch_priv); + if (VUT.k_arg > 0) + VUT.k_arg--; + if (i >= 0 && VUT.k_arg == 0) + return (-1); /* End of file */ + return (i); +} + void VUT_Error(int status, const char *fmt, ...) { @@ -114,6 +132,7 @@ int VUT_Arg(int opt, const char *arg) { int i; + char *p; switch (opt) { case 'd': @@ -127,6 +146,12 @@ VUT_Arg(int opt, const char *arg) case 'g': /* Grouping */ return (VUT_g_Arg(arg)); + case 'k': + /* Log transaction limit */ + VUT.k_arg = (int)strtol(arg, &p, 10); + if (*p != '\0' || VUT.k_arg <= 0) + VUT_Error(1, "-k: Invalid number '%s'", arg); + return (1); case 'n': /* Varnish instance */ if (VUT.vsm == NULL) @@ -178,6 +203,7 @@ VUT_Init(const char *progname) AZ(VUT.vsl); VUT.vsl = VSL_New(); AN(VUT.vsl); + VUT.k_arg = -1; } void @@ -281,8 +307,7 @@ VUT_Main(void) /* Flush and report any incomplete records */ VUT.sigusr1 = 0; if (VUT.vslq != NULL) - VSLQ_Flush(VUT.vslq, VUT.dispatch_f, - VUT.dispatch_priv); + VSLQ_Flush(VUT.vslq, vut_dispatch, NULL); } if (VUT.vslq == NULL) { @@ -307,7 +332,7 @@ VUT_Main(void) VUT_Error(0, "Log reacquired"); } - i = VSLQ_Dispatch(VUT.vslq, VUT.dispatch_f, VUT.dispatch_priv); + i = VSLQ_Dispatch(VUT.vslq, vut_dispatch, NULL); if (i == 1) /* Call again */ continue; @@ -330,7 +355,7 @@ VUT_Main(void) /* XXX: Make continuation optional */ - VSLQ_Flush(VUT.vslq, VUT.dispatch_f, VUT.dispatch_priv); + VSLQ_Flush(VUT.vslq, vut_dispatch, NULL); VSLQ_Delete(&VUT.vslq); AZ(VUT.vslq); From lkarsten at varnish-software.com Wed Oct 8 07:44:39 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Wed, 08 Oct 2014 09:44:39 +0200 Subject: [4.0] bfe7cd1 Prepare 4.0.2. Message-ID: commit bfe7cd198d07ab2197f7d178b08df0caa5e6b7a3 Author: Lasse Karstensen Date: Wed Oct 8 09:41:39 2014 +0200 Prepare 4.0.2. diff --git a/configure.ac b/configure.ac index 4fab5be..fe379b4 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.59) AC_COPYRIGHT([Copyright (c) 2006 Verdens Gang AS Copyright (c) 2006-2014 Varnish Software AS]) AC_REVISION([$Id$]) -AC_INIT([Varnish], [4.0.2-rc1], [varnish-dev at varnish-cache.org]) +AC_INIT([Varnish], [4.0.2], [varnish-dev at varnish-cache.org]) AC_CONFIG_SRCDIR(include/miniobj.h) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/doc/changes.rst b/doc/changes.rst index 4f0e27c..536f603 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -1,3 +1,11 @@ +============================================ +Changes from 4.0.2-rc1 to 4.0.2 (2014-10-08) +============================================ + +New since 4.0.2-rc1: + +- [varnishlog] -k argument is back. (exit after n records) +- [varnishadm] vcl.show is now listed in help. ============================================ Changes from 4.0.1 to 4.0.2-rc1 (2014-09-23) diff --git a/redhat/varnish.spec b/redhat/varnish.spec index 1a66a1e..33f418d 100644 --- a/redhat/varnish.spec +++ b/redhat/varnish.spec @@ -1,4 +1,4 @@ -%define v_rc rc1 +%define XXXv_rc rc1 %define vd_rc %{?v_rc:-%{?v_rc}} %define _use_internal_dependency_generator 0 %define __find_provides %{_builddir}/varnish-%{version}%{?v_rc:-%{?v_rc}}/redhat/find-provides From lkarsten at varnish-software.com Wed Oct 8 07:48:06 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Wed, 08 Oct 2014 09:48:06 +0200 Subject: [master] b57ba12 Add changes.rst updates from 4.0 branch. Message-ID: commit b57ba129a39d7c8220d26bf90b50f92069fb736d Author: Lasse Karstensen Date: Wed Oct 8 09:47:36 2014 +0200 Add changes.rst updates from 4.0 branch. diff --git a/doc/changes.rst b/doc/changes.rst index d66e7a0..536f603 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -1,3 +1,106 @@ +============================================ +Changes from 4.0.2-rc1 to 4.0.2 (2014-10-08) +============================================ + +New since 4.0.2-rc1: + +- [varnishlog] -k argument is back. (exit after n records) +- [varnishadm] vcl.show is now listed in help. + +============================================ +Changes from 4.0.1 to 4.0.2-rc1 (2014-09-23) +============================================ + +New since 4.0.1: + +- [libvmod-std] New function strstr() for matching substrings. +- server.(hostname|identity) is now available in all VCL functions. +- VCL variable type BYTES was added. +- `workspace_client` default is now 9k. +- [varnishstat] Update interval can now be subsecond. +- Document that reloading VCL does not reload a VMOD. +- Guru meditation page is now valid HTML5. +- [varnishstat] hitrate calculation is back. +- New parameter `group_cc` adds a GID to the grouplist of + VCL compiler sandbox. +- Parameter shm_reclen is now an alias for vsl_reclen. +- Workspace overflows are now handled with a 500 client response. +- VCL variable type added: HTTP, representing a HTTP header set. +- It is now possible to return(synth) from vcl_deliver. +- [varnishadm] vcl.show now has a -v option that output the + complete set of VCL and included VCL files. +- RHEL7 packaging (systemd) was added. +- [libvmod-std] querysort() fixed parameter limit has been lifted. +- Fix small memory leak in ESI parser. +- Fix unreported race/assert in V1D_Deliver(). + +Bugs fixed +---------- + +* 1553_ - Fully reset workspace (incl. Vary state) before reusing it. +* 1551_ - Handle workspace exhaustion during purge. +* 1591_ - Group entries correctly in varnishtop. +* 1592_ - Bail out on workspace exhaustion in VRT_IP_string. +* 1538_ - Relax VMOD ABI check for release branches. +* 1584_ - Don't log garbage/non-HTTP requests. [varnishncsa] +* 1407_ - Don't rename VSM file until child has started. +* 1466_ - Don't leak request structs on restart after waitinglist. +* 1580_ - Output warning if started without -b and -f. [varnishd] +* 1583_ - Abort on fatal sandbox errors on Solaris. (Related: 1572_) +* 1585_ - Handle fatal sandbox errors. +* 1572_ - Exit codes have been cleaned up. +* 1569_ - Order of symbols should not influence compilation result. +* 1579_ - Clean up type inference in VCL. +* 1578_ - Don't count Age twice when computing new object TTL. +* 1574_ - std.syslog() logged empty strings. +* 1555_ - autoconf editline/readline build issue. +* 1568_ - Skip NULL arguments when hashing. +* 1567_ - Compile on systems without SO_SNDTIMEO/SO_RCVTIMEO. +* 1512_ - Changes to bereq are lost between v_b_r and v_b_f. +* 1563_ - Increase varnishtest read timeout. +* 1562_ - Fail correctly when rereading a failed client request body. +* 1521_ - VCL compilation fails on OSX x86_64. +* 1547_ - Panic when increasing shm_reclen. +* 1503_ - Document return(retry). +* 1581_ - Don't log duplicate Begin records to shmlog. +* 1588_ - Correct timestamps on pipelined requests. +* 1575_ - Use all director backends when looking for a healthy one. +* 1577_ - Read the full request body if shunted to synth. +* 1532_ - Use correct VCL representation of reals. +* 1531_ - Work around libedit bug in varnishadm. + +.. _1553: https://www.varnish-cache.org/trac/ticket/1553 +.. _1551: https://www.varnish-cache.org/trac/ticket/1551 +.. _1591: https://www.varnish-cache.org/trac/ticket/1591 +.. _1592: https://www.varnish-cache.org/trac/ticket/1592 +.. _1538: https://www.varnish-cache.org/trac/ticket/1538 +.. _1584: https://www.varnish-cache.org/trac/ticket/1584 +.. _1407: https://www.varnish-cache.org/trac/ticket/1407 +.. _1466: https://www.varnish-cache.org/trac/ticket/1466 +.. _1580: https://www.varnish-cache.org/trac/ticket/1580 +.. _1583: https://www.varnish-cache.org/trac/ticket/1583 +.. _1585: https://www.varnish-cache.org/trac/ticket/1585 +.. _1572: https://www.varnish-cache.org/trac/ticket/1572 +.. _1569: https://www.varnish-cache.org/trac/ticket/1569 +.. _1579: https://www.varnish-cache.org/trac/ticket/1579 +.. _1578: https://www.varnish-cache.org/trac/ticket/1578 +.. _1574: https://www.varnish-cache.org/trac/ticket/1574 +.. _1555: https://www.varnish-cache.org/trac/ticket/1555 +.. _1568: https://www.varnish-cache.org/trac/ticket/1568 +.. _1567: https://www.varnish-cache.org/trac/ticket/1567 +.. _1512: https://www.varnish-cache.org/trac/ticket/1512 +.. _1563: https://www.varnish-cache.org/trac/ticket/1563 +.. _1562: https://www.varnish-cache.org/trac/ticket/1562 +.. _1521: https://www.varnish-cache.org/trac/ticket/1521 +.. _1547: https://www.varnish-cache.org/trac/ticket/1547 +.. _1503: https://www.varnish-cache.org/trac/ticket/1503 +.. _1581: https://www.varnish-cache.org/trac/ticket/1581 +.. _1588: https://www.varnish-cache.org/trac/ticket/1588 +.. _1575: https://www.varnish-cache.org/trac/ticket/1575 +.. _1577: https://www.varnish-cache.org/trac/ticket/1577 +.. _1532: https://www.varnish-cache.org/trac/ticket/1532 +.. _1531: https://www.varnish-cache.org/trac/ticket/1531 + ======================================== Changes from 4.0.0 to 4.0.1 (2014-06-24) From phk at FreeBSD.org Wed Oct 8 09:17:20 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 08 Oct 2014 11:17:20 +0200 Subject: [master] 3fedf4e Old but tiny patch I found in my mailbox one late summer morning Message-ID: commit 3fedf4ef1a36ae77db2419c083b67f7396332fec Author: Poul-Henning Kamp Date: Wed Oct 8 07:52:34 2014 +0000 Old but tiny patch I found in my mailbox one late summer morning Submitted by: Martin Clausen diff --git a/include/vend.h b/include/vend.h index d27b533..7bd5aaa 100644 --- a/include/vend.h +++ b/include/vend.h @@ -30,6 +30,7 @@ */ #ifndef VEND_H_INCLUDED +#define VEND_H_INCLUDED /* Alignment-agnostic encode/decode bytestream to/from little/big endian. */ From phk at FreeBSD.org Wed Oct 8 09:17:20 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 08 Oct 2014 11:17:20 +0200 Subject: [master] 4e96da0 minor polish Message-ID: commit 4e96da03217d445e33fbf8941a0bdbe8752f2f2c Author: Poul-Henning Kamp Date: Wed Oct 8 09:16:52 2014 +0000 minor polish diff --git a/lib/libvmod_std/vmod.vcc b/lib/libvmod_std/vmod.vcc index 61c539f..6882ef5 100644 --- a/lib/libvmod_std/vmod.vcc +++ b/lib/libvmod_std/vmod.vcc @@ -201,11 +201,15 @@ Example $Function VOID cache_req_body(BYTES) Description - Cache the req.body if it is smaller than the given size + Cache the req.body if it is smaller than the given size Example - std.cache_req_body(1KB); + std.cache_req_body(1KB); - This will cache the req.body if its size is smaller than 1KB. + This will cache the req.body if its size is smaller than 1KB. + + Caching the req.body makes it possible to retry pass + operations (POST, PUT). + $Function STRING strstr(STRING, STRING) From lkarsten at varnish-software.com Wed Oct 8 15:28:02 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Wed, 08 Oct 2014 17:28:02 +0200 Subject: [master] 7239fe3 Document how comments work in VCL. Message-ID: commit 7239fe3eaa309a5b3742b92ebadaf9d13944f31c Author: Lasse Karstensen Date: Wed Oct 8 17:21:27 2014 +0200 Document how comments work in VCL. This was mentioned in the user guide, but not in the man page itself. Pointed out by: Brett Fitzgerald diff --git a/doc/sphinx/reference/vcl.rst b/doc/sphinx/reference/vcl.rst index 90ac019..a621e4f 100644 --- a/doc/sphinx/reference/vcl.rst +++ b/doc/sphinx/reference/vcl.rst @@ -166,6 +166,21 @@ Example:: std.log("foo"); } +Comments +-------- + +Single lines of VCL can be commented out using // or #. Multi-line blocks can +be commented out with \/\* block \/\*. + +Example:: + + sub vcl_recv { + // Single line of out-commented VCL. + # Another way of commenting out a single line. + /* + Multi-line block of commented-out VCL. + */ + } Backend definition From fgsch at lodoss.net Wed Oct 8 16:11:02 2014 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Wed, 08 Oct 2014 18:11:02 +0200 Subject: [master] b4da689 Document -v param in vcl.show Message-ID: commit b4da6893d263b26f8c4f4308673bf0e4d67055cb Author: Federico G. Schwindt Date: Wed Oct 8 17:10:35 2014 +0100 Document -v param in vcl.show diff --git a/include/vcli.h b/include/vcli.h index f6b75da..4a18c82 100644 --- a/include/vcli.h +++ b/include/vcli.h @@ -97,7 +97,7 @@ #define CLI_VCL_SHOW \ "vcl.show", \ - "vcl.show ", \ + "vcl.show [-v] ", \ "\tDisplay the source code for the specified configuration.", \ 1, 2 From lkarsten at varnish-software.com Thu Oct 9 08:39:11 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Thu, 09 Oct 2014 10:39:11 +0200 Subject: [4.0] 7b70a83 Add forgotten bugfix to list. Message-ID: commit 7b70a83fb38f400dea1201d1e572ef71f98cbbab Author: Lasse Karstensen Date: Thu Oct 9 10:38:07 2014 +0200 Add forgotten bugfix to list. Noted by: Matt Robenolt diff --git a/doc/changes.rst b/doc/changes.rst index 536f603..846f975 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -58,6 +58,7 @@ Bugs fixed * 1567_ - Compile on systems without SO_SNDTIMEO/SO_RCVTIMEO. * 1512_ - Changes to bereq are lost between v_b_r and v_b_f. * 1563_ - Increase varnishtest read timeout. +* 1561_ - Never call a VDP with zero length unless done. * 1562_ - Fail correctly when rereading a failed client request body. * 1521_ - VCL compilation fails on OSX x86_64. * 1547_ - Panic when increasing shm_reclen. @@ -90,6 +91,7 @@ Bugs fixed .. _1567: https://www.varnish-cache.org/trac/ticket/1567 .. _1512: https://www.varnish-cache.org/trac/ticket/1512 .. _1563: https://www.varnish-cache.org/trac/ticket/1563 +.. _1561: https://www.varnish-cache.org/trac/ticket/1561 .. _1562: https://www.varnish-cache.org/trac/ticket/1562 .. _1521: https://www.varnish-cache.org/trac/ticket/1521 .. _1547: https://www.varnish-cache.org/trac/ticket/1547 From lkarsten at varnish-software.com Thu Oct 9 08:40:03 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Thu, 09 Oct 2014 10:40:03 +0200 Subject: [master] a813eb3 Add forgotten bugfix to list. Message-ID: commit a813eb39d33fbd87fdcd9269a16b9823b20f9087 Author: Lasse Karstensen Date: Thu Oct 9 10:38:07 2014 +0200 Add forgotten bugfix to list. Noted by: Matt Robenolt diff --git a/doc/changes.rst b/doc/changes.rst index 536f603..846f975 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -58,6 +58,7 @@ Bugs fixed * 1567_ - Compile on systems without SO_SNDTIMEO/SO_RCVTIMEO. * 1512_ - Changes to bereq are lost between v_b_r and v_b_f. * 1563_ - Increase varnishtest read timeout. +* 1561_ - Never call a VDP with zero length unless done. * 1562_ - Fail correctly when rereading a failed client request body. * 1521_ - VCL compilation fails on OSX x86_64. * 1547_ - Panic when increasing shm_reclen. @@ -90,6 +91,7 @@ Bugs fixed .. _1567: https://www.varnish-cache.org/trac/ticket/1567 .. _1512: https://www.varnish-cache.org/trac/ticket/1512 .. _1563: https://www.varnish-cache.org/trac/ticket/1563 +.. _1561: https://www.varnish-cache.org/trac/ticket/1561 .. _1562: https://www.varnish-cache.org/trac/ticket/1562 .. _1521: https://www.varnish-cache.org/trac/ticket/1521 .. _1547: https://www.varnish-cache.org/trac/ticket/1547 From nils.goroll at uplex.de Thu Oct 9 10:06:51 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 09 Oct 2014 12:06:51 +0200 Subject: [master] b3960b3 don't need ps2pdf to generate graphviz pdf output Message-ID: commit b3960b37a31c790f67b3d84a24de872211d8e89f Author: Nils Goroll Date: Thu Oct 9 12:05:43 2014 +0200 don't need ps2pdf to generate graphviz pdf output dot -Tpdf seems to work fine diff --git a/configure.ac b/configure.ac index 0691424..f1b5c73 100644 --- a/configure.ac +++ b/configure.ac @@ -81,17 +81,6 @@ AC_ARG_WITH([dot], fi]) AM_CONDITIONAL(HAVE_DOT,[test "x$DOT" != "xno"]) -AC_ARG_WITH([ps2pdf], - AS_HELP_STRING([--with-ps2pdf=PATH], - [Location of the ps2pdf tool from ghostscript (auto)]), - [PS2PDF="$withval"], - [AC_CHECK_PROGS(PS2PDF, [ps2pdf], [no]) - if test "x$PS2PDF" = "xno"; then - AC_MSG_WARN( - [ps2pdf not found - can't generate graphviz output for documentation.]) - fi]) -AM_CONDITIONAL(HAVE_PS2PDF,[test "x$PS2PDF" != "xno"]) - # Checks for libraries. save_LIBS="${LIBS}" LIBS="" diff --git a/doc/graphviz/Makefile.am b/doc/graphviz/Makefile.am index 51e2b4c..6280eab 100644 --- a/doc/graphviz/Makefile.am +++ b/doc/graphviz/Makefile.am @@ -6,7 +6,6 @@ SIZE = 8.4,11.7 if HAVE_DOT -if HAVE_PS2PDF PDFS = \ cache_http1_fsm.pdf \ @@ -16,10 +15,6 @@ PDFS = \ pdf: $(PDFS) endif -endif - -%.ps: %.dot - @DOT@ -Tps -Gsize=$(SIZE) $< >$@ -%.pdf: %.ps - @PS2PDF@ $< +%.pdf: %.dot + @DOT@ -Tpdf -Gsize=$(SIZE) $< >$@ From fgsch at lodoss.net Thu Oct 9 12:02:06 2014 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 09 Oct 2014 14:02:06 +0200 Subject: [master] cf36b0a Spelling Message-ID: commit cf36b0ad5354b6e44b67e48d329ed89e256c73ee Author: Federico G. Schwindt Date: Thu Oct 9 13:01:55 2014 +0100 Spelling diff --git a/include/tbl/vsc_f_main.h b/include/tbl/vsc_f_main.h index 72c2568..3a2b59c 100644 --- a/include/tbl/vsc_f_main.h +++ b/include/tbl/vsc_f_main.h @@ -38,7 +38,7 @@ * 'c' - Counter, never decreases. * 'g' - Gauge, goes up and down * 'i' - Integer (deprecated, use 'g') - * e - Explantion: Short explanation of field (for screen use) + * e - Explanation: Short explanation of field (for screen use) * d - Description: Long explanation of field (for doc use) * * Please describe Gauge variables as "Number of..." to indicate that @@ -73,7 +73,7 @@ VSC_F(uptime, uint64_t, 0, 'a', info, VSC_F(sess_conn, uint64_t, 1, 'c', info, "Sessions accepted", - "Count of sessions succesfully accepted" + "Count of sessions successfully accepted" ) VSC_F(sess_drop, uint64_t, 1, 'c', info, @@ -85,7 +85,7 @@ VSC_F(sess_fail, uint64_t, 1, 'c', info, "Session accept failures", "Count of failures to accept TCP connection." " Either the client changed its mind, or the kernel ran out of" - " some resource like filedescriptors." + " some resource like file descriptors." ) VSC_F(sess_pipe_overflow, uint64_t, 1, 'c', info, @@ -108,7 +108,7 @@ VSC_F(client_req_411, uint64_t, 1, 'a', info, VSC_F(client_req_413, uint64_t, 1, 'a', info, "Client requests received, subject to 413 errors", - "413 means that HTTP headers execeeded length or count limits." + "413 means that HTTP headers exceeded length or count limits." ) VSC_F(client_req_417, uint64_t, 1, 'a', info, @@ -389,7 +389,7 @@ VSC_F(s_resp_hdrbytes, uint64_t, 1, 'a', info, "Total response header bytes transmitted" ) VSC_F(s_resp_bodybytes, uint64_t, 1, 'a', info, - "Reponse body bytes", + "Response body bytes", "Total response body bytes transmitted" ) VSC_F(s_pipe_hdrbytes, uint64_t, 0, 'a', info, From nils.goroll at uplex.de Thu Oct 9 15:00:18 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 09 Oct 2014 17:00:18 +0200 Subject: [master] cbb9269 document bereq.uncacheable and beresp.uncacheable Message-ID: commit cbb92690ff862590e89cbd1a6f73fddd8c0ac2c7 Author: Nils Goroll Date: Thu Oct 9 17:00:10 2014 +0200 document bereq.uncacheable and beresp.uncacheable diff --git a/lib/libvcc/generate.py b/lib/libvcc/generate.py index c82ae0e..98d54ce 100755 --- a/lib/libvcc/generate.py +++ b/lib/libvcc/generate.py @@ -361,6 +361,16 @@ sp_variables = [ 'BOOL', ( 'backend', ), ( 'backend', ), """ + Indicates whether the object requested from the backend is + going to be uncacheable - either because the request was an + explicit pass from the client side or a hit on an uncacheable + ("hit for pass") object. + + Setting this variable in vcl_backend_fetch makes the object + uncacheable. + + Clearing the variable has no effect and will log the warning + "Ignoring attempt to reset bereq.uncacheable". """ ), ('bereq.connect_timeout', @@ -462,6 +472,13 @@ sp_variables = [ 'BOOL', ( 'backend_response', 'backend_error'), ( 'backend_response', 'backend_error'), """ + Inherited from bereq.uncacheable, see there. + + Setting this variable makes the object uncacheable, which may + get stored as a hit-for-pass object in the cache. + + Clearing the variable has no effect and will log the warning + "Ignoring attempt to reset beresp.uncacheable". """ ), ('beresp.ttl', From nils.goroll at uplex.de Thu Oct 9 15:07:51 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 09 Oct 2014 17:07:51 +0200 Subject: [master] 92c2a3f document keep Message-ID: commit 92c2a3f2ee023aad4d6f18fb5d1c1cde5ef7b624 Author: Nils Goroll Date: Thu Oct 9 17:07:08 2014 +0200 document keep diff --git a/lib/libvcc/generate.py b/lib/libvcc/generate.py index 98d54ce..e82d610 100755 --- a/lib/libvcc/generate.py +++ b/lib/libvcc/generate.py @@ -506,6 +506,13 @@ sp_variables = [ 'DURATION', ( 'backend_response', 'backend_error'), ( 'backend_response', 'backend_error'), """ + Set to a period to enable conditional backend requests. + + The keep time is cache lifetime in addition to the ttl. + + Objects with ttl expired but with keep time left may be used + to issue conditional (If-Modified-Since / If-None-Match) + requests to the backend to refresh them. """ ), ('beresp.backend', From nils.goroll at uplex.de Thu Oct 9 15:24:57 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 09 Oct 2014 17:24:57 +0200 Subject: [master] e591352 document some more object variables Message-ID: commit e5913523e43200d6d4c11b52eebd61e9e103c2e4 Author: Nils Goroll Date: Thu Oct 9 17:24:54 2014 +0200 document some more object variables diff --git a/lib/libvcc/generate.py b/lib/libvcc/generate.py index e82d610..b92705b 100755 --- a/lib/libvcc/generate.py +++ b/lib/libvcc/generate.py @@ -604,19 +604,21 @@ sp_variables = [ 'DURATION', ( 'hit', ), ( ), """ - The object's grace period in seconds. + The object's remaining grace period in seconds. """ ), ('obj.keep', 'DURATION', ( 'hit', ), ( ), """ + The object's remaining keep period in seconds. """ ), ('obj.uncacheable', 'BOOL', ( 'hit', ), ( ), """ + Whether the object is uncacheable (aka hit-for-pass) """ ), ('resp', From nils.goroll at uplex.de Thu Oct 9 15:28:32 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 09 Oct 2014 17:28:32 +0200 Subject: [master] 90b8ec3 make bereq.uncacheable read-only outside backend_fetch Message-ID: commit 90b8ec32602851367a86752ffa997809a07f8d10 Author: Nils Goroll Date: Thu Oct 9 17:28:20 2014 +0200 make bereq.uncacheable read-only outside backend_fetch Writing to bereq.uncacheable in backend_response and backend_error would only make sense in the context of a retry. In most real world cases, writing to be*resp*.uncacheable would be intended in backend_response and backend_error. diff --git a/lib/libvcc/generate.py b/lib/libvcc/generate.py index b92705b..ea07a32 100755 --- a/lib/libvcc/generate.py +++ b/lib/libvcc/generate.py @@ -360,7 +360,7 @@ sp_variables = [ ('bereq.uncacheable', 'BOOL', ( 'backend', ), - ( 'backend', ), """ + ( 'backend_fetch', ), """ Indicates whether the object requested from the backend is going to be uncacheable - either because the request was an explicit pass from the client side or a hit on an uncacheable From lkarsten at varnish-software.com Thu Oct 9 16:01:55 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Thu, 09 Oct 2014 18:01:55 +0200 Subject: [master] 1df739c Varnish version in master should be trunk. Message-ID: commit 1df739c006c129748f5d1a3b31467fbda20c32ea Author: Lasse Karstensen Date: Thu Oct 9 17:59:09 2014 +0200 Varnish version in master should be trunk. Try to avoid confusing everyone, since "4.0.1" (really trunk) has fresher data than 4.0.2 (proper 4.0). Mostly important for the sphinx builds put online. diff --git a/configure.ac b/configure.ac index f1b5c73..e221fa7 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.59) AC_COPYRIGHT([Copyright (c) 2006 Verdens Gang AS Copyright (c) 2006-2014 Varnish Software AS]) AC_REVISION([$Id$]) -AC_INIT([Varnish], [4.0.1], [varnish-dev at varnish-cache.org]) +AC_INIT([Varnish], [trunk], [varnish-dev at varnish-cache.org]) AC_CONFIG_SRCDIR(include/miniobj.h) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) From fgsch at lodoss.net Thu Oct 9 18:22:18 2014 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 09 Oct 2014 20:22:18 +0200 Subject: [master] c1791d8 Include the Varnish version on panic Message-ID: commit c1791d8b085502cf551794bd55cd8ddde15723cb Author: Federico G. Schwindt Date: Thu Oct 9 19:21:56 2014 +0100 Include the Varnish version on panic diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index ca169d9..ab95e03 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -510,6 +510,7 @@ pan_ic(const char *func, const char *file, int line, const char *cond, if (q != NULL) VSB_printf(pan_vsp, "thread = (%s)\n", q); + VSB_printf(pan_vsp, "version = %s\n", VCS_version); VSB_printf(pan_vsp, "ident = %s,%s\n", VSB_data(vident) + 1, WAIT_GetName()); From fgsch at lodoss.net Thu Oct 9 21:44:01 2014 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 09 Oct 2014 23:44:01 +0200 Subject: [master] 4e7961a vcl_pass might return fetch, not pass Message-ID: commit 4e7961ac9ae3e3c0bce6e341f40fc68286beb8ea Author: Federico G. Schwindt Date: Thu Oct 9 22:42:45 2014 +0100 vcl_pass might return fetch, not pass Spotted by: coredump diff --git a/doc/sphinx/users-guide/vcl-built-in-subs.rst b/doc/sphinx/users-guide/vcl-built-in-subs.rst index 9c9c690..276265c 100644 --- a/doc/sphinx/users-guide/vcl-built-in-subs.rst +++ b/doc/sphinx/users-guide/vcl-built-in-subs.rst @@ -73,7 +73,7 @@ of the following keywords: synth(status code, reason) Return the specified status code to the client and abandon the request. - pass + fetch Proceed with pass mode. restart From fgsch at lodoss.net Fri Oct 10 00:11:57 2014 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Fri, 10 Oct 2014 02:11:57 +0200 Subject: [master] 5d61fb2 Skip the argument names when writing the prototypes Message-ID: commit 5d61fb2b28c270bf3184273443d7537f4e4ed2a3 Author: Federico G. Schwindt Date: Fri Oct 10 00:13:26 2014 +0100 Skip the argument names when writing the prototypes diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py index 14d9c95..99caca4 100755 --- a/lib/libvcc/vmodtool.py +++ b/lib/libvcc/vmodtool.py @@ -368,8 +368,6 @@ class Func(object): for a in self.al: s += p + ctypes[a.typ] p = ", " - if a.nam != None: - s += " " + a.nam s += ");" return s From fgsch at lodoss.net Fri Oct 10 00:11:57 2014 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Fri, 10 Oct 2014 02:11:57 +0200 Subject: [master] 9d296da Polish Message-ID: commit 9d296da802a2c69a2795f665dcd853b706fb22e5 Author: Federico G. Schwindt Date: Fri Oct 10 01:01:27 2014 +0100 Polish Improve consistency, add argument names and rewording. diff --git a/lib/libvmod_std/vmod.vcc b/lib/libvmod_std/vmod.vcc index 6882ef5..5dae97b 100644 --- a/lib/libvmod_std/vmod.vcc +++ b/lib/libvmod_std/vmod.vcc @@ -41,25 +41,25 @@ which all have the form:: These functions attempt to convert STRING to the TYPE, and if that fails, they return the second argument, which must have the given TYPE. -$Function STRING toupper(STRING_LIST) +$Function STRING toupper(STRING_LIST s) Description - Converts the string *s* to upper case. + Converts the string *s* to uppercase. Example set beresp.http.x-scream = std.toupper("yes!"); -$Function STRING tolower(STRING_LIST) +$Function STRING tolower(STRING_LIST s) Description - Converts the string *s* to lower case. + Converts the string *s* to lowercase. Example set beresp.http.x-nice = std.tolower("VerY"); -$Function VOID set_ip_tos(INT) +$Function VOID set_ip_tos(INT tos) Description - Sets the Type-of-Service flag for the current session. Please - note that the TOS flag is not removed by the end of the + Sets the IP type-of-service (TOS) field for the current session to *tos*. + Please note that the TOS field is not removed by the end of the request so probably want to set it on every request should you utilize it. Example @@ -67,24 +67,24 @@ Example | std.set_ip_tos(0x0); | } -$Function REAL random(REAL, REAL) +$Function REAL random(REAL lo, REAL hi) Description - Returns a random REAL number between *a* and *b*. + Returns a random real number between *lo* and *hi*. Example set beresp.http.x-random-number = std.random(1, 100); -$Function VOID log(STRING_LIST) +$Function VOID log(STRING_LIST s) Description - Logs *string* to the shared memory log, using VSL tag *SLT_VCL_Log*. + Logs the string *s* to the shared memory log, using VSL tag *SLT_VCL_Log*. Example std.log("Something fishy is going on with the vhost " + req.host); -$Function VOID syslog(INT, STRING_LIST) +$Function VOID syslog(INT priority, STRING_LIST s) Description - Logs *string* to syslog marked with *priority*. See your + Logs the string *s* to syslog marked with *priority*. See your system's syslog.h file for the legal values of *priority*. Example std.syslog(8 + 1, "Something is wrong"); @@ -99,132 +99,133 @@ Description Example set beresp.http.x-served-by = std.fileread("/etc/hostname"); -$Function VOID collect(HEADER) +$Function VOID collect(HEADER hdr) Description - Collapses the header, joining the headers into one. + Collapses the header *hdr*, joining them into one. Example std.collect(req.http.cookie); + This will collapse several Cookie: headers into one, long cookie header. -$Function DURATION duration(STRING, DURATION) +$Function DURATION duration(STRING s, DURATION fallback) Description Converts the string *s* to seconds. *s* must be quantified with ms (milliseconds), s (seconds), m (minutes), h (hours), - d (days), w (weeks) or y (years) units. If *s* fails to parse, + d (days), w (weeks) or y (years) units. If conversion fails, *fallback* will be returned. Example set beresp.ttl = std.duration("1w", 3600s); -$Function INT integer(STRING, INT) +$Function INT integer(STRING s, INT fallback) Description - Converts the string *s* to an integer. If *s* fails to parse, + Converts the string *s* to an integer. If conversion fails, *fallback* will be returned. Example - if (std.integer(beresp.http.x-foo, 0) > 5) { ... } + | if (std.integer(beresp.http.x-foo, 0) > 5) { + | ... + | } -$Function IP ip(STRING, IP) +$Function IP ip(STRING s, IP fallback) Description - Converts string *s* to the first IP number returned by + Converts the string *s* to the first IP number returned by the system library function getaddrinfo(3). If conversion fails, *fallback* will be returned. Example - if (std.ip(req.http.X-forwarded-for, "0.0.0.0") ~ my_acl) { ... } + | if (std.ip(req.http.X-forwarded-for, "0.0.0.0") ~ my_acl) { + | ... + | } -$Function REAL real(STRING, REAL) +$Function REAL real(STRING s, REAL fallback) Description - Converts the string *s* to a real. If *s* fails to parse, + Converts the string *s* to a real. If conversion fails, *fallback* will be returned. Example set req.http.x-real = std.real(req.http.x-foo, 0.0); -$Function TIME real2time(REAL) +$Function TIME real2time(REAL r) Description Converts the real *r* to a time. Example set req.http.x-time = std.real2time(1140618699.00); -$Function INT time2integer(TIME) +$Function INT time2integer(TIME t) Description Converts the time *t* to a integer. Example set req.http.x-int = std.time2integer(now); -$Function REAL time2real(TIME) +$Function REAL time2real(TIME t) Description Converts the time *t* to a real. Example set req.http.x-real = std.time2real(now); -$Function BOOL healthy(BACKEND) +$Function BOOL healthy(BACKEND be) Description - Returns true if the backend is healthy. + Returns `true` if the backend *be* is healthy. -$Function INT port(IP) +$Function INT port(IP ip) Description - Returns the port number of an IP address. + Returns the port number of the IP address *ip*. -$Function VOID rollback(HTTP) +$Function VOID rollback(HTTP h) Description - Restore *h* HTTP headers to their original state. + Restores the *h* HTTP headers to their original state. Example std.rollback(bereq); -$Function VOID timestamp(STRING) +$Function VOID timestamp(STRING s) Description - Introduces a timestamp in the log with the current time. Uses - the argument as the timespamp label. This is useful to time - the execution of lengthy VCL procedures, and makes the - timestamps inserted automatically by Varnish more accurate. + Introduces a timestamp in the log with the current time, using + the string *s* as the label. This is useful to time the execution + of lengthy VCL procedures, and makes the timestamps inserted + automatically by Varnish more accurate. Example std.timestamp("curl-request"); $Function STRING querysort(STRING) Description - Sorts the querystring for cache normalization purposes. + Sorts the query string for cache normalization purposes. Example set req.url = std.querysort(req.url); -$Function VOID cache_req_body(BYTES) +$Function VOID cache_req_body(BYTES size) Description - Cache the req.body if it is smaller than the given size + Cache the req.body if it is smaller than *size*. + + Caching the req.body makes it possible to retry pass + operations (POST, PUT). Example std.cache_req_body(1KB); This will cache the req.body if its size is smaller than 1KB. - Caching the req.body makes it possible to retry pass - operations (POST, PUT). - - -$Function STRING strstr(STRING, STRING) +$Function STRING strstr(STRING s1, STRING s2) Description - Returns the substring if the second string is a substring of the first - string. Note that the comparison is case sensitive. You can - use the tolower function on both strings if you want case - insensitivity. - - If there is no match a NULL pointer is returned which would - evaluate to false in an if-test. + Returns the first occurrence of the string *s2* in the string + *s1*, or an empty string if not found. + Note that the comparison is case sensitive. Example - if (std.strstr(req.url, req.http.x-restrict)) - + | if (std.strstr(req.url, req.http.x-restrict)) { + | ... + | } SEE ALSO From fgsch at lodoss.net Fri Oct 10 00:11:57 2014 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Fri, 10 Oct 2014 02:11:57 +0200 Subject: [master] d5e7a11 Cosmetic Message-ID: commit d5e7a116c690d9bd6a8a9fd4ed0dc8c738bcfe74 Author: Federico G. Schwindt Date: Fri Oct 10 01:09:54 2014 +0100 Cosmetic diff --git a/lib/libvmod_std/vmod_std.c b/lib/libvmod_std/vmod_std.c index 4bba4b7..792f04b 100644 --- a/lib/libvmod_std/vmod_std.c +++ b/lib/libvmod_std/vmod_std.c @@ -235,18 +235,19 @@ VCL_VOID __match_proto__(td_std_cache_req_body) vmod_cache_req_body(VRT_CTX, VCL_BYTES size) { int result; + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); result = VRT_CacheReqBody(ctx, size); - VSLb(ctx->vsl, SLT_Debug,"VRT_CacheReqBody(%zu): %d", (size_t)size, result); + VSLb(ctx->vsl, SLT_Debug,"VRT_CacheReqBody(%zu): %d", + (size_t)size, result); } VCL_STRING __match_proto__(td_std_strstr) -vmod_strstr(VRT_CTX, VCL_STRING mstr, VCL_STRING msubstr) +vmod_strstr(VRT_CTX, VCL_STRING s1, VCL_STRING s2) { CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); - - if ((mstr == NULL) || (msubstr == NULL)) + if (s1 == NULL || s2 == NULL) return (NULL); - return(strstr(mstr, msubstr)); + return (strstr(s1, s2)); } From perbu at varnish-software.com Fri Oct 10 07:02:55 2014 From: perbu at varnish-software.com (Per Buer) Date: Fri, 10 Oct 2014 09:02:55 +0200 Subject: [master] 262aa04 document vcl_synth Message-ID: commit 262aa042fded0d0e46fac03032c9850116f4b702 Author: Per Buer Date: Fri Oct 10 09:02:53 2014 +0200 document vcl_synth diff --git a/doc/sphinx/users-guide/vcl-built-in-subs.rst b/doc/sphinx/users-guide/vcl-built-in-subs.rst index 276265c..48b19c9 100644 --- a/doc/sphinx/users-guide/vcl-built-in-subs.rst +++ b/doc/sphinx/users-guide/vcl-built-in-subs.rst @@ -229,6 +229,23 @@ with one of the following keywords: the number of retries is higher than *max_retries* Varnish emits a guru meditation error. +vcl_synth +~~~~~~~~~ + +Called to deliver a synthetic object. A synthetic object is generated +in VCL, not fetched from the backend. It is typically contructed using +the synthetic() function. + + +The subroutine may terminate with calling ``return()`` with one of the +following keywords: + + deliver + Deliver the object. If the object has a positive TTL then the + object is also stored in cache. + + restart + Restart processing the object. vcl_init ~~~~~~~~ From phk at FreeBSD.org Mon Oct 13 07:56:47 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 13 Oct 2014 09:56:47 +0200 Subject: [master] 6c4cbc4 typo Message-ID: commit 6c4cbc4c602f8c6f2163d0bcba911638ef3361ca Author: Poul-Henning Kamp Date: Mon Oct 13 07:56:31 2014 +0000 typo diff --git a/doc/sphinx/phk/dough.rst b/doc/sphinx/phk/dough.rst index 3e71fe6..65b53f8 100644 --- a/doc/sphinx/phk/dough.rst +++ b/doc/sphinx/phk/dough.rst @@ -42,7 +42,7 @@ But in 2004 crowd-funding was not yet "in", and I had to figure out how to do it myself. My parents brought me up to think that finances is a private matter -but I concluded that the only way you could ask strangers to trow +but I concluded that the only way you could ask strangers to throw money at you, would be to run an open book, where they could see what happened to them, so I did open books. From phk at FreeBSD.org Mon Oct 13 08:42:30 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 13 Oct 2014 10:42:30 +0200 Subject: [master] 4dad6c4 Make WS_Alloc() return a void* like any sane memory allocator should Message-ID: commit 4dad6c4163abae013c980da01bb04a881e8346b1 Author: Poul-Henning Kamp Date: Mon Oct 13 08:42:08 2014 +0000 Make WS_Alloc() return a void* like any sane memory allocator should diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 254c22e..839516d 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -1146,7 +1146,7 @@ void WS_Release(struct ws *ws, unsigned bytes); void WS_ReleaseP(struct ws *ws, char *ptr); void WS_Assert(const struct ws *ws); void WS_Reset(struct ws *ws, char *p); -char *WS_Alloc(struct ws *ws, unsigned bytes); +void *WS_Alloc(struct ws *ws, unsigned bytes); void *WS_Copy(struct ws *ws, const void *str, int len); char *WS_Snapshot(struct ws *ws); int WS_Overflowed(const struct ws *ws); diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index eca1eee..030ccbf 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -522,7 +522,7 @@ ESI_DeliverChild(struct req *req) */ memset(tailbuf, 0xdd, sizeof tailbuf); - dbits = (void*)WS_Alloc(req->ws, 8); + dbits = WS_Alloc(req->ws, 8); AN(dbits); ll = 0; oi = ObjIterBegin(req->wrk, req->objcore); diff --git a/bin/varnishd/cache/cache_esi_parse.c b/bin/varnishd/cache/cache_esi_parse.c index ab2a4f5..1956a18 100644 --- a/bin/varnishd/cache/cache_esi_parse.c +++ b/bin/varnishd/cache/cache_esi_parse.c @@ -1045,7 +1045,7 @@ VEP_Init(struct vfp_ctx *vc, const struct http *req, vep_callback_t *cb, CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); CHECK_OBJ_NOTNULL(req, HTTP_MAGIC); - vep = (void*)WS_Alloc(vc->http->ws, sizeof *vep); + vep = WS_Alloc(vc->http->ws, sizeof *vep); AN(vep); memset(vep, 0, sizeof *vep); diff --git a/bin/varnishd/cache/cache_fetch_proc.c b/bin/varnishd/cache/cache_fetch_proc.c index e2d9796..5859bd6 100644 --- a/bin/varnishd/cache/cache_fetch_proc.c +++ b/bin/varnishd/cache/cache_fetch_proc.c @@ -201,7 +201,7 @@ VFP_Push(struct vfp_ctx *vc, const struct vfp *vfp, int top) CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); CHECK_OBJ_NOTNULL(vc->http, HTTP_MAGIC); - vfe = (void*)WS_Alloc(vc->http->ws, sizeof *vfe); + vfe = WS_Alloc(vc->http->ws, sizeof *vfe); AN(vfe); vfe->magic = VFP_ENTRY_MAGIC; vfe->vfp = vfp; diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index 001dad7..c2a0836 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -86,7 +86,7 @@ ses_new(struct sesspool *pp) p = (void*)PRNDUP(p); assert(p < e); WS_Init(sp->ws, "ses", p, e - p); - sp->addrs = (void*)WS_Alloc(sp->ws, vsa_suckaddr_len * 2); + sp->addrs = WS_Alloc(sp->ws, vsa_suckaddr_len * 2); sp->t_open = NAN; sp->t_idle = NAN; diff --git a/bin/varnishd/cache/cache_wrw.c b/bin/varnishd/cache/cache_wrw.c index cc02bbf..814a791 100644 --- a/bin/varnishd/cache/cache_wrw.c +++ b/bin/varnishd/cache/cache_wrw.c @@ -79,7 +79,7 @@ WRW_Reserve(struct worker *wrk, int *fd, struct vsl_log *vsl, double t0) CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); AZ(wrk->wrw); - wrw = (void*)WS_Alloc(wrk->aws, sizeof *wrw); + wrw = WS_Alloc(wrk->aws, sizeof *wrw); AN(wrw); memset(wrw, 0, sizeof *wrw); wrw->magic = WRW_MAGIC; diff --git a/bin/varnishd/cache/cache_ws.c b/bin/varnishd/cache/cache_ws.c index 91613b5..42e6121 100644 --- a/bin/varnishd/cache/cache_ws.c +++ b/bin/varnishd/cache/cache_ws.c @@ -114,7 +114,7 @@ WS_Reset(struct ws *ws, char *p) WS_Assert(ws); } -char * +void * WS_Alloc(struct ws *ws, unsigned bytes) { char *r; From phk at FreeBSD.org Mon Oct 13 09:37:33 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 13 Oct 2014 11:37:33 +0200 Subject: [master] 7ffb0af Allocate bo->htc from the bo->ws when we needed it. Message-ID: commit 7ffb0afa7ab735b38ad1daadf9697876774a7f55 Author: Poul-Henning Kamp Date: Mon Oct 13 09:08:05 2014 +0000 Allocate bo->htc from the bo->ws when we needed it. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 839516d..f08631f 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -496,7 +496,7 @@ struct busyobj { struct objcore *ims_oc; struct objcore *fetch_objcore; - struct http_conn htc[1]; + struct http_conn *htc; struct pool_task fetch_task; diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 0f141e2..a42f731 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -352,6 +352,12 @@ vbe_dir_getfd(const struct director *d, struct busyobj *bo) CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC); + + AZ(bo->htc); + bo->htc = WS_Alloc(bo->ws, sizeof *bo->htc); + memset(bo->htc, 0, sizeof *bo->htc); + bo->htc->magic = HTTP_CONN_MAGIC; + vc = vbe_GetVbe(bo, vs); if (vc != NULL) { FIND_TMO(first_byte_timeout, @@ -390,6 +396,7 @@ vbe_dir_gethdrs(const struct director *d, struct worker *wrk, bo->vbc = vbe_dir_getfd(d, bo); if (bo->vbc == NULL) { VSLb(bo->vsl, SLT_FetchError, "no backend connection"); + bo->htc = NULL; return (-1); } @@ -406,6 +413,7 @@ vbe_dir_gethdrs(const struct director *d, struct worker *wrk, bo->vbc = vbe_dir_getfd(d, bo); if (bo->vbc == NULL) { VSLb(bo->vsl, SLT_FetchError, "no backend connection"); + bo->htc = NULL; return (-1); } i = V1F_fetch_hdr(wrk, bo); @@ -442,6 +450,8 @@ vbe_dir_finish(const struct director *d, struct worker *wrk, CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC); + bo->htc = NULL; if (bo->vbc == NULL) return; bp = bo->vbc->backend; diff --git a/bin/varnishd/cache/cache_busyobj.c b/bin/varnishd/cache/cache_busyobj.c index 4256400..e605ef4 100644 --- a/bin/varnishd/cache/cache_busyobj.c +++ b/bin/varnishd/cache/cache_busyobj.c @@ -82,6 +82,7 @@ VBO_Free(struct busyobj **bop) bo = *bop; *bop = NULL; CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + AZ(bo->htc); AZ(bo->refcount); AZ(pthread_cond_destroy(&bo->cond)); Lck_Delete(&bo->mtx); @@ -187,6 +188,8 @@ VBO_DerefBusyObj(struct worker *wrk, struct busyobj **pbo) if (r) return; + AZ(bo->htc); + VSLb(bo->vsl, SLT_BereqAcct, "%ju %ju %ju %ju %ju %ju", (uintmax_t)bo->acct.bereq_hdrbytes, (uintmax_t)bo->acct.bereq_bodybytes, diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c index 2d63159..64bb63a 100644 --- a/bin/varnishd/http1/cache_http1_fetch.c +++ b/bin/varnishd/http1/cache_http1_fetch.c @@ -87,6 +87,7 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo) CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC); CHECK_OBJ_NOTNULL(bo->vbc, VBC_MAGIC); CHECK_OBJ_ORNULL(bo->req, REQ_MAGIC); From phk at FreeBSD.org Mon Oct 13 09:37:33 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 13 Oct 2014 11:37:33 +0200 Subject: [master] 4e5828d move vbc from bo to bo->htc Message-ID: commit 4e5828d80b63df8c6d91a37d8b8a35883c014d77 Author: Poul-Henning Kamp Date: Mon Oct 13 09:37:20 2014 +0000 move vbc from bo to bo->htc diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index f08631f..0748d66 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -254,6 +254,7 @@ struct http_conn { ssize_t content_length; enum body_status body_status; struct vfp_ctx vfc[1]; + struct vbc *vbc; }; /*--------------------------------------------------------------------*/ @@ -489,7 +490,6 @@ struct busyobj { struct ws ws[1]; char *ws_bo; - struct vbc *vbc; struct http *bereq0; struct http *bereq; struct http *beresp; diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index a42f731..d073e60 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -353,20 +353,20 @@ vbe_dir_getfd(const struct director *d, struct busyobj *bo) CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC); - AZ(bo->htc); - bo->htc = WS_Alloc(bo->ws, sizeof *bo->htc); - memset(bo->htc, 0, sizeof *bo->htc); - bo->htc->magic = HTTP_CONN_MAGIC; - vc = vbe_GetVbe(bo, vs); - if (vc != NULL) { - FIND_TMO(first_byte_timeout, - vc->first_byte_timeout, bo, vs->vrt); - FIND_TMO(between_bytes_timeout, - vc->between_bytes_timeout, bo, vs->vrt); - } - if (vc == NULL) + if (vc == NULL) { VSLb(bo->vsl, SLT_FetchError, "no backend connection"); + return (NULL); + } + + if (bo->htc == NULL) + bo->htc = WS_Alloc(bo->ws, sizeof *bo->htc); + memset(bo->htc, 0, sizeof *bo->htc); + bo->htc->magic = HTTP_CONN_MAGIC; + bo->htc->vbc = vc; + bo->htc->fd = vc->fd; + FIND_TMO(first_byte_timeout, vc->first_byte_timeout, bo, vs->vrt); + FIND_TMO(between_bytes_timeout, vc->between_bytes_timeout, bo, vs->vrt); return (vc); } @@ -388,15 +388,15 @@ vbe_dir_gethdrs(const struct director *d, struct worker *wrk, struct busyobj *bo) { int i; + struct vbc *vbc; CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - bo->vbc = vbe_dir_getfd(d, bo); - if (bo->vbc == NULL) { + vbc = vbe_dir_getfd(d, bo); + if (vbc == NULL) { VSLb(bo->vsl, SLT_FetchError, "no backend connection"); - bo->htc = NULL; return (-1); } @@ -407,11 +407,11 @@ vbe_dir_gethdrs(const struct director *d, struct worker *wrk, * Do a single retry in that case. */ if (i == 1) { - AZ(bo->vbc); + AZ(bo->htc); VSC_C_main->backend_retry++; bo->doclose = SC_NULL; - bo->vbc = vbe_dir_getfd(d, bo); - if (bo->vbc == NULL) { + bo->htc->vbc = vbe_dir_getfd(d, bo); + if (bo->htc->vbc == NULL) { VSLb(bo->vsl, SLT_FetchError, "no backend connection"); bo->htc = NULL; return (-1); @@ -420,9 +420,9 @@ vbe_dir_gethdrs(const struct director *d, struct worker *wrk, } if (i != 0) { bo->doclose = SC_NULL; - AZ(bo->vbc); + AZ(bo->htc); } else { - AN(bo->vbc); + AN(bo->htc->vbc); } return (i); } @@ -451,26 +451,26 @@ vbe_dir_finish(const struct director *d, struct worker *wrk, CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC); - bo->htc = NULL; - if (bo->vbc == NULL) + if (bo->htc->vbc == NULL) return; - bp = bo->vbc->backend; + bp = bo->htc->vbc->backend; if (bo->doclose != SC_NULL) { - VSLb(bo->vsl, SLT_BackendClose, "%d %s", bo->vbc->fd, + VSLb(bo->vsl, SLT_BackendClose, "%d %s", bo->htc->vbc->fd, bp->display_name); - VTCP_close(&bo->vbc->fd); + VTCP_close(&bo->htc->vbc->fd); VBE_DropRefConn(bp, &bo->acct); - bo->vbc->backend = NULL; - VBE_ReleaseConn(bo->vbc); + bo->htc->vbc->backend = NULL; + VBE_ReleaseConn(bo->htc->vbc); } else { - VSLb(bo->vsl, SLT_BackendReuse, "%d %s", bo->vbc->fd, + VSLb(bo->vsl, SLT_BackendReuse, "%d %s", bo->htc->vbc->fd, bp->display_name); Lck_Lock(&bp->mtx); VSC_C_main->backend_recycle++; - VTAILQ_INSERT_HEAD(&bp->connlist, bo->vbc, list); + VTAILQ_INSERT_HEAD(&bp->connlist, bo->htc->vbc, list); VBE_DropRefLocked(bp, &bo->acct); } - bo->vbc = NULL; + bo->htc->vbc = NULL; + bo->htc = NULL; } static struct suckaddr * __match_proto__(vdi_suckaddr_f) @@ -481,8 +481,8 @@ vbe_dir_suckaddr(const struct director *d, struct worker *wrk, CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - if (bo->vbc != NULL) - return(bo->vbc->addr); + if (bo->htc->vbc != NULL) + return(bo->htc->vbc->addr); return (NULL); } diff --git a/bin/varnishd/cache/cache_busyobj.c b/bin/varnishd/cache/cache_busyobj.c index e605ef4..ad31e11 100644 --- a/bin/varnishd/cache/cache_busyobj.c +++ b/bin/varnishd/cache/cache_busyobj.c @@ -200,7 +200,7 @@ VBO_DerefBusyObj(struct worker *wrk, struct busyobj **pbo) VSL_End(bo->vsl); - AZ(bo->vbc); + AZ(bo->htc); if (bo->fetch_objcore != NULL) { AN(wrk); diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index ab95e03..5b977be 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -338,8 +338,8 @@ pan_busyobj(const struct busyobj *bo) VSB_printf(pan_vsp, "\n"); } VSB_printf(pan_vsp, " },\n"); - if (VALID_OBJ(bo->vbc, BACKEND_MAGIC)) - pan_vbc(bo->vbc); + if (VALID_OBJ(bo->htc->vbc, BACKEND_MAGIC)) + pan_vbc(bo->htc->vbc); if (bo->bereq->ws != NULL) pan_http("bereq", bo->bereq, 4); if (bo->beresp->ws != NULL) diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c index 64bb63a..3289acd 100644 --- a/bin/varnishd/http1/cache_http1_fetch.c +++ b/bin/varnishd/http1/cache_http1_fetch.c @@ -88,12 +88,12 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo) CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC); - CHECK_OBJ_NOTNULL(bo->vbc, VBC_MAGIC); + CHECK_OBJ_NOTNULL(bo->htc->vbc, VBC_MAGIC); CHECK_OBJ_ORNULL(bo->req, REQ_MAGIC); htc = bo->htc; hp = bo->bereq; - vc = bo->vbc; + vc = htc->vbc; if (vc->recycled) retry = 1; diff --git a/bin/varnishd/http1/cache_http1_pipe.c b/bin/varnishd/http1/cache_http1_pipe.c index 5620d0d..84d91c4 100644 --- a/bin/varnishd/http1/cache_http1_pipe.c +++ b/bin/varnishd/http1/cache_http1_pipe.c @@ -120,12 +120,13 @@ V1P_Process(struct req *req, struct busyobj *bo) SES_Close(req->sp, SC_OVERLOAD); return; } - bo->vbc = vc; /* For panic dumping */ + CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC); + assert(bo->htc->fd >= 0); bo->wrk = req->wrk; bo->director_state = DIR_S_BODY; - (void)VTCP_blocking(vc->fd); + (void)VTCP_blocking(bo->htc->fd); - WRW_Reserve(wrk, &vc->fd, bo->vsl, req->t_req); + WRW_Reserve(wrk, &bo->htc->fd, bo->vsl, req->t_req); hdrbytes = HTTP1_Write(wrk, bo->bereq, HTTP1_Req); if (req->htc->pipeline_b != NULL) @@ -142,7 +143,7 @@ V1P_Process(struct req *req, struct busyobj *bo) if (i == 0) { memset(fds, 0, sizeof fds); - fds[0].fd = vc->fd; + fds[0].fd = bo->htc->fd; fds[0].events = POLLIN | POLLERR; fds[1].fd = req->sp->fd; fds[1].events = POLLIN | POLLERR; @@ -155,20 +156,20 @@ V1P_Process(struct req *req, struct busyobj *bo) if (i < 1) break; if (fds[0].revents && - rdf(vc->fd, req->sp->fd, &acct_pipe.out)) { + rdf(bo->htc->fd, req->sp->fd, &acct_pipe.out)) { if (fds[1].fd == -1) break; - (void)shutdown(vc->fd, SHUT_RD); + (void)shutdown(bo->htc->fd, SHUT_RD); (void)shutdown(req->sp->fd, SHUT_WR); fds[0].events = 0; fds[0].fd = -1; } if (fds[1].revents && - rdf(req->sp->fd, vc->fd, &acct_pipe.in)) { + rdf(req->sp->fd, bo->htc->fd, &acct_pipe.in)) { if (fds[0].fd == -1) break; (void)shutdown(req->sp->fd, SHUT_RD); - (void)shutdown(vc->fd, SHUT_WR); + (void)shutdown(bo->htc->fd, SHUT_WR); fds[1].events = 0; fds[1].fd = -1; } From daghf at varnish-software.com Mon Oct 13 11:57:00 2014 From: daghf at varnish-software.com (Dag Haavi Finstad) Date: Mon, 13 Oct 2014 13:57:00 +0200 Subject: [master] b3e08ac Update forgotten varnishlog example to 4.0 syntax. Message-ID: commit b3e08acc60e1c5652ce5f82cf84f26cc917341b9 Author: Dag Haavi Finstad Date: Mon Oct 13 13:55:59 2014 +0200 Update forgotten varnishlog example to 4.0 syntax. Fixes: #1610 diff --git a/doc/sphinx/users-guide/troubleshooting.rst b/doc/sphinx/users-guide/troubleshooting.rst index d05b9d6..4be7543 100644 --- a/doc/sphinx/users-guide/troubleshooting.rst +++ b/doc/sphinx/users-guide/troubleshooting.rst @@ -106,16 +106,17 @@ give you a clue. Since `varnishlog` logs a lot of data it might be hard to track the entries down. You can set `varnishlog` to log all your 503 errors by issuing the following command:: - $ varnishlog -c -m TxStatus:503 + $ varnishlog -q 'RespStatus == 503' -g request If the error happened just a short time ago the transaction might still be in the shared memory log segment. To get `varnishlog` to process the whole shared memory log just add the '-d' parameter:: - $ varnishlog -d -c -m TxStatus:503 + $ varnishlog -d -q 'RespStatus == 503' -g request -Please see the `varnishlog` man page for elaborations on further -filtering capabilities and explanation of the various options. +Please see the `vsl-query` and `varnishlog` man pages for elaborations +on further filtering capabilities and explanation of the various +options. Varnish doesn't cache From lkarsten at varnish-software.com Mon Oct 13 12:02:15 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Mon, 13 Oct 2014 14:02:15 +0200 Subject: [master] 383476d Remove description lint. Message-ID: commit 383476d818f6bfae692da885bd8558995280f73b Author: Lasse Karstensen Date: Mon Oct 13 13:52:44 2014 +0200 Remove description lint. diff --git a/include/tbl/vsc_f_main.h b/include/tbl/vsc_f_main.h index 3a2b59c..34f70c1 100644 --- a/include/tbl/vsc_f_main.h +++ b/include/tbl/vsc_f_main.h @@ -117,7 +117,7 @@ VSC_F(client_req_417, uint64_t, 1, 'a', info, ) VSC_F(client_req, uint64_t, 1, 'a', info, - "Good Client requests received", + "Good client requests received", "" ) @@ -580,7 +580,7 @@ VSC_F(n_purges, uint64_t, 0, 'i', info, "" ) VSC_F(n_obj_purged, uint64_t, 0, 'i', info, - "number of purged objects", + "Number of purged objects", "" ) From lkarsten at varnish-software.com Mon Oct 13 12:02:15 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Mon, 13 Oct 2014 14:02:15 +0200 Subject: [master] 1066f83 Improve counter descriptions. Message-ID: commit 1066f8303846805b8d6ad4b11a5e78ee1288dc82 Author: Lasse Karstensen Date: Mon Oct 13 13:53:23 2014 +0200 Improve counter descriptions. Make the help text for the VSC counters a bit more explanatory. diff --git a/include/tbl/vsc_f_main.h b/include/tbl/vsc_f_main.h index 34f70c1..3524569 100644 --- a/include/tbl/vsc_f_main.h +++ b/include/tbl/vsc_f_main.h @@ -309,41 +309,41 @@ VSC_F(sess_dropped, uint64_t, 0, 'c', info, /*---------------------------------------------------------------------*/ VSC_F(n_object, uint64_t, 1, 'i', info, - "N struct object", + "Number of object structs made", "" ) VSC_F(n_vampireobject, uint64_t, 1, 'i', diag, - "N unresurrected objects", + "Number of unresurrected objects", "" ) VSC_F(n_objectcore, uint64_t, 1, 'i', info, - "N struct objectcore", + "Number of objectcore structs made", "" ) VSC_F(n_objecthead, uint64_t, 1, 'i', info, - "N struct objecthead", + "Number of objecthead structs made", "" ) VSC_F(n_waitinglist, uint64_t, 1, 'i', debug, - "N struct waitinglist", + "Number of waitinglist structs made", "" ) VSC_F(n_backend, uint64_t, 0, 'i', info, - "N backends", + "Number of backends", "" ) VSC_F(n_expired, uint64_t, 0, 'i', info, - "N expired objects", + "Number of expired objects", "" ) VSC_F(n_lru_nuked, uint64_t, 0, 'i', info, - "N LRU nuked objects", + "Number of LRU nuked objects", "" ) VSC_F(n_lru_moved, uint64_t, 0, 'i', diag, - "N LRU moved objects", + "Number of LRU moved objects", "" ) @@ -353,27 +353,27 @@ VSC_F(losthdr, uint64_t, 0, 'a', info, ) VSC_F(s_sess, uint64_t, 1, 'a', info, - "Total Sessions", + "Total sessions seen", "" ) VSC_F(s_req, uint64_t, 1, 'a', info, - "Total Requests", + "Total requests seen", "" ) VSC_F(s_pipe, uint64_t, 1, 'a', info, - "Total pipe", + "Total pipe sessions seen", "" ) VSC_F(s_pass, uint64_t, 1, 'a', info, - "Total pass", + "Total pass-ed requests seen", "" ) VSC_F(s_fetch, uint64_t, 1, 'a', info, - "Total fetch", + "Total backend fetches initiated", "" ) VSC_F(s_synth, uint64_t, 1, 'a', info, - "Total synth", + "Total synthethic responses made", "" ) VSC_F(s_req_hdrbytes, uint64_t, 1, 'a', info, @@ -480,15 +480,15 @@ VSC_F(backend_req, uint64_t, 0, 'a', info, /*--------------------------------------------------------------------*/ VSC_F(n_vcl, uint64_t, 0, 'a', info, - "N vcl total", + "Number of loaded VCLs in total", "" ) VSC_F(n_vcl_avail, uint64_t, 0, 'a', diag, - "N vcl available", + "Number of VCLs available", "" ) VSC_F(n_vcl_discard, uint64_t, 0, 'a', diag, - "N vcl discarded", + "Number of discarded VCLs", "" ) @@ -576,7 +576,7 @@ VSC_F(bans_persisted_fragmentation, uint64_t, 0, 'g', diag, /*--------------------------------------------------------------------*/ VSC_F(n_purges, uint64_t, 0, 'i', info, - "Number of purge operations", + "Number of purge operations executed", "" ) VSC_F(n_obj_purged, uint64_t, 0, 'i', info, From phk at FreeBSD.org Mon Oct 13 12:46:12 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 13 Oct 2014 14:46:12 +0200 Subject: [master] 591dd5b Unbreak backend retries Message-ID: commit 591dd5b63b19e2b74a19b574a58e21f05ca2f3ba Author: Poul-Henning Kamp Date: Mon Oct 13 12:45:51 2014 +0000 Unbreak backend retries diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index d073e60..2e233e9 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -399,6 +399,7 @@ vbe_dir_gethdrs(const struct director *d, struct worker *wrk, VSLb(bo->vsl, SLT_FetchError, "no backend connection"); return (-1); } + AN(bo->htc); i = V1F_fetch_hdr(wrk, bo); /* @@ -410,12 +411,13 @@ vbe_dir_gethdrs(const struct director *d, struct worker *wrk, AZ(bo->htc); VSC_C_main->backend_retry++; bo->doclose = SC_NULL; - bo->htc->vbc = vbe_dir_getfd(d, bo); - if (bo->htc->vbc == NULL) { + vbc = vbe_dir_getfd(d, bo); + if (vbc == NULL) { VSLb(bo->vsl, SLT_FetchError, "no backend connection"); bo->htc = NULL; return (-1); } + AN(bo->htc); i = V1F_fetch_hdr(wrk, bo); } if (i != 0) { From nils.goroll at uplex.de Mon Oct 13 15:19:08 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 13 Oct 2014 17:19:08 +0200 Subject: [master] 5cfcdb0 whitespace ocd before further editing Message-ID: commit 5cfcdb0b41db2460f27cf8170d06fca855d8ac87 Author: Nils Goroll Date: Mon Oct 13 12:58:42 2014 +0200 whitespace ocd before further editing diff --git a/doc/sphinx/users-guide/vcl-built-in-subs.rst b/doc/sphinx/users-guide/vcl-built-in-subs.rst index 48b19c9..e7a7e83 100644 --- a/doc/sphinx/users-guide/vcl-built-in-subs.rst +++ b/doc/sphinx/users-guide/vcl-built-in-subs.rst @@ -1,4 +1,3 @@ - .. _vcl-built-in-subs: .. XXX:This document needs substantional review. @@ -17,7 +16,7 @@ serve the request, how to do it, and, if applicable, which backend to use. It is also used to modify the request, something you'll probably find -yourself doing frequently. +yourself doing frequently. The `vcl_recv` subroutine may terminate with calling ``return()`` on one of the following keywords: @@ -37,7 +36,7 @@ of the following keywords: caching. Passes the control over to vcl_hash. purge - Purge the object and it's variants. Control passes through + Purge the object and it's variants. Control passes through vcl_hash to vcl_purge. vcl_pipe @@ -85,9 +84,10 @@ of the following keywords: vcl_hit ~~~~~~~ -Called when a cache lookup is successful. +Called when a cache lookup is successful. -The `vcl_hit` subroutine may terminate with calling ``return()`` with one of the following keywords: +The `vcl_hit` subroutine may terminate with calling ``return()`` +with one of the following keywords: restart @@ -216,7 +216,7 @@ The `vcl_backend_response` subroutine may terminate with calling vcl_backend_error ~~~~~~~~~~~~~~~~~ -This subroutine is called if we fail the backend fetch. +This subroutine is called if we fail the backend fetch. The `vcl_backend_error` subroutine may terminate with calling ``return()`` with one of the following keywords: @@ -240,7 +240,7 @@ the synthetic() function. The subroutine may terminate with calling ``return()`` with one of the following keywords: - deliver + deliver Deliver the object. If the object has a positive TTL then the object is also stored in cache. From nils.goroll at uplex.de Mon Oct 13 15:19:08 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 13 Oct 2014 17:19:08 +0200 Subject: [master] 9d70ce5 move the label to the right place Message-ID: commit 9d70ce57e214e868f5981a8082464581641cc451 Author: Nils Goroll Date: Mon Oct 13 13:59:58 2014 +0200 move the label to the right place diff --git a/doc/sphinx/users-guide/vcl-built-in-subs.rst b/doc/sphinx/users-guide/vcl-built-in-subs.rst index e7a7e83..32f8fbd 100644 --- a/doc/sphinx/users-guide/vcl-built-in-subs.rst +++ b/doc/sphinx/users-guide/vcl-built-in-subs.rst @@ -1,7 +1,7 @@ -.. _vcl-built-in-subs: .. XXX:This document needs substantional review. +.. _vcl-built-in-subs: Built in subroutines -------------------- From nils.goroll at uplex.de Mon Oct 13 15:19:08 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 13 Oct 2014 17:19:08 +0200 Subject: [master] 7a41c54 generate svgs Message-ID: commit 7a41c54502ce968778c219535c7e95ee25eee515 Author: Nils Goroll Date: Mon Oct 13 14:00:35 2014 +0200 generate svgs diff --git a/.gitignore b/.gitignore index 516380e..5795c63 100644 --- a/.gitignore +++ b/.gitignore @@ -100,6 +100,7 @@ cscope.*out /doc/sphinx/include/vcl_var.rst # graphviz-generated /doc/graphviz/*.pdf +/doc/graphviz/*.svg # NetBeans insists on this /nbproject/private/ diff --git a/doc/graphviz/Makefile.am b/doc/graphviz/Makefile.am index 6280eab..3823fab 100644 --- a/doc/graphviz/Makefile.am +++ b/doc/graphviz/Makefile.am @@ -12,9 +12,23 @@ PDFS = \ cache_req_fsm.pdf \ cache_fetch.pdf +SVGS = \ + cache_http1_fsm.svg \ + cache_req_fsm.svg \ + cache_fetch.svg + pdf: $(PDFS) +html: $(SVGS) + endif +# XXX does not fit onto a4 unless in landscape +cache_fetch.pdf: cache_fetch.dot + @DOT@ -Tpdf -Gsize=$(SIZE) -Grotate=90 $< >$@ + %.pdf: %.dot @DOT@ -Tpdf -Gsize=$(SIZE) $< >$@ + +%.svg: %.dot + @DOT@ -Tsvg $< >$@ diff --git a/doc/graphviz/cache_fetch.dot b/doc/graphviz/cache_fetch.dot index db292f0..1daf76f 100644 --- a/doc/graphviz/cache_fetch.dot +++ b/doc/graphviz/cache_fetch.dot @@ -1,7 +1,6 @@ digraph cache_fetch { margin="0.5" center="1" - rotate=90 /*** cache_fetch.c ***/ subgraph cluster_backend { From nils.goroll at uplex.de Mon Oct 13 15:19:08 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 13 Oct 2014 17:19:08 +0200 Subject: [master] 32749a4 get vcl_purge via vcl_hash right Message-ID: commit 32749a4dfb54de1164f84988c75a9e32221ccfde Author: Nils Goroll Date: Mon Oct 13 15:59:04 2014 +0200 get vcl_purge via vcl_hash right diff --git a/doc/graphviz/cache_req_fsm.dot b/doc/graphviz/cache_req_fsm.dot index 1949757..15e7818 100644 --- a/doc/graphviz/cache_req_fsm.dot +++ b/doc/graphviz/cache_req_fsm.dot @@ -111,10 +111,10 @@ digraph cache_req_fsm { label=" {cnt_lookup:| hash lookup| - {busy?| - hit?| + {hit?| miss?| - hit-for-pass?}}" + hit-for-pass?| + busy?}}" ] lookup2 [ shape=record @@ -128,7 +128,7 @@ digraph cache_req_fsm { pass}}" ] } - lookup:busy:w -> lookup:top:w [label="(waitinglist)", + lookup:busy:e -> lookup:top:e [label="(waitinglist)", color=grey, fontcolor=grey] lookup:miss:s -> miss [style=bold,color=blue] @@ -214,10 +214,10 @@ digraph cache_req_fsm { {cnt_recv:| {vcl_recv\{\}|req.*}| {hash| + purge| pass| pipe| - synth| - purge}}" + synth}}" ] recv:hash -> hash [style=bold,color=green] hash [ @@ -229,15 +229,16 @@ digraph cache_req_fsm { } recv:pipe -> pipe [style=bold,color=orange] recv:pass -> pass [style=bold,color=red] - hash:lookup:s -> lookup [style=bold,color=green] - recv:purge:s -> purge [style=bold,color=purple] + hash:lookup:w -> lookup [style=bold,color=green] + hash:lookup:s -> purge:top:n [style=bold,color=purple] + recv:purge:s -> hash [style=bold,color=purple] /* cnt_purge */ subgraph xcluster_purge { purge [ shape=record label=" - {cnt_purge:| + {cnt_purge:| {vcl_purge\{\}|req.*}| {synth| restart}}" From nils.goroll at uplex.de Mon Oct 13 15:19:08 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 13 Oct 2014 17:19:08 +0200 Subject: [master] a48147a add svg versions of the graphviz-generated graphs to html docs Message-ID: commit a48147aae7157fbc2d7de19b9e541ffa18fc9fa3 Author: Nils Goroll Date: Mon Oct 13 16:02:16 2014 +0200 add svg versions of the graphviz-generated graphs to html docs diff --git a/doc/Makefile.am b/doc/Makefile.am index 927b54a..e420a99 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -14,4 +14,5 @@ else @false endif -SUBDIRS = sphinx graphviz +# build graphviz before sphinx, so sphinx docs can use svg output +SUBDIRS = graphviz sphinx diff --git a/doc/sphinx/reference/index.rst b/doc/sphinx/reference/index.rst index 32458a6..72924e3 100644 --- a/doc/sphinx/reference/index.rst +++ b/doc/sphinx/reference/index.rst @@ -8,6 +8,7 @@ The Varnish Reference Manual :maxdepth: 2 vcl.rst + states.rst varnish-cli.rst varnishadm.rst varnishd.rst diff --git a/doc/sphinx/reference/states.rst b/doc/sphinx/reference/states.rst new file mode 100644 index 0000000..098e5a2 --- /dev/null +++ b/doc/sphinx/reference/states.rst @@ -0,0 +1,40 @@ +.. _reference-states: + +========================= +Varnish Processing States +========================= + +------------ +Introduction +------------ + +Varnish processing of client and backend requests is implemented as +state machines. Whenever a state is entered, a C function is called, +which in turn calls the appropriate Varnish core code functions to +process the request or response at this stage. For most states, core +code also calls into a state-specific function compiled from VCL, a +VCL subroutine (see :ref:`vcl-built-in-subs` ). + +As a general guideline, core code aims to prepare objects accessible +from VCL with good defaults for the most common cases before calling +into the respective VCL subroutine. These can then be modified from +VCL where necessary. + +The following graphs attempt to provide an overview over the +processing states, their transisions and the most relevant functions +in core code. They represent a compromise between usefulness for +core/VMOD developers and administrators and are intended to serve as +the reference basis for deriavtive work, such as more VCL-centric +views. + +----------- +Client Side +----------- + +.. image:: ../../graphviz/cache_req_fsm.svg + +------------ +Backend Side +------------ + +.. image:: ../../graphviz/cache_fetch.svg From nils.goroll at uplex.de Mon Oct 13 15:19:08 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 13 Oct 2014 17:19:08 +0200 Subject: [master] a6dc0f8 complete overhaul of vcl-built-in-subs.rst documentation Message-ID: commit a6dc0f809d439c85f4d45563e09774cc15b00389 Author: Nils Goroll Date: Mon Oct 13 17:13:41 2014 +0200 complete overhaul of vcl-built-in-subs.rst documentation Add missing bits and sync with reality. Relevant fixes: * a synth object is never cached * by a backend_response object may be diff --git a/doc/sphinx/users-guide/vcl-built-in-subs.rst b/doc/sphinx/users-guide/vcl-built-in-subs.rst index 32f8fbd..cd78355 100644 --- a/doc/sphinx/users-guide/vcl-built-in-subs.rst +++ b/doc/sphinx/users-guide/vcl-built-in-subs.rst @@ -1,44 +1,55 @@ - -.. XXX:This document needs substantional review. - .. _vcl-built-in-subs: +==================== Built in subroutines --------------------- +==================== + +Various built-in subroutines are called during processing of client- +and backend requests as well as upon ``vcl.load`` and ``vcl.discard``. + +See :ref:`reference-states` for a defailed graphical overview of the +states and how they relate to core code functions and VCL subroutines. +----------- +client side +----------- + +.. _vcl_recv: vcl_recv ~~~~~~~~ Called at the beginning of a request, after the complete request has -been received and parsed. Its purpose is to decide whether or not to -serve the request, how to do it, and, if applicable, which backend to -use. +been received and parsed, after a `restart` or as the result of an ESI +include. -It is also used to modify the request, something you'll probably find -yourself doing frequently. +Its purpose is to decide whether or not to serve the request, possibly +modify it and decide on how to process it further. A backend hint may +be set as a default for the backend processing side. The `vcl_recv` subroutine may terminate with calling ``return()`` on one of the following keywords: - synth(status code, reason) - Return a synthetic object with the specified status code to the - client and abandon the request. + ``hash`` + Continue processing the object as a potential candidate for + caching. Passes the control over to :ref:`vcl_hash`. - pass - Switch to pass mode. Control will eventually pass to vcl_pass. + ``pass`` + Switch to pass mode. Control will eventually pass to :ref:`vcl_pass`. - pipe - Switch to pipe mode. Control will eventually pass to vcl_pipe. + ``pipe`` + Switch to pipe mode. Control will eventually pass to :ref:`vcl_pipe`. - hash - Continue processing the object as a potential candidate for - caching. Passes the control over to vcl_hash. + ``synth(status code, reason)`` + Transition to :ref:`vcl_synth` with ``resp.status`` and + ``resp.reason`` being preset to the arguments of ``synth()``. - purge + ``purge`` Purge the object and it's variants. Control passes through vcl_hash to vcl_purge. +.. _vcl_pipe: + vcl_pipe ~~~~~~~~ @@ -52,12 +63,15 @@ other VCL subroutine will ever get called after `vcl_pipe`. The `vcl_pipe` subroutine may terminate with calling ``return()`` with one of the following keywords: - synth(status code, reason) - Return the specified status code to the client and abandon the request. - - pipe + ``pipe`` Proceed with pipe mode. + ``synth(status code, reason)`` + Transition to :ref:`vcl_synth` with ``resp.status`` and + ``resp.reason`` being preset to the arguments of ``synth()``. + +.. _vcl_pass: + vcl_pass ~~~~~~~~ @@ -69,64 +83,86 @@ submitted over the same client connection are handled normally. The `vcl_pass` subroutine may terminate with calling ``return()`` with one of the following keywords: - synth(status code, reason) - Return the specified status code to the client and abandon the request. + ``fetch`` + Proceed with pass mode - initiate a backend request. - fetch - Proceed with pass mode. - - restart + ``restart`` Restart the transaction. Increases the restart counter. If the number of restarts is higher than *max_restarts* Varnish emits a guru meditation error. + ``synth(status code, reason)`` + Transition to :ref:`vcl_synth` with ``resp.status`` and + ``resp.reason`` being preset to the arguments of ``synth()``. + +.. _vcl_hit: vcl_hit ~~~~~~~ -Called when a cache lookup is successful. +Called when a cache lookup is successful. The object being hit may be +stale: It can have a zero or negative `ttl` with only `grace` or +`keep` time left. The `vcl_hit` subroutine may terminate with calling ``return()`` with one of the following keywords: + ``deliver`` + Deliver the object. If it is stale, a background fetch to refresh + it is triggered. + + ``fetch`` + Synchronously refresh the object from the backend despite the + cache hit. Control will eventually pass to :ref:`vcl_miss`. - restart + ``pass`` + Switch to pass mode. Control will eventually pass to :ref:`vcl_pass`. + + ``restart`` Restart the transaction. Increases the restart counter. If the number of restarts is higher than *max_restarts* Varnish emits a guru meditation error. - deliver - Deliver the object. Control passes to `vcl_deliver`. + ``synth(status code, reason)`` + Transition to :ref:`vcl_synth` with ``resp.status`` and + ``resp.reason`` being preset to the arguments of ``synth()``. - synth(status code, reason) - Return the specified status code to the client and abandon the request. +.. XXX: #1603 hit should not go to miss +.. _vcl_miss: vcl_miss ~~~~~~~~ Called after a cache lookup if the requested document was not found in -the cache. Its purpose is to decide whether or not to attempt to -retrieve the document from the backend, and which backend to use. +the cache or if :ref:`vcl_hit` returned ``fetch``. + +Its purpose is to decide whether or not to attempt to retrieve the +document from the backend. A backend hint may be set as a default for +the backend processing side. The `vcl_miss` subroutine may terminate with calling ``return()`` with one of the following keywords: - synth(status code, reason) - Return the specified status code to the client and abandon the request. - - pass - Switch to pass mode. Control will eventually pass to `vcl_pass`. - - fetch + ``fetch`` Retrieve the requested object from the backend. Control will eventually pass to `vcl_backend_fetch`. - restart + ``pass`` + Switch to pass mode. Control will eventually pass to :ref:`vcl_pass`. + + ``restart`` Restart the transaction. Increases the restart counter. If the number of restarts is higher than *max_restarts* Varnish emits a guru meditation error. + ``synth(status code, reason)`` + Transition to :ref:`vcl_synth` with ``resp.status`` and + ``resp.reason`` being preset to the arguments of ``synth()``. + +.. XXX: #1603 hit should not go to miss + +.. _vcl_hash: vcl_hash ~~~~~~~~ @@ -134,13 +170,18 @@ vcl_hash Called after `vcl_recv` to create a hash value for the request. This is used as a key to look up the object in Varnish. -The `vcl_hash` subroutine may terminate with calling ``return()`` with one -of the following keywords: +The `vcl_hash` subroutine may only terminate with calling ``return(lookup)``: - lookup - Look up the object in cache. Control passes to vcl_miss, vcl_hit - or vcl_purge. + ``lookup`` + Look up the object in cache. + Control passes to :ref:`vcl_purge` when coming from a ``purge`` + return in `vcl_recv`. + Otherwise control passes to :ref:`vcl_hit`, :ref:`vcl_miss` or + :ref:`vcl_pass` if the cache lookup result was a hit, a miss or hit + on a hit-for-pass object (object with ``obj.uncacheable == + true``), respectively. +.. _vcl_purge: vcl_purge ~~~~~~~~~ @@ -150,31 +191,66 @@ Called after the purge has been executed and all its variants have been evited. The `vcl_purge` subroutine may terminate with calling ``return()`` with one of the following keywords: - synth - Produce a response. - - restart + ``restart`` Restart the transaction. Increases the restart counter. If the number of restarts is higher than *max_restarts* Varnish emits a guru meditation error. + ``synth(status code, reason)`` + Transition to :ref:`vcl_synth` with ``resp.status`` and + ``resp.reason`` being preset to the arguments of ``synth()``. + +.. _vcl_deliver: vcl_deliver ~~~~~~~~~~~ -Called before a cached object is delivered to the client. +Called before any object except a `vcl_synth` result is delivered to the client. The `vcl_deliver` subroutine may terminate with calling ``return()`` with one of the following keywords: - deliver + ``deliver`` Deliver the object to the client. - restart + ``restart`` + Restart the transaction. Increases the restart counter. If the number + of restarts is higher than *max_restarts* Varnish emits a guru meditation + error. + + ``synth(status code, reason)`` + Transition to :ref:`vcl_synth` with ``resp.status`` and + ``resp.reason`` being preset to the arguments of ``synth()``. + +.. _vcl_synth: + +vcl_synth +~~~~~~~~~ + +Called to deliver a synthetic object. A synthetic object is generated +in VCL, not fetched from the backend. Its body may be contructed using +the ``synthetic()`` function. + +A `vcl_synth` defined object never enters the cache, contrary to a +:ref:`vcl_backend_error` defined object, which may end up in cache. + +The subroutine may terminate with calling ``return()`` with one of the +following keywords: + + ``deliver`` + Directly deliver the object defined by `vcl_synth` to the + client without calling `vcl_deliver`. + + ``restart`` Restart the transaction. Increases the restart counter. If the number of restarts is higher than *max_restarts* Varnish emits a guru meditation error. +------------ +Backend Side +------------ + +.. _vcl_backend_fetch: vcl_backend_fetch ~~~~~~~~~~~~~~~~~ @@ -185,67 +261,71 @@ typically alter the request before it gets to the backend. The `vcl_backend_fetch` subroutine may terminate with calling ``return()`` with one of the following keywords: - fetch + ``fetch`` Fetch the object from the backend. - abandon - Abandon the backend request and generates an error. + ``abandon`` + Abandon the backend request. Unless the backend request was a + background fetch, control is passed to :ref:`vcl_synth` on the + client side with ``resp.status`` preset to 503. +.. _vcl_backend_response: vcl_backend_response ~~~~~~~~~~~~~~~~~~~~ -Called after the response headers has been successfully retrieved from +Called after the response headers have been successfully retrieved from the backend. The `vcl_backend_response` subroutine may terminate with calling ``return()`` with one of the following keywords: - deliver - Possibly insert the object into the cache, then deliver it to the - Control will eventually pass to `vcl_deliver`. + ``deliver`` + For a 304 response, create an updated cache object. + Otherwise, fetch the object body from the backend and initiate + delivery to any waiting client requests, possibly in parallel + (streaming). - abandon - Abandon the backend request and generates an error. + ``abandon`` + Abandon the backend request. Unless the backend request was a + background fetch, control is passed to :ref:`vcl_synth` on the + client side with ``resp.status`` preset to 503. - retry + ``retry`` Retry the backend transaction. Increases the `retries` counter. - If the number of retries is higher than *max_retries* Varnish - emits a guru meditation error. + If the number of retries is higher than *max_retries*, + control will be passed to :ref:`vcl_backend_error`. + +.. _vcl_backend_error: vcl_backend_error ~~~~~~~~~~~~~~~~~ -This subroutine is called if we fail the backend fetch. +This subroutine is called if we fail the backend fetch or if +*max_retries* has been exceeded. + +A synthetic object is generated in VCL, whose body may be contructed +using the ``synthetic()`` function. The `vcl_backend_error` subroutine may terminate with calling ``return()`` with one of the following keywords: - deliver - Deliver the error. + ``deliver`` + Deliver and possibly cache the object defined in + `vcl_backend_error` **as if it was fetched from the backend**, also + referred to as a "backend synth". - retry - Retry the backend transaction. Increases the `retries` counter. If - the number of retries is higher than *max_retries* Varnish emits a - guru meditation error. - -vcl_synth -~~~~~~~~~ - -Called to deliver a synthetic object. A synthetic object is generated -in VCL, not fetched from the backend. It is typically contructed using -the synthetic() function. - - -The subroutine may terminate with calling ``return()`` with one of the -following keywords: + ``retry`` + Retry the backend transaction. Increases the `retries` counter. + If the number of retries is higher than *max_retries*, + :ref:`vcl_synth` on the client side is called with ``resp.status`` + preset to 503. - deliver - Deliver the object. If the object has a positive TTL then the - object is also stored in cache. +---------------------- +vcl.load / vcl.discard +---------------------- - restart - Restart processing the object. +.. _vcl_init: vcl_init ~~~~~~~~ @@ -256,9 +336,13 @@ Typically used to initialize VMODs. The `vcl_init` subroutine may terminate with calling ``return()`` with one of the following keywords: - ok + ``ok`` Normal return, VCL continues loading. + ``fail`` + Abort loading of this VCL. + +.. _vcl_fini: vcl_fini ~~~~~~~~ @@ -269,5 +353,5 @@ Typically used to clean up VMODs. The `vcl_fini` subroutine may terminate with calling ``return()`` with one of the following keywords: - ok + ``ok`` Normal return, VCL will be discarded. From nils.goroll at uplex.de Mon Oct 13 15:52:03 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 13 Oct 2014 17:52:03 +0200 Subject: [master] a1a5122 fix out-of-tree make dist Message-ID: commit a1a5122e5c2fbf6437e4c851da9dd58cf8416f65 Author: Nils Goroll Date: Mon Oct 13 17:51:45 2014 +0200 fix out-of-tree make dist diff --git a/doc/graphviz/Makefile.am b/doc/graphviz/Makefile.am index 3823fab..3f20340 100644 --- a/doc/graphviz/Makefile.am +++ b/doc/graphviz/Makefile.am @@ -1,5 +1,20 @@ # Makefile for graphviz outputs -# + +# for an out-of-tree build, sphinx needs the output in builddir +# XXX is there a better way to do this? + +.PHONY: link_srcdir + +link_srcdir: + if test "x$(srcdir)" != "x$(builddir)" && \ + test ! -f cache_http1_fsm.svg ; then \ + d=`pwd`/$(builddir) ; \ + cd $(srcdir) && find . -name \*.svg -type f | \ + cpio -ldmp $${d} ; \ + fi + +dist-hook: + $(MAKE) html # You can set these variables from the command line. # this is a4, letter is 8.5,11 @@ -19,7 +34,7 @@ SVGS = \ pdf: $(PDFS) -html: $(SVGS) +html: $(SVGS) link_srcdir endif From nils.goroll at uplex.de Mon Oct 13 15:59:25 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 13 Oct 2014 17:59:25 +0200 Subject: [master] 8c1b35c remote debugging of jenkins build failures via git pushes Message-ID: commit 8c1b35c982dd0d362706c82411b63ca8c1597a25 Author: Nils Goroll Date: Mon Oct 13 17:58:19 2014 +0200 remote debugging of jenkins build failures via git pushes diff --git a/doc/graphviz/Makefile.am b/doc/graphviz/Makefile.am index 3f20340..dc3c3be 100644 --- a/doc/graphviz/Makefile.am +++ b/doc/graphviz/Makefile.am @@ -7,7 +7,7 @@ link_srcdir: if test "x$(srcdir)" != "x$(builddir)" && \ - test ! -f cache_http1_fsm.svg ; then \ + test ! -f $(builddir)/cache_http1_fsm.svg ; then \ d=`pwd`/$(builddir) ; \ cd $(srcdir) && find . -name \*.svg -type f | \ cpio -ldmp $${d} ; \ From nils.goroll at uplex.de Mon Oct 13 16:05:28 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 13 Oct 2014 18:05:28 +0200 Subject: [master] d36df31 this should really fix the build issues due to missing svg files Message-ID: commit d36df31c6fdb1c8eac06daffebf8719314c234a7 Author: Nils Goroll Date: Mon Oct 13 18:05:14 2014 +0200 this should really fix the build issues due to missing svg files diff --git a/doc/sphinx/Makefile.am b/doc/sphinx/Makefile.am index 176c07d..0ec3328 100644 --- a/doc/sphinx/Makefile.am +++ b/doc/sphinx/Makefile.am @@ -38,7 +38,12 @@ link_srcdir: cd $(srcdir) && find . -name \*.rst -type f | cpio -ldmp $${d} ; \ fi -sphinx_prereq: link_srcdir conf.py +# work around for make html called within doc/sphinx +.PHONY: graphviz +graphviz: + cd ../graphviz && $(MAKE) html + +sphinx_prereq: link_srcdir graphviz conf.py html: sphinx_prereq $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html From nils.goroll at uplex.de Mon Oct 13 16:38:59 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 13 Oct 2014 18:38:59 +0200 Subject: [master] 5772d3c bail out with a clear error if graphviz is missing for building the html and pdf targets Message-ID: commit 5772d3cf7f8f93662c08a778a1c84a4571d442ce Author: Nils Goroll Date: Mon Oct 13 18:38:56 2014 +0200 bail out with a clear error if graphviz is missing for building the html and pdf targets diff --git a/doc/graphviz/Makefile.am b/doc/graphviz/Makefile.am index dc3c3be..dd2ef4c 100644 --- a/doc/graphviz/Makefile.am +++ b/doc/graphviz/Makefile.am @@ -21,7 +21,6 @@ dist-hook: SIZE = 8.4,11.7 if HAVE_DOT - PDFS = \ cache_http1_fsm.pdf \ cache_req_fsm.pdf \ @@ -31,11 +30,22 @@ SVGS = \ cache_http1_fsm.svg \ cache_req_fsm.svg \ cache_fetch.svg +endif pdf: $(PDFS) +if ! HAVE_DOT + @echo ================================================== + @echo You need graphviz installed to generate pdf output + @echo ================================================== + @false +endif html: $(SVGS) link_srcdir - +if ! HAVE_DOT + @echo =================================================== + @echo You need graphviz installed to generate html output + @echo =================================================== + @false endif # XXX does not fit onto a4 unless in landscape From nils.goroll at uplex.de Mon Oct 13 17:23:52 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 13 Oct 2014 19:23:52 +0200 Subject: [master] e0dec59 try to make ancient graphvizes happy with our multi line strings Message-ID: commit e0dec59df9e32f095d342569777cee18987d41e0 Author: Nils Goroll Date: Mon Oct 13 19:23:35 2014 +0200 try to make ancient graphvizes happy with our multi line strings diff --git a/doc/graphviz/cache_req_fsm.dot b/doc/graphviz/cache_req_fsm.dot index 15e7818..527977a 100644 --- a/doc/graphviz/cache_req_fsm.dot +++ b/doc/graphviz/cache_req_fsm.dot @@ -44,11 +44,11 @@ digraph cache_req_fsm { /* cnt_deliver() */ deliver [ shape=record - label=" - {cnt_deliver:| - Filter obj.-\>resp.| - {vcl_deliver\{\}| - {req.*|resp.*}}| + label="\ + {cnt_deliver:|\ + Filter obj.-\>resp.|\ + {vcl_deliver\{\}|\ + {req.*|resp.*}}|\ {restart|deliver|synth}}" ] @@ -66,9 +66,9 @@ digraph cache_req_fsm { subgraph xcluster_synth { synth [ shape=record - label=" - {cnt_synth:| - {vcl_synth\{\}|{req.*|resp.*}}| + label="\ + {cnt_synth:|\ + {vcl_synth\{\}|{req.*|resp.*}}|\ {deliver|restart}}" ] @@ -108,23 +108,23 @@ digraph cache_req_fsm { shape=record color=grey fontcolor=grey - label=" - {cnt_lookup:| - hash lookup| - {hit?| - miss?| - hit-for-pass?| + label="\ + {cnt_lookup:|\ + hash lookup|\ + {hit?|\ + miss?|\ + hit-for-pass?|\ busy?}}" ] lookup2 [ shape=record - label=" - {cnt_lookup:| - {vcl_hit\{\}|{req.*|obj.*}}| - {deliver| - fetch| - restart| - synth| + label="\ + {cnt_lookup:|\ + {vcl_hit\{\}|{req.*|obj.*}}|\ + {deliver|\ + fetch|\ + restart|\ + synth|\ pass}}" ] } @@ -145,12 +145,12 @@ digraph cache_req_fsm { subgraph xcluster_miss { miss [ shape=record - label=" - {cnt_miss:| - {vcl_miss\{\}|req.*}| - {fetch| - synth| - restart| + label="\ + {cnt_miss:|\ + {vcl_miss\{\}|req.*}|\ + {fetch|\ + synth|\ + restart|\ pass}}" ] } @@ -161,10 +161,10 @@ digraph cache_req_fsm { subgraph xcluster_pass { pass [ shape=record - label="{cnt_pass:| - {vcl_pass\{\}|req.*}| - {fetch| - synth| + label="{cnt_pass:|\ + {vcl_pass\{\}|req.*}|\ + {fetch|\ + synth|\ restart}}" ] } @@ -174,11 +174,11 @@ digraph cache_req_fsm { subgraph xcluster_pipe { pipe [ shape=record - label=" - {cnt_pipe:| - filter req.*-\>bereq.*| - {vcl_pipe\{\}|{req.*|bereq.*}}| - {pipe| + label="\ + {cnt_pipe:|\ + filter req.*-\>bereq.*|\ + {vcl_pipe\{\}|{req.*|bereq.*}}|\ + {pipe|\ synth}}" ] pipe_do [ @@ -195,9 +195,9 @@ digraph cache_req_fsm { shape=record color=grey fontcolor=grey - label=" - {cnt_restart:| - {ok?| + label="\ + {cnt_restart:|\ + {ok?|\ max_restarts?}}" ] } @@ -210,21 +210,21 @@ digraph cache_req_fsm { subgraph xcluster_recv { recv [ shape=record - label=" - {cnt_recv:| - {vcl_recv\{\}|req.*}| - {hash| - purge| - pass| - pipe| + label="\ + {cnt_recv:|\ + {vcl_recv\{\}|req.*}|\ + {hash|\ + purge|\ + pass|\ + pipe|\ synth}}" ] recv:hash -> hash [style=bold,color=green] hash [ shape=record - label=" - {cnt_recv:| - {vcl_hash\{\}|req.*}| + label="\ + {cnt_recv:|\ + {vcl_hash\{\}|req.*}|\ {lookup}}"] } recv:pipe -> pipe [style=bold,color=orange] @@ -237,10 +237,10 @@ digraph cache_req_fsm { subgraph xcluster_purge { purge [ shape=record - label=" - {cnt_purge:| - {vcl_purge\{\}|req.*}| - {synth| + label="\ + {cnt_purge:|\ + {vcl_purge\{\}|req.*}|\ + {synth|\ restart}}" ] } From nils.goroll at uplex.de Mon Oct 13 17:34:46 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 13 Oct 2014 19:34:46 +0200 Subject: [master] 744c8fd make labels illegible for elderly graphvizes Message-ID: commit 744c8fd39071b9dd61241df720a9afa8d3ec7cbb Author: Nils Goroll Date: Mon Oct 13 19:34:42 2014 +0200 make labels illegible for elderly graphvizes diff --git a/doc/graphviz/cache_req_fsm.dot b/doc/graphviz/cache_req_fsm.dot index 527977a..e3a70d9 100644 --- a/doc/graphviz/cache_req_fsm.dot +++ b/doc/graphviz/cache_req_fsm.dot @@ -1,3 +1,21 @@ +/* + * we should format labels in a reable form like + * label="\ + * {cnt_deliver:|\ + * Filter obj.-\>resp.|\ + * {vcl_deliver\{\}|\ + * {req.*|resp.*}}|\ + * {restart|deliver|synth}}" + * + * + * ... but some servers in the v-c.o build farm use old graphviz 2.26.3 + * which cannot handle labels with additional whitespace properly, so + * for the time being we need to fall back into dark middle ages and + * use illegibly long lines + * + * -- slink 20141013 + */ + digraph cache_req_fsm { margin="0.25" ranksep="0.5" @@ -44,12 +62,7 @@ digraph cache_req_fsm { /* cnt_deliver() */ deliver [ shape=record - label="\ - {cnt_deliver:|\ - Filter obj.-\>resp.|\ - {vcl_deliver\{\}|\ - {req.*|resp.*}}|\ - {restart|deliver|synth}}" + label="{cnt_deliver:|Filter obj.-\>resp.|{vcl_deliver\{\}|{req.*|resp.*}}|{restart|deliver|synth}}" ] deliver:deliver:s -> V1D_Deliver [style=bold,color=green] @@ -66,10 +79,7 @@ digraph cache_req_fsm { subgraph xcluster_synth { synth [ shape=record - label="\ - {cnt_synth:|\ - {vcl_synth\{\}|{req.*|resp.*}}|\ - {deliver|restart}}" + label="{cnt_synth:|{vcl_synth\{\}|{req.*|resp.*}}|{deliver|restart}}" ] SYNTH -> synth [color=purple] @@ -108,24 +118,11 @@ digraph cache_req_fsm { shape=record color=grey fontcolor=grey - label="\ - {cnt_lookup:|\ - hash lookup|\ - {hit?|\ - miss?|\ - hit-for-pass?|\ - busy?}}" + label="{cnt_lookup:|hash lookup|{hit?|miss?|hit-for-pass?|busy?}}" ] lookup2 [ shape=record - label="\ - {cnt_lookup:|\ - {vcl_hit\{\}|{req.*|obj.*}}|\ - {deliver|\ - fetch|\ - restart|\ - synth|\ - pass}}" + label="{cnt_lookup:|{vcl_hit\{\}|{req.*|obj.*}}|{deliver|fetch|restart|synth|pass}}" ] } lookup:busy:e -> lookup:top:e [label="(waitinglist)", @@ -145,13 +142,7 @@ digraph cache_req_fsm { subgraph xcluster_miss { miss [ shape=record - label="\ - {cnt_miss:|\ - {vcl_miss\{\}|req.*}|\ - {fetch|\ - synth|\ - restart|\ - pass}}" + label="{cnt_miss:|{vcl_miss\{\}|req.*}|{fetch|synth|restart|pass}}" ] } miss:fetch:s -> FETCH [style=bold,color=blue] @@ -161,11 +152,7 @@ digraph cache_req_fsm { subgraph xcluster_pass { pass [ shape=record - label="{cnt_pass:|\ - {vcl_pass\{\}|req.*}|\ - {fetch|\ - synth|\ - restart}}" + label="{cnt_pass:|{vcl_pass\{\}|req.*}|{fetch|synth|restart}}" ] } pass:fetch:s -> FETCH [style=bold, color=red] @@ -174,12 +161,7 @@ digraph cache_req_fsm { subgraph xcluster_pipe { pipe [ shape=record - label="\ - {cnt_pipe:|\ - filter req.*-\>bereq.*|\ - {vcl_pipe\{\}|{req.*|bereq.*}}|\ - {pipe|\ - synth}}" + label="{cnt_pipe:|filter req.*-\>bereq.*|{vcl_pipe\{\}|{req.*|bereq.*}}|{pipe|synth}}" ] pipe_do [ shape=ellipse @@ -195,10 +177,7 @@ digraph cache_req_fsm { shape=record color=grey fontcolor=grey - label="\ - {cnt_restart:|\ - {ok?|\ - max_restarts?}}" + label="{cnt_restart:|{ok?|max_restarts?}}" ] } RESTART -> restart [color=purple] @@ -210,22 +189,13 @@ digraph cache_req_fsm { subgraph xcluster_recv { recv [ shape=record - label="\ - {cnt_recv:|\ - {vcl_recv\{\}|req.*}|\ - {hash|\ - purge|\ - pass|\ - pipe|\ - synth}}" - ] + label="{cnt_recv:|{vcl_recv\{\}|req.*}|{hash|purge|pass|pipe|synth}}" + ] recv:hash -> hash [style=bold,color=green] hash [ shape=record label="\ - {cnt_recv:|\ - {vcl_hash\{\}|req.*}|\ - {lookup}}"] + {cnt_recv:|{vcl_hash\{\}|req.*}|{lookup}}"] } recv:pipe -> pipe [style=bold,color=orange] recv:pass -> pass [style=bold,color=red] @@ -237,11 +207,7 @@ digraph cache_req_fsm { subgraph xcluster_purge { purge [ shape=record - label="\ - {cnt_purge:|\ - {vcl_purge\{\}|req.*}|\ - {synth|\ - restart}}" + label="{cnt_purge:|{vcl_purge\{\}|req.*}|{synth|restart}}" ] } } \ No newline at end of file From nils.goroll at uplex.de Mon Oct 13 17:36:04 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 13 Oct 2014 19:36:04 +0200 Subject: [master] 6c1e7f8 missed one last label -- make labels illegible for elderly graphvizes Message-ID: commit 6c1e7f8b76a7f9a6f879f20f824aa0d841725c2a Author: Nils Goroll Date: Mon Oct 13 19:36:01 2014 +0200 missed one last label -- make labels illegible for elderly graphvizes diff --git a/doc/graphviz/cache_req_fsm.dot b/doc/graphviz/cache_req_fsm.dot index e3a70d9..7311c6f 100644 --- a/doc/graphviz/cache_req_fsm.dot +++ b/doc/graphviz/cache_req_fsm.dot @@ -194,8 +194,8 @@ digraph cache_req_fsm { recv:hash -> hash [style=bold,color=green] hash [ shape=record - label="\ - {cnt_recv:|{vcl_hash\{\}|req.*}|{lookup}}"] + label="{cnt_recv:|{vcl_hash\{\}|req.*}|{lookup}}" + ] } recv:pipe -> pipe [style=bold,color=orange] recv:pass -> pass [style=bold,color=red] From nils.goroll at uplex.de Mon Oct 13 17:40:52 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 13 Oct 2014 19:40:52 +0200 Subject: [master] e82cedd typo Message-ID: commit e82cedd26561dc7900049d32afed93f65a42c36b Author: Nils Goroll Date: Mon Oct 13 19:37:37 2014 +0200 typo diff --git a/doc/graphviz/cache_req_fsm.dot b/doc/graphviz/cache_req_fsm.dot index 7311c6f..5ccfdf0 100644 --- a/doc/graphviz/cache_req_fsm.dot +++ b/doc/graphviz/cache_req_fsm.dot @@ -1,5 +1,5 @@ /* - * we should format labels in a reable form like + * we should format labels in a readable form like * label="\ * {cnt_deliver:|\ * Filter obj.-\>resp.|\ From nils.goroll at uplex.de Mon Oct 13 17:40:52 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 13 Oct 2014 19:40:52 +0200 Subject: [master] 3b5ff14 cache_fetch.dot: long lines for the elderly graphvizes Message-ID: commit 3b5ff141e3547e6d6e7aa10a8625a1863b20af11 Author: Nils Goroll Date: Mon Oct 13 19:40:49 2014 +0200 cache_fetch.dot: long lines for the elderly graphvizes diff --git a/doc/graphviz/cache_fetch.dot b/doc/graphviz/cache_fetch.dot index 1daf76f..4bc64de 100644 --- a/doc/graphviz/cache_fetch.dot +++ b/doc/graphviz/cache_fetch.dot @@ -1,3 +1,20 @@ +/* + * we should format labels in a readable form like + * label=" + * {vbf_stp_startfetch:| + * {vcl_backend_fetch\{\}|bereq.*}| + * {abandon| + * fetch}}" + * + * + * ... but some servers in the v-c.o build farm use old graphviz 2.26.3 + * which cannot handle labels with additional whitespace properly, so + * for the time being we need to fall back into dark middle ages and + * use illegibly long lines + * + * -- slink 20141013 + */ + digraph cache_fetch { margin="0.5" center="1" @@ -22,11 +39,7 @@ digraph cache_fetch { /* vbf_stp_startfetch() */ v_b_f [ shape=record - label=" - {vbf_stp_startfetch:| - {vcl_backend_fetch\{\}|bereq.*}| - {abandon| - fetch}}" + label="{vbf_stp_startfetch:|{vcl_backend_fetch\{\}|bereq.*}|{abandon|fetch}}" ] v_b_f:fetch:s -> v_b_hdrs [style=bold] v_b_hdrs [ label="send bereq,\nread beresp (headers)"] @@ -34,14 +47,7 @@ digraph cache_fetch { v_b_hdrs -> v_b_e v_b_r [ shape=record - label=" - {vbf_stp_startfetch:| - {vcl_backend_response\{\}|{ - bereq.*|beresp.*}}| - {{retry|{max?|ok?}}| - abandon| - {deliver|{304?| - other?}}}}" + label="{vbf_stp_startfetch:|{vcl_backend_response\{\}|{bereq.*|beresp.*}}|{{retry|{max?|ok?}}|abandon|{deliver|{304?|other?}}}}" ] v_b_r:retry -> v_b_r_retry [color=purple] v_b_r:max -> v_b_e @@ -54,23 +60,15 @@ digraph cache_fetch { shape=record fontcolor=grey color=grey - label=" - {vbf_stp_fetch:| - setup VFPs| - fetch| - {fetch_fail?|error?|ok?}}" - ] + label="{vbf_stp_fetch:|setup VFPs|fetch|{fetch_fail?|error?|ok?}}" + ] vbf_stp_fetch:ok:s -> FETCH_DONE vbf_stp_condfetch [ shape=record fontcolor=grey color=grey - label=" - {vbf_stp_condfetch:| - copy obj attr| - steal body| - {fetch_fail?|ok?}}" + label="{vbf_stp_condfetch:|copy obj attr|steal body|{fetch_fail?|ok?}}" ] vbf_stp_condfetch:ok:s -> FETCH_DONE @@ -81,13 +79,8 @@ digraph cache_fetch { /* vbf_stp_error */ v_b_e [ shape=record - label=" - {vbf_stp_error:| - {vcl_backend_error\{\}|{ - bereq.*|beresp.*}}| - {{retry|{max?|ok?}}| - deliver}}}" - ] + label="{vbf_stp_error:|{vcl_backend_error\{\}|{bereq.*|beresp.*}}|{{retry|{max?|ok?}}|deliver}}}" + ] // v_b_e:deliver aka "backend synth" - goes into cache v_b_e:deliver -> FETCH_DONE [label="\"backend synth\""] v_b_e:retry -> v_b_e_retry [color=purple] From fgsch at lodoss.net Tue Oct 14 00:52:18 2014 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Tue, 14 Oct 2014 02:52:18 +0200 Subject: [master] b9e53ea Fix lookbehind handling in regsuball Message-ID: commit b9e53ea2ebbb59d739bb2307b16743a9179090a4 Author: Federico G. Schwindt Date: Tue Oct 14 01:41:57 2014 +0100 Fix lookbehind handling in regsuball Do not advance the subject but use the ovector information as offset, pcre might need to peek back when handling lookbehinds. Original patch from MegaMaddin via github. Fixes: #1557 diff --git a/bin/varnishd/cache/cache_vrt_re.c b/bin/varnishd/cache/cache_vrt_re.c index 822f373..d784c13 100644 --- a/bin/varnishd/cache/cache_vrt_re.c +++ b/bin/varnishd/cache/cache_vrt_re.c @@ -107,6 +107,7 @@ VRT_regsub(VRT_CTX, int all, const char *str, void *re, const char *s; unsigned u, x; int options = 0; + int offset = 0; size_t len; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); @@ -135,7 +136,7 @@ VRT_regsub(VRT_CTX, int all, const char *str, void *re, do { /* Copy prefix to match */ - Tadd(&res_b, res_e, str, ovector[0]); + Tadd(&res_b, res_e, str + offset, ovector[0] - offset); for (s = sub ; *s != '\0'; s++ ) { if (*s != '\\' || s[1] == '\0') { if (res_b < res_e) @@ -153,13 +154,12 @@ VRT_regsub(VRT_CTX, int all, const char *str, void *re, *res_b++ = *s; } } - str += ovector[1]; - len -= ovector[1]; + offset = ovector[1]; if (!all) break; memset(&ovector, 0, sizeof(ovector)); options |= VRE_NOTEMPTY; - i = VRE_exec(t, str, len, 0, options, ovector, 30, + i = VRE_exec(t, str, len, offset, options, ovector, 30, &cache_param->vre_limits); if (i < VRE_ERROR_NOMATCH ) { WS_Release(ctx->ws, 0); @@ -170,7 +170,7 @@ VRT_regsub(VRT_CTX, int all, const char *str, void *re, } while (i != VRE_ERROR_NOMATCH); /* Copy suffix to match */ - Tadd(&res_b, res_e, str, len+1); + Tadd(&res_b, res_e, str + offset, len - offset + 1); if (res_b >= res_e) { WS_Release(ctx->ws, 0); return (str); diff --git a/bin/varnishtest/tests/r01557.vtc b/bin/varnishtest/tests/r01557.vtc new file mode 100644 index 0000000..8ada32f --- /dev/null +++ b/bin/varnishtest/tests/r01557.vtc @@ -0,0 +1,19 @@ +varnishtest "Test case for #1557" + +server s1 { + rxreq + expect req.url == "/?foobar=2" + txresp +} -start + +varnish v1 -vcl+backend { + sub vcl_recv { + set req.url = regsuball(req.url, + "(?<=[&\?])(foo|bar)=[^&]+(?:&|$)", ""); + } +} -start + +client c1 { + txreq -url "/?foo=0&bar=1&foobar=2" + rxresp +} -run From phk at FreeBSD.org Tue Oct 14 06:37:57 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 14 Oct 2014 08:37:57 +0200 Subject: [master] 216f878 Minor polish Message-ID: commit 216f878414563a5e479d5d8f15ffd5b86acfd600 Author: Poul-Henning Kamp Date: Tue Oct 14 06:37:35 2014 +0000 Minor polish diff --git a/bin/varnishd/cache/cache_vrt_re.c b/bin/varnishd/cache/cache_vrt_re.c index d784c13..15b11a5 100644 --- a/bin/varnishd/cache/cache_vrt_re.c +++ b/bin/varnishd/cache/cache_vrt_re.c @@ -157,7 +157,7 @@ VRT_regsub(VRT_CTX, int all, const char *str, void *re, offset = ovector[1]; if (!all) break; - memset(&ovector, 0, sizeof(ovector)); + memset(ovector, 0, sizeof(ovector)); options |= VRE_NOTEMPTY; i = VRE_exec(t, str, len, offset, options, ovector, 30, &cache_param->vre_limits); @@ -170,7 +170,7 @@ VRT_regsub(VRT_CTX, int all, const char *str, void *re, } while (i != VRE_ERROR_NOMATCH); /* Copy suffix to match */ - Tadd(&res_b, res_e, str + offset, len - offset + 1); + Tadd(&res_b, res_e, str + offset, 1 + len - offset); if (res_b >= res_e) { WS_Release(ctx->ws, 0); return (str); From phk at FreeBSD.org Tue Oct 14 06:37:57 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 14 Oct 2014 08:37:57 +0200 Subject: [master] 6289a84 Make vdir->getfd() actually return a fd Message-ID: commit 6289a84ddcafcabed21616b2bae9ef6773bdc25f Author: Poul-Henning Kamp Date: Tue Oct 14 06:37:41 2014 +0000 Make vdir->getfd() actually return a fd diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 2e233e9..6d99562 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -343,7 +343,7 @@ VBE_DiscardHealth(const struct director *vdi) * */ -static struct vbc * __match_proto__(vdi_getfd_f) +static int __match_proto__(vdi_getfd_f) vbe_dir_getfd(const struct director *d, struct busyobj *bo) { struct vbe_dir *vs; @@ -356,7 +356,7 @@ vbe_dir_getfd(const struct director *d, struct busyobj *bo) vc = vbe_GetVbe(bo, vs); if (vc == NULL) { VSLb(bo->vsl, SLT_FetchError, "no backend connection"); - return (NULL); + return (-1); } if (bo->htc == NULL) @@ -364,10 +364,9 @@ vbe_dir_getfd(const struct director *d, struct busyobj *bo) memset(bo->htc, 0, sizeof *bo->htc); bo->htc->magic = HTTP_CONN_MAGIC; bo->htc->vbc = vc; - bo->htc->fd = vc->fd; FIND_TMO(first_byte_timeout, vc->first_byte_timeout, bo, vs->vrt); FIND_TMO(between_bytes_timeout, vc->between_bytes_timeout, bo, vs->vrt); - return (vc); + return (vc->fd); } static unsigned __match_proto__(vdi_healthy_f) @@ -388,14 +387,13 @@ vbe_dir_gethdrs(const struct director *d, struct worker *wrk, struct busyobj *bo) { int i; - struct vbc *vbc; CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - vbc = vbe_dir_getfd(d, bo); - if (vbc == NULL) { + i = vbe_dir_getfd(d, bo); + if (i < 0) { VSLb(bo->vsl, SLT_FetchError, "no backend connection"); return (-1); } @@ -411,8 +409,8 @@ vbe_dir_gethdrs(const struct director *d, struct worker *wrk, AZ(bo->htc); VSC_C_main->backend_retry++; bo->doclose = SC_NULL; - vbc = vbe_dir_getfd(d, bo); - if (vbc == NULL) { + i = vbe_dir_getfd(d, bo); + if (i < 0) { VSLb(bo->vsl, SLT_FetchError, "no backend connection"); bo->htc = NULL; return (-1); diff --git a/bin/varnishd/cache/cache_director.c b/bin/varnishd/cache/cache_director.c index 7a961ad..c79b3a8 100644 --- a/bin/varnishd/cache/cache_director.c +++ b/bin/varnishd/cache/cache_director.c @@ -125,7 +125,7 @@ VDI_Finish(const struct director *d, struct worker *wrk, struct busyobj *bo) /* Get a connection --------------------------------------------------*/ -struct vbc * +int VDI_GetFd(const struct director *d, struct worker *wrk, struct busyobj *bo) { @@ -135,7 +135,7 @@ VDI_GetFd(const struct director *d, struct worker *wrk, struct busyobj *bo) d = vdi_resolve(wrk, bo, d); if (d == NULL) - return (NULL); + return (-1); AN(d->getfd); return (d->getfd(d, bo)); diff --git a/bin/varnishd/cache/cache_director.h b/bin/varnishd/cache/cache_director.h index f717aa4..cef951d 100644 --- a/bin/varnishd/cache/cache_director.h +++ b/bin/varnishd/cache/cache_director.h @@ -42,7 +42,7 @@ * backends to use. */ -typedef struct vbc *vdi_getfd_f(const struct director *, struct busyobj *); +typedef int vdi_getfd_f(const struct director *, struct busyobj *); typedef unsigned vdi_healthy_f(const struct director *, double *changed); typedef const struct director *vdi_resolve_f(const struct director *, struct worker *, struct busyobj *); @@ -76,8 +76,7 @@ int VDI_GetBody(const struct director *d, struct worker *wrk, struct busyobj *bo); void VDI_Finish(const struct director *d, struct worker *wrk, struct busyobj *bo); -struct vbc *VDI_GetFd(const struct director *d, struct worker *wrk, - struct busyobj *); +int VDI_GetFd(const struct director *d, struct worker *wrk, struct busyobj *); int VDI_Healthy(const struct director *); struct suckaddr *VDI_Suckaddr(const struct director *d, struct worker *wrk, struct busyobj *bo); diff --git a/bin/varnishd/http1/cache_http1_pipe.c b/bin/varnishd/http1/cache_http1_pipe.c index 84d91c4..f3fdb6a 100644 --- a/bin/varnishd/http1/cache_http1_pipe.c +++ b/bin/varnishd/http1/cache_http1_pipe.c @@ -95,10 +95,9 @@ pipecharge(struct req *req, const struct acct_pipe *a, struct VSC_C_vbe *b) void V1P_Process(struct req *req, struct busyobj *bo) { - struct vbc *vc; struct worker *wrk; struct pollfd fds[2]; - int i; + int i, fd; struct acct_pipe acct_pipe; ssize_t hdrbytes; @@ -114,19 +113,18 @@ V1P_Process(struct req *req, struct busyobj *bo) acct_pipe.req = req->acct.req_hdrbytes; req->acct.req_hdrbytes = 0; - vc = VDI_GetFd(bo->director_req, wrk, bo); - if (vc == NULL) { + fd = VDI_GetFd(bo->director_req, wrk, bo); + if (fd < 0) { pipecharge(req, &acct_pipe, NULL); SES_Close(req->sp, SC_OVERLOAD); return; } CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC); - assert(bo->htc->fd >= 0); bo->wrk = req->wrk; bo->director_state = DIR_S_BODY; - (void)VTCP_blocking(bo->htc->fd); + (void)VTCP_blocking(fd); - WRW_Reserve(wrk, &bo->htc->fd, bo->vsl, req->t_req); + WRW_Reserve(wrk, &fd, bo->vsl, req->t_req); hdrbytes = HTTP1_Write(wrk, bo->bereq, HTTP1_Req); if (req->htc->pipeline_b != NULL) @@ -143,7 +141,7 @@ V1P_Process(struct req *req, struct busyobj *bo) if (i == 0) { memset(fds, 0, sizeof fds); - fds[0].fd = bo->htc->fd; + fds[0].fd = fd; fds[0].events = POLLIN | POLLERR; fds[1].fd = req->sp->fd; fds[1].events = POLLIN | POLLERR; @@ -156,27 +154,27 @@ V1P_Process(struct req *req, struct busyobj *bo) if (i < 1) break; if (fds[0].revents && - rdf(bo->htc->fd, req->sp->fd, &acct_pipe.out)) { + rdf(fd, req->sp->fd, &acct_pipe.out)) { if (fds[1].fd == -1) break; - (void)shutdown(bo->htc->fd, SHUT_RD); + (void)shutdown(fd, SHUT_RD); (void)shutdown(req->sp->fd, SHUT_WR); fds[0].events = 0; fds[0].fd = -1; } if (fds[1].revents && - rdf(req->sp->fd, bo->htc->fd, &acct_pipe.in)) { + rdf(req->sp->fd, fd, &acct_pipe.in)) { if (fds[0].fd == -1) break; (void)shutdown(req->sp->fd, SHUT_RD); - (void)shutdown(bo->htc->fd, SHUT_WR); + (void)shutdown(fd, SHUT_WR); fds[1].events = 0; fds[1].fd = -1; } } } VSLb_ts_req(req, "PipeSess", W_TIM_real(wrk)); - pipecharge(req, &acct_pipe, vc->backend->vsc); + pipecharge(req, &acct_pipe, bo->htc->vbc->backend->vsc); SES_Close(req->sp, SC_TX_PIPE); bo->doclose = SC_TX_PIPE; VDI_Finish(bo->director_resp, bo->wrk, bo); From daghf at varnish-software.com Tue Oct 14 08:53:58 2014 From: daghf at varnish-software.com (Dag Haavi Finstad) Date: Tue, 14 Oct 2014 10:53:58 +0200 Subject: [master] 03a5a8d Make cache_director.h available for use with out-of-tree director VMODs. Message-ID: commit 03a5a8dd2c8dbb409b114505eed6b1c4c0275c26 Author: Dag Haavi Finstad Date: Tue Oct 14 10:52:06 2014 +0200 Make cache_director.h available for use with out-of-tree director VMODs. diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index fdec53b..6e97946 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -109,6 +109,7 @@ nobase_pkgdatainclude_HEADERS = \ cache/cache.h \ cache/cache_filter.h \ cache/cache_backend.h \ + cache/cache_director.h \ common/common.h \ common/params.h From phk at FreeBSD.org Thu Oct 16 08:52:47 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Oct 2014 10:52:47 +0200 Subject: [master] da82191 Assert we don't run out of session workspace. Message-ID: commit da821915be061ed7d24eb7ccbfada7b195a270b0 Author: Poul-Henning Kamp Date: Thu Oct 16 08:52:30 2014 +0000 Assert we don't run out of session workspace. diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index c2a0836..2532f12 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -87,6 +87,7 @@ ses_new(struct sesspool *pp) assert(p < e); WS_Init(sp->ws, "ses", p, e - p); sp->addrs = WS_Alloc(sp->ws, vsa_suckaddr_len * 2); + AN(sp->addrs); sp->t_open = NAN; sp->t_idle = NAN; @@ -169,7 +170,9 @@ ses_vsl_socket(struct sess *sp, const char *lsockname) VTCP_name(sess_remote_addr(sp), laddr, sizeof laddr, lport, sizeof lport); sp->client_addr_str = WS_Copy(sp->ws, laddr, -1); + AN(sp->client_addr_str); sp->client_port_str = WS_Copy(sp->ws, lport, -1); + AN(sp->client_port_str); VTCP_name(sess_local_addr(sp), laddr, sizeof laddr, lport, sizeof lport); VSL(SLT_Begin, sp->vxid, "sess 0 HTTP/1"); From phk at FreeBSD.org Thu Oct 16 09:14:26 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Oct 2014 11:14:26 +0200 Subject: [master] 8aa461e Put a canary byte at the end of workspaces Message-ID: commit 8aa461e2aab84e3da6af6dc37eab6db37fc968cc Author: Poul-Henning Kamp Date: Thu Oct 16 09:14:05 2014 +0000 Put a canary byte at the end of workspaces diff --git a/bin/varnishd/cache/cache_ws.c b/bin/varnishd/cache/cache_ws.c index 42e6121..aad9fec 100644 --- a/bin/varnishd/cache/cache_ws.c +++ b/bin/varnishd/cache/cache_ws.c @@ -57,6 +57,7 @@ WS_Assert(const struct ws *ws) assert(ws->r <= ws->e); assert(PAOK(ws->r)); } + assert(*ws->e == 0x15); } /* @@ -75,8 +76,9 @@ WS_Init(struct ws *ws, const char *id, void *space, unsigned len) ws->magic = WS_MAGIC; ws->s = space; assert(PAOK(space)); - len = PRNDDN(len); + len = PRNDDN(len - 1); ws->e = ws->s + len; + *ws->e = 0x15; ws->f = ws->s; assert(id[0] & 0x40); assert(strlen(id) < sizeof ws->id); From nils.goroll at uplex.de Thu Oct 16 10:04:41 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 16 Oct 2014 12:04:41 +0200 Subject: [3.0] 7c39957 recommend system libjemalloc Message-ID: commit 7c399574bedf21a2caebfff59b2cee43fa68aeb0 Author: Nils Goroll Date: Thu Oct 16 12:04:15 2014 +0200 recommend system libjemalloc diff --git a/doc/sphinx/installation/install.rst b/doc/sphinx/installation/install.rst index 1c6414f..794e938 100644 --- a/doc/sphinx/installation/install.rst +++ b/doc/sphinx/installation/install.rst @@ -97,6 +97,10 @@ installed. On a Debian or Ubuntu system these are: * libpcre3-dev * pkg-config +recommended: + +* libjemalloc-dev + Build dependencies on Red Hat / CentOS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -112,6 +116,10 @@ packages installed: * pcre-devel * pkgconfig +recommended: + +* jemalloc-devel + Configuring and compiling ~~~~~~~~~~~~~~~~~~~~~~~~~ From lkarsten at varnish-software.com Thu Oct 16 13:29:45 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Thu, 16 Oct 2014 15:29:45 +0200 Subject: [3.0] dc17564 Prepare 3.0.6rc2. Message-ID: commit dc17564b9de4e4543c0feea64f410b1bafba9775 Author: Lasse Karstensen Date: Thu Oct 16 15:29:39 2014 +0200 Prepare 3.0.6rc2. diff --git a/configure.ac b/configure.ac index 04c0096..af231e5 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.59) AC_COPYRIGHT([Copyright (c) 2006 Verdens Gang AS Copyright (c) 2006-2014 Varnish Software AS]) AC_REVISION([$Id$]) -AC_INIT([Varnish], [3.0.6rc1], [varnish-dev at varnish-cache.org]) +AC_INIT([Varnish], [3.0.6rc2], [varnish-dev at varnish-cache.org]) AC_CONFIG_SRCDIR(include/varnishapi.h) AM_CONFIG_HEADER(config.h) diff --git a/doc/changes.rst b/doc/changes.rst index 247547c..857f7d1 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -1,5 +1,15 @@ +============================================== +Changes from 3.0.6rc1 to 3.0.6rc2 (2014-10-16) +============================================== + +- Minor changes to documentation. +- [varnishadm] Add termcap workaround for libedit. Bug 1514_. + +.. _1531: http://varnish-cache.org/trac/ticket/1531 + + ============================================ -Changes from 3.0.5 to 3.0.6-rc1 (2014-06-24) +Changes from 3.0.5 to 3.0.6rc1 (2014-06-24) ============================================ - Document storage..* VCL variables. Bug 1514_. From lkarsten at varnish-software.com Thu Oct 16 13:33:39 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Thu, 16 Oct 2014 15:33:39 +0200 Subject: [3.0] 928b0af Forgotten version number in last commit. Message-ID: commit 928b0aff4b337164529328b5e0fb5e73717851a4 Author: Lasse Karstensen Date: Thu Oct 16 15:33:26 2014 +0200 Forgotten version number in last commit. diff --git a/redhat/varnish.spec b/redhat/varnish.spec index bc4b4f3..2d2de1a 100644 --- a/redhat/varnish.spec +++ b/redhat/varnish.spec @@ -2,7 +2,7 @@ %define __find_provides %{_builddir}/varnish-%{version}%{?v_rc:-%{?v_rc}}/redhat/find-provides Summary: High-performance HTTP accelerator Name: varnish -Version: 3.0.6rc1 +Version: 3.0.6rc2 Release: 1%{?dist} License: BSD Group: System Environment/Daemons From lkarsten at varnish-software.com Thu Oct 16 13:36:20 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Thu, 16 Oct 2014 15:36:20 +0200 Subject: [3.0] 80381e6 Improve description of effects of bug 1470. Message-ID: commit 80381e671cb8e81ccd354864495b813bcd844cd4 Author: Lasse Karstensen Date: Thu Oct 16 15:34:57 2014 +0200 Improve description of effects of bug 1470. Spotted by: scoof diff --git a/doc/changes.rst b/doc/changes.rst index 857f7d1..4a9a7ed 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -17,7 +17,7 @@ Changes from 3.0.5 to 3.0.6rc1 (2014-06-24) - Avoid negative ReqEnd timestamps with ESI. Bug 1297_. - %D format for varnishncsa is now an integer (as documented) - Fix compile errors with clang. -- Clear objectcore flags earlier in ban lurker. Bug 1470_. +- Clear objectcore flags earlier in ban lurker to avoid spinning thread. Bug 1470_. - Patch embedded jemalloc to avoid segfault. Bug 1448_. - Allow backend names to start with if, include or else. Bug 1439_. - Stop handling gzip after gzip body end. Bug 1086_. From lkarsten at varnish-software.com Thu Oct 16 14:00:12 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Thu, 16 Oct 2014 16:00:12 +0200 Subject: [4.0] 5c5634d Only override CFLAGS on RHEL6. Message-ID: commit 5c5634dbd9211c4b784268166709a22177d643de Author: Lasse Karstensen Date: Thu Oct 16 15:57:36 2014 +0200 Only override CFLAGS on RHEL6. And also don't disable the default compiler optimization. diff --git a/redhat/varnish.spec b/redhat/varnish.spec index 33f418d..6c0e104 100644 --- a/redhat/varnish.spec +++ b/redhat/varnish.spec @@ -102,7 +102,9 @@ Documentation files for %name export PCRE_LIBS="`pcre-config --libs`" %endif -export CFLAGS="$CFLAGS -Wp,-D_FORTIFY_SOURCE=0" +%if 0%{?rhel} == 6 +export CFLAGS="$CFLAGS -O2 -g -Wp,-D_FORTIFY_SOURCE=0" +%endif # Remove "--disable static" if you want to build static libraries # jemalloc is not compatible with Red Hat's ppc64 RHEL kernel :-( From lkarsten at varnish-software.com Thu Oct 16 14:00:21 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Thu, 16 Oct 2014 16:00:21 +0200 Subject: [master] e74ad45 Only override CFLAGS on RHEL6. Message-ID: commit e74ad45e2ec6f46dee897f6a8b8bf372929316c0 Author: Lasse Karstensen Date: Thu Oct 16 15:57:36 2014 +0200 Only override CFLAGS on RHEL6. And also don't disable the default compiler optimization. diff --git a/redhat/varnish.spec b/redhat/varnish.spec index ad2a914..146548d 100644 --- a/redhat/varnish.spec +++ b/redhat/varnish.spec @@ -102,7 +102,9 @@ Documentation files for %name export PCRE_LIBS="`pcre-config --libs`" %endif -export CFLAGS="$CFLAGS -Wp,-D_FORTIFY_SOURCE=0" +%if 0%{?rhel} == 6 +export CFLAGS="$CFLAGS -O2 -g -Wp,-D_FORTIFY_SOURCE=0" +%endif # Remove "--disable static" if you want to build static libraries # jemalloc is not compatible with Red Hat's ppc64 RHEL kernel :-( From lkarsten at varnish-software.com Thu Oct 16 14:25:37 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Thu, 16 Oct 2014 16:25:37 +0200 Subject: [3.0] 3cf2f3f Update copyright statement. Message-ID: commit 3cf2f3f82b7979a6686a2c642036245c989c1235 Author: Lasse Karstensen Date: Mon Sep 29 15:25:17 2014 +0200 Update copyright statement. diff --git a/LICENSE b/LICENSE index a6cf987..67dc00a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ Copyright (c) 2006 Verdens Gang AS -Copyright (c) 2006-2011 Varnish Software AS +Copyright (c) 2006-2014 Varnish Software AS All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/lib/libvarnish/version.c b/lib/libvarnish/version.c index 3427ee7..27aef30 100644 --- a/lib/libvarnish/version.c +++ b/lib/libvarnish/version.c @@ -44,5 +44,5 @@ VCS_Message(const char *progname) { fprintf(stderr, "%s (%s)\n", progname, VCS_version); fprintf(stderr, "Copyright (c) 2006 Verdens Gang AS\n"); - fprintf(stderr, "Copyright (c) 2006-2011 Varnish Software AS\n"); + fprintf(stderr, "Copyright (c) 2006-2014 Varnish Software AS\n"); } From lkarsten at varnish-software.com Thu Oct 16 14:25:37 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Thu, 16 Oct 2014 16:25:37 +0200 Subject: [3.0] 1899836 Prepare 3.0.6. Message-ID: commit 189983631ab483acc2fccde99a5f4c8723065936 Author: Lasse Karstensen Date: Thu Oct 16 16:24:56 2014 +0200 Prepare 3.0.6. diff --git a/configure.ac b/configure.ac index af231e5..3ad3f53 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.59) AC_COPYRIGHT([Copyright (c) 2006 Verdens Gang AS Copyright (c) 2006-2014 Varnish Software AS]) AC_REVISION([$Id$]) -AC_INIT([Varnish], [3.0.6rc2], [varnish-dev at varnish-cache.org]) +AC_INIT([Varnish], [3.0.6], [varnish-dev at varnish-cache.org]) AC_CONFIG_SRCDIR(include/varnishapi.h) AM_CONFIG_HEADER(config.h) diff --git a/doc/changes.rst b/doc/changes.rst index 4a9a7ed..56c53d6 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -1,6 +1,6 @@ -============================================== -Changes from 3.0.6rc1 to 3.0.6rc2 (2014-10-16) -============================================== +=========================================== +Changes from 3.0.6rc1 to 3.0.6 (2014-10-16) +=========================================== - Minor changes to documentation. - [varnishadm] Add termcap workaround for libedit. Bug 1514_. diff --git a/redhat/varnish.spec b/redhat/varnish.spec index 2d2de1a..72d12be 100644 --- a/redhat/varnish.spec +++ b/redhat/varnish.spec @@ -2,7 +2,7 @@ %define __find_provides %{_builddir}/varnish-%{version}%{?v_rc:-%{?v_rc}}/redhat/find-provides Summary: High-performance HTTP accelerator Name: varnish -Version: 3.0.6rc2 +Version: 3.0.6 Release: 1%{?dist} License: BSD Group: System Environment/Daemons From nils.goroll at uplex.de Thu Oct 16 16:07:04 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 16 Oct 2014 18:07:04 +0200 Subject: [master] 8c5d5b5 Add dot sources to the distribution and clean output Message-ID: commit 8c5d5b5d90a39f0bf3ce1d0c3f774fff224200cd Author: Nils Goroll Date: Thu Oct 16 18:06:37 2014 +0200 Add dot sources to the distribution and clean output This should survive a distcheck again. diff --git a/doc/graphviz/Makefile.am b/doc/graphviz/Makefile.am index dd2ef4c..acbe4fe 100644 --- a/doc/graphviz/Makefile.am +++ b/doc/graphviz/Makefile.am @@ -20,6 +20,8 @@ dist-hook: # this is a4, letter is 8.5,11 SIZE = 8.4,11.7 +EXTRA_DIST = $(srcdir)/*.dot + if HAVE_DOT PDFS = \ cache_http1_fsm.pdf \ @@ -30,6 +32,10 @@ SVGS = \ cache_http1_fsm.svg \ cache_req_fsm.svg \ cache_fetch.svg + +CLEANFILES = \ + $(PDFS) \ + $(SVGS) endif pdf: $(PDFS) From fgsch at lodoss.net Thu Oct 16 23:07:58 2014 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Fri, 17 Oct 2014 01:07:58 +0200 Subject: [master] 25dc9af Remove more varnishsizes references Message-ID: commit 25dc9af97a584e7f3eb893d4ac84848fa656d55f Author: Federico G. Schwindt Date: Thu Oct 16 23:30:05 2014 +0100 Remove more varnishsizes references diff --git a/doc/sphinx/reference/index.rst b/doc/sphinx/reference/index.rst index 72924e3..fa69356 100644 --- a/doc/sphinx/reference/index.rst +++ b/doc/sphinx/reference/index.rst @@ -16,7 +16,6 @@ The Varnish Reference Manual varnishlog.rst varnishncsa.rst varnishreplay.rst - varnishsizes.rst varnishstat.rst varnishtest.rst varnishtop.rst diff --git a/doc/sphinx/reference/varnishsizes.rst b/doc/sphinx/reference/varnishsizes.rst deleted file mode 100644 index af2e05b..0000000 --- a/doc/sphinx/reference/varnishsizes.rst +++ /dev/null @@ -1,86 +0,0 @@ -============ -varnishsizes -============ - -------------------------------------- -Varnish object size request histogram -------------------------------------- - - -SYNOPSIS -======== - -varnishsizes [-b] [-C] [-c] [-d] [-I regex] [-i tag] [-m tag:regex ...] - [-n varnish_name] [-r file] [-V] [-w delay] [-X regex] [-x tag] - -DESCRIPTION -=========== - -The varnishsizes utility reads varnishd(1) shared memory logs and presents -a continuously updated histogram showing the distribution of the last N -requests by their processing. The value of N and the vertical scale are -displayed in the top left corner. The horizontal scale is a logarithmic -representation of bytes. Hits are marked with a pipe character -("|"), and misses are marked with a hash character ("#"). - -The following options are available: - --b Include log entries which result from communication with a backend server. - If neither -b nor -c is specified, varnishsizes acts as if they both were. - --C Ignore case when matching regular expressions. - --c Include log entries which result from communication with a client. - If neither -b nor -c is specified, varnishsizes acts as if they both were. - --d Process old log entries on startup. Normally, varnishsizes will only - process entries which are written to the log after it starts. - --I regex Include log entries which match the specified regular expression. - If neither -I nor -i is specified, all log entries are included. - --i tag Include log entries with the specified tag. If neither -I nor -i - is specified, all log entries are included. - --m tag:regex only list record where tag matches regex. Multiple -m - options are AND-ed together. - --n Specifies the name of the varnishd instance to get logs from. - If -n is not specified, the host name is used. - --r file Read log entries from file instead of shared memory. - --V Display the version number and exit. - --w delay Wait at least delay seconds between each update. The default is 1. - file instead of displaying them. The file will be overwritten - unless the -a option was specified. - --X regex Exclude log entries which match the specified regular expression. - --x tag Exclude log entries with the specified tag. - -SEE ALSO -======== - -* varnishd(1) -* varnishlog(1) -* varnishncsa(1) -* varnishstat(1) -* varnishtop(1) - -HISTORY -======= - -The varnishsizes utility was developed by Kristian Lyngst?l based on -varnishhist. This manual page was written by Kristian Lyngst?l, -Dag-Erling Sm?rgrav and Per Buer. - - -COPYRIGHT -========= - -This document is licensed under the same licence as Varnish -itself. See LICENCE for details. - -* Copyright (c) 2010 Varnish Software AS From daghf at varnish-software.com Fri Oct 17 12:17:04 2014 From: daghf at varnish-software.com (Dag Haavi Finstad) Date: Fri, 17 Oct 2014 14:17:04 +0200 Subject: [master] b521466 Docfix: Make SLT_TTL format match with reality. Message-ID: commit b5214662e8f7fa58a21a9ccb8cbfc35198fca18b Author: Dag Haavi Finstad Date: Fri Oct 17 14:14:32 2014 +0200 Docfix: Make SLT_TTL format match with reality. diff --git a/include/tbl/vsl_tags.h b/include/tbl/vsl_tags.h index 0fc3b86..4e134ba 100644 --- a/include/tbl/vsl_tags.h +++ b/include/tbl/vsl_tags.h @@ -197,12 +197,12 @@ SLTM(TTL, 0, "TTL set on object", "A TTL record is emitted whenever the ttl, grace or keep" " values for an object is set.\n\n" "The format is::\n\n" - "\t%s %d %d %d %d %d [ %d %u %u ]\n" - "\t| | | | | | | | |\n" - "\t| | | | | | | | +- Max-Age from Cache-Control header\n" - "\t| | | | | | | +---- Expires header\n" - "\t| | | | | | +------- Date header\n" - "\t| | | | | +------------ Age (incl Age: header value)\n" + "\t%s %d %d %d %d [ %d %d %u %u ]\n" + "\t| | | | | | | | |\n" + "\t| | | | | | | | +- Max-Age from Cache-Control header\n" + "\t| | | | | | | +---- Expires header\n" + "\t| | | | | | +------- Date header\n" + "\t| | | | | +---------- Age (incl Age: header value)\n" "\t| | | | +--------------- Reference time for TTL\n" "\t| | | +------------------ Keep\n" "\t| | +--------------------- Grace\n" From fgsch at lodoss.net Sat Oct 18 11:07:06 2014 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Sat, 18 Oct 2014 13:07:06 +0200 Subject: [master] 682a5cd Update examples Message-ID: commit 682a5cdda8398215fba044e83d3229356580643a Author: Federico G. Schwindt Date: Sat Oct 18 12:05:35 2014 +0100 Update examples diff --git a/include/tbl/vsl_tags.h b/include/tbl/vsl_tags.h index 4e134ba..8ca37d0 100644 --- a/include/tbl/vsl_tags.h +++ b/include/tbl/vsl_tags.h @@ -211,12 +211,8 @@ SLTM(TTL, 0, "TTL set on object", "\n" "The last four fields are only present in \"RFC\" headers.\n\n" "Examples::\n\n" - "\tRFC 19 -1 -1 1312966109 4 0 0 23\n" - "\tVCL 10 -1 -1 1312966109 4\n" - "\tVCL 7 -1 -1 1312966111 6\n" - "\tVCL 7 120 -1 1312966111 6\n" - "\tVCL 7 120 3600 1312966111 6\n" - "\tVCL 12 120 3600 1312966113 8\n" + "\tRFC 60 -1 -1 1312966109 1312966109 1312966109 0 60\n" + "\tVCL 120 10 0 1312966111\n" "\n" ) From phk at FreeBSD.org Mon Oct 20 08:51:09 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 20 Oct 2014 10:51:09 +0200 Subject: [master] 9cc77a4 Add an assert for Coverity Message-ID: commit 9cc77a45a85b611f7e45058aa0f0d25fb43917fb Author: Poul-Henning Kamp Date: Mon Oct 20 07:33:38 2014 +0000 Add an assert for Coverity diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 6d99562..c796ea7 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -361,6 +361,7 @@ vbe_dir_getfd(const struct director *d, struct busyobj *bo) if (bo->htc == NULL) bo->htc = WS_Alloc(bo->ws, sizeof *bo->htc); + AN(bo->htc); memset(bo->htc, 0, sizeof *bo->htc); bo->htc->magic = HTTP_CONN_MAGIC; bo->htc->vbc = vc; From phk at FreeBSD.org Mon Oct 20 08:51:09 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 20 Oct 2014 10:51:09 +0200 Subject: [master] f766f17 For esi-child + gzip, wait for BOS_Finished rather than for busyobj pointer to disappear. Message-ID: commit f766f17fc6bec17ff53fefef49aa28bf85fec594 Author: Poul-Henning Kamp Date: Mon Oct 20 08:50:01 2014 +0000 For esi-child + gzip, wait for BOS_Finished rather than for busyobj pointer to disappear. diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 0e63c41..7759581 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -338,10 +338,8 @@ V1D_Deliver(struct req *req, struct busyobj *bo) ESI_Deliver(req); } else if (req->res_mode & RES_ESI_CHILD && req->gzip_resp) { l = -1; - while (req->objcore->busyobj) { - assert(bo != NULL); - l = VBO_waitlen(req->wrk, bo, l); - } + if (bo != NULL) + VBO_waitstate(bo, BOS_FINISHED); ESI_DeliverChild(req); } else if (req->res_mode & RES_GUNZIP || (req->res_mode & RES_ESI_CHILD && From phk at FreeBSD.org Mon Oct 20 08:51:09 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 20 Oct 2014 10:51:09 +0200 Subject: [master] 1e639d1 If we are not going to stream, wait for BOS_FINISH. Message-ID: commit 1e639d1c41b0be6af3007b3b832ba8829655b00e Author: Poul-Henning Kamp Date: Mon Oct 20 08:50:43 2014 +0000 If we are not going to stream, wait for BOS_FINISH. diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 4649231..30507ff 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -138,8 +138,14 @@ cnt_deliver(struct worker *wrk, struct req *req) /* Grab a ref to the bo if there is one, and hand it down */ bo = HSH_RefBusy(req->objcore); - if (bo != NULL && req->esi_level == 0 && bo->state == BOS_FINISHED) - VBO_DerefBusyObj(wrk, &bo); + if (bo != NULL) { + if (req->esi_level == 0 && bo->state == BOS_FINISHED) { + VBO_DerefBusyObj(wrk, &bo); + } else if (!bo->do_stream) { + VBO_waitstate(bo, BOS_FINISHED); + VBO_DerefBusyObj(wrk, &bo); + } + } V1D_Deliver(req, bo); if (bo != NULL) VBO_DerefBusyObj(wrk, &bo); From phk at FreeBSD.org Mon Oct 20 10:15:00 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 20 Oct 2014 12:15:00 +0200 Subject: [master] cd64cd8 Remove unused variable Message-ID: commit cd64cd802a5f4c50d5a813f829d9e5e414b6cd81 Author: Poul-Henning Kamp Date: Mon Oct 20 10:14:20 2014 +0000 Remove unused variable diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 7759581..83883f3 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -232,7 +232,6 @@ V1D_Deliver(struct req *req, struct busyobj *bo) { const char *r; enum objiter_status ois; - ssize_t l; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); @@ -337,7 +336,6 @@ V1D_Deliver(struct req *req, struct busyobj *bo) } else if (req->res_mode & RES_ESI) { ESI_Deliver(req); } else if (req->res_mode & RES_ESI_CHILD && req->gzip_resp) { - l = -1; if (bo != NULL) VBO_waitstate(bo, BOS_FINISHED); ESI_DeliverChild(req); From phk at FreeBSD.org Mon Oct 20 10:15:00 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 20 Oct 2014 12:15:00 +0200 Subject: [master] 7b3bfa0 Remove unused VSC counters Message-ID: commit 7b3bfa0d4276e648ea549f7bbbda4bda3e7e8b2c Author: Poul-Henning Kamp Date: Mon Oct 20 10:14:32 2014 +0000 Remove unused VSC counters diff --git a/include/tbl/vsc_f_main.h b/include/tbl/vsc_f_main.h index 3524569..7e592ef 100644 --- a/include/tbl/vsc_f_main.h +++ b/include/tbl/vsc_f_main.h @@ -449,29 +449,6 @@ VSC_F(shm_cycles, uint64_t, 0, 'a', diag, /*--------------------------------------------------------------------*/ -VSC_F(sms_nreq, uint64_t, 0, 'a', diag, - "SMS allocator requests", - "" -) -VSC_F(sms_nobj, uint64_t, 0, 'i', diag, - "SMS outstanding allocations", - "" -) -VSC_F(sms_nbytes, uint64_t, 0, 'i', diag, - "SMS outstanding bytes", - "" -) -VSC_F(sms_balloc, uint64_t, 0, 'i', diag, - "SMS bytes allocated", - "" -) -VSC_F(sms_bfree, uint64_t, 0, 'i', diag, - "SMS bytes freed", - "" -) - -/*--------------------------------------------------------------------*/ - VSC_F(backend_req, uint64_t, 0, 'a', info, "Backend requests made", "" From phk at FreeBSD.org Mon Oct 20 12:22:23 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 20 Oct 2014 14:22:23 +0200 Subject: [master] 9a2a221 Fix the leaking req on failure to put a waiting-list session back in play in a way that does not lead to panics. Message-ID: commit 9a2a221c713b7329231d7a1b9e996a4a41eedcf2 Author: Poul-Henning Kamp Date: Mon Oct 20 12:21:31 2014 +0000 Fix the leaking req on failure to put a waiting-list session back in play in a way that does not lead to panics. Spotted by: Martin Fixes #1607 diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c index 7fe3d86..2c5592f 100644 --- a/bin/varnishd/cache/cache_hash.c +++ b/bin/varnishd/cache/cache_hash.c @@ -533,13 +533,8 @@ hsh_rush(struct worker *wrk, struct objhead *oh) AZ(req->wrk); VTAILQ_REMOVE(&wl->list, req, w_list); DSL(DBG_WAITINGLIST, req->vsl->wid, "off waiting list"); - if (SES_ScheduleReq(req)) { - /* - * We could not schedule the session, put it back. - */ - VTAILQ_INSERT_HEAD(&wl->list, req, w_list); + if (SES_ScheduleReq(req)) break; - } } if (VTAILQ_EMPTY(&wl->list)) { oh->waitinglist = NULL; diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index 2532f12..ef3f11b 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -241,6 +241,7 @@ SES_ScheduleReq(struct req *req) if (Pool_Task(pp->pool, &sp->task, POOL_QUEUE_FRONT)) { AN (req->vcl); VCL_Rel(&req->vcl); + SES_ReleaseReq(req); SES_Delete(sp, SC_OVERLOAD, NAN); return (1); } From phk at FreeBSD.org Mon Oct 20 12:54:38 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 20 Oct 2014 14:54:38 +0200 Subject: [master] 9fbcb4e If we fail to reschedule from the waiting list, we ditch the entire waiting list in an attempt to recover. Message-ID: commit 9fbcb4e94942a1bc7ff540f0a475b057a616b1ae Author: Poul-Henning Kamp Date: Mon Oct 20 12:53:43 2014 +0000 If we fail to reschedule from the waiting list, we ditch the entire waiting list in an attempt to recover. This also fixes buglet in previous commit which failed to call CNT_AcctLogCharge() diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c index 2c5592f..5f603b1 100644 --- a/bin/varnishd/cache/cache_hash.c +++ b/bin/varnishd/cache/cache_hash.c @@ -517,6 +517,7 @@ hsh_rush(struct worker *wrk, struct objhead *oh) { unsigned u; struct req *req; + struct sess *sp; struct waitinglist *wl; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); @@ -533,8 +534,29 @@ hsh_rush(struct worker *wrk, struct objhead *oh) AZ(req->wrk); VTAILQ_REMOVE(&wl->list, req, w_list); DSL(DBG_WAITINGLIST, req->vsl->wid, "off waiting list"); - if (SES_ScheduleReq(req)) + if (SES_ScheduleReq(req)) { + /* + * In case of overloads, we ditch the entire + * waiting list. + */ + while (1) { + AN (req->vcl); + VCL_Rel(&req->vcl); + sp = req->sp; + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CNT_AcctLogCharge(wrk->stats, req); + SES_ReleaseReq(req); + SES_Delete(sp, SC_OVERLOAD, NAN); + req = VTAILQ_FIRST(&wl->list); + if (req == NULL) + break; + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + VTAILQ_REMOVE(&wl->list, req, w_list); + DSL(DBG_WAITINGLIST, req->vsl->wid, + "kill from waiting list"); + } break; + } } if (VTAILQ_EMPTY(&wl->list)) { oh->waitinglist = NULL; diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index ef3f11b..04a4ca5 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -238,14 +238,7 @@ SES_ScheduleReq(struct req *req) sp->task.func = ses_req_pool_task; sp->task.priv = req; - if (Pool_Task(pp->pool, &sp->task, POOL_QUEUE_FRONT)) { - AN (req->vcl); - VCL_Rel(&req->vcl); - SES_ReleaseReq(req); - SES_Delete(sp, SC_OVERLOAD, NAN); - return (1); - } - return (0); + return (Pool_Task(pp->pool, &sp->task, POOL_QUEUE_FRONT)); } /*-------------------------------------------------------------------- From phk at FreeBSD.org Mon Oct 20 13:23:00 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 20 Oct 2014 15:23:00 +0200 Subject: [master] 242dcf0 Add a counter for "killed from waiting list" Message-ID: commit 242dcf06affd7df5eca17ca23948000775446184 Author: Poul-Henning Kamp Date: Mon Oct 20 13:22:46 2014 +0000 Add a counter for "killed from waiting list" diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c index 5f603b1..dc18cfe 100644 --- a/bin/varnishd/cache/cache_hash.c +++ b/bin/varnishd/cache/cache_hash.c @@ -539,7 +539,9 @@ hsh_rush(struct worker *wrk, struct objhead *oh) * In case of overloads, we ditch the entire * waiting list. */ + wrk->stats->busy_wakeup--; while (1) { + wrk->stats->busy_killed++; AN (req->vcl); VCL_Rel(&req->vcl); sp = req->sp; diff --git a/include/tbl/vsc_f_main.h b/include/tbl/vsc_f_main.h index 7e592ef..f714e33 100644 --- a/include/tbl/vsc_f_main.h +++ b/include/tbl/vsc_f_main.h @@ -293,6 +293,12 @@ VSC_F(busy_wakeup, uint64_t, 1, 'c', info, " and rescheduled." ) +VSC_F(busy_killed, uint64_t, 1, 'c', info, + "Number of requests killed after sleep on busy objhdr", + "Number of requests killed from the busy object sleep list" + " due to lack of resources." +) + VSC_F(sess_queued, uint64_t, 0, 'c', info, "Sessions queued for thread", "Number of times session was queued waiting for a thread." From phk at FreeBSD.org Tue Oct 21 09:01:31 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 21 Oct 2014 11:01:31 +0200 Subject: [master] 44a996f Fix a cornercase related to empty pass objects. Message-ID: commit 44a996f4c15c59eda38b263af5de81af5e8cd2fd Author: Poul-Henning Kamp Date: Tue Oct 21 09:00:52 2014 +0000 Fix a cornercase related to empty pass objects. Fixes #1612 Testcase by: daghf diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 83883f3..3f0f341 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -238,31 +238,38 @@ V1D_Deliver(struct req *req, struct busyobj *bo) req->res_mode = 0; + if (req->esi_level > 0) + req->res_mode |= RES_ESI_CHILD; + if (!req->disable_esi && ObjGetattr(req->wrk, req->objcore, OA_ESIDATA, NULL) != NULL) { /* In ESI mode, we can't know the aggregate length */ - req->res_mode &= ~RES_LEN; req->res_mode |= RES_ESI; + RFC2616_Weaken_Etag(req->resp); + } + + if (req->res_mode & (RES_ESI_CHILD|RES_ESI)) { + /* nothing */ } else if (http_IsStatus(req->resp, 304)) { req->res_mode &= ~RES_LEN; http_Unset(req->resp, H_Content_Length); req->wantbody = 0; - } else if (bo == NULL) { - /* XXX: Not happy with this convoluted test */ + } else if (bo != NULL) { + /* Streaming, decide CHUNKED/EOF later */ + } else if ((req->objcore->flags & OC_F_PASS) && !req->wantbody) { + /* + * if we pass a HEAD the C-L header may already be in the + * object and it will not match the actual storage length + * which is zero. + * Hand that C-L header back to client. + */ req->res_mode |= RES_LEN; - if (!(req->objcore->flags & OC_F_PASS) || - ObjGetLen(req->wrk, req->objcore) != 0) { - http_Unset(req->resp, H_Content_Length); - http_PrintfHeader(req->resp, - "Content-Length: %ju", (uintmax_t)ObjGetLen( - req->wrk, req->objcore)); - } - } - - if (req->esi_level > 0) { - /* Included ESI object, always CHUNKED or EOF */ - req->res_mode &= ~RES_LEN; - req->res_mode |= RES_ESI_CHILD; + } else { + req->res_mode |= RES_LEN; + http_Unset(req->resp, H_Content_Length); + http_PrintfHeader(req->resp, + "Content-Length: %ju", (uintmax_t)ObjGetLen( + req->wrk, req->objcore)); } if (cache_param->http_gzip_support && @@ -315,9 +322,6 @@ V1D_Deliver(struct req *req, struct busyobj *bo) v1d_dorange(req, bo, r); } - if (req->res_mode & RES_ESI) - RFC2616_Weaken_Etag(req->resp); - WRW_Reserve(req->wrk, &req->sp->fd, req->vsl, req->t_prev); /* diff --git a/bin/varnishtest/tests/r00730.vtc b/bin/varnishtest/tests/r00730.vtc index bb416e8..67b9598 100644 --- a/bin/varnishtest/tests/r00730.vtc +++ b/bin/varnishtest/tests/r00730.vtc @@ -4,7 +4,7 @@ server s1 { rxreq txresp -bodylen 5 rxreq - txresp -bodylen 6 + txresp -nolen -hdr "Content-Length: 6" } -start varnish v1 -vcl+backend { diff --git a/bin/varnishtest/tests/r01612.vtc b/bin/varnishtest/tests/r01612.vtc new file mode 100644 index 0000000..e66d3ec --- /dev/null +++ b/bin/varnishtest/tests/r01612.vtc @@ -0,0 +1,52 @@ +varnishtest "Missing Content-Length/T-E on passed empty chunked responses." + +server s1 { + # Empty c-l response is OK. + rxreq + expect req.url == "/0" + txresp + + # Nonzero chunked response is OK. + rxreq + expect req.url == "/1" + send "HTTP/1.1 200 OK\n" + send "Transfer-encoding: chunked\n" + send "\n" + chunkedlen 20 + chunkedlen 0 + + # Empty chunked response is not. + rxreq + expect req.url == "/2" + send "HTTP/1.1 200 OK\n" + send "Transfer-encoding: chunked\n" + send "\n" + chunkedlen 0 +} -start + +varnish v1 -vcl+backend { + sub vcl_recv { + return (pass); + } + sub vcl_backend_response { + set beresp.do_stream = false; + } +} -start + + +client c1 { + txreq -url "/0" + rxresp + expect resp.bodylen == 0 + expect resp.http.Content-Length == "0" + + txreq -url "/1" + rxresp + expect resp.bodylen == 20 + expect resp.http.Content-Length == "20" + + txreq -url "/2" + rxresp + expect resp.bodylen == 0 + expect resp.http.Content-Length == "0" +} -run From martin at varnish-software.com Tue Oct 21 10:25:42 2014 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 21 Oct 2014 12:25:42 +0200 Subject: [master] 2909721 Remove the 80% file system free space check Message-ID: commit 29097215caf53e30e77ccdee17b9fe9317e722f8 Author: Martin Blix Grydeland Date: Mon Oct 6 15:14:37 2014 +0200 Remove the 80% file system free space check This check never worked as intended for several reasons: - Didn't take the existing file size into account, causing it to succeed on first startup but fail on next - Sparse files were not handled, and can't be handled as we don't know where in the file a hole could be and whether truncation actually would change the number of blocks used at all Fixes: #1343 diff --git a/bin/varnishd/storage/stevedore_utils.c b/bin/varnishd/storage/stevedore_utils.c index a86d57e..e30cbcc 100644 --- a/bin/varnishd/storage/stevedore_utils.c +++ b/bin/varnishd/storage/stevedore_utils.c @@ -223,11 +223,6 @@ STV_FileSize(int fd, const char *size, unsigned *granularity, const char *ctx) if (i) fprintf(stderr, "WARNING: (%s) file size reduced" " to %ju due to system \"off_t\" limitations\n", ctx, l); - else if (l - st.st_size > fssize) { - l = fssize * 80 / 100; - fprintf(stderr, "WARNING: (%s) file size reduced" - " to %ju (80%% of available disk space)\n", ctx, l); - } if (sizeof(void *) == 4 && l > INT32_MAX) { /*lint !e506 !e774 !e845 */ fprintf(stderr, From martin at varnish-software.com Tue Oct 21 10:25:42 2014 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 21 Oct 2014 12:25:42 +0200 Subject: [master] 93a6c4c Report error in STV_FileSize on empty file and no size specified Message-ID: commit 93a6c4ca01994babecee152704178f50e2f2b6eb Author: Martin Blix Grydeland Date: Tue Oct 7 12:44:37 2014 +0200 Report error in STV_FileSize on empty file and no size specified diff --git a/bin/varnishd/storage/stevedore_utils.c b/bin/varnishd/storage/stevedore_utils.c index e30cbcc..359b5ea 100644 --- a/bin/varnishd/storage/stevedore_utils.c +++ b/bin/varnishd/storage/stevedore_utils.c @@ -196,6 +196,9 @@ STV_FileSize(int fd, const char *size, unsigned *granularity, const char *ctx) * use its existing size. */ l = st.st_size; + } else if (size == NULL || *size == '\0') { + ARGV_ERR("(%s) no size specified\n", + ctx); } else { AN(size); q = VNUM_2bytes(size, &l, fssize); From martin at varnish-software.com Tue Oct 21 10:25:42 2014 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 21 Oct 2014 12:25:42 +0200 Subject: [master] 3eeafa8 Don't allow relative sizes for stevedore file size Message-ID: commit 3eeafa8b0298ec3c2d429df25fdd92ba4216af20 Author: Martin Blix Grydeland Date: Mon Oct 6 15:36:19 2014 +0200 Don't allow relative sizes for stevedore file size diff --git a/bin/varnishd/storage/stevedore_utils.c b/bin/varnishd/storage/stevedore_utils.c index 359b5ea..daff6d7 100644 --- a/bin/varnishd/storage/stevedore_utils.c +++ b/bin/varnishd/storage/stevedore_utils.c @@ -201,7 +201,7 @@ STV_FileSize(int fd, const char *size, unsigned *granularity, const char *ctx) ctx); } else { AN(size); - q = VNUM_2bytes(size, &l, fssize); + q = VNUM_2bytes(size, &l, 0); if (q != NULL) ARGV_ERR("(%s) size \"%s\": %s\n", ctx, size, q); From martin at varnish-software.com Tue Oct 21 10:25:42 2014 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 21 Oct 2014 12:25:42 +0200 Subject: [master] 22ad1c9 VFIL_fsinfo function to retrieve file system information Message-ID: commit 22ad1c95f7a0a6588c1dc4d682183616587595ef Author: Martin Blix Grydeland Date: Tue Oct 7 13:27:57 2014 +0200 VFIL_fsinfo function to retrieve file system information diff --git a/include/vfil.h b/include/vfil.h index 533dfd8..32f2c78 100644 --- a/include/vfil.h +++ b/include/vfil.h @@ -34,3 +34,4 @@ int VFIL_tmpfile(char *); char *VFIL_readfile(const char *pfx, const char *fn, ssize_t *sz); char *VFIL_readfd(int fd, ssize_t *sz); int VFIL_nonblocking(int fd); +int VFIL_fsinfo(int fd, unsigned *pbs, uintmax_t *size, uintmax_t *space); diff --git a/lib/libvarnish/vfil.c b/lib/libvarnish/vfil.c index 920a06f..b3743f2 100644 --- a/lib/libvarnish/vfil.c +++ b/lib/libvarnish/vfil.c @@ -38,6 +38,18 @@ #include #include #include +#include +#include +#ifdef HAVE_SYS_MOUNT_H +# include +# include +#endif +#ifdef HAVE_SYS_STATVFS_H +# include +#endif +#ifdef HAVE_SYS_VFS_H +# include +#endif #include "vas.h" #include "vdef.h" @@ -136,3 +148,42 @@ VFIL_nonblocking(int fd) assert(i != -1); return (i); } + +/* + * Get file system information from an fd + * Returns block size, total size and space available in the passed pointers + * Returns 0 on success, or -1 on failure with errno set + */ +int +VFIL_fsinfo(int fd, unsigned *pbs, uintmax_t *psize, uintmax_t *pspace) +{ + unsigned bs; + uintmax_t size, space; +#if defined(HAVE_SYS_STATVFS_H) + struct statvfs fsst; + + if (fstatvfs(fd, &fsst)) + return (-1); + bs = fsst.f_frsize; + size = fsst.f_blocks * fsst.f_frsize; + space = fsst.f_bavail * fsst.f_frsize; +#elif defined(HAVE_SYS_MOUNT_H) || defined(HAVE_SYS_VFS_H) + struct statfs fsst; + + if (fstatfs(fd, &fsst)) + return (-1); + bs = fsst.f_bsize; + size = fsst.f_blocks * fsst.f_bsize; + space = fsst.f_bavail * fsst.f_bsize; +#else +#error no struct statfs / struct statvfs +#endif + + if (pbs) + *pbs = bs; + if (psize) + *psize = size; + if (pspace) + *pspace = space; + return (0); +} From martin at varnish-software.com Tue Oct 21 10:25:42 2014 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 21 Oct 2014 12:25:42 +0200 Subject: [master] 1f4067c Use VFIL_fsinfo in STV_FileSize, and drop the old implementation Message-ID: commit 1f4067c95f144d80cc619cca629d339b72635d92 Author: Martin Blix Grydeland Date: Tue Oct 7 13:46:57 2014 +0200 Use VFIL_fsinfo in STV_FileSize, and drop the old implementation diff --git a/bin/varnishd/storage/stevedore_utils.c b/bin/varnishd/storage/stevedore_utils.c index daff6d7..60b640b 100644 --- a/bin/varnishd/storage/stevedore_utils.c +++ b/bin/varnishd/storage/stevedore_utils.c @@ -54,6 +54,7 @@ #include "storage/storage.h" #include "vnum.h" +#include "vfil.h" #ifndef O_LARGEFILE #define O_LARGEFILE 0 @@ -133,38 +134,6 @@ STV_GetFile(const char *fn, int *fdp, const char **fnp, const char *ctx) } /*-------------------------------------------------------------------- - * Figure out how much space is in a filesystem - */ - -static uintmax_t -stv_fsspace(int fd, unsigned *bs) -{ - uintmax_t bsize, bavail; -#if defined(HAVE_SYS_STATVFS_H) - struct statvfs fsst; - - AZ(fstatvfs(fd, &fsst)); - bsize = fsst.f_frsize; - bavail = fsst.f_bavail; -#elif defined(HAVE_SYS_MOUNT_H) || defined(HAVE_SYS_VFS_H) - struct statfs fsst; - - AZ(fstatfs(sc->fd, &fsst)); - bsize = fsst.f_bsize; - bavail = fsst.f_bavail; -#else -#error no struct statfs / struct statvfs -#endif - - /* We use units of the larger of filesystem blocksize and pagesize */ - if (*bs < bsize) - *bs = bsize; - XXXAZ(*bs % bsize); - return (bsize * bavail); -} - - -/*-------------------------------------------------------------------- * Decide file size. * * If the sizespecification is empty and the file exists with non-zero @@ -183,12 +152,16 @@ STV_FileSize(int fd, const char *size, unsigned *granularity, const char *ctx) off_t o; struct stat st; + AN(granularity); + AN(ctx); + AZ(fstat(fd, &st)); xxxassert(S_ISREG(st.st_mode)); - bs = *granularity; - fssize = stv_fsspace(fd, &bs); - XXXAZ(bs % *granularity); + AZ(VFIL_fsinfo(fd, &bs, &fssize, NULL)); + /* Increase granularity if it is lower than the filesystem block size */ + if (*granularity < bs) + *granularity = bs; if ((size == NULL || *size == '\0') && st.st_size != 0) { /* @@ -235,9 +208,8 @@ STV_FileSize(int fd, const char *size, unsigned *granularity, const char *ctx) l = INT32_MAX; } - /* round down to multiple of filesystem blocksize or pagesize */ - l -= (l % bs); + /* Round down */ + l -= (l % *granularity); - *granularity = bs; return(l); } From martin at varnish-software.com Tue Oct 21 10:25:42 2014 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 21 Oct 2014 12:25:42 +0200 Subject: [master] f769dd1 Bail out with arg error if specifying a size larger than the file system size Message-ID: commit f769dd1cb8bfb0666784aa4af2a35011a44f9662 Author: Martin Blix Grydeland Date: Mon Oct 6 15:33:34 2014 +0200 Bail out with arg error if specifying a size larger than the file system size This is to spot obvious typos diff --git a/bin/varnishd/storage/stevedore_utils.c b/bin/varnishd/storage/stevedore_utils.c index 60b640b..32a447f 100644 --- a/bin/varnishd/storage/stevedore_utils.c +++ b/bin/varnishd/storage/stevedore_utils.c @@ -182,6 +182,10 @@ STV_FileSize(int fd, const char *size, unsigned *granularity, const char *ctx) if (l < 1024*1024) ARGV_ERR("(%s) size \"%s\": too small, " "did you forget to specify M or G?\n", ctx, size); + + if (l > fssize) + ARGV_ERR("(%s) size \"%s\": larger than file system\n", + ctx, size); } /* From martin at varnish-software.com Tue Oct 21 10:25:42 2014 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 21 Oct 2014 12:25:42 +0200 Subject: [master] e55924a Add a VFIL_allocate function Message-ID: commit e55924adaae8e647144c692d4ab4883437c93e75 Author: Martin Blix Grydeland Date: Mon Oct 6 17:46:34 2014 +0200 Add a VFIL_allocate function This function makes sure that the filesystem can accomodate the file of the given size. Checks the filesystem free space up against the allocated blocks as a sanity check. Uses fallocate if available to preallocate the needed blocks. If fallocate isn't available, it will write zero bytes if insist is true. diff --git a/configure.ac b/configure.ac index e221fa7..a66d61a 100644 --- a/configure.ac +++ b/configure.ac @@ -216,6 +216,7 @@ AC_CHECK_FUNCS([getdtablesize]) AC_CHECK_FUNCS([timegm]) AC_CHECK_FUNCS([nanosleep]) AC_CHECK_FUNCS([setppriv]) +AC_CHECK_FUNCS([fallocate]) save_LIBS="${LIBS}" LIBS="${PTHREAD_LIBS}" diff --git a/include/vfil.h b/include/vfil.h index 32f2c78..dff6560 100644 --- a/include/vfil.h +++ b/include/vfil.h @@ -35,3 +35,4 @@ char *VFIL_readfile(const char *pfx, const char *fn, ssize_t *sz); char *VFIL_readfd(int fd, ssize_t *sz); int VFIL_nonblocking(int fd); int VFIL_fsinfo(int fd, unsigned *pbs, uintmax_t *size, uintmax_t *space); +int VFIL_allocate(int fd, off_t size, int insist); diff --git a/lib/libvarnish/vfil.c b/lib/libvarnish/vfil.c index b3743f2..d985e3e 100644 --- a/lib/libvarnish/vfil.c +++ b/lib/libvarnish/vfil.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #ifdef HAVE_SYS_MOUNT_H # include @@ -187,3 +188,55 @@ VFIL_fsinfo(int fd, unsigned *pbs, uintmax_t *psize, uintmax_t *pspace) *pspace = space; return (0); } + +/* Make sure that the file system can accomodate the file of the given + * size. Will use fallocate if available. If fallocate is not available + * and insist is true, it will write size zero bytes. + * + * Returns 0 on success, -1 on failure with errno set. + */ +int +VFIL_allocate(int fd, off_t size, int insist) +{ + struct stat st; + uintmax_t fsspace; + size_t l; + ssize_t l2; + char buf[64 * 1024]; + + if (ftruncate(fd, size)) + return (-1); + if (fstat(fd, &st)) + return (-1); + if (VFIL_fsinfo(fd, NULL, NULL, &fsspace)) + return (-1); + if ((st.st_blocks * 512) + fsspace < size) { + /* Sum of currently allocated blocks and available space + is less than requested size */ + errno = ENOSPC; + return (-1); + } +#ifdef HAVE_FALLOCATE + if (!fallocate(fd, 0, 0, size)) + return (0); + if (errno == ENOSPC) + return (-1); +#endif + if (!insist) + return (0); + + /* Write size zero bytes to make sure the entire file is allocated + in the file system */ + memset(buf, 0, sizeof buf); + assert(lseek(fd, 0, SEEK_SET) == 0); + for (l = 0; l < size; l += l2) { + l2 = sizeof buf; + if (l + l2 > size) + l2 = size - l; + l2 = write(fd, buf, l2); + if (l2 < 0) + return (-1); + } + assert(lseek(fd, 0, SEEK_SET) == 0); + return (0); +} From martin at varnish-software.com Tue Oct 21 10:25:42 2014 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 21 Oct 2014 12:25:42 +0200 Subject: [master] 82ba5b9 Remove default size from -sfile Message-ID: commit 82ba5b928d5204df386a9a212dca9334d7a2bb41 Author: Martin Blix Grydeland Date: Tue Oct 7 14:46:34 2014 +0200 Remove default size from -sfile diff --git a/bin/varnishd/storage/storage_file.c b/bin/varnishd/storage/storage_file.c index 863ad25..b1be095 100644 --- a/bin/varnishd/storage/storage_file.c +++ b/bin/varnishd/storage/storage_file.c @@ -108,7 +108,6 @@ smf_initfile(struct smf_sc *sc, const char *size) /* XXX: force block allocation here or in open ? */ } -static const char default_size[] = "100M"; static const char default_filename[] = "."; static void @@ -122,7 +121,7 @@ smf_init(struct stevedore *parent, int ac, char * const *av) AZ(av[ac]); fn = default_filename; - size = default_size; + size = NULL; page_size = getpagesize(); if (ac > 3) @@ -139,7 +138,6 @@ smf_init(struct stevedore *parent, int ac, char * const *av) } AN(fn); - AN(size); ALLOC_OBJ(sc, SMF_SC_MAGIC); XXXAN(sc); From martin at varnish-software.com Tue Oct 21 10:25:42 2014 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 21 Oct 2014 12:25:42 +0200 Subject: [master] 9133222 Fix varnishd usage line order Message-ID: commit 9133222fc45170d2016086dedaae866185f6a5d2 Author: Martin Blix Grydeland Date: Tue Oct 7 15:48:33 2014 +0200 Fix varnishd usage line order diff --git a/bin/varnishd/mgt/mgt_main.c b/bin/varnishd/mgt/mgt_main.c index 28b4823..cb0896d 100644 --- a/bin/varnishd/mgt/mgt_main.c +++ b/bin/varnishd/mgt/mgt_main.c @@ -174,9 +174,9 @@ usage(void) fprintf(stderr, FMT, "", " -s file [default: use /tmp]"); fprintf(stderr, FMT, "", " -s file,"); fprintf(stderr, FMT, "", " -s file,,"); - fprintf(stderr, FMT, "", " -s persist{experimenta}"); fprintf(stderr, FMT, "", " -s file,,,"); + fprintf(stderr, FMT, "", " -s persist{experimenta}"); fprintf(stderr, FMT, "-S secret-file", "Secret file for CLI authentication"); fprintf(stderr, FMT, "-T address:port", From martin at varnish-software.com Tue Oct 21 10:25:43 2014 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 21 Oct 2014 12:25:43 +0200 Subject: [master] 24eb71a Fix varnishd usage output typo Message-ID: commit 24eb71a3e0ccfa777433e360745f14da01a0008d Author: Martin Blix Grydeland Date: Tue Oct 7 15:49:13 2014 +0200 Fix varnishd usage output typo diff --git a/bin/varnishd/mgt/mgt_main.c b/bin/varnishd/mgt/mgt_main.c index cb0896d..ae90fe0 100644 --- a/bin/varnishd/mgt/mgt_main.c +++ b/bin/varnishd/mgt/mgt_main.c @@ -176,7 +176,7 @@ usage(void) fprintf(stderr, FMT, "", " -s file,,"); fprintf(stderr, FMT, "", " -s file,,,"); - fprintf(stderr, FMT, "", " -s persist{experimenta}"); + fprintf(stderr, FMT, "", " -s persist{experimental}"); fprintf(stderr, FMT, "-S secret-file", "Secret file for CLI authentication"); fprintf(stderr, FMT, "-T address:port", From martin at varnish-software.com Tue Oct 21 10:25:43 2014 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 21 Oct 2014 12:25:43 +0200 Subject: [master] 0a556c7 Make path mandatory in -sfile Message-ID: commit 0a556c7a996a089bb375964f8a92bb61d318bbe9 Author: Martin Blix Grydeland Date: Tue Oct 7 15:55:36 2014 +0200 Make path mandatory in -sfile diff --git a/bin/varnishd/mgt/mgt_main.c b/bin/varnishd/mgt/mgt_main.c index ae90fe0..5c1e580 100644 --- a/bin/varnishd/mgt/mgt_main.c +++ b/bin/varnishd/mgt/mgt_main.c @@ -171,7 +171,6 @@ usage(void) #ifdef HAVE_LIBUMEM fprintf(stderr, FMT, "", " -s umem"); #endif - fprintf(stderr, FMT, "", " -s file [default: use /tmp]"); fprintf(stderr, FMT, "", " -s file,"); fprintf(stderr, FMT, "", " -s file,,"); fprintf(stderr, FMT, "", diff --git a/bin/varnishd/storage/storage_file.c b/bin/varnishd/storage/storage_file.c index b1be095..04d9707 100644 --- a/bin/varnishd/storage/storage_file.c +++ b/bin/varnishd/storage/storage_file.c @@ -108,8 +108,6 @@ smf_initfile(struct smf_sc *sc, const char *size) /* XXX: force block allocation here or in open ? */ } -static const char default_filename[] = "."; - static void smf_init(struct stevedore *parent, int ac, char * const *av) { @@ -120,14 +118,15 @@ smf_init(struct stevedore *parent, int ac, char * const *av) AZ(av[ac]); - fn = default_filename; + fn = NULL; size = NULL; page_size = getpagesize(); if (ac > 3) ARGV_ERR("(-sfile) too many arguments\n"); - if (ac > 0 && *av[0] != '\0') - fn = av[0]; + if (ac < 1 || *av[0] == '\0') + ARGV_ERR("(-sfile) path is mandatory\n"); + fn = av[0]; if (ac > 1 && *av[1] != '\0') size = av[1]; if (ac > 2 && *av[2] != '\0') { diff --git a/doc/sphinx/reference/varnishd.rst b/doc/sphinx/reference/varnishd.rst index 6014637..4bc9cc9 100644 --- a/doc/sphinx/reference/varnishd.rst +++ b/doc/sphinx/reference/varnishd.rst @@ -112,7 +112,7 @@ OPTIONS -s [name=]type[,options] Use the specified storage backend. The storage backends can be one of the following: * malloc[,size] - * file[,path[,size[,granularity]]] + * file,path[,size[,granularity]] * persistent,path,size See Storage Types in the Users Guide for more information @@ -177,7 +177,7 @@ malloc is a memory based backend. file ~~~~ -syntax: file[,path[,size[,granularity]]] +syntax: file,path[,size[,granularity]] The file backend stores data in a file on disk. The file will be accessed using mmap. From martin at varnish-software.com Tue Oct 21 10:25:43 2014 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 21 Oct 2014 12:25:43 +0200 Subject: [master] eb1ca9d Use VFIL_allocate in -sfile Message-ID: commit eb1ca9d710bbfbf0ab9306b6e9b2789bbcf15c1e Author: Martin Blix Grydeland Date: Tue Oct 7 16:09:40 2014 +0200 Use VFIL_allocate in -sfile diff --git a/bin/varnishd/storage/storage_file.c b/bin/varnishd/storage/storage_file.c index 04d9707..9b6a794 100644 --- a/bin/varnishd/storage/storage_file.c +++ b/bin/varnishd/storage/storage_file.c @@ -40,6 +40,7 @@ #include "storage/storage.h" #include "vnum.h" +#include "vfil.h" #ifndef MAP_NOCORE #define MAP_NOCORE 0 /* XXX Linux */ @@ -99,16 +100,6 @@ struct smf_sc { /*--------------------------------------------------------------------*/ static void -smf_initfile(struct smf_sc *sc, const char *size) -{ - sc->filesize = STV_FileSize(sc->fd, size, &sc->pagesize, "-sfile"); - - AZ(ftruncate(sc->fd, (off_t)sc->filesize)); - - /* XXX: force block allocation here or in open ? */ -} - -static void smf_init(struct stevedore *parent, int ac, char * const *av) { const char *size, *fn, *r; @@ -149,9 +140,10 @@ smf_init(struct stevedore *parent, int ac, char * const *av) parent->priv = sc; (void)STV_GetFile(fn, &sc->fd, &sc->filename, "-sfile"); - mgt_child_inherit(sc->fd, "storage_file"); - smf_initfile(sc, size); + sc->filesize = STV_FileSize(sc->fd, size, &sc->pagesize, "-sfile"); + if (VFIL_allocate(sc->fd, (off_t)sc->filesize, 0)) + ARGV_ERR("(-sfile) allocation error: %s\n", strerror(errno)); } /*-------------------------------------------------------------------- From martin at varnish-software.com Tue Oct 21 10:25:43 2014 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 21 Oct 2014 12:25:43 +0200 Subject: [master] 45cf215 Use VFIL_allocate in vsm_zerofile Message-ID: commit 45cf21512b772c01b53696b35ac499eb79431fcd Author: Martin Blix Grydeland Date: Tue Oct 7 16:17:26 2014 +0200 Use VFIL_allocate in vsm_zerofile Here we insist the file is completely allocated diff --git a/bin/varnishd/mgt/mgt_shmem.c b/bin/varnishd/mgt/mgt_shmem.c index dc1fa5c..04634b8 100644 --- a/bin/varnishd/mgt/mgt_shmem.c +++ b/bin/varnishd/mgt/mgt_shmem.c @@ -47,6 +47,7 @@ #include "flopen.h" #include "vapi/vsm_int.h" #include "vmb.h" +#include "vfil.h" #ifndef MAP_HASSEMAPHORE #define MAP_HASSEMAPHORE 0 /* XXX Linux */ @@ -147,8 +148,6 @@ static int vsm_zerofile(const char *fn, ssize_t size) { int fd; - ssize_t i, u; - char buf[64*1024]; int flags; fd = flopen(fn, O_RDWR | O_CREAT | O_EXCL | O_NONBLOCK, 0644); @@ -161,18 +160,11 @@ vsm_zerofile(const char *fn, ssize_t size) assert(flags != -1); flags &= ~O_NONBLOCK; AZ(fcntl(fd, F_SETFL, flags)); - - memset(buf, 0, sizeof buf); - for (u = 0; u < size; ) { - i = write(fd, buf, sizeof buf); - if (i <= 0) { - fprintf(stderr, "Write error %s: %s\n", - fn, strerror(errno)); - return (-1); - } - u += i; + if (VFIL_allocate(fd, (off_t)size, 1)) { + fprintf(stderr, "File allocation error %s: %s\n", + fn, strerror(errno)); + return (-1); } - AZ(ftruncate(fd, (off_t)size)); return (fd); } From martin at varnish-software.com Tue Oct 21 10:25:43 2014 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 21 Oct 2014 12:25:43 +0200 Subject: [master] ca0b9cf Update the -sfile documentation Message-ID: commit ca0b9cfda2a9725bd045ac8c605925ed0d936ac9 Author: Martin Blix Grydeland Date: Tue Oct 7 16:25:00 2014 +0200 Update the -sfile documentation diff --git a/doc/sphinx/reference/varnishd.rst b/doc/sphinx/reference/varnishd.rst index 4bc9cc9..8372086 100644 --- a/doc/sphinx/reference/varnishd.rst +++ b/doc/sphinx/reference/varnishd.rst @@ -179,7 +179,19 @@ file syntax: file,path[,size[,granularity]] -The file backend stores data in a file on disk. The file will be accessed using mmap. +The file backend stores data in a file on disk. The file will be +accessed using mmap. + +The path is mandatory. If path points to a directory, a temporary file +will be created in that directory and immediately unlinked. If path +points to a non-existing file, the file will be created. + +If size is omitted, and path points to an existing file with a size +greater than zero, the size of that file will be used. If not, an +error is reported. + +Granularity sets the allocation block size. Defaults to the system +page size or the filesystem block size, whichever is larger. persistent (experimental) ~~~~~~~~~~~~~~~~~~~~~~~~~ From daghf at varnish-software.com Tue Oct 21 10:49:24 2014 From: daghf at varnish-software.com (Dag Haavi Finstad) Date: Tue, 21 Oct 2014 12:49:24 +0200 Subject: [master] 9ec96da Use the proper symbol name when evaluating vcl 'new' invocations. Message-ID: commit 9ec96da73047622a40c476073d148876c95beeb8 Author: Dag Haavi Finstad Date: Tue Oct 21 12:49:07 2014 +0200 Use the proper symbol name when evaluating vcl 'new' invocations. diff --git a/lib/libvcc/vcc_action.c b/lib/libvcc/vcc_action.c index 1b0c4b2..c4f984d 100644 --- a/lib/libvcc/vcc_action.c +++ b/lib/libvcc/vcc_action.c @@ -219,7 +219,7 @@ parse_new(struct vcc *tl) vcc_NextToken(tl); bprintf(buf1, ", &vo_%s, \"%s\"", sy1->name, sy1->name); - vcc_Eval_Func(tl, s_init, buf1, "ASDF", s_init + strlen(s_init) + 1); + vcc_Eval_Func(tl, s_init, buf1, sy2->name, s_init + strlen(s_init) + 1); ifp = New_IniFin(tl); VSB_printf(ifp->fin, "\t%s(&vo_%s);", s_fini, sy1->name); ExpectErr(tl, ';'); From phk at FreeBSD.org Tue Oct 21 11:10:45 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 21 Oct 2014 13:10:45 +0200 Subject: [master] c74bd5f Simplify delivery by making a private objcore in vcl_synth{} Message-ID: commit c74bd5f8af46f3a5374d364db33373c44049b862 Author: Poul-Henning Kamp Date: Tue Oct 21 11:10:10 2014 +0000 Simplify delivery by making a private objcore in vcl_synth{} diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 0748d66..185b3e8 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -743,7 +743,6 @@ extern const int HTTP1_Resp[3]; /* cache_http1_deliver.c */ unsigned V1D_FlushReleaseAcct(struct req *req); void V1D_Deliver(struct req *, struct busyobj *); -void V1D_Deliver_Synth(struct req *req); /* cache_http1_pipe.c */ void V1P_Init(void); diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 30507ff..9c2627a 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -108,7 +108,6 @@ cnt_deliver(struct worker *wrk, struct req *req) wrk->handling = VCL_RET_DELIVER; if (wrk->handling != VCL_RET_DELIVER) { - assert(req->objcore == req->objcore); (void)HSH_DerefObjCore(wrk, &req->objcore); http_Teardown(req->resp); @@ -155,14 +154,8 @@ cnt_deliver(struct worker *wrk, struct req *req) if (http_HdrIs(req->resp, H_Connection, "close")) req->doclose = SC_RESP_CLOSE; - if (req->objcore->flags & OC_F_PASS) { - /* - * No point in saving the body if it is hit-for-pass, - * but we can't yank it until the fetching thread has - * finished/abandoned also. - */ - while (req->objcore->busyobj != NULL) - (void)usleep(100000); + if ((req->objcore->flags & OC_F_PASS) && bo != NULL) { + VBO_waitstate(bo, BOS_FINISHED); ObjSlim(wrk, req->objcore); } @@ -194,6 +187,7 @@ cnt_synth(struct worker *wrk, struct req *req) if (req->err_code < 100 || req->err_code > 999) req->err_code = 501; + HTTP_Setup(req->resp, req->ws, req->vsl, SLT_RespMethod); h = req->resp; VTIM_format(now, date); @@ -212,6 +206,9 @@ cnt_synth(struct worker *wrk, struct req *req) AZ(VSB_finish(req->synth_body)); + /* Discard any lingering request body before delivery */ + (void)VRB_Ignore(req); + if (wrk->handling == VCL_RET_RESTART) { HTTP_Setup(h, req->ws, req->vsl, SLT_RespMethod); VSB_delete(req->synth_body); @@ -224,16 +221,30 @@ cnt_synth(struct worker *wrk, struct req *req) if (http_HdrIs(req->resp, H_Connection, "close")) req->doclose = SC_RESP_CLOSE; - /* Discard any lingering request body before delivery */ - (void)VRB_Ignore(req); + req->objcore = HSH_Private(wrk); + CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); + if (STV_NewObject(req->objcore, wrk, TRANSIENT_STORAGE, 1024)) { + ssize_t sz, szl; + uint8_t *ptr; + + szl = VSB_len(req->synth_body); + assert(szl >= 0); + if (szl > 0) { + sz = szl; + AN(ObjGetSpace(wrk, req->objcore, &sz, &ptr)); + assert(sz >= szl); + memcpy(ptr, VSB_data(req->synth_body), szl); + ObjExtend(wrk, req->objcore, szl); + } + VSB_delete(req->synth_body); + req->synth_body = NULL; - V1D_Deliver_Synth(req); + V1D_Deliver(req, NULL); + (void)HSH_DerefObjCore(wrk, &req->objcore); + } VSLb_ts_req(req, "Resp", W_TIM_real(wrk)); - VSB_delete(req->synth_body); - req->synth_body = NULL; - req->err_code = 0; req->err_reason = NULL; return (REQ_FSM_DONE); diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 3f0f341..08d3264 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -176,6 +176,7 @@ v1d_WriteDirObj(struct req *req) oi = ObjIterBegin(req->wrk, req->objcore); XXXAN(oi); + AZ(req->synth_body); do { ois = ObjIter(req->objcore, oi, &ptr, &len); @@ -365,99 +366,3 @@ V1D_Deliver(struct req *req, struct busyobj *bo) if ((V1D_FlushReleaseAcct(req) || ois != OIS_DONE) && req->sp->fd >= 0) SES_Close(req->sp, SC_REM_CLOSE); } - -void -V1D_Deliver_Synth(struct req *req) -{ - const char *r; - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - AN(req->synth_body); - - req->res_mode = 0; - if (http_IsStatus(req->resp, 304)) { - req->res_mode &= ~RES_LEN; - http_Unset(req->resp, H_Content_Length); - req->wantbody = 0; - } else { - req->res_mode |= RES_LEN; - http_Unset(req->resp, H_Content_Length); - http_PrintfHeader(req->resp, "Content-Length: %zd", - VSB_len(req->synth_body)); - } - - if (req->esi_level > 0) { - /* Included ESI object, always CHUNKED or EOF */ - req->res_mode &= ~RES_LEN; - req->res_mode |= RES_ESI_CHILD; - } - - if (!(req->res_mode & (RES_LEN|RES_CHUNKED|RES_EOF))) { - /* We havn't chosen yet, do so */ - if (!req->wantbody) { - /* Nothing */ - } else if (req->http->protover >= 11) { - req->res_mode |= RES_CHUNKED; - } else { - req->res_mode |= RES_EOF; - req->doclose = SC_TX_EOF; - } - } - VSLb(req->vsl, SLT_Debug, "RES_MODE %x", req->res_mode); - - if (!(req->res_mode & RES_LEN)) - http_Unset(req->resp, H_Content_Length); - - if (req->res_mode & RES_GUNZIP) - http_Unset(req->resp, H_Content_Encoding); - - if (req->res_mode & RES_CHUNKED) - http_SetHeader(req->resp, "Transfer-Encoding: chunked"); - - http_SetHeader(req->resp, - req->doclose ? "Connection: close" : "Connection: keep-alive"); - - req->vdps[0] = v1d_bytes; - req->vdp_nxt = 0; - - if ( - req->wantbody && - !(req->res_mode & RES_ESI_CHILD) && - cache_param->http_range_support && - http_IsStatus(req->resp, 200)) { - http_SetHeader(req->resp, "Accept-Ranges: bytes"); - if (http_GetHdr(req->http, H_Range, &r)) - v1d_dorange(req, NULL, r); - } - - WRW_Reserve(req->wrk, &req->sp->fd, req->vsl, req->t_prev); - - /* - * Send HTTP protocol header, unless interior ESI object - */ - if (!(req->res_mode & RES_ESI_CHILD)) - req->resp_hdrbytes += - HTTP1_Write(req->wrk, req->resp, HTTP1_Resp); - - if (req->res_mode & RES_CHUNKED) - WRW_Chunked(req->wrk); - - if (!req->wantbody) { - /* This was a HEAD or conditional request */ -#if 0 - XXX: Missing pretend GZIP for esi-children - } else if (req->res_mode & RES_ESI_CHILD && req->gzip_resp) { - ESI_DeliverChild(req); -#endif - } else { - (void)VDP_bytes(req, VDP_FLUSH, VSB_data(req->synth_body), - VSB_len(req->synth_body)); - (void)VDP_bytes(req, VDP_FINISH, NULL, 0); - } - - if (req->res_mode & RES_CHUNKED && !(req->res_mode & RES_ESI_CHILD)) - WRW_EndChunk(req->wrk); - - if (V1D_FlushReleaseAcct(req) && req->sp->fd >= 0) - SES_Close(req->sp, SC_REM_CLOSE); -} diff --git a/bin/varnishtest/tests/r01284.vtc b/bin/varnishtest/tests/r01284.vtc index d613ab8..7c0502d 100644 --- a/bin/varnishtest/tests/r01284.vtc +++ b/bin/varnishtest/tests/r01284.vtc @@ -44,8 +44,8 @@ client c1 { delay 1 } -run -# Three failures, one for obj2, one for vcl_backend_error{} -varnish v1 -expect SMA.Transient.c_fail == 2 +# Three failures, one for obj2, one for vcl_backend_error{}, one for synth objcore +varnish v1 -expect SMA.Transient.c_fail == 3 client c1 { # Check that Varnish is still alive From nils.goroll at uplex.de Tue Oct 21 11:16:11 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 21 Oct 2014 13:16:11 +0200 Subject: [master] b259f6f Remove V1D_Deliver_Synth from dot-umentation Message-ID: commit b259f6f3d6a22a3e45a020d3603005f5f430de78 Author: Nils Goroll Date: Tue Oct 21 13:15:34 2014 +0200 Remove V1D_Deliver_Synth from dot-umentation to reflect changes from c74bd5f8af46f3a5374d364db33373c44049b862 diff --git a/doc/graphviz/cache_req_fsm.dot b/doc/graphviz/cache_req_fsm.dot index 5ccfdf0..5856984 100644 --- a/doc/graphviz/cache_req_fsm.dot +++ b/doc/graphviz/cache_req_fsm.dot @@ -83,9 +83,7 @@ digraph cache_req_fsm { ] SYNTH -> synth [color=purple] - synth:del:s -> V1D_Deliver_Synth [color=purple] - - V1D_Deliver_Synth -> DONE + synth:del:s -> V1D_Deliver [color=purple] } subgraph cluster_backend { From daghf at varnish-software.com Tue Oct 21 11:36:11 2014 From: daghf at varnish-software.com (Dag Haavi Finstad) Date: Tue, 21 Oct 2014 13:36:11 +0200 Subject: [master] f584597 Permit uppercase letters in vmod.vcc identifiers. Message-ID: commit f5845973494d58f6e58ce071ee8f5dfd3d15a626 Author: Dag Haavi Finstad Date: Tue Oct 21 13:35:41 2014 +0200 Permit uppercase letters in vmod.vcc identifiers. diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py index 99caca4..bff415a 100755 --- a/lib/libvcc/vmodtool.py +++ b/lib/libvcc/vmodtool.py @@ -106,7 +106,7 @@ def lwrap(s, w=72): ####################################################################### def is_c_name(s): - return None != re.match("^[a-z][a-z0-9_]*$", s) + return None != re.match("^[a-zA-Z][a-zA-Z0-9_]*$", s) class ParseError(Exception): From fgsch at lodoss.net Tue Oct 21 13:54:56 2014 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Tue, 21 Oct 2014 15:54:56 +0200 Subject: [master] 82158a0 Move vmod director tests to the d* space Message-ID: commit 82158a0c52c1ae41144d41d65e73d4b041a58afb Author: Federico G. Schwindt Date: Tue Oct 21 13:44:54 2014 +0100 Move vmod director tests to the d* space diff --git a/bin/varnishtest/tests/README b/bin/varnishtest/tests/README index c181fcc..a504ec5 100644 --- a/bin/varnishtest/tests/README +++ b/bin/varnishtest/tests/README @@ -16,10 +16,11 @@ Naming scheme id ~ [a] --> varnishtest(1) tests id ~ [b] --> Basic functionality tests id ~ [c] --> Complex functionality tests + id ~ [d] --> Director VMOD tests id ~ [e] --> ESI tests id ~ [g] --> GZIP tests id ~ [l] --> VSL tests - id ~ [m] --> VMOD tests + id ~ [m] --> VMOD tests excluding director id ~ [p] --> Persistent tests id ~ [r] --> Regression tests, same number as ticket id ~ [s] --> Slow tests, expiry, grace etc. diff --git a/bin/varnishtest/tests/d00000.vtc b/bin/varnishtest/tests/d00000.vtc new file mode 100644 index 0000000..780e17c --- /dev/null +++ b/bin/varnishtest/tests/d00000.vtc @@ -0,0 +1,71 @@ +varnishtest "Test round robin director" + +server s1 { + rxreq + txresp -body "1" +} -start + +server s2 { + rxreq + txresp -body "22" +} -start + + +server s3 { + rxreq + txresp -body "333" +} -start + +server s4 { + rxreq + txresp -body "4444" +} -start + +varnish v1 -vcl+backend { + import ${vmod_directors}; + + sub vcl_init { + new rr = directors.round_robin(); + rr.add_backend(s1); + rr.add_backend(s2); + rr.add_backend(s3); + rr.add_backend(s4); + } + + sub vcl_backend_fetch { + set bereq.backend = rr.backend(); + } + + sub vcl_backend_response { + set beresp.http.where = bereq.backend + "-->" + beresp.backend; + } +} -start + +client c1 { + timeout 3 + txreq -url "/foo1" + rxresp + expect resp.bodylen == 1 + txreq -url "/foo2" + rxresp + expect resp.bodylen == 2 + txreq -url "/foo3" + rxresp + expect resp.bodylen == 3 + txreq -url "/foo4" + rxresp + expect resp.bodylen == 4 +} -run + +server s1 -start +server s2 -start + +client c2 { + timeout 3 + txreq -url "/foo11" + rxresp + expect resp.bodylen == 1 + txreq -url "/foo22" + rxresp + expect resp.bodylen == 2 +} -run diff --git a/bin/varnishtest/tests/d00001.vtc b/bin/varnishtest/tests/d00001.vtc new file mode 100644 index 0000000..233be8e --- /dev/null +++ b/bin/varnishtest/tests/d00001.vtc @@ -0,0 +1,62 @@ +varnishtest "Test fallback director" + +server s1 { + rxreq + txresp -hdr "Foo: 1" +} -start + +server s2 { + rxreq + txresp -hdr "Foo: 2" +} -start + +server s3 { + rxreq + txresp -hdr "Foo: 3" +} -start + +varnish v1 -vcl+backend { + import ${vmod_directors}; + + sub vcl_init { + new fb1 = directors.fallback(); + fb1.add_backend(s1); + fb1.add_backend(s2); + fb1.add_backend(s3); + } + + sub vcl_recv { + return (pass); + } + + sub vcl_backend_fetch { + set bereq.backend = fb1.backend(); + } + +} -start + +varnish v1 -cliok "backend.set_health s1 sick" +varnish v1 -cliok "backend.set_health s2 sick" + +client c1 { + # s1 & s2 are both sick, expect response from s3 + txreq + rxresp + expect resp.http.foo == "3" +} -run + +varnish v1 -cliok "backend.set_health s2 healthy" + +client c1 { + txreq + rxresp + expect resp.http.foo == "2" +} -run + +varnish v1 -cliok "backend.set_health s1 healthy" + +client c1 { + txreq + rxresp + expect resp.http.foo == "1" +} -run diff --git a/bin/varnishtest/tests/d00002.vtc b/bin/varnishtest/tests/d00002.vtc new file mode 100644 index 0000000..b477176 --- /dev/null +++ b/bin/varnishtest/tests/d00002.vtc @@ -0,0 +1,35 @@ +varnishtest "Test random director" + +server s1 { + rxreq + txresp -body "foo1" + rxreq + txresp -body "bar1" +} -start + +varnish v1 -vcl+backend { + import ${vmod_directors}; + + sub vcl_init { + new foo = directors.random(); + foo.add_backend(s1, 1); + foo.add_backend(s1, 1); + } + + sub vcl_backend_fetch { + set bereq.backend = foo.backend(); + } + + sub vcl_backend_response { + set beresp.http.where = bereq.backend + "-->" + beresp.backend; + } +} -start + +client c1 { + txreq -url "/foo" + rxresp + expect resp.http.where == "foo-->s1" + txreq -url "/bar" + rxresp + expect resp.http.where == "foo-->s1" +} -run diff --git a/bin/varnishtest/tests/d00003.vtc b/bin/varnishtest/tests/d00003.vtc new file mode 100644 index 0000000..b81e482 --- /dev/null +++ b/bin/varnishtest/tests/d00003.vtc @@ -0,0 +1,77 @@ +varnishtest "Test hash director" + +server s1 { + rxreq + txresp -hdr "Foo: 1" -body "1" + rxreq + txresp -hdr "Foo: 3" -body "3" +} -start + +server s2 { + rxreq + txresp -hdr "Foo: 2" -body "2" + rxreq + txresp -hdr "Foo: 4" -body "4" + rxreq + txresp -hdr "Foo: 6" -body "6" + rxreq + txresp -hdr "Foo: 8" -body "8" +} -start + +varnish v1 -vcl+backend { + import ${vmod_directors}; + + sub vcl_init { + new h1 = directors.hash(); + h1.add_backend(s1, 1); + h1.add_backend(s2, 1); + } + + sub vcl_recv { + return(pass); + } + + sub vcl_backend_fetch { + if (bereq.url == "/nohdr") { + set bereq.backend = h1.backend(bereq.http.Void); + } else if (bereq.url == "/emptystring") { + set bereq.backend = h1.backend(""); + } else if (bereq.url == "/13") { + set bereq.backend = h1.backend(bereq.http.Void + "" + bereq.url); + } else { + set bereq.backend = h1.backend(bereq.url); + } + } + + sub vcl_backend_response { + set beresp.http.where = bereq.backend + "-->" + beresp.backend; + } + +} -start + + +client c1 { + txreq -url /1 + rxresp + expect resp.http.foo == "1" + + txreq -url /3 + rxresp + expect resp.http.foo == "2" + + txreq -url /13 + rxresp + expect resp.http.foo == "3" + + txreq -url /8 + rxresp + expect resp.http.foo == "4" + + txreq -url /emptystring + rxresp + expect resp.http.foo == "6" + + txreq -url /nohdr + rxresp + expect resp.http.foo == "8" +} -run diff --git a/bin/varnishtest/tests/d00004.vtc b/bin/varnishtest/tests/d00004.vtc new file mode 100644 index 0000000..cef05f0 --- /dev/null +++ b/bin/varnishtest/tests/d00004.vtc @@ -0,0 +1,93 @@ +varnishtest "Deeper test of random director" + +random + +server s1 { + rxreq + txresp -body "1" +} -start + +server s2 { + rxreq + txresp -body "22" + rxreq + txresp -body "22" + rxreq + txresp -body "22" + rxreq + txresp -body "22" +} -start + +server s3 { + rxreq + txresp -body "333" +} -start + +server s4 { + rxreq + txresp -body "4444" + rxreq + txresp -body "4444" + rxreq + txresp -body "4444" + rxreq + txresp -body "4444" +} -start + +varnish v1 -vcl+backend { + import ${vmod_directors}; + + sub vcl_init { + new foo = directors.random(); + foo.add_backend(s1, 1); + foo.add_backend(s2, 1); + foo.add_backend(s3, 1); + foo.add_backend(s4, 1); + } + + sub vcl_recv { + return(pass); + } + + sub vcl_backend_fetch { + set bereq.backend = foo.backend(); + } +} -start + +# NB: Do not change the number 1 +# NB: Only srandom(1) is standardized as deterministic. + +varnish v1 -cliok "debug.srandom 1" + +client c1 { + txreq + rxresp + expect resp.bodylen == 2 + txreq + rxresp + expect resp.bodylen == 4 + txreq + rxresp + expect resp.bodylen == 4 + txreq + rxresp + expect resp.bodylen == 4 + txreq + rxresp + expect resp.bodylen == 1 + txreq + rxresp + expect resp.bodylen == 2 + txreq + rxresp + expect resp.bodylen == 4 + txreq + rxresp + expect resp.bodylen == 2 + txreq + rxresp + expect resp.bodylen == 3 + txreq + rxresp + expect resp.bodylen == 2 +} -run diff --git a/bin/varnishtest/tests/d00005.vtc b/bin/varnishtest/tests/d00005.vtc new file mode 100644 index 0000000..d00e9c0 --- /dev/null +++ b/bin/varnishtest/tests/d00005.vtc @@ -0,0 +1,90 @@ +varnishtest "Test round robin stacked within fallback" + +server s1 -repeat 2 { + rxreq + txresp -body "1" +} -start + +server s2 -repeat 4 { + rxreq + txresp -body "22" +} -start + +server s3 -repeat 2 { + rxreq + txresp -body "333" +} -start + +server s4 -repeat 2 { + rxreq + txresp -body "4444" +} -start + +varnish v1 -vcl+backend { + import ${vmod_directors}; + + sub vcl_init { + new rr1 = directors.round_robin(); + rr1.add_backend(s1); + rr1.add_backend(s2); + + new rr2 = directors.round_robin(); + rr2.add_backend(s3); + rr2.add_backend(s4); + + new fb = directors.fallback(); + fb.add_backend(rr1.backend()); + fb.add_backend(rr2.backend()); + } + + sub vcl_recv { + return (pass); + } + + sub vcl_backend_fetch { + set bereq.backend = fb.backend(); + } +} -start + +client c1 { + txreq + rxresp + expect resp.body == "1" + txreq + rxresp + expect resp.body == "22" + txreq + rxresp + expect resp.body == "1" + txreq + rxresp + expect resp.body == "22" +} -run + +varnish v1 -cliok "backend.set_health s1 sick" + +client c1 { + txreq + rxresp + expect resp.body == "22" + txreq + rxresp + expect resp.body == "22" +} -run + +varnish v1 -cliok "backend.set_health s2 sick" + +client c1 { + txreq + rxresp + expect resp.body == "333" + txreq + rxresp + expect resp.body == "4444" + txreq + rxresp + expect resp.body == "333" + txreq + rxresp + expect resp.body == "4444" +} -run diff --git a/bin/varnishtest/tests/m00009.vtc b/bin/varnishtest/tests/m00009.vtc deleted file mode 100644 index 01b3e0a..0000000 --- a/bin/varnishtest/tests/m00009.vtc +++ /dev/null @@ -1,72 +0,0 @@ -varnishtest "Test vmod.directors round robin director" - - -server s1 { - rxreq - txresp -body "1" -} -start - -server s2 { - rxreq - txresp -body "22" -} -start - - -server s3 { - rxreq - txresp -body "333" -} -start - -server s4 { - rxreq - txresp -body "4444" -} -start - - -varnish v1 -vcl+backend { - - import ${vmod_directors}; - sub vcl_init { - new rr = directors.round_robin(); - rr.add_backend(s1); - rr.add_backend(s2); - rr.add_backend(s3); - rr.add_backend(s4); - } - - sub vcl_backend_fetch { - set bereq.backend = rr.backend(); - } - sub vcl_backend_response { - set beresp.http.where = bereq.backend + "-->" + beresp.backend; - } -} -start - -client c1 { - timeout 3 - txreq -url "/foo1" - rxresp - expect resp.bodylen == 1 - txreq -url "/foo2" - rxresp - expect resp.bodylen == 2 - txreq -url "/foo3" - rxresp - expect resp.bodylen == 3 - txreq -url "/foo4" - rxresp - expect resp.bodylen == 4 -} -run - -server s1 -start -server s2 -start - -client c2 { - timeout 3 - txreq -url "/foo11" - rxresp - expect resp.bodylen == 1 - txreq -url "/foo22" - rxresp - expect resp.bodylen == 2 -} -run diff --git a/bin/varnishtest/tests/v00007.vtc b/bin/varnishtest/tests/v00007.vtc deleted file mode 100644 index 7f9507f..0000000 --- a/bin/varnishtest/tests/v00007.vtc +++ /dev/null @@ -1,34 +0,0 @@ -varnishtest "Test random director" - -server s1 { - rxreq - txresp -body "foo1" - rxreq - txresp -body "bar1" -} -start - -varnish v1 -vcl+backend { - import ${vmod_directors}; - - sub vcl_init { - new foo = directors.random(); - foo.add_backend(s1, 1); - foo.add_backend(s1, 1); - } - - sub vcl_backend_fetch { - set bereq.backend = foo.backend(); - } - sub vcl_backend_response { - set beresp.http.where = bereq.backend + "-->" + beresp.backend; - } -} -start - -client c1 { - txreq -url "/foo" - rxresp - expect resp.http.where == "foo-->s1" - txreq -url "/bar" - rxresp - expect resp.http.where == "foo-->s1" -} -run diff --git a/bin/varnishtest/tests/v00009.vtc b/bin/varnishtest/tests/v00009.vtc deleted file mode 100644 index af925fb..0000000 --- a/bin/varnishtest/tests/v00009.vtc +++ /dev/null @@ -1,68 +0,0 @@ -varnishtest "Test round robin director" - -server s1 { - rxreq - txresp -body "1" -} -start - -server s2 { - rxreq - txresp -body "22" -} -start - - -server s3 { - rxreq - txresp -body "333" -} -start - -server s4 { - rxreq - txresp -body "4444" -} -start - - -varnish v1 -vcl+backend { - import ${vmod_directors}; - - sub vcl_init { - new batman = directors.round_robin(); - batman.add_backend(s1); - batman.add_backend(s2); - batman.add_backend(s3); - batman.add_backend(s4); - } - - sub vcl_backend_fetch { - set bereq.backend = batman.backend(); - } -} -start - -client c1 { - timeout 3 - txreq -url "/foo1" - rxresp - expect resp.bodylen == 1 - txreq -url "/foo2" - rxresp - expect resp.bodylen == 2 - txreq -url "/foo3" - rxresp - expect resp.bodylen == 3 - txreq -url "/foo4" - rxresp - expect resp.bodylen == 4 -} -run - -server s1 -start -server s2 -start - -client c2 { - timeout 3 - txreq -url "/foo11" - rxresp - expect resp.bodylen == 1 - txreq -url "/foo22" - rxresp - expect resp.bodylen == 2 -} -run diff --git a/bin/varnishtest/tests/v00022.vtc b/bin/varnishtest/tests/v00022.vtc deleted file mode 100644 index 5e5a17b..0000000 --- a/bin/varnishtest/tests/v00022.vtc +++ /dev/null @@ -1,89 +0,0 @@ -varnishtest "Deeper test of random director" - -random - -server s1 { - rxreq - txresp -body "1" -} -start -server s2 { - rxreq - txresp -body "22" - rxreq - txresp -body "22" - rxreq - txresp -body "22" - rxreq - txresp -body "22" -} -start -server s3 { - rxreq - txresp -body "333" -} -start -server s4 { - rxreq - txresp -body "4444" - rxreq - txresp -body "4444" - rxreq - txresp -body "4444" - rxreq - txresp -body "4444" -} -start - -varnish v1 -vcl+backend { - import ${vmod_directors}; - - sub vcl_init { - new foo = directors.random(); - foo.add_backend(s1, 1); - foo.add_backend(s2, 1); - foo.add_backend(s3, 1); - foo.add_backend(s4, 1); - } - - sub vcl_recv { - return(pass); - } - sub vcl_backend_fetch { - set bereq.backend = foo.backend(); - } -} -start - -# NB: Do not change the number 1 -# NB: Only srandom(1) is standardized as deterministic. - -varnish v1 -cliok "debug.srandom 1" - -client c1 { - txreq - rxresp - expect resp.bodylen == 2 - txreq - rxresp - expect resp.bodylen == 4 - txreq - rxresp - expect resp.bodylen == 4 - txreq - rxresp - expect resp.bodylen == 4 - txreq - rxresp - expect resp.bodylen == 1 - txreq - rxresp - expect resp.bodylen == 2 - txreq - rxresp - expect resp.bodylen == 4 - txreq - rxresp - expect resp.bodylen == 2 - txreq - rxresp - expect resp.bodylen == 3 - txreq - rxresp - expect resp.bodylen == 2 -} -run diff --git a/bin/varnishtest/tests/v00026.vtc b/bin/varnishtest/tests/v00026.vtc deleted file mode 100644 index 11475dc..0000000 --- a/bin/varnishtest/tests/v00026.vtc +++ /dev/null @@ -1,78 +0,0 @@ -varnishtest "Hash director" - -server s1 { - rxreq - txresp -hdr "Foo: 1" -body "1" - rxreq - txresp -hdr "Foo: 3" -body "3" -} -start - -server s2 { - rxreq - txresp -hdr "Foo: 2" -body "2" - rxreq - txresp -hdr "Foo: 4" -body "4" - rxreq - txresp -hdr "Foo: 6" -body "6" - rxreq - txresp -hdr "Foo: 8" -body "8" -} -start - - -varnish v1 -vcl+backend { - import ${vmod_directors}; - - sub vcl_init { - new h1 = directors.hash(); - h1.add_backend(s1, 1); - h1.add_backend(s2, 1); - } - - sub vcl_recv { - return(pass); - } - sub vcl_backend_fetch { - if (bereq.url == "/nohdr") { - set bereq.backend = h1.backend(bereq.http.Void); - } else if (bereq.url == "/emptystring") { - set bereq.backend = h1.backend(""); - } else if (bereq.url == "/13") { - set bereq.backend = h1.backend(bereq.http.Void + "" + bereq.url); - } else { - set bereq.backend = h1.backend(bereq.url); - } - } - sub vcl_backend_response { - set beresp.http.where = bereq.backend + "-->" + beresp.backend; - } - -} -start - - -client c1 { - txreq -url /1 - rxresp - expect resp.http.foo == "1" - - txreq -url /3 - rxresp - expect resp.http.foo == "2" - - txreq -url /13 - rxresp - expect resp.http.foo == "3" - - txreq -url /8 - rxresp - expect resp.http.foo == "4" - - txreq -url /emptystring - rxresp - expect resp.http.foo == "6" - - txreq -url /nohdr - rxresp - expect resp.http.foo == "8" - - -} -run diff --git a/bin/varnishtest/tests/v00036.vtc b/bin/varnishtest/tests/v00036.vtc deleted file mode 100644 index 2a7009c..0000000 --- a/bin/varnishtest/tests/v00036.vtc +++ /dev/null @@ -1,61 +0,0 @@ -varnishtest "Test fallback director" - -server s1 { - rxreq - txresp -hdr "Foo: 1" -} -start - -server s2 { - rxreq - txresp -hdr "Foo: 2" -} -start - -server s3 { - rxreq - txresp -hdr "Foo: 3" -} -start - -varnish v1 -vcl+backend { - import ${vmod_directors}; - - sub vcl_init { - new fb1 = directors.fallback(); - fb1.add_backend(s1); - fb1.add_backend(s2); - fb1.add_backend(s3); - } - - sub vcl_recv { - return (pass); - } - sub vcl_backend_fetch { - set bereq.backend = fb1.backend(); - } - -} -start - -varnish v1 -cliok "backend.set_health s1 sick" -varnish v1 -cliok "backend.set_health s2 sick" - -client c1 { - # s1 & s2 are both sick, expect response from s3 - txreq - rxresp - expect resp.http.foo == "3" -} -run - -varnish v1 -cliok "backend.set_health s2 healthy" - -client c1 { - txreq - rxresp - expect resp.http.foo == "2" -} -run - -varnish v1 -cliok "backend.set_health s1 healthy" - -client c1 { - txreq - rxresp - expect resp.http.foo == "1" -} -run From phk at FreeBSD.org Tue Oct 21 19:19:12 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 21 Oct 2014 21:19:12 +0200 Subject: [master] a70c927 FlexeLint polish Message-ID: commit a70c92743fb9c7a16ac1bb6f27676d3571bffe96 Author: Poul-Henning Kamp Date: Tue Oct 21 19:18:58 2014 +0000 FlexeLint polish diff --git a/bin/varnishd/storage/storage_file.c b/bin/varnishd/storage/storage_file.c index 9b6a794..3974a5c 100644 --- a/bin/varnishd/storage/storage_file.c +++ b/bin/varnishd/storage/storage_file.c @@ -109,7 +109,6 @@ smf_init(struct stevedore *parent, int ac, char * const *av) AZ(av[ac]); - fn = NULL; size = NULL; page_size = getpagesize(); From phk at FreeBSD.org Tue Oct 21 20:25:03 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 21 Oct 2014 22:25:03 +0200 Subject: [master] 1632279 Start moving ESI delivery towards the VDP pipeline Message-ID: commit 163227929bba82804e3a34ed070766d2a0fc4a42 Author: Poul-Henning Kamp Date: Tue Oct 21 20:24:44 2014 +0000 Start moving ESI delivery towards the VDP pipeline diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index 030ccbf..ba72bb7 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -205,7 +205,7 @@ ved_decode_len(uint8_t **pp) * the stream with a bit more overhead. */ -static void +static int ved_pretend_gzip(struct req *req, const uint8_t *p, ssize_t l) { uint8_t buf1[5], buf2[5]; @@ -219,24 +219,25 @@ ved_pretend_gzip(struct req *req, const uint8_t *p, ssize_t l) while (l > 0) { if (l >= 65535) { lx = 65535; - req->resp_bodybytes += - WRW_Write(req->wrk, buf1, sizeof buf1); + if (VDP_bytes(req, VDP_NULL, buf1, sizeof buf1)) + return (-1); } else { lx = (uint16_t)l; buf2[0] = 0; vle16enc(buf2 + 1, lx); vle16enc(buf2 + 3, ~lx); - req->resp_bodybytes += - WRW_Write(req->wrk, buf2, sizeof buf2); + if (VDP_bytes(req, VDP_NULL, buf2, sizeof buf2)) + return (-1); } - req->resp_bodybytes += WRW_Write(req->wrk, p, lx); + if (VDP_bytes(req, VDP_NULL, p, lx)) + return (-1); req->crc = crc32(req->crc, p, lx); req->l_crc += lx; l -= lx; p += lx; } /* buf2 is local, have to flush */ - (void)WRW_Flush(req->wrk); + return (VDP_bytes(req, VDP_FLUSH, NULL, 0)); } /*--------------------------------------------------------------------- @@ -289,8 +290,7 @@ ESI_Deliver(struct req *req) if (isgzip && !(req->res_mode & RES_GUNZIP)) { assert(sizeof gzip_hdr == 10); /* Send out the gzip header */ - req->resp_bodybytes += - WRW_Write(req->wrk, gzip_hdr, 10); + (void)VDP_bytes(req, VDP_NULL, gzip_hdr, 10); req->l_crc = 0; req->gzip_resp = 1; req->crc = crc32(0L, Z_NULL, 0); @@ -349,14 +349,13 @@ ESI_Deliver(struct req *req) * We have a gzip'ed VEC and delivers * a gzip'ed ESI response. */ - req->resp_bodybytes += - WRW_Write(req->wrk, pp, l2); + (void)VDP_bytes(req, VDP_NULL, pp, l2); } else if (req->gzip_resp) { /* * A gzip'ed ESI response, but the VEC * was not gzip'ed. */ - ved_pretend_gzip(req, pp, l2); + (void)ved_pretend_gzip(req, pp, l2); } else if (isgzip) { /* * A gzip'ed VEC, but ungzip'ed ESI @@ -375,8 +374,7 @@ ESI_Deliver(struct req *req) /* * Ungzip'ed VEC, ungzip'ed ESI response */ - req->resp_bodybytes += - WRW_Write(req->wrk, pp, l2); + (void)VDP_bytes(req, VDP_NULL, pp, l2); } pp += l2; if (sl == 0) { @@ -421,7 +419,7 @@ ESI_Deliver(struct req *req) AN(r); if (vgz != NULL) VGZ_WrwFlush(req, vgz); - if (WRW_Flush(req->wrk)) { + if (VDP_bytes(req, VDP_FLUSH, NULL, 0)) { SES_Close(req->sp, SC_REM_CLOSE); p = e; break; @@ -454,9 +452,9 @@ ESI_Deliver(struct req *req) /* MOD(2^32) length */ vle32enc(tailbuf + 9, req->l_crc); - req->resp_bodybytes += WRW_Write(req->wrk, tailbuf, 13); + (void)VDP_bytes(req, VDP_NULL, tailbuf, 13); } - (void)WRW_Flush(req->wrk); + (void)VDP_bytes(req, VDP_FLUSH, NULL, 0); ObjIterEnd(req->objcore, &oi); } @@ -488,8 +486,8 @@ ESI_DeliverChild(struct req *req) oi = ObjIterBegin(req->wrk, req->objcore); do { ois = ObjIter(req->objcore, oi, &sp, &sl); - if (sl > 0) - ved_pretend_gzip(req, sp, sl); + if (sl > 0 && ved_pretend_gzip(req, sp, sl)) + break; } while (ois == OIS_DATA || ois == OIS_STREAM); ObjIterEnd(req->objcore, &oi); return; @@ -547,8 +545,8 @@ ESI_DeliverChild(struct req *req) if (dl > 0) { if (dl > sl) dl = sl; - req->resp_bodybytes += - WRW_Write(req->wrk, pp, dl); + if (VDP_bytes(req, VDP_NULL, pp, dl)) + break; ll += dl; sl -= dl; pp += dl; @@ -558,7 +556,8 @@ ESI_DeliverChild(struct req *req) /* Remove the "LAST" bit */ dbits[0] = *pp; dbits[0] &= ~(1U << (last & 7)); - req->resp_bodybytes += WRW_Write(req->wrk, dbits, 1); + if (VDP_bytes(req, VDP_NULL, dbits, 1)) + break; ll++; sl--; pp++; @@ -569,8 +568,8 @@ ESI_DeliverChild(struct req *req) if (dl > 0) { if (dl > sl) dl = sl; - req->resp_bodybytes += - WRW_Write(req->wrk, pp, dl); + if (VDP_bytes(req, VDP_NULL, pp, dl)) + break; ll += dl; sl -= dl; pp += dl; @@ -631,8 +630,8 @@ ESI_DeliverChild(struct req *req) default: WRONG("compiler must be broken"); } - req->resp_bodybytes += - WRW_Write(req->wrk, dbits + 1, lpad); + if (VDP_bytes(req, VDP_NULL, dbits + 1, lpad)) + break; } if (sl > 0) { /* Recover GZIP tail */ From phk at FreeBSD.org Tue Oct 21 20:43:41 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 21 Oct 2014 22:43:41 +0200 Subject: [master] 3247c51 Make pretend_gzip a VDP Message-ID: commit 3247c51d0e36654c3bf597347bb6a52530433e6b Author: Poul-Henning Kamp Date: Tue Oct 21 20:43:15 2014 +0000 Make pretend_gzip a VDP diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 185b3e8..7705ea4 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -1119,6 +1119,7 @@ void VRTPRIV_dynamic_kill(struct sess *sp, uintptr_t id); void ESI_Deliver(struct req *); void ESI_DeliverChild(struct req *); +vdp_bytes VED_pretend_gzip; /* cache_vrt_vmod.c */ void VMOD_Init(void); diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index ba72bb7..cfb488e 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -205,12 +205,18 @@ ved_decode_len(uint8_t **pp) * the stream with a bit more overhead. */ -static int -ved_pretend_gzip(struct req *req, const uint8_t *p, ssize_t l) +int __match_proto__(vdp_bytes) +VED_pretend_gzip(struct req *req, enum vdp_action act, const void *pv, + ssize_t l) { uint8_t buf1[5], buf2[5]; + const uint8_t *p; uint16_t lx; + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + (void)act; + p = pv; + lx = 65535; buf1[0] = 0; vle16enc(buf1 + 1, lx); @@ -355,7 +361,8 @@ ESI_Deliver(struct req *req) * A gzip'ed ESI response, but the VEC * was not gzip'ed. */ - (void)ved_pretend_gzip(req, pp, l2); + (void)VED_pretend_gzip(req, VDP_NULL, + pp, l2); } else if (isgzip) { /* * A gzip'ed VEC, but ungzip'ed ESI @@ -482,16 +489,8 @@ ESI_DeliverChild(struct req *req) CHECK_OBJ_NOTNULL(req, REQ_MAGIC); CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); - if (!ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) { - oi = ObjIterBegin(req->wrk, req->objcore); - do { - ois = ObjIter(req->objcore, oi, &sp, &sl); - if (sl > 0 && ved_pretend_gzip(req, sp, sl)) - break; - } while (ois == OIS_DATA || ois == OIS_STREAM); - ObjIterEnd(req->objcore, &oi); - return; - } + AN(ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)); + /* * This is the interesting case: Deliver all the deflate * blocks, stripping the "LAST" bit of the last one and diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 08d3264..70d61c7 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -340,6 +340,11 @@ V1D_Deliver(struct req *req, struct busyobj *bo) /* This was a HEAD or conditional request */ } else if (req->res_mode & RES_ESI) { ESI_Deliver(req); + } else if (req->res_mode & RES_ESI_CHILD && req->gzip_resp && + !ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) { + VDP_push(req, VED_pretend_gzip); + ois = v1d_WriteDirObj(req); + VDP_pop(req, VED_pretend_gzip); } else if (req->res_mode & RES_ESI_CHILD && req->gzip_resp) { if (bo != NULL) VBO_waitstate(bo, BOS_FINISHED); From phk at FreeBSD.org Tue Oct 21 21:15:13 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 21 Oct 2014 23:15:13 +0200 Subject: [master] 11c6e33 Make space for VDP's to have a priv pointer Message-ID: commit 11c6e33e4ab9292d9931e5f4c9485fec663c46c3 Author: Poul-Henning Kamp Date: Tue Oct 21 21:14:57 2014 +0000 Make space for VDP's to have a priv pointer diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 7705ea4..01d3ce8 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -616,6 +616,7 @@ struct req { /* Deliver pipeline */ #define N_VDPS 5 vdp_bytes *vdps[N_VDPS]; + void *vdpp[N_VDPS]; int vdp_nxt; /* Range */ @@ -765,7 +766,7 @@ VDP_bytes(struct req *req, enum vdp_action act, const void *ptr, ssize_t len) /* Call the present layer, while pointing to the next layer down */ i = req->vdp_nxt--; assert(i >= 0 && i < N_VDPS); - retval = req->vdps[i](req, act, ptr, len); + retval = req->vdps[i](req, act, req->vdpp[i], ptr, len); req->vdp_nxt++; return (retval); } @@ -780,6 +781,9 @@ VDP_push(struct req *req, vdp_bytes *func) assert(req->vdp_nxt >= 0); assert(req->vdp_nxt + 1 < N_VDPS); req->vdps[++req->vdp_nxt] = func; + req->vdpp[req->vdp_nxt] = NULL; + AZ(req->vdps[req->vdp_nxt](req, VDP_INIT, + &req->vdpp[req->vdp_nxt], NULL, 0)); } static inline void @@ -791,6 +795,10 @@ VDP_pop(struct req *req, vdp_bytes *func) assert(req->vdp_nxt >= 1); assert(req->vdp_nxt < N_VDPS); assert(req->vdps[req->vdp_nxt] == func); + AZ(req->vdps[req->vdp_nxt](req, VDP_FINI, + &req->vdpp[req->vdp_nxt], NULL, 0)); + AZ(req->vdpp[req->vdp_nxt]); + req->vdps[req->vdp_nxt] = NULL; req->vdp_nxt--; } diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index cfb488e..a126b53 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -206,15 +206,17 @@ ved_decode_len(uint8_t **pp) */ int __match_proto__(vdp_bytes) -VED_pretend_gzip(struct req *req, enum vdp_action act, const void *pv, - ssize_t l) +VED_pretend_gzip(struct req *req, enum vdp_action act, void *priv, + const void *pv, ssize_t l) { uint8_t buf1[5], buf2[5]; const uint8_t *p; uint16_t lx; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - (void)act; + (void)priv; + if (act == VDP_INIT || act == VDP_FINI) + return (0); p = pv; lx = 65535; @@ -362,7 +364,7 @@ ESI_Deliver(struct req *req) * was not gzip'ed. */ (void)VED_pretend_gzip(req, VDP_NULL, - pp, l2); + NULL, pp, l2); } else if (isgzip) { /* * A gzip'ed VEC, but ungzip'ed ESI diff --git a/bin/varnishd/cache/cache_filter.h b/bin/varnishd/cache/cache_filter.h index a5a705a..9377a89 100644 --- a/bin/varnishd/cache/cache_filter.h +++ b/bin/varnishd/cache/cache_filter.h @@ -72,9 +72,11 @@ enum vfp_status VFP_Error(struct vfp_ctx *, const char *fmt, ...) /* Deliver processors ------------------------------------------------*/ enum vdp_action { + VDP_INIT, VDP_NULL, VDP_FLUSH, VDP_FINISH, + VDP_FINI, }; -typedef int vdp_bytes(struct req *, enum vdp_action, const void *ptr, - ssize_t len); +typedef int vdp_bytes(struct req *, enum vdp_action, void *priv, + const void *ptr, ssize_t len); diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index 5e2125b..9e437bb 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -285,7 +285,8 @@ VGZ_WrwInit(struct vgz *vg) */ int __match_proto__(vdp_bytes) -VDP_gunzip(struct req *req, enum vdp_action act, const void *ptr, ssize_t len) +VDP_gunzip(struct req *req, enum vdp_action act, void *priv, + const void *ptr, ssize_t len) { enum vgzret_e vr; ssize_t dl; @@ -296,6 +297,9 @@ VDP_gunzip(struct req *req, enum vdp_action act, const void *ptr, ssize_t len) CHECK_OBJ_NOTNULL(req, REQ_MAGIC); wrk = req->wrk; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + (void)priv; + if (act == VDP_INIT || act == VDP_FINI) + return (0); vg = req->vgz; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); AN(vg->m_buf); diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 70d61c7..b744350 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -36,11 +36,15 @@ /*--------------------------------------------------------------------*/ static int __match_proto__(vdp_bytes) -v1d_bytes(struct req *req, enum vdp_action act, const void *ptr, ssize_t len) +v1d_bytes(struct req *req, enum vdp_action act, void *priv, + const void *ptr, ssize_t len) { ssize_t wl = 0; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + (void)priv; + if (act == VDP_INIT || act == VDP_FINI) + return (0); assert(req->vdp_nxt == -1); /* always at the bottom of the pile */ @@ -57,14 +61,17 @@ v1d_bytes(struct req *req, enum vdp_action act, const void *ptr, ssize_t len) /*--------------------------------------------------------------------*/ static int __match_proto__(vdp_bytes) -v1d_range_bytes(struct req *req, enum vdp_action act, const void *ptr, - ssize_t len) +v1d_range_bytes(struct req *req, enum vdp_action act, void *priv, + const void *ptr, ssize_t len) { int retval = 0; ssize_t l; const char *p = ptr; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + (void)priv; + if (act == VDP_INIT || act == VDP_FINI) + return (0); l = req->range_low - req->range_off; if (l > 0) { if (l > len) From phk at FreeBSD.org Tue Oct 21 21:37:08 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 21 Oct 2014 23:37:08 +0200 Subject: [master] c613a53 Make range and gunzip VDP's manage their own private data. Message-ID: commit c613a535a05338e4f56d858e4058c1abf9e65f71 Author: Poul-Henning Kamp Date: Tue Oct 21 21:36:51 2014 +0000 Make range and gunzip VDP's manage their own private data. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 01d3ce8..4031ada 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -619,14 +619,6 @@ struct req { void *vdpp[N_VDPS]; int vdp_nxt; - /* Range */ - ssize_t range_low; - ssize_t range_high; - ssize_t range_off; - - /* Gunzip */ - struct vgz *vgz; - /* Transaction VSL buffer */ struct vsl_log vsl[1]; @@ -766,13 +758,13 @@ VDP_bytes(struct req *req, enum vdp_action act, const void *ptr, ssize_t len) /* Call the present layer, while pointing to the next layer down */ i = req->vdp_nxt--; assert(i >= 0 && i < N_VDPS); - retval = req->vdps[i](req, act, req->vdpp[i], ptr, len); + retval = req->vdps[i](req, act, &req->vdpp[i], ptr, len); req->vdp_nxt++; return (retval); } static inline void -VDP_push(struct req *req, vdp_bytes *func) +VDP_push(struct req *req, vdp_bytes *func, void *priv) { CHECK_OBJ_NOTNULL(req, REQ_MAGIC); AN(func); @@ -781,7 +773,7 @@ VDP_push(struct req *req, vdp_bytes *func) assert(req->vdp_nxt >= 0); assert(req->vdp_nxt + 1 < N_VDPS); req->vdps[++req->vdp_nxt] = func; - req->vdpp[req->vdp_nxt] = NULL; + req->vdpp[req->vdp_nxt] = priv; AZ(req->vdps[req->vdp_nxt](req, VDP_INIT, &req->vdpp[req->vdp_nxt], NULL, 0)); } diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index a126b53..7c347b8 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -206,7 +206,7 @@ ved_decode_len(uint8_t **pp) */ int __match_proto__(vdp_bytes) -VED_pretend_gzip(struct req *req, enum vdp_action act, void *priv, +VED_pretend_gzip(struct req *req, enum vdp_action act, void **priv, const void *pv, ssize_t l) { uint8_t buf1[5], buf2[5]; diff --git a/bin/varnishd/cache/cache_filter.h b/bin/varnishd/cache/cache_filter.h index 9377a89..b2e1ddd 100644 --- a/bin/varnishd/cache/cache_filter.h +++ b/bin/varnishd/cache/cache_filter.h @@ -78,5 +78,5 @@ enum vdp_action { VDP_FINISH, VDP_FINI, }; -typedef int vdp_bytes(struct req *, enum vdp_action, void *priv, +typedef int vdp_bytes(struct req *, enum vdp_action, void **priv, const void *ptr, ssize_t len); diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index 9e437bb..2087c00 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -285,7 +285,7 @@ VGZ_WrwInit(struct vgz *vg) */ int __match_proto__(vdp_bytes) -VDP_gunzip(struct req *req, enum vdp_action act, void *priv, +VDP_gunzip(struct req *req, enum vdp_action act, void **priv, const void *ptr, ssize_t len) { enum vgzret_e vr; @@ -297,11 +297,19 @@ VDP_gunzip(struct req *req, enum vdp_action act, void *priv, CHECK_OBJ_NOTNULL(req, REQ_MAGIC); wrk = req->wrk; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - (void)priv; - if (act == VDP_INIT || act == VDP_FINI) + if (act == VDP_INIT) { + vg = VGZ_NewUngzip(req->vsl, "U D -"); + AN(vg); + AZ(VGZ_WrwInit(vg)); + *priv = vg; return (0); - vg = req->vgz; - CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); + } + CAST_OBJ_NOTNULL(vg, *priv, VGZ_MAGIC); + if (act == VDP_FINI) { + (void)VGZ_Destroy(&vg); + *priv = NULL; + return (0); + } AN(vg->m_buf); if (len == 0) { diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index b744350..3ab930e 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -36,7 +36,7 @@ /*--------------------------------------------------------------------*/ static int __match_proto__(vdp_bytes) -v1d_bytes(struct req *req, enum vdp_action act, void *priv, +v1d_bytes(struct req *req, enum vdp_action act, void **priv, const void *ptr, ssize_t len) { ssize_t wl = 0; @@ -60,43 +60,58 @@ v1d_bytes(struct req *req, enum vdp_action act, void *priv, /*--------------------------------------------------------------------*/ +struct v1rp { + unsigned magic; +#define V1RP_MAGIC 0xb886e711 + ssize_t range_low; + ssize_t range_high; + ssize_t range_off; +}; + static int __match_proto__(vdp_bytes) -v1d_range_bytes(struct req *req, enum vdp_action act, void *priv, +v1d_range_bytes(struct req *req, enum vdp_action act, void **priv, const void *ptr, ssize_t len) { int retval = 0; ssize_t l; const char *p = ptr; + struct v1rp *v1rp; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - (void)priv; - if (act == VDP_INIT || act == VDP_FINI) + if (act == VDP_INIT) return (0); - l = req->range_low - req->range_off; + if (act == VDP_FINI) { + *priv = NULL; + return (0); + } + CAST_OBJ_NOTNULL(v1rp, *priv, V1RP_MAGIC); + l = v1rp->range_low - v1rp->range_off; if (l > 0) { if (l > len) l = len; - req->range_off += l; + v1rp->range_off += l; p += l; len -= l; } - l = req->range_high - req->range_off; + l = v1rp->range_high - v1rp->range_off; if (l > len) l = len; if (l > 0) retval = VDP_bytes(req, act, p, l); else if (act > VDP_NULL) retval = VDP_bytes(req, act, p, 0); - req->range_off += len; + v1rp->range_off += len; return (retval); } /*--------------------------------------------------------------------*/ + static void v1d_dorange(struct req *req, struct busyobj *bo, const char *r) { ssize_t len, low, high, has_low; + struct v1rp *v1rp; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); @@ -163,10 +178,14 @@ v1d_dorange(struct req *req, struct busyobj *bo, const char *r) (intmax_t)(1 + high - low)); http_PutResponse(req->resp, "HTTP/1.1", 206, NULL); - req->range_off = 0; - req->range_low = low; - req->range_high = high + 1; - VDP_push(req, v1d_range_bytes); + v1rp = WS_Alloc(req->ws, sizeof *v1rp); + XXXAN(v1rp); + memset(v1rp, 0, sizeof *v1rp); + v1rp->magic = V1RP_MAGIC; + v1rp->range_off = 0; + v1rp->range_low = low; + v1rp->range_high = high + 1; + VDP_push(req, v1d_range_bytes, v1rp); } /*--------------------------------------------------------------------*/ @@ -349,7 +368,7 @@ V1D_Deliver(struct req *req, struct busyobj *bo) ESI_Deliver(req); } else if (req->res_mode & RES_ESI_CHILD && req->gzip_resp && !ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) { - VDP_push(req, VED_pretend_gzip); + VDP_push(req, VED_pretend_gzip, NULL); ois = v1d_WriteDirObj(req); VDP_pop(req, VED_pretend_gzip); } else if (req->res_mode & RES_ESI_CHILD && req->gzip_resp) { @@ -360,11 +379,8 @@ V1D_Deliver(struct req *req, struct busyobj *bo) (req->res_mode & RES_ESI_CHILD && !req->gzip_resp && ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED))) { - VDP_push(req, VDP_gunzip); - req->vgz = VGZ_NewUngzip(req->vsl, "U D -"); - AZ(VGZ_WrwInit(req->vgz)); + VDP_push(req, VDP_gunzip, NULL); ois = v1d_WriteDirObj(req); - (void)VGZ_Destroy(&req->vgz); VDP_pop(req, VDP_gunzip); } else { ois = v1d_WriteDirObj(req); From phk at FreeBSD.org Tue Oct 21 22:14:26 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Oct 2014 00:14:26 +0200 Subject: [master] 8bcaeac Start a separate source file for VDP infrastructure Message-ID: commit 8bcaeac68ecbeb1b624c6496e589f4f959e2c774 Author: Poul-Henning Kamp Date: Tue Oct 21 21:44:13 2014 +0000 Start a separate source file for VDP infrastructure diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 6e97946..922459e 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -16,6 +16,7 @@ varnishd_SOURCES = \ cache/cache_ban.c \ cache/cache_busyobj.c \ cache/cache_cli.c \ + cache/cache_deliver_proc.c \ cache/cache_director.c \ cache/cache_esi_deliver.c \ cache/cache_esi_fetch.c \ diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 4031ada..47a9e0a 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -747,53 +747,6 @@ int VRB_Cache(struct req *req, ssize_t maxsize); int VRB_Iterate(struct req *req, req_body_iter_f *func, void *priv); void VRB_Free(struct req *req); -static inline int -VDP_bytes(struct req *req, enum vdp_action act, const void *ptr, ssize_t len) -{ - int i, retval; - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - - assert(act > VDP_NULL || len > 0); - /* Call the present layer, while pointing to the next layer down */ - i = req->vdp_nxt--; - assert(i >= 0 && i < N_VDPS); - retval = req->vdps[i](req, act, &req->vdpp[i], ptr, len); - req->vdp_nxt++; - return (retval); -} - -static inline void -VDP_push(struct req *req, vdp_bytes *func, void *priv) -{ - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - AN(func); - - /* Push another layer */ - assert(req->vdp_nxt >= 0); - assert(req->vdp_nxt + 1 < N_VDPS); - req->vdps[++req->vdp_nxt] = func; - req->vdpp[req->vdp_nxt] = priv; - AZ(req->vdps[req->vdp_nxt](req, VDP_INIT, - &req->vdpp[req->vdp_nxt], NULL, 0)); -} - -static inline void -VDP_pop(struct req *req, vdp_bytes *func) -{ - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - - /* Pop top layer */ - assert(req->vdp_nxt >= 1); - assert(req->vdp_nxt < N_VDPS); - assert(req->vdps[req->vdp_nxt] == func); - AZ(req->vdps[req->vdp_nxt](req, VDP_FINI, - &req->vdpp[req->vdp_nxt], NULL, 0)); - AZ(req->vdpp[req->vdp_nxt]); - req->vdps[req->vdp_nxt] = NULL; - req->vdp_nxt--; -} - /* cache_req_fsm.c [CNT] */ enum req_fsm_nxt CNT_Request(struct worker *, struct req *); void CNT_AcctLogCharge(struct dstat *, struct req *); diff --git a/bin/varnishd/cache/cache_deliver_proc.c b/bin/varnishd/cache/cache_deliver_proc.c new file mode 100644 index 0000000..f231da0 --- /dev/null +++ b/bin/varnishd/cache/cache_deliver_proc.c @@ -0,0 +1,80 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2014 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 "cache.h" +//#include "cache_filter.h" + +int +VDP_bytes(struct req *req, enum vdp_action act, const void *ptr, ssize_t len) +{ + int i, retval; + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + + assert(act > VDP_NULL || len > 0); + /* Call the present layer, while pointing to the next layer down */ + i = req->vdp_nxt--; + assert(i >= 0 && i < N_VDPS); + retval = req->vdps[i](req, act, &req->vdpp[i], ptr, len); + req->vdp_nxt++; + return (retval); +} + +void +VDP_push(struct req *req, vdp_bytes *func, void *priv) +{ + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + AN(func); + + /* Push another layer */ + assert(req->vdp_nxt >= 0); + assert(req->vdp_nxt + 1 < N_VDPS); + req->vdps[++req->vdp_nxt] = func; + req->vdpp[req->vdp_nxt] = priv; + AZ(req->vdps[req->vdp_nxt](req, VDP_INIT, + &req->vdpp[req->vdp_nxt], NULL, 0)); +} + +void +VDP_pop(struct req *req, vdp_bytes *func) +{ + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + + /* Pop top layer */ + assert(req->vdp_nxt >= 1); + assert(req->vdp_nxt < N_VDPS); + assert(req->vdps[req->vdp_nxt] == func); + AZ(req->vdps[req->vdp_nxt](req, VDP_FINI, + &req->vdpp[req->vdp_nxt], NULL, 0)); + AZ(req->vdpp[req->vdp_nxt]); + req->vdps[req->vdp_nxt] = NULL; + req->vdp_nxt--; +} diff --git a/bin/varnishd/cache/cache_filter.h b/bin/varnishd/cache/cache_filter.h index b2e1ddd..1ee0952 100644 --- a/bin/varnishd/cache/cache_filter.h +++ b/bin/varnishd/cache/cache_filter.h @@ -80,3 +80,7 @@ enum vdp_action { }; typedef int vdp_bytes(struct req *, enum vdp_action, void **priv, const void *ptr, ssize_t len); + +int VDP_bytes(struct req *, enum vdp_action act, const void *ptr, ssize_t len); +void VDP_push(struct req *, vdp_bytes *func, void *priv); +void VDP_pop(struct req *, vdp_bytes *func); From phk at FreeBSD.org Tue Oct 21 22:14:26 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Oct 2014 00:14:26 +0200 Subject: [master] ac1fe6e Used a linked list allocated of req->ws for VDPs Message-ID: commit ac1fe6e814a7d7277f3fde41aa2d81d5e882749d Author: Poul-Henning Kamp Date: Tue Oct 21 22:08:34 2014 +0000 Used a linked list allocated of req->ws for VDPs diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 47a9e0a..048830a 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -201,18 +201,6 @@ struct http { * VFP filter state */ -struct vfp_entry { - unsigned magic; -#define VFP_ENTRY_MAGIC 0xbe32a027 - const struct vfp *vfp; - void *priv1; - intptr_t priv2; - enum vfp_status closed; - VTAILQ_ENTRY(vfp_entry) list; - uint64_t calls; - uint64_t bytes_out; -}; - VTAILQ_HEAD(vfp_entry_s, vfp_entry); struct vfp_ctx { @@ -534,6 +522,8 @@ struct busyobj { /*--------------------------------------------------------------------*/ +VTAILQ_HEAD(vdp_entry_s, vdp_entry); + struct req { unsigned magic; #define REQ_MAGIC 0x2751aaa1 @@ -614,10 +604,8 @@ struct req { #define RES_PIPE (1<<7) /* Deliver pipeline */ -#define N_VDPS 5 - vdp_bytes *vdps[N_VDPS]; - void *vdpp[N_VDPS]; - int vdp_nxt; + struct vdp_entry_s vdp; + struct vdp_entry *vdp_nxt; /* Transaction VSL buffer */ struct vsl_log vsl[1]; diff --git a/bin/varnishd/cache/cache_deliver_proc.c b/bin/varnishd/cache/cache_deliver_proc.c index f231da0..55e1d9f 100644 --- a/bin/varnishd/cache/cache_deliver_proc.c +++ b/bin/varnishd/cache/cache_deliver_proc.c @@ -35,46 +35,52 @@ int VDP_bytes(struct req *req, enum vdp_action act, const void *ptr, ssize_t len) { - int i, retval; + int retval; + struct vdp_entry *vdp; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + vdp = req->vdp_nxt; + CHECK_OBJ_NOTNULL(vdp, VDP_ENTRY_MAGIC); + req->vdp_nxt = VTAILQ_NEXT(vdp, list); assert(act > VDP_NULL || len > 0); /* Call the present layer, while pointing to the next layer down */ - i = req->vdp_nxt--; - assert(i >= 0 && i < N_VDPS); - retval = req->vdps[i](req, act, &req->vdpp[i], ptr, len); - req->vdp_nxt++; + retval = vdp->func(req, act, &vdp->priv, ptr, len); + req->vdp_nxt = vdp; return (retval); } void VDP_push(struct req *req, vdp_bytes *func, void *priv) { + struct vdp_entry *vdp; + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); AN(func); - /* Push another layer */ - assert(req->vdp_nxt >= 0); - assert(req->vdp_nxt + 1 < N_VDPS); - req->vdps[++req->vdp_nxt] = func; - req->vdpp[req->vdp_nxt] = priv; - AZ(req->vdps[req->vdp_nxt](req, VDP_INIT, - &req->vdpp[req->vdp_nxt], NULL, 0)); + vdp = WS_Alloc(req->ws, sizeof *vdp); + AN(vdp); + memset(vdp, 0, sizeof *vdp); + vdp->magic = VDP_ENTRY_MAGIC; + vdp->func = func; + vdp->priv = priv; + VTAILQ_INSERT_HEAD(&req->vdp, vdp, list); + req->vdp_nxt = vdp; + + AZ(func(req, VDP_INIT, &vdp->priv, NULL, 0)); } void VDP_pop(struct req *req, vdp_bytes *func) { + struct vdp_entry *vdp; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - /* Pop top layer */ - assert(req->vdp_nxt >= 1); - assert(req->vdp_nxt < N_VDPS); - assert(req->vdps[req->vdp_nxt] == func); - AZ(req->vdps[req->vdp_nxt](req, VDP_FINI, - &req->vdpp[req->vdp_nxt], NULL, 0)); - AZ(req->vdpp[req->vdp_nxt]); - req->vdps[req->vdp_nxt] = NULL; - req->vdp_nxt--; + vdp = VTAILQ_FIRST(&req->vdp); + CHECK_OBJ_NOTNULL(vdp, VDP_ENTRY_MAGIC); + assert(vdp->func == func); + VTAILQ_REMOVE(&req->vdp, vdp, list); + AZ(vdp->func(req, VDP_FINI, &vdp->priv, NULL, 0)); + AZ(vdp->priv); + req->vdp_nxt = VTAILQ_FIRST(&req->vdp); } diff --git a/bin/varnishd/cache/cache_filter.h b/bin/varnishd/cache/cache_filter.h index 1ee0952..c26c665 100644 --- a/bin/varnishd/cache/cache_filter.h +++ b/bin/varnishd/cache/cache_filter.h @@ -55,6 +55,19 @@ struct vfp { intptr_t priv2; }; +struct vfp_entry { + unsigned magic; +#define VFP_ENTRY_MAGIC 0xbe32a027 + const struct vfp *vfp; + void *priv1; + intptr_t priv2; + enum vfp_status closed; + VTAILQ_ENTRY(vfp_entry) list; + uint64_t calls; + uint64_t bytes_out; +}; + + extern const struct vfp vfp_gunzip; extern const struct vfp vfp_gzip; extern const struct vfp vfp_testgunzip; @@ -78,9 +91,18 @@ enum vdp_action { VDP_FINISH, VDP_FINI, }; + typedef int vdp_bytes(struct req *, enum vdp_action, void **priv, const void *ptr, ssize_t len); +struct vdp_entry { + unsigned magic; +#define VDP_ENTRY_MAGIC 0x353eb781 + vdp_bytes *func; + void *priv; + VTAILQ_ENTRY(vdp_entry) list; +}; + int VDP_bytes(struct req *, enum vdp_action act, const void *ptr, ssize_t len); void VDP_push(struct req *, vdp_bytes *func, void *priv); void VDP_pop(struct req *, vdp_bytes *func); diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 3ab930e..b97c925 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -46,7 +46,7 @@ v1d_bytes(struct req *req, enum vdp_action act, void **priv, if (act == VDP_INIT || act == VDP_FINI) return (0); - assert(req->vdp_nxt == -1); /* always at the bottom of the pile */ + AZ(req->vdp_nxt); /* always at the bottom of the pile */ if (len > 0) wl = WRW_Write(req->wrk, ptr, len); @@ -336,8 +336,9 @@ V1D_Deliver(struct req *req, struct busyobj *bo) http_SetHeader(req->resp, req->doclose ? "Connection: close" : "Connection: keep-alive"); - req->vdps[0] = v1d_bytes; req->vdp_nxt = 0; + VTAILQ_INIT(&req->vdp); + VDP_push(req, v1d_bytes, NULL); if ( req->wantbody && From phk at FreeBSD.org Tue Oct 21 22:14:26 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Oct 2014 00:14:26 +0200 Subject: [master] 36bec2b Reduce scope of cache_filter.h Message-ID: commit 36bec2bbcbd6ae75c188d919274d1e8483c56a10 Author: Poul-Henning Kamp Date: Tue Oct 21 22:14:09 2014 +0000 Reduce scope of cache_filter.h diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 048830a..bcf2903 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -36,7 +36,6 @@ #include "common/common.h" -#include "cache/cache_filter.h" #include "vapi/vsl_int.h" #include @@ -769,7 +768,6 @@ void VBF_Fetch(struct worker *wrk, struct req *req, struct objcore *oc, struct objcore *oldoc, enum vbf_fetch_mode_e); /* cache_fetch_proc.c */ -enum vfp_status VFP_GetStorage(struct vfp_ctx *, ssize_t *sz, uint8_t **ptr); void VFP_Init(void); /* cache_gzip.c */ @@ -794,7 +792,6 @@ enum vgzret_e VGZ_Gzip(struct vgz *, const void **, ssize_t *len, enum vgzret_e VGZ_Gunzip(struct vgz *, const void **, ssize_t *len); enum vgzret_e VGZ_Destroy(struct vgz **); void VGZ_UpdateObj(const struct vfp_ctx *, const struct vgz*); -vdp_bytes VDP_gunzip; int VGZ_WrwInit(struct vgz *vg); enum vgzret_e VGZ_WrwGunzip(struct req *, struct vgz *, const void *ibuf, @@ -1060,7 +1057,6 @@ void VRTPRIV_dynamic_kill(struct sess *sp, uintptr_t id); void ESI_Deliver(struct req *); void ESI_DeliverChild(struct req *); -vdp_bytes VED_pretend_gzip; /* cache_vrt_vmod.c */ void VMOD_Init(void); diff --git a/bin/varnishd/cache/cache_deliver_proc.c b/bin/varnishd/cache/cache_deliver_proc.c index 55e1d9f..921ea65 100644 --- a/bin/varnishd/cache/cache_deliver_proc.c +++ b/bin/varnishd/cache/cache_deliver_proc.c @@ -30,7 +30,7 @@ #include "config.h" #include "cache.h" -//#include "cache_filter.h" +#include "cache_filter.h" int VDP_bytes(struct req *req, enum vdp_action act, const void *ptr, ssize_t len) diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index 7c347b8..056db1e 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -34,6 +34,7 @@ #include #include "cache.h" +#include "cache_filter.h" #include "vtim.h" #include "cache_esi.h" diff --git a/bin/varnishd/cache/cache_esi_fetch.c b/bin/varnishd/cache/cache_esi_fetch.c index a2aadb7..9091197 100644 --- a/bin/varnishd/cache/cache_esi_fetch.c +++ b/bin/varnishd/cache/cache_esi_fetch.c @@ -33,6 +33,7 @@ #include #include "cache.h" +#include "cache_filter.h" #include "cache_esi.h" diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 2f9ab92..0810eea 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -36,6 +36,7 @@ #include "cache.h" #include "cache_director.h" +#include "cache_filter.h" #include "vend.h" #include "hash/hash_slinger.h" #include "vcl.h" diff --git a/bin/varnishd/cache/cache_fetch_proc.c b/bin/varnishd/cache/cache_fetch_proc.c index 5859bd6..da67df7 100644 --- a/bin/varnishd/cache/cache_fetch_proc.c +++ b/bin/varnishd/cache/cache_fetch_proc.c @@ -35,6 +35,7 @@ #include #include "cache.h" +#include "cache_filter.h" #include "hash/hash_slinger.h" diff --git a/bin/varnishd/cache/cache_filter.h b/bin/varnishd/cache/cache_filter.h index c26c665..80dc7d2 100644 --- a/bin/varnishd/cache/cache_filter.h +++ b/bin/varnishd/cache/cache_filter.h @@ -82,6 +82,9 @@ enum vfp_status VFP_Suck(struct vfp_ctx *, void *p, ssize_t *lp); enum vfp_status VFP_Error(struct vfp_ctx *, const char *fmt, ...) __printflike(2, 3); +/* cache_fetch_proc.c */ +enum vfp_status VFP_GetStorage(struct vfp_ctx *, ssize_t *sz, uint8_t **ptr); + /* Deliver processors ------------------------------------------------*/ enum vdp_action { @@ -106,3 +109,7 @@ struct vdp_entry { int VDP_bytes(struct req *, enum vdp_action act, const void *ptr, ssize_t len); void VDP_push(struct req *, vdp_bytes *func, void *priv); void VDP_pop(struct req *, vdp_bytes *func); + +vdp_bytes VDP_gunzip; +vdp_bytes VED_pretend_gzip; + diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index 2087c00..574bcf3 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -42,6 +42,7 @@ #include #include "cache.h" +#include "cache_filter.h" #include "vend.h" #include "vgz.h" diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index 5b977be..bc1f992 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -39,6 +39,7 @@ #include #include "cache.h" +#include "cache_filter.h" #include "vend.h" #include "common/heritage.h" diff --git a/bin/varnishd/cache/cache_req_body.c b/bin/varnishd/cache/cache_req_body.c index 223b728..9368c1d 100644 --- a/bin/varnishd/cache/cache_req_body.c +++ b/bin/varnishd/cache/cache_req_body.c @@ -34,6 +34,7 @@ #include #include "cache.h" +#include "cache_filter.h" #include "vtim.h" #include "storage/storage.h" #include "hash/hash_slinger.h" diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index b97c925..e4c026a 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -30,6 +30,7 @@ #include "config.h" #include "cache/cache.h" +#include "cache/cache_filter.h" #include "vct.h" diff --git a/bin/varnishd/http1/cache_http1_vfp.c b/bin/varnishd/http1/cache_http1_vfp.c index daf81a5..5c712bd 100644 --- a/bin/varnishd/http1/cache_http1_vfp.c +++ b/bin/varnishd/http1/cache_http1_vfp.c @@ -38,6 +38,7 @@ #include #include "cache/cache.h" +#include "cache/cache_filter.h" #include "vct.h" From phk at FreeBSD.org Wed Oct 22 00:05:14 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Oct 2014 02:05:14 +0200 Subject: [master] eaebe01 Untangle the esi delivery and make it almost a set of plain VDPs. Message-ID: commit eaebe011b5ac0aceb841a929d26cc5f464613492 Author: Poul-Henning Kamp Date: Wed Oct 22 00:04:47 2014 +0000 Untangle the esi delivery and make it almost a set of plain VDPs. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index bcf2903..63fbcf4 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -781,7 +781,7 @@ enum vgzret_e { }; enum vgz_flag { VGZ_NORMAL, VGZ_ALIGN, VGZ_RESET, VGZ_FINISH }; -struct vgz *VGZ_NewUngzip(struct vsl_log *vsl, const char *id); +// struct vgz *VGZ_NewUngzip(struct vsl_log *vsl, const char *id); struct vgz *VGZ_NewGzip(struct vsl_log *vsl, const char *id); void VGZ_Ibuf(struct vgz *, const void *, ssize_t len); int VGZ_IbufEmpty(const struct vgz *vg); @@ -789,15 +789,10 @@ void VGZ_Obuf(struct vgz *, void *, ssize_t len); int VGZ_ObufFull(const struct vgz *vg); enum vgzret_e VGZ_Gzip(struct vgz *, const void **, ssize_t *len, enum vgz_flag); -enum vgzret_e VGZ_Gunzip(struct vgz *, const void **, ssize_t *len); +// enum vgzret_e VGZ_Gunzip(struct vgz *, const void **, ssize_t *len); enum vgzret_e VGZ_Destroy(struct vgz **); void VGZ_UpdateObj(const struct vfp_ctx *, const struct vgz*); -int VGZ_WrwInit(struct vgz *vg); -enum vgzret_e VGZ_WrwGunzip(struct req *, struct vgz *, const void *ibuf, - ssize_t ibufl); -void VGZ_WrwFlush(struct req *, struct vgz *vg); - /* cache_http.c */ unsigned HTTP_estimate(unsigned nhttp); void HTTP_Copy(struct http *to, const struct http * const fm); @@ -958,7 +953,6 @@ void Pool_Sumstat(struct worker *w); void Pool_PurgeStat(unsigned nobj); #define WRW_IsReleased(w) ((w)->wrw == NULL) -int WRW_Error(const struct worker *w); void WRW_Chunked(const struct worker *w); void WRW_EndChunk(const struct worker *w); void WRW_Reserve(struct worker *w, int *fd, struct vsl_log *, double t0); diff --git a/bin/varnishd/cache/cache_deliver_proc.c b/bin/varnishd/cache/cache_deliver_proc.c index 921ea65..1346898 100644 --- a/bin/varnishd/cache/cache_deliver_proc.c +++ b/bin/varnishd/cache/cache_deliver_proc.c @@ -67,7 +67,7 @@ VDP_push(struct req *req, vdp_bytes *func, void *priv) VTAILQ_INSERT_HEAD(&req->vdp, vdp, list); req->vdp_nxt = vdp; - AZ(func(req, VDP_INIT, &vdp->priv, NULL, 0)); + AZ(vdp->func(req, VDP_INIT, &vdp->priv, NULL, 0)); } void diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index 056db1e..06e2570 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -111,6 +111,10 @@ ved_include(struct req *preq, const char *src, const char *host) req->crc = preq->crc; req->l_crc = preq->l_crc; + + req->vdp = preq->vdp; + req->vdp_nxt = preq->vdp_nxt; + THR_SetRequest(req); VSLb_ts_req(req, "Start", W_TIM_real(wrk)); @@ -267,10 +271,6 @@ ESI_Deliver(struct req *req) uint32_t icrc = 0; uint8_t tailbuf[8 + 5]; int isgzip; - struct vgz *vgz = NULL; - ssize_t dl; - const void *dp; - int i; void *oi; enum objiter_status ois; void *sp; @@ -296,7 +296,7 @@ ESI_Deliver(struct req *req) * Only the top level document gets to decide this. */ req->gzip_resp = 0; - if (isgzip && !(req->res_mode & RES_GUNZIP)) { + if (isgzip) { assert(sizeof gzip_hdr == 10); /* Send out the gzip header */ (void)VDP_bytes(req, VDP_NULL, gzip_hdr, 10); @@ -306,18 +306,6 @@ ESI_Deliver(struct req *req) } } - if (isgzip && !req->gzip_resp) { - vgz = VGZ_NewUngzip(req->vsl, "U D E"); - AZ(VGZ_WrwInit(vgz)); - - /* Feed a gzip header to gunzip to make it happy */ - VGZ_Ibuf(vgz, gzip_hdr, sizeof gzip_hdr); - i = VGZ_Gunzip(vgz, &dp, &dl); - assert(i == VGZ_OK); - assert(VGZ_IbufEmpty(vgz)); - AZ(dl); - } - oi = ObjIterBegin(req->wrk, req->objcore); ois = ObjIter(req->objcore, oi, &sp, &sl); assert(ois != OIS_ERROR); @@ -366,24 +354,7 @@ ESI_Deliver(struct req *req) */ (void)VED_pretend_gzip(req, VDP_NULL, NULL, pp, l2); - } else if (isgzip) { - /* - * A gzip'ed VEC, but ungzip'ed ESI - * response - */ - AN(vgz); - i = VGZ_WrwGunzip(req, vgz, pp, l2); - if (WRW_Error(req->wrk)) { - SES_Close(req->sp, - SC_REM_CLOSE); - p = e; - break; - } - assert(i == VGZ_OK || i == VGZ_END); } else { - /* - * Ungzip'ed VEC, ungzip'ed ESI response - */ (void)VDP_bytes(req, VDP_NULL, pp, l2); } pp += l2; @@ -427,8 +398,6 @@ ESI_Deliver(struct req *req) q++; r = (void*)strchr((const char*)q, '\0'); AN(r); - if (vgz != NULL) - VGZ_WrwFlush(req, vgz); if (VDP_bytes(req, VDP_FLUSH, NULL, 0)) { SES_Close(req->sp, SC_REM_CLOSE); p = e; @@ -444,10 +413,6 @@ ESI_Deliver(struct req *req) INCOMPL(); } } - if (vgz != NULL) { - VGZ_WrwFlush(req, vgz); - (void)VGZ_Destroy(&vgz); - } if (req->gzip_resp && req->esi_level == 0) { /* Emit a gzip literal block with finish bit set */ tailbuf[0] = 0x01; diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index 574bcf3..93b16dd 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -56,7 +56,6 @@ struct vgz { int last_i; enum vgz_flag flag; - /* Wrw stuff */ char *m_buf; ssize_t m_sz; ssize_t m_len; @@ -80,7 +79,7 @@ vgz_alloc_vgz(struct vsl_log *vsl, const char *id) return (vg); } -struct vgz * +static struct vgz * VGZ_NewUngzip(struct vsl_log *vsl, const char *id) { struct vgz *vg; @@ -193,7 +192,7 @@ VGZ_ObufFull(const struct vgz *vg) /*--------------------------------------------------------------------*/ -enum vgzret_e +static enum vgzret_e VGZ_Gunzip(struct vgz *vg, const void **pptr, ssize_t *plen) { int i; @@ -266,22 +265,6 @@ VGZ_Gzip(struct vgz *vg, const void **pptr, ssize_t *plen, enum vgz_flag flags) } /*-------------------------------------------------------------------- - */ - -int -VGZ_WrwInit(struct vgz *vg) -{ - - CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); - - if (vgz_getmbuf(vg)) - return (-1); - - VGZ_Obuf(vg, vg->m_buf, vg->m_sz); - return (0); -} - -/*-------------------------------------------------------------------- * VDP for gunzip'ing */ @@ -294,6 +277,7 @@ VDP_gunzip(struct req *req, enum vdp_action act, void **priv, const void *dp; struct worker *wrk; struct vgz *vg; + int retval; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); wrk = req->wrk; @@ -301,7 +285,9 @@ VDP_gunzip(struct req *req, enum vdp_action act, void **priv, if (act == VDP_INIT) { vg = VGZ_NewUngzip(req->vsl, "U D -"); AN(vg); - AZ(VGZ_WrwInit(vg)); + if (vgz_getmbuf(vg)) + return (-1); + VGZ_Obuf(vg, vg->m_buf, vg->m_sz); *priv = vg; return (0); } @@ -315,7 +301,10 @@ VDP_gunzip(struct req *req, enum vdp_action act, void **priv, if (len == 0) { AN(act > VDP_NULL); - return (VDP_bytes(req, act, vg->m_buf, vg->m_len)); + retval = VDP_bytes(req, act, vg->m_buf, vg->m_len); + vg->m_len = 0; + VGZ_Obuf(vg, vg->m_buf, vg->m_sz); + return (retval); } VGZ_Ibuf(vg, ptr, len); @@ -339,68 +328,6 @@ VDP_gunzip(struct req *req, enum vdp_action act, void **priv, return (0); } -/*-------------------------------------------------------------------- - * Gunzip ibuf into outb, if it runs full, emit it with WRW. - * Leave flushing to caller, more data may be coming. - */ - -enum vgzret_e -VGZ_WrwGunzip(struct req *req, struct vgz *vg, const void *ibuf, - ssize_t ibufl) -{ - enum vgzret_e vr; - ssize_t dl; - const void *dp; - struct worker *wrk; - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - wrk = req->wrk; - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); - AN(vg->m_buf); - VGZ_Ibuf(vg, ibuf, ibufl); - if (ibufl == 0) - return (VGZ_OK); - do { - if (vg->m_len == vg->m_sz) - vr = VGZ_STUCK; - else { - vr = VGZ_Gunzip(vg, &dp, &dl); - vg->m_len += dl; - } - if (vr < VGZ_OK) - return (vr); - if (vg->m_len == vg->m_sz || vr == VGZ_STUCK) { - (void)VDP_bytes(req, VDP_FLUSH, vg->m_buf, vg->m_len); - vg->m_len = 0; - VGZ_Obuf(vg, vg->m_buf, vg->m_sz); - } - } while (!VGZ_IbufEmpty(vg)); - if (vr == VGZ_STUCK) - vr = VGZ_OK; - return (vr); -} - -/*--------------------------------------------------------------------*/ - -void -VGZ_WrwFlush(struct req *req, struct vgz *vg) -{ - struct worker *wrk; - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - wrk = req->wrk; - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); - - if (vg->m_len == 0) - return; - - (void)VDP_bytes(req, VDP_FLUSH, vg->m_buf, vg->m_len); - vg->m_len = 0; - VGZ_Obuf(vg, vg->m_buf, vg->m_sz); -} - /*--------------------------------------------------------------------*/ void diff --git a/bin/varnishd/cache/cache_wrw.c b/bin/varnishd/cache/cache_wrw.c index 814a791..948c562 100644 --- a/bin/varnishd/cache/cache_wrw.c +++ b/bin/varnishd/cache/cache_wrw.c @@ -64,13 +64,6 @@ struct wrw { /*-------------------------------------------------------------------- */ -int -WRW_Error(const struct worker *wrk) -{ - - return (wrk->wrw->werr); -} - void WRW_Reserve(struct worker *wrk, int *fd, struct vsl_log *vsl, double t0) { diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index e4c026a..5ed5be5 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -255,6 +255,8 @@ V1D_FlushReleaseAcct(struct req *req) return (u); } +/*-------------------------------------------------------------------- + */ void V1D_Deliver(struct req *req, struct busyobj *bo) { @@ -337,9 +339,11 @@ V1D_Deliver(struct req *req, struct busyobj *bo) http_SetHeader(req->resp, req->doclose ? "Connection: close" : "Connection: keep-alive"); - req->vdp_nxt = 0; - VTAILQ_INIT(&req->vdp); - VDP_push(req, v1d_bytes, NULL); + if (req->esi_level == 0) { + req->vdp_nxt = 0; + VTAILQ_INIT(&req->vdp); + VDP_push(req, v1d_bytes, NULL); + } if ( req->wantbody && @@ -367,20 +371,32 @@ V1D_Deliver(struct req *req, struct busyobj *bo) if (!req->wantbody) { /* This was a HEAD or conditional request */ } else if (req->res_mode & RES_ESI) { + if (req->esi_level == 0 && req->res_mode & RES_GUNZIP) + VDP_push(req, VDP_gunzip, NULL); ESI_Deliver(req); - } else if (req->res_mode & RES_ESI_CHILD && req->gzip_resp && - !ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) { - VDP_push(req, VED_pretend_gzip, NULL); - ois = v1d_WriteDirObj(req); - VDP_pop(req, VED_pretend_gzip); - } else if (req->res_mode & RES_ESI_CHILD && req->gzip_resp) { - if (bo != NULL) - VBO_waitstate(bo, BOS_FINISHED); - ESI_DeliverChild(req); - } else if (req->res_mode & RES_GUNZIP || - (req->res_mode & RES_ESI_CHILD && - !req->gzip_resp && - ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED))) { + if (req->esi_level == 0 && req->res_mode & RES_GUNZIP) + VDP_pop(req, VDP_gunzip); + } else if (req->res_mode & RES_ESI_CHILD) { + if (req->gzip_resp && + !ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) { + VDP_push(req, VED_pretend_gzip, NULL); + ois = v1d_WriteDirObj(req); + VDP_pop(req, VED_pretend_gzip); + } else if (req->gzip_resp) { + if (bo != NULL) + VBO_waitstate(bo, BOS_FINISHED); + ESI_DeliverChild(req); + } else if (!req->gzip_resp && + ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) { + VDP_push(req, VDP_gunzip, NULL); + ois = v1d_WriteDirObj(req); + VDP_pop(req, VDP_gunzip); + } else { + /* The toplevel will gunzip if needed */ + ois = v1d_WriteDirObj(req); + } + } else if ((req->res_mode & RES_GUNZIP) && + ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) { VDP_push(req, VDP_gunzip, NULL); ois = v1d_WriteDirObj(req); VDP_pop(req, VDP_gunzip); From fgsch at lodoss.net Wed Oct 22 01:02:42 2014 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Wed, 22 Oct 2014 03:02:42 +0200 Subject: [master] d387f09 Better description for strstr. Message-ID: commit d387f09127ff3cb05c011a1aa2103f85af9a1cf8 Author: Federico G. Schwindt Date: Tue Oct 21 23:06:50 2014 +0100 Better description for strstr. diff --git a/lib/libvmod_std/vmod.vcc b/lib/libvmod_std/vmod.vcc index 5dae97b..73835f9 100644 --- a/lib/libvmod_std/vmod.vcc +++ b/lib/libvmod_std/vmod.vcc @@ -218,8 +218,8 @@ Example $Function STRING strstr(STRING s1, STRING s2) Description - Returns the first occurrence of the string *s2* in the string - *s1*, or an empty string if not found. + Returns a string beginning at the first occurrence of the string + *s2* in the string *s1*, or an empty string if *s2* is not found. Note that the comparison is case sensitive. Example From fgsch at lodoss.net Wed Oct 22 01:02:42 2014 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Wed, 22 Oct 2014 03:02:42 +0200 Subject: [master] 75c8014 Test the return value more closely Message-ID: commit 75c8014566e5773a6eb370eda9b4a03c225076cf Author: Federico G. Schwindt Date: Tue Oct 21 23:08:02 2014 +0100 Test the return value more closely diff --git a/bin/varnishtest/tests/m00018.vtc b/bin/varnishtest/tests/m00018.vtc index e2b501d..35000ce 100644 --- a/bin/varnishtest/tests/m00018.vtc +++ b/bin/varnishtest/tests/m00018.vtc @@ -1,34 +1,24 @@ -varnishtest "Test substring matching in std" +varnishtest "Test std.substr" -server s1 { - rxreq - txresp - - rxreq - txresp +server s1 -repeat 2 { + rxreq + txresp } -start varnish v1 -vcl+backend { import ${vmod_std}; sub vcl_deliver { - if (std.strstr(req.url, "foo")) { - set resp.http.sub = "found"; - } else { - set resp.http.sub = "not found"; - } - + set resp.http.sub = std.strstr(req.url, "b"); } } -start client c1 { txreq -url "/foobar" rxresp - expect resp.http.sub == "found" - + expect resp.http.sub == "bar" txreq -url "/quux" rxresp - expect resp.http.sub == "not found" + expect resp.http.sub == "" } -run - From fgsch at lodoss.net Wed Oct 22 01:02:42 2014 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Wed, 22 Oct 2014 03:02:42 +0200 Subject: [master] 5a20429 Remove dead code and extra newlines Message-ID: commit 5a20429888d685cf5c44e48b4eeb8f0702fd9d57 Author: Federico G. Schwindt Date: Tue Oct 21 23:10:39 2014 +0100 Remove dead code and extra newlines diff --git a/bin/varnishtest/tests/d00000.vtc b/bin/varnishtest/tests/d00000.vtc index 780e17c..a88634f 100644 --- a/bin/varnishtest/tests/d00000.vtc +++ b/bin/varnishtest/tests/d00000.vtc @@ -10,7 +10,6 @@ server s2 { txresp -body "22" } -start - server s3 { rxreq txresp -body "333" @@ -35,10 +34,6 @@ varnish v1 -vcl+backend { sub vcl_backend_fetch { set bereq.backend = rr.backend(); } - - sub vcl_backend_response { - set beresp.http.where = bereq.backend + "-->" + beresp.backend; - } } -start client c1 { diff --git a/bin/varnishtest/tests/d00001.vtc b/bin/varnishtest/tests/d00001.vtc index 233be8e..c373b4d 100644 --- a/bin/varnishtest/tests/d00001.vtc +++ b/bin/varnishtest/tests/d00001.vtc @@ -32,7 +32,6 @@ varnish v1 -vcl+backend { sub vcl_backend_fetch { set bereq.backend = fb1.backend(); } - } -start varnish v1 -cliok "backend.set_health s1 sick" diff --git a/bin/varnishtest/tests/d00003.vtc b/bin/varnishtest/tests/d00003.vtc index b81e482..0c95d61 100644 --- a/bin/varnishtest/tests/d00003.vtc +++ b/bin/varnishtest/tests/d00003.vtc @@ -42,14 +42,8 @@ varnish v1 -vcl+backend { set bereq.backend = h1.backend(bereq.url); } } - - sub vcl_backend_response { - set beresp.http.where = bereq.backend + "-->" + beresp.backend; - } - } -start - client c1 { txreq -url /1 rxresp From phk at FreeBSD.org Wed Oct 22 07:33:32 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Oct 2014 09:33:32 +0200 Subject: [master] dd40eaa Make WRW_WriteH() an internal http1_proto helper Message-ID: commit dd40eaa800e0fe6cb9bdd4db6594817b6127d34c Author: Poul-Henning Kamp Date: Wed Oct 22 07:33:19 2014 +0000 Make WRW_WriteH() an internal http1_proto helper diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 63fbcf4..0e9668e 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -959,7 +959,6 @@ void WRW_Reserve(struct worker *w, int *fd, struct vsl_log *, double t0); unsigned WRW_Flush(const struct worker *w); unsigned WRW_FlushRelease(struct worker *w, uint64_t *pacc); unsigned WRW_Write(const struct worker *w, const void *ptr, int len); -unsigned WRW_WriteH(const struct worker *w, const txt *hh, const char *suf); /* cache_session.c [SES] */ void SES_Close(struct sess *sp, enum sess_close reason); diff --git a/bin/varnishd/cache/cache_wrw.c b/bin/varnishd/cache/cache_wrw.c index 948c562..2206ea7 100644 --- a/bin/varnishd/cache/cache_wrw.c +++ b/bin/varnishd/cache/cache_wrw.c @@ -224,23 +224,6 @@ WRW_FlushRelease(struct worker *wrk, uint64_t *pacc) } unsigned -WRW_WriteH(const struct worker *wrk, const txt *hh, const char *suf) -{ - unsigned u; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - AN(wrk->wrw->wfd); - AN(wrk); - AN(hh); - AN(hh->b); - AN(hh->e); - u = WRW_Write(wrk, hh->b, hh->e - hh->b); - if (suf != NULL) - u += WRW_Write(wrk, suf, -1); - return (u); -} - -unsigned WRW_Write(const struct worker *wrk, const void *ptr, int len) { struct wrw *wrw; diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index 8eac608..70a007e 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -519,6 +519,22 @@ HTTP1_DissectResponse(struct http *hp, struct http_conn *htc) /*--------------------------------------------------------------------*/ +static unsigned +http1_WrTxt(const struct worker *wrk, const txt *hh, const char *suf) +{ + unsigned u; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + AN(wrk); + AN(hh); + AN(hh->b); + AN(hh->e); + u = WRW_Write(wrk, hh->b, hh->e - hh->b); + if (suf != NULL) + u += WRW_Write(wrk, suf, -1); + return (u); +} + unsigned HTTP1_Write(const struct worker *w, const struct http *hp, const int *hf) { @@ -528,12 +544,12 @@ HTTP1_Write(const struct worker *w, const struct http *hp, const int *hf) AN(hp->hd[hf[0]].b); AN(hp->hd[hf[1]].b); AN(hp->hd[hf[2]].b); - l = WRW_WriteH(w, &hp->hd[hf[0]], " "); - l += WRW_WriteH(w, &hp->hd[hf[1]], " "); - l += WRW_WriteH(w, &hp->hd[hf[2]], "\r\n"); + l = http1_WrTxt(w, &hp->hd[hf[0]], " "); + l += http1_WrTxt(w, &hp->hd[hf[1]], " "); + l += http1_WrTxt(w, &hp->hd[hf[2]], "\r\n"); for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) - l += WRW_WriteH(w, &hp->hd[u], "\r\n"); + l += http1_WrTxt(w, &hp->hd[u], "\r\n"); l += WRW_Write(w, "\r\n", -1); return (l); } From phk at FreeBSD.org Wed Oct 22 07:37:48 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Oct 2014 09:37:48 +0200 Subject: [master] 989c6d2 Add INIT_OBJ() macro which zeros and sets magic Message-ID: commit 989c6d2fbea54186b6ee09091137ed1a543de810 Author: Poul-Henning Kamp Date: Wed Oct 22 07:37:23 2014 +0000 Add INIT_OBJ() macro which zeros and sets magic diff --git a/include/miniobj.h b/include/miniobj.h index e1db10d..746f606 100644 --- a/include/miniobj.h +++ b/include/miniobj.h @@ -5,6 +5,12 @@ * */ +#define INIT_OBJ(to, type_magic) \ + do { \ + (void)memset(to, 0, sizeof *to); \ + (to)->magic = (type_magic); \ + } while (0) + #define ALLOC_OBJ(to, type_magic) \ do { \ (to) = calloc(sizeof *(to), 1); \ From phk at FreeBSD.org Wed Oct 22 08:02:12 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Oct 2014 10:02:12 +0200 Subject: [master] 277340c Use INIT_OBJ() Message-ID: commit 277340c6a384804e55f97bc1c2a26a6ed80aea06 Author: Poul-Henning Kamp Date: Wed Oct 22 08:01:08 2014 +0000 Use INIT_OBJ() diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index c796ea7..4ddc3ca 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -362,8 +362,7 @@ vbe_dir_getfd(const struct director *d, struct busyobj *bo) if (bo->htc == NULL) bo->htc = WS_Alloc(bo->ws, sizeof *bo->htc); AN(bo->htc); - memset(bo->htc, 0, sizeof *bo->htc); - bo->htc->magic = HTTP_CONN_MAGIC; + INIT_OBJ(bo->htc, HTTP_CONN_MAGIC); bo->htc->vbc = vc; FIND_TMO(first_byte_timeout, vc->first_byte_timeout, bo, vs->vrt); FIND_TMO(between_bytes_timeout, vc->between_bytes_timeout, bo, vs->vrt); diff --git a/bin/varnishd/cache/cache_deliver_proc.c b/bin/varnishd/cache/cache_deliver_proc.c index 1346898..dc0b4f7 100644 --- a/bin/varnishd/cache/cache_deliver_proc.c +++ b/bin/varnishd/cache/cache_deliver_proc.c @@ -60,8 +60,7 @@ VDP_push(struct req *req, vdp_bytes *func, void *priv) vdp = WS_Alloc(req->ws, sizeof *vdp); AN(vdp); - memset(vdp, 0, sizeof *vdp); - vdp->magic = VDP_ENTRY_MAGIC; + INIT_OBJ(vdp, VDP_ENTRY_MAGIC); vdp->func = func; vdp->priv = priv; VTAILQ_INSERT_HEAD(&req->vdp, vdp, list); diff --git a/bin/varnishd/cache/cache_esi_parse.c b/bin/varnishd/cache/cache_esi_parse.c index 1956a18..b4beb75 100644 --- a/bin/varnishd/cache/cache_esi_parse.c +++ b/bin/varnishd/cache/cache_esi_parse.c @@ -1048,8 +1048,7 @@ VEP_Init(struct vfp_ctx *vc, const struct http *req, vep_callback_t *cb, vep = WS_Alloc(vc->http->ws, sizeof *vep); AN(vep); - memset(vep, 0, sizeof *vep); - vep->magic = VEP_MAGIC; + INIT_OBJ(vep, VEP_MAGIC); vep->url = req->hd[HTTP_HDR_URL].b; vep->vc = vc; vep->vsb = VSB_new_auto(); diff --git a/bin/varnishd/cache/cache_fetch_proc.c b/bin/varnishd/cache/cache_fetch_proc.c index da67df7..91bf0e1 100644 --- a/bin/varnishd/cache/cache_fetch_proc.c +++ b/bin/varnishd/cache/cache_fetch_proc.c @@ -106,8 +106,8 @@ VFP_GetStorage(struct vfp_ctx *vc, ssize_t *sz, uint8_t **ptr) void VFP_Setup(struct vfp_ctx *vc) { - memset(vc, 0, sizeof *vc); - vc->magic = VFP_CTX_MAGIC; + + INIT_OBJ(vc, VFP_CTX_MAGIC); VTAILQ_INIT(&vc->vfp); } @@ -204,7 +204,7 @@ VFP_Push(struct vfp_ctx *vc, const struct vfp *vfp, int top) CHECK_OBJ_NOTNULL(vc->http, HTTP_MAGIC); vfe = WS_Alloc(vc->http->ws, sizeof *vfe); AN(vfe); - vfe->magic = VFP_ENTRY_MAGIC; + INIT_OBJ(vfe, VFP_ENTRY_MAGIC); vfe->vfp = vfp; vfe->closed = VFP_OK; if (top) diff --git a/bin/varnishd/cache/cache_pool.c b/bin/varnishd/cache/cache_pool.c index 916c4a3..ee84862 100644 --- a/bin/varnishd/cache/cache_pool.c +++ b/bin/varnishd/cache/cache_pool.c @@ -212,8 +212,7 @@ pool_accept(struct worker *wrk, void *arg) VTIM_sleep(.1); while (1) { - memset(wa, 0, sizeof *wa); - wa->magic = WRK_ACCEPT_MAGIC; + INIT_OBJ(wa, WRK_ACCEPT_MAGIC); if (ps->lsock->sock < 0) { /* Socket Shutdown */ diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c index 72dc303..713abe6 100644 --- a/bin/varnishd/cache/cache_vcl.c +++ b/bin/varnishd/cache/cache_vcl.c @@ -212,8 +212,7 @@ VCL_Load(const char *fn, const char *name, struct cli *cli) return (1); } - memset(&ctx, 0, sizeof ctx); - ctx.magic = VRT_CTX_MAGIC; + INIT_OBJ(&ctx, VRT_CTX_MAGIC); ctx.method = VCL_MET_INIT; ctx.handling = &hand; ctx.cli = cli; @@ -259,8 +258,7 @@ VCL_Nuke(struct vcls *vcl) struct vrt_ctx ctx; unsigned hand = 0; - memset(&ctx, 0, sizeof ctx); - ctx.magic = VRT_CTX_MAGIC; + INIT_OBJ(&ctx, VRT_CTX_MAGIC); ASSERT_CLI(); assert(vcl != vcl_active); assert(vcl->conf->discard); @@ -436,8 +434,7 @@ vcl_call_method(struct worker *wrk, struct req *req, struct busyobj *bo, struct vrt_ctx ctx; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - memset(&ctx, 0, sizeof ctx); - ctx.magic = VRT_CTX_MAGIC; + INIT_OBJ(&ctx, VRT_CTX_MAGIC); if (req != NULL) { CHECK_OBJ_NOTNULL(req, REQ_MAGIC); CHECK_OBJ_NOTNULL(req->sp, SESS_MAGIC); diff --git a/bin/varnishd/cache/cache_wrk.c b/bin/varnishd/cache/cache_wrk.c index 26930ff..416f974 100644 --- a/bin/varnishd/cache/cache_wrk.c +++ b/bin/varnishd/cache/cache_wrk.c @@ -59,8 +59,7 @@ wrk_bgthread(void *arg) CAST_OBJ_NOTNULL(bt, arg, BGTHREAD_MAGIC); THR_SetName(bt->name); - memset(&wrk, 0, sizeof wrk); - wrk.magic = WORKER_MAGIC; + INIT_OBJ(&wrk, WORKER_MAGIC); (void)bt->func(&wrk, bt->priv); @@ -98,8 +97,7 @@ WRK_Thread(struct pool *qp, size_t stacksize, unsigned thread_workspace) THR_SetName("cache-worker"); w = &ww; - memset(w, 0, sizeof *w); - w->magic = WORKER_MAGIC; + INIT_OBJ(w, WORKER_MAGIC); w->lastused = NAN; AZ(pthread_cond_init(&w->cond, NULL)); diff --git a/bin/varnishd/cache/cache_wrw.c b/bin/varnishd/cache/cache_wrw.c index 2206ea7..ef7b322 100644 --- a/bin/varnishd/cache/cache_wrw.c +++ b/bin/varnishd/cache/cache_wrw.c @@ -74,8 +74,7 @@ WRW_Reserve(struct worker *wrk, int *fd, struct vsl_log *vsl, double t0) AZ(wrk->wrw); wrw = WS_Alloc(wrk->aws, sizeof *wrw); AN(wrw); - memset(wrw, 0, sizeof *wrw); - wrw->magic = WRW_MAGIC; + INIT_OBJ(wrw, WRW_MAGIC); u = WS_Reserve(wrk->aws, 0); u = PRNDDN(u); u /= sizeof(struct iovec); diff --git a/bin/varnishd/cache/cache_ws.c b/bin/varnishd/cache/cache_ws.c index aad9fec..3264797 100644 --- a/bin/varnishd/cache/cache_ws.c +++ b/bin/varnishd/cache/cache_ws.c @@ -72,8 +72,7 @@ WS_Init(struct ws *ws, const char *id, void *space, unsigned len) DSL(DBG_WORKSPACE, 0, "WS_Init(%p, \"%s\", %p, %u)", ws, id, space, len); assert(space != NULL); - memset(ws, 0, sizeof *ws); - ws->magic = WS_MAGIC; + INIT_OBJ(ws, WS_MAGIC); ws->s = space; assert(PAOK(space)); len = PRNDDN(len - 1); diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 5ed5be5..05be1f1 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -181,8 +181,7 @@ v1d_dorange(struct req *req, struct busyobj *bo, const char *r) v1rp = WS_Alloc(req->ws, sizeof *v1rp); XXXAN(v1rp); - memset(v1rp, 0, sizeof *v1rp); - v1rp->magic = V1RP_MAGIC; + INIT_OBJ(v1rp, V1RP_MAGIC); v1rp->range_off = 0; v1rp->range_low = low; v1rp->range_high = high + 1; diff --git a/bin/varnishd/mgt/mgt_main.c b/bin/varnishd/mgt/mgt_main.c index 5c1e580..6c6ba8a 100644 --- a/bin/varnishd/mgt/mgt_main.c +++ b/bin/varnishd/mgt/mgt_main.c @@ -450,8 +450,7 @@ main(int argc, char * const *argv) */ SHA256_Test(); - memset(cli, 0, sizeof cli); - cli[0].magic = CLI_MAGIC; + INIT_OBJ(cli, CLI_MAGIC); cli[0].sb = VSB_new_auto(); XXXAN(cli[0].sb); cli[0].result = CLIS_OK; diff --git a/bin/varnishd/mgt/mgt_vcc.c b/bin/varnishd/mgt/mgt_vcc.c index 7866f8a..f18fe41 100644 --- a/bin/varnishd/mgt/mgt_vcc.c +++ b/bin/varnishd/mgt/mgt_vcc.c @@ -256,8 +256,7 @@ mgt_run_cc(const char *vcl, struct vsb *sb, int C_flag, unsigned *status) /* Run the VCC compiler in a sub-process */ - memset(&vp, 0, sizeof vp); - vp.magic = VCC_PRIV_MAGIC; + INIT_OBJ(&vp, VCC_PRIV_MAGIC); vp.sf = sf; vp.vcl = vcl; subs = VSUB_run(sb, run_vcc, &vp, "VCC-compiler", -1); diff --git a/bin/varnishd/storage/stevedore.c b/bin/varnishd/storage/stevedore.c index ec03354..30d8422 100644 --- a/bin/varnishd/storage/stevedore.c +++ b/bin/varnishd/storage/stevedore.c @@ -200,8 +200,7 @@ STV_MkObject(struct stevedore *stv, struct objcore *oc, void *ptr) assert(PAOK(ptr)); o = ptr; - memset(o, 0, sizeof *o); - o->magic = OBJECT_MAGIC; + INIT_OBJ(o, OBJECT_MAGIC); VTAILQ_INIT(&o->list); diff --git a/bin/varnishd/storage/storage_file.c b/bin/varnishd/storage/storage_file.c index 3974a5c..5c94e28 100644 --- a/bin/varnishd/storage/storage_file.c +++ b/bin/varnishd/storage/storage_file.c @@ -342,9 +342,8 @@ new_smf(struct smf_sc *sc, unsigned char *ptr, off_t off, size_t len) struct smf *sp, *sp2; AZ(len % sc->pagesize); - sp = calloc(sizeof *sp, 1); + ALLOC_OBJ(sp, SMF_MAGIC); XXXAN(sp); - sp->magic = SMF_MAGIC; sp->s.magic = STORAGE_MAGIC; sc->stats->g_smf++; diff --git a/bin/varnishd/storage/storage_persistent.c b/bin/varnishd/storage/storage_persistent.c index 411fc9a..2565052 100644 --- a/bin/varnishd/storage/storage_persistent.c +++ b/bin/varnishd/storage/storage_persistent.c @@ -489,8 +489,7 @@ smp_allocx(struct stevedore *st, size_t min_size, size_t max_size, assert(max_size >= min_size); /* Fill the storage structure */ - memset(ss, 0, sizeof *ss); - ss->magic = STORAGE_MAGIC; + INIT_OBJ(ss, STORAGE_MAGIC); ss->ptr = PRNUP(sc, ss + 1); ss->space = max_size; ss->priv = sc; diff --git a/bin/varnishd/storage/storage_persistent_silo.c b/bin/varnishd/storage/storage_persistent_silo.c index 2dbfb0a..8d02ed3 100644 --- a/bin/varnishd/storage/storage_persistent_silo.c +++ b/bin/varnishd/storage/storage_persistent_silo.c @@ -188,8 +188,7 @@ smp_new_seg(struct smp_sc *sc) /* XXX: find where it goes in silo */ - memset(&tmpsg, 0, sizeof tmpsg); - tmpsg.magic = SMP_SEG_MAGIC; + INIT_OBJ(&tmpsg, SMP_SEG_MAGIC); tmpsg.sc = sc; tmpsg.p.offset = sc->free_offset; /* XXX: align */ From phk at FreeBSD.org Wed Oct 22 08:29:32 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Oct 2014 10:29:32 +0200 Subject: [master] fb9eaf0 Check the basic stats also Message-ID: commit fb9eaf0dbed13c30641ca04739a1ae931df830c5 Author: Poul-Henning Kamp Date: Wed Oct 22 08:29:17 2014 +0000 Check the basic stats also diff --git a/bin/varnishtest/tests/b00000.vtc b/bin/varnishtest/tests/b00000.vtc index 2e34a13..716a3df 100644 --- a/bin/varnishtest/tests/b00000.vtc +++ b/bin/varnishtest/tests/b00000.vtc @@ -26,3 +26,5 @@ varnish v1 -expect client_req == 1 varnish v1 -expect cache_miss == 1 varnish v1 -expect s_sess == 1 varnish v1 -expect s_req == 1 +varnish v1 -expect s_resp_bodybytes == 7 +varnish v1 -expect s_resp_hdrbytes == 167 From phk at FreeBSD.org Wed Oct 22 11:11:25 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Oct 2014 13:11:25 +0200 Subject: [master] eb67706 Dump the length of received headers Message-ID: commit eb67706d453bc9e991cbdbfabca371c829e3ee17 Author: Poul-Henning Kamp Date: Wed Oct 22 09:38:08 2014 +0000 Dump the length of received headers diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index f2998d4..1a4b12f 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -507,6 +507,7 @@ http_rxhdr(struct http *hp) break; } vtc_dump(hp->vl, 4, "rxhdr", hp->rxbuf, -1); + vtc_log(hp->vl, 4, "rxhdrlen = %zd", strlen(hp->rxbuf)); } From phk at FreeBSD.org Wed Oct 22 11:11:25 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Oct 2014 13:11:25 +0200 Subject: [master] f445127 Don't stream Message-ID: commit f445127d4abd020a49e2fa01a89a7cf4bd3fd379 Author: Poul-Henning Kamp Date: Wed Oct 22 09:38:24 2014 +0000 Don't stream diff --git a/bin/varnishtest/tests/b00000.vtc b/bin/varnishtest/tests/b00000.vtc index 716a3df..ce81478 100644 --- a/bin/varnishtest/tests/b00000.vtc +++ b/bin/varnishtest/tests/b00000.vtc @@ -5,7 +5,11 @@ server s1 { txresp -body "012345\n" } -start -varnish v1 -vcl+backend {} -start +varnish v1 -vcl+backend { + sub vcl_backend_response { + set beresp.do_stream = false; + } +} -start varnish v1 -cliok "param.set debug +workspace" From phk at FreeBSD.org Wed Oct 22 11:11:25 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Oct 2014 13:11:25 +0200 Subject: [master] e5e3421 Suppress the "skp" log records, they're noisy and the content is already in the l%d log records Message-ID: commit e5e3421c5bd07b68a044ec843352ce11c6fb2354 Author: Poul-Henning Kamp Date: Wed Oct 22 09:44:25 2014 +0000 Suppress the "skp" log records, they're noisy and the content is already in the l%d log records diff --git a/bin/varnishtest/vtc_logexp.c b/bin/varnishtest/vtc_logexp.c index a2b6323..86de1ea 100644 --- a/bin/varnishtest/vtc_logexp.c +++ b/bin/varnishtest/vtc_logexp.c @@ -233,7 +233,7 @@ logexp_dispatch(struct VSL_data *vsl, struct VSL_transaction * const pt[], legend = "ok"; } else if (skip) { lvl = 4; - legend = "skp"; + legend = NULL; } else { lvl = 0; legend = "err"; @@ -241,8 +241,9 @@ logexp_dispatch(struct VSL_data *vsl, struct VSL_transaction * const pt[], type = VSL_CLIENT(t->c->rec.ptr) ? 'c' : VSL_BACKEND(t->c->rec.ptr) ? 'b' : '-'; - vtc_log(le->vl, lvl, "%3s| %10u %-15s %c %.*s", - legend, vxid, VSL_tags[tag], type, len, data); + if (legend != NULL) + vtc_log(le->vl, lvl, "%3s| %10u %-15s %c %.*s", + legend, vxid, VSL_tags[tag], type, len, data); if (ok) { le->vxid_last = vxid; From phk at FreeBSD.org Wed Oct 22 11:11:25 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Oct 2014 13:11:25 +0200 Subject: [master] f1e4277 Overhaul request accounting, particularly for ESI. Message-ID: commit f1e42779fa318d4a21eb349195c89f4705aeebab Author: Poul-Henning Kamp Date: Wed Oct 22 10:14:19 2014 +0000 Overhaul request accounting, particularly for ESI. Give ESI subrequests a ReqAcct. Make the bodycount in ReqAcct only the actual body, not including transmission overhead (such as chunked encoding) diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 0e9668e..3ba86b7 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -557,9 +557,6 @@ struct req { unsigned char wantbody; uint64_t req_bodybytes; /* Parsed req bodybytes */ - uint64_t resp_hdrbytes; /* Scheduled resp hdrbytes */ - uint64_t resp_bodybytes; /* Scheduled resp bodybytes */ - uint16_t err_code; const char *err_reason; @@ -721,7 +718,6 @@ extern const int HTTP1_Req[3]; extern const int HTTP1_Resp[3]; /* cache_http1_deliver.c */ -unsigned V1D_FlushReleaseAcct(struct req *req); void V1D_Deliver(struct req *, struct busyobj *); /* cache_http1_pipe.c */ diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index 06e2570..2663c7d 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -56,7 +56,7 @@ ved_include(struct req *preq, const char *src, const char *host) if (preq->esi_level >= cache_param->max_esi_depth) return; - (void)V1D_FlushReleaseAcct(preq); + (void)WRW_FlushRelease(preq->wrk, NULL); /* Take a workspace snapshot */ wrk_ws_wm = WS_Snapshot(wrk->aws); /* XXX ? */ @@ -132,11 +132,11 @@ ved_include(struct req *preq, const char *src, const char *host) } AN(WRW_IsReleased(wrk)); - VSL_End(req->vsl); - - /* Charge the transmitted body byte counts to the parent request */ + /* Charge the transmitted body byte counts also to the parent request */ preq->acct.resp_bodybytes += req->acct.resp_bodybytes; - req->acct.resp_bodybytes = 0; + + CNT_AcctLogCharge(wrk->stats, req); + VSL_End(req->vsl); /* Reset the workspace */ WS_Reset(wrk->aws, wrk_ws_wm); /* XXX ? */ diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 9c2627a..48e894d 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -791,10 +791,6 @@ CNT_Request(struct worker *wrk, struct req *req) wrk->vsl = NULL; if (nxt == REQ_FSM_DONE) { AN(req->vsl->wid); - if (req->res_mode & (RES_ESI|RES_ESI_CHILD)) - VSLb(req->vsl, SLT_ESI_BodyBytes, "%ju", - (uintmax_t)req->resp_bodybytes); - VRB_Free(req); req->wrk = NULL; } diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index 04a4ca5..5d5b289 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -366,8 +366,6 @@ SES_GetReq(const struct worker *wrk, struct sess *sp) WS_Init(req->ws, "req", p, e - p); req->req_bodybytes = 0; - req->resp_hdrbytes = 0; - req->resp_bodybytes = 0; req->t_first = NAN; req->t_prev = NAN; diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 05be1f1..cde97b5 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -51,7 +51,7 @@ v1d_bytes(struct req *req, enum vdp_action act, void **priv, if (len > 0) wl = WRW_Write(req->wrk, ptr, len); - req->resp_bodybytes += wl; + req->acct.resp_bodybytes += len; if (act > VDP_NULL && WRW_Flush(req->wrk)) return (-1); if (len != wl) @@ -228,33 +228,6 @@ v1d_WriteDirObj(struct req *req) } /*-------------------------------------------------------------------- - * V1D_FlushReleaseAcct() - * Call WRW_FlushRelease on the worker and update the requests - * byte accounting with the number of bytes transmitted - * - * Returns the return value from WRW_FlushRelease() - */ -unsigned -V1D_FlushReleaseAcct(struct req *req) -{ - unsigned u; - uint64_t txcnt = 0, hdrbytes; - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - CHECK_OBJ_NOTNULL(req->wrk, WORKER_MAGIC); - u = WRW_FlushRelease(req->wrk, &txcnt); - if (req->acct.resp_hdrbytes < req->resp_hdrbytes) { - hdrbytes = req->resp_hdrbytes - req->acct.resp_hdrbytes; - if (hdrbytes > txcnt) - hdrbytes = txcnt; - } else - hdrbytes = 0; - req->acct.resp_hdrbytes += hdrbytes; - req->acct.resp_bodybytes += txcnt - hdrbytes; - return (u); -} - -/*-------------------------------------------------------------------- */ void V1D_Deliver(struct req *req, struct busyobj *bo) @@ -360,7 +333,7 @@ V1D_Deliver(struct req *req, struct busyobj *bo) * Send HTTP protocol header, unless interior ESI object */ if (!(req->res_mode & RES_ESI_CHILD)) - req->resp_hdrbytes += + req->acct.resp_hdrbytes += HTTP1_Write(req->wrk, req->resp, HTTP1_Resp); if (req->res_mode & RES_CHUNKED) @@ -408,6 +381,7 @@ V1D_Deliver(struct req *req, struct busyobj *bo) !(req->res_mode & RES_ESI_CHILD)) WRW_EndChunk(req->wrk); - if ((V1D_FlushReleaseAcct(req) || ois != OIS_DONE) && req->sp->fd >= 0) + if ((WRW_FlushRelease(req->wrk, NULL) || ois != OIS_DONE) && + req->sp->fd >= 0) SES_Close(req->sp, SC_REM_CLOSE); } diff --git a/bin/varnishd/http1/cache_http1_fsm.c b/bin/varnishd/http1/cache_http1_fsm.c index 4850df2..1737e65 100644 --- a/bin/varnishd/http1/cache_http1_fsm.c +++ b/bin/varnishd/http1/cache_http1_fsm.c @@ -171,8 +171,6 @@ http1_cleanup(struct sess *sp, struct worker *wrk, struct req *req) AN(req->vsl->wid); CNT_AcctLogCharge(wrk->stats, req); req->req_bodybytes = 0; - req->resp_hdrbytes = 0; - req->resp_bodybytes = 0; VSL_End(req->vsl); @@ -285,7 +283,7 @@ http1_dissect(struct worker *wrk, struct req *req) req->err_code = 417; r = write(req->sp->fd, r_417, strlen(r_417)); if (r > 0) - req->resp_hdrbytes += r; + req->acct.resp_hdrbytes += r; SES_Close(req->sp, SC_RX_JUNK); return (REQ_FSM_DONE); } diff --git a/bin/varnishtest/tests/e00003.vtc b/bin/varnishtest/tests/e00003.vtc index bf61f4f..935e1f0 100644 --- a/bin/varnishtest/tests/e00003.vtc +++ b/bin/varnishtest/tests/e00003.vtc @@ -8,6 +8,7 @@ server s1 { Before include After include + } rxreq expect req.url == "/body1" @@ -27,17 +28,41 @@ varnish v1 -vcl+backend { } } -start +logexpect l1 -v v1 -g request { + expect 0 1001 Begin "^req .* rxreq" + expect * = ReqAcct "^18 0 18 154 75 229$" + expect 0 = End + + expect 0 1002 Begin "^bereq " + expect * = End + + expect 0 1003 Begin "^req .* esi" + expect * = ReqAcct "^0 0 0 0 18 18$" + expect 0 = End + + expect 0 1004 Begin "^bereq " + expect * = End + + expect 0 1005 Begin "^req .* rxreq" + expect * = ReqAcct "^18 0 18 159 75 234$" + expect 0 = End +} -start + client c1 { txreq rxresp - expect resp.bodylen == 65 + expect resp.bodylen == 75 expect resp.status == 200 + + delay .1 # test that there is no difference on miss/hit txreq rxresp - expect resp.bodylen == 65 + expect resp.bodylen == 75 expect resp.status == 200 } client c1 -run varnish v1 -expect esi_errors == 0 + +logexpect l1 -wait diff --git a/bin/varnishtest/tests/l00003.vtc b/bin/varnishtest/tests/l00003.vtc index 86c9e2a..851073c 100644 --- a/bin/varnishtest/tests/l00003.vtc +++ b/bin/varnishtest/tests/l00003.vtc @@ -39,33 +39,25 @@ varnish v1 -vcl+backend { # Total: 71 bytes # Response body: -# 003\r\n 5 bytes # 123\r\n 5 bytes -# 003\r\n 5 bytes # abc\r\n 5 bytes -# 003\r\n 5 bytes # 123\r\n 5 bytes -# 003\r\n 5 bytes # def\r\n 5 bytes -# 003\r\n 5 bytes # ghi\r\n 5 bytes -# 0\r\n 3 bytes -# \r\n 2 bytes -# Total: 55 bytes +# Total: 15 bytes logexpect l1 -v v1 -g request { expect 0 1001 Begin "^req .* rxreq" - expect * = ESI_BodyBytes "^3" - expect * = ReqAcct "^18 0 18 71 55 126$" + expect * = ReqAcct "^18 0 18 71 15 86$" expect 0 = End expect * 1003 Begin "^req .* esi" - expect * = ESI_BodyBytes "^6$" + expect * = ReqAcct "^0 0 0 0 12 12$" expect 0 = End expect * 1005 Begin "^req .* esi" - expect * = ESI_BodyBytes "^3$" + expect * = ReqAcct "^0 0 0 0 3 3$" expect 0 = End expect * 1007 Begin "^req .* esi" - expect * = ESI_BodyBytes "^3$" + expect * = ReqAcct "^0 0 0 0 3 3$" expect 0 = End } -start @@ -81,4 +73,4 @@ logexpect l1 -wait varnish v1 -expect s_req_hdrbytes == 18 varnish v1 -expect s_req_bodybytes == 0 varnish v1 -expect s_resp_hdrbytes == 71 -varnish v1 -expect s_resp_bodybytes == 55 +varnish v1 -expect s_resp_bodybytes == 33 diff --git a/include/tbl/vsl_tags.h b/include/tbl/vsl_tags.h index 8ca37d0..b483f2c 100644 --- a/include/tbl/vsl_tags.h +++ b/include/tbl/vsl_tags.h @@ -444,9 +444,10 @@ SLTM(Timestamp, 0, "Timing information", ) SLTM(ReqAcct, 0, "Request handling byte counts", - "Contains byte counts for the request handling. This record is not" - " logged for ESI sub-requests, but the sub-requests' response" - " body count is added to the main request.\n\n" + "Contains byte counts for the request handling.\n" + "ESI sub-request counts are also added to their parent request.\n" + "The body bytes count does not include transmission " + "(ie: chunked encoding) overhead.\n" "The format is::\n\n" "\t%d %d %d %d %d %d\n" "\t| | | | | |\n" @@ -459,16 +460,6 @@ SLTM(ReqAcct, 0, "Request handling byte counts", "\n" ) -SLTM(ESI_BodyBytes, 0, "ESI body fragment byte counter", - "Contains the body byte count for this ESI body fragment." - " This number does not include any transfer encoding overhead.\n\n" - "The format is::\n\n" - "\t%d\n" - "\t|\n" - "\t+- Body bytes\n" - "\n" -) - SLTM(PipeAcct, 0, "Pipe byte counts", "Contains byte counters for pipe sessions.\n\n" "The format is::\n\n" From phk at FreeBSD.org Wed Oct 22 20:56:46 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Oct 2014 22:56:46 +0200 Subject: [master] bc31f5c Rename WRW to V1L (Version 1 Lineprotocol) Message-ID: commit bc31f5c13883ce4e88a2d50603b3d7454d539a61 Author: Poul-Henning Kamp Date: Wed Oct 22 20:56:22 2014 +0000 Rename WRW to V1L (Version 1 Lineprotocol) diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 922459e..a347119 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -46,7 +46,6 @@ varnishd_SOURCES = \ cache/cache_vrt_var.c \ cache/cache_vrt_vmod.c \ cache/cache_wrk.c \ - cache/cache_wrw.c \ cache/cache_ws.c \ common/common_vsm.c \ common/common_vsc.c \ @@ -57,6 +56,7 @@ varnishd_SOURCES = \ http1/cache_http1_deliver.c \ http1/cache_http1_fetch.c \ http1/cache_http1_fsm.c \ + http1/cache_http1_line.c \ http1/cache_http1_pipe.c \ http1/cache_http1_proto.c \ http1/cache_http1_vfp.c \ diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 3ba86b7..6b63de3 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -123,7 +123,7 @@ struct vrt_privs; struct vsb; struct waitinglist; struct worker; -struct wrw; +struct v1l; #define DIGEST_LEN 32 @@ -344,7 +344,7 @@ struct worker { double lastused; - struct wrw *wrw; + struct v1l *v1l; pthread_cond_t cond; @@ -948,13 +948,13 @@ int Pool_Task(struct pool *pp, struct pool_task *task, enum pool_how how); void Pool_Sumstat(struct worker *w); void Pool_PurgeStat(unsigned nobj); -#define WRW_IsReleased(w) ((w)->wrw == NULL) -void WRW_Chunked(const struct worker *w); -void WRW_EndChunk(const struct worker *w); -void WRW_Reserve(struct worker *w, int *fd, struct vsl_log *, double t0); -unsigned WRW_Flush(const struct worker *w); -unsigned WRW_FlushRelease(struct worker *w, uint64_t *pacc); -unsigned WRW_Write(const struct worker *w, const void *ptr, int len); +#define V1L_IsReleased(w) ((w)->v1l == NULL) +void V1L_Chunked(const struct worker *w); +void V1L_EndChunk(const struct worker *w); +void V1L_Reserve(struct worker *w, int *fd, struct vsl_log *, double t0); +unsigned V1L_Flush(const struct worker *w); +unsigned V1L_FlushRelease(struct worker *w, uint64_t *pacc); +unsigned V1L_Write(const struct worker *w, const void *ptr, int len); /* cache_session.c [SES] */ void SES_Close(struct sess *sp, enum sess_close reason); diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index 2663c7d..886bec2 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -56,7 +56,7 @@ ved_include(struct req *preq, const char *src, const char *host) if (preq->esi_level >= cache_param->max_esi_depth) return; - (void)WRW_FlushRelease(preq->wrk, NULL); + (void)V1L_FlushRelease(preq->wrk, NULL); /* Take a workspace snapshot */ wrk_ws_wm = WS_Snapshot(wrk->aws); /* XXX ? */ @@ -130,7 +130,7 @@ ved_include(struct req *preq, const char *src, const char *host) AZ(req->wrk); (void)usleep(10000); } - AN(WRW_IsReleased(wrk)); + AN(V1L_IsReleased(wrk)); /* Charge the transmitted body byte counts also to the parent request */ preq->acct.resp_bodybytes += req->acct.resp_bodybytes; @@ -141,9 +141,9 @@ ved_include(struct req *preq, const char *src, const char *host) /* Reset the workspace */ WS_Reset(wrk->aws, wrk_ws_wm); /* XXX ? */ - WRW_Reserve(preq->wrk, &preq->sp->fd, preq->vsl, preq->t_prev); + V1L_Reserve(preq->wrk, &preq->sp->fd, preq->vsl, preq->t_prev); if (preq->res_mode & RES_CHUNKED) - WRW_Chunked(preq->wrk); + V1L_Chunked(preq->wrk); preq->vcl = req->vcl; req->vcl = NULL; diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 0810eea..1bf0934 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -588,7 +588,7 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo) return (F_STP_ERROR); } - assert(WRW_IsReleased(wrk)); + assert(V1L_IsReleased(wrk)); if (bo->do_gzip || (bo->is_gzip && !bo->do_gunzip)) @@ -875,7 +875,7 @@ vbf_fetch_thread(struct worker *wrk, void *priv) WRONG("Illegal fetch_step"); } } - assert(WRW_IsReleased(wrk)); + assert(V1L_IsReleased(wrk)); assert(bo->director_state == DIR_S_NULL); diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 48e894d..3b5755b 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -63,7 +63,7 @@ cnt_deliver(struct worker *wrk, struct req *req) CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); CHECK_OBJ_NOTNULL(req->objcore->objhead, OBJHEAD_MAGIC); CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); - assert(WRW_IsReleased(wrk)); + assert(V1L_IsReleased(wrk)); assert(req->objcore->refcnt > 0); @@ -159,7 +159,7 @@ cnt_deliver(struct worker *wrk, struct req *req) ObjSlim(wrk, req->objcore); } - assert(WRW_IsReleased(wrk)); + assert(V1L_IsReleased(wrk)); (void)HSH_DerefObjCore(wrk, &req->objcore); http_Teardown(req->resp); return (REQ_FSM_DONE); @@ -517,7 +517,7 @@ cnt_pipe(struct worker *wrk, struct req *req) assert(wrk->handling == VCL_RET_PIPE); V1P_Process(req, bo); - assert(WRW_IsReleased(wrk)); + assert(V1L_IsReleased(wrk)); http_Teardown(bo->bereq); THR_SetBusyobj(NULL); VBO_DerefBusyObj(wrk, &bo); @@ -794,7 +794,7 @@ CNT_Request(struct worker *wrk, struct req *req) VRB_Free(req); req->wrk = NULL; } - assert(WRW_IsReleased(wrk)); + assert(V1L_IsReleased(wrk)); return (nxt); } diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index 5d5b289..024d74f 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -114,7 +114,7 @@ ses_req_pool_task(struct worker *wrk, void *arg) wrk->lastused = NAN; HTTP1_Session(wrk, req); WS_Assert(wrk->aws); - AZ(wrk->wrw); + AZ(wrk->v1l); if (DO_DEBUG(DBG_VCLREL) && wrk->vcl != NULL) VCL_Rel(&wrk->vcl); THR_SetRequest(NULL); diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c index 04c24a8..8554658 100644 --- a/bin/varnishd/cache/cache_shmlog.c +++ b/bin/varnishd/cache/cache_shmlog.c @@ -371,7 +371,7 @@ VSLb_ts(struct vsl_log *vsl, const char *event, double first, double *pprev, /* XXX: Make an option to turn off some unnecessary timestamp logging. This must be done carefully because some functions - (e.g. WRW_Reserve) takes the last timestamp as it's inital + (e.g. V1L_Reserve) takes the last timestamp as it's inital value for timeout calculation. */ vsl_sanity(vsl); assert(!isnan(now) && now != 0.); diff --git a/bin/varnishd/cache/cache_wrw.c b/bin/varnishd/cache/cache_wrw.c deleted file mode 100644 index ef7b322..0000000 --- a/bin/varnishd/cache/cache_wrw.c +++ /dev/null @@ -1,295 +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. - * - * Write data to fd - * We try to use writev() if possible in order to minimize number of - * syscalls made and packets sent. It also just might allow the worker - * thread to complete the request without holding stuff locked. - */ - -#include "config.h" - -#include -#include - -#include -#include - -#include "cache.h" -#include "vtim.h" - -/*--------------------------------------------------------------------*/ - -struct wrw { - unsigned magic; -#define WRW_MAGIC 0x2f2142e5 - int *wfd; - unsigned werr; /* valid after WRW_Flush() */ - struct iovec *iov; - unsigned siov; - unsigned niov; - ssize_t liov; - ssize_t cliov; - unsigned ciov; /* Chunked header marker */ - double t0; - struct vsl_log *vsl; - ssize_t cnt; /* Flushed byte count */ -}; - -/*-------------------------------------------------------------------- - */ - -void -WRW_Reserve(struct worker *wrk, int *fd, struct vsl_log *vsl, double t0) -{ - struct wrw *wrw; - unsigned u; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - AZ(wrk->wrw); - wrw = WS_Alloc(wrk->aws, sizeof *wrw); - AN(wrw); - INIT_OBJ(wrw, WRW_MAGIC); - u = WS_Reserve(wrk->aws, 0); - u = PRNDDN(u); - u /= sizeof(struct iovec); - if (u > IOV_MAX) - u = IOV_MAX; - AN(u); - wrw->iov = (void*)PRNDUP(wrk->aws->f); - wrw->siov = u; - wrw->ciov = u; - wrw->werr = 0; - wrw->liov = 0; - wrw->niov = 0; - wrw->wfd = fd; - wrw->t0 = t0; - wrw->vsl = vsl; - wrk->wrw = wrw; -} - -static void -wrw_release(struct worker *wrk, uint64_t *pacc) -{ - struct wrw *wrw; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - wrw = wrk->wrw; - wrk->wrw = NULL; - CHECK_OBJ_NOTNULL(wrw, WRW_MAGIC); - if (pacc != NULL) - *pacc += wrw->cnt; - WS_Release(wrk->aws, 0); - WS_Reset(wrk->aws, NULL); -} - -static void -wrw_prune(struct wrw *wrw, ssize_t bytes) -{ - ssize_t used = 0; - ssize_t j, used_here; - - for (j = 0; j < wrw->niov; j++) { - if (used + wrw->iov[j].iov_len > bytes) { - /* Cutoff is in this iov */ - used_here = bytes - used; - wrw->iov[j].iov_len -= used_here; - wrw->iov[j].iov_base = - (char*)wrw->iov[j].iov_base + used_here; - memmove(wrw->iov, &wrw->iov[j], - (wrw->niov - j) * sizeof(struct iovec)); - wrw->niov -= j; - wrw->liov -= bytes; - return; - } - used += wrw->iov[j].iov_len; - } - AZ(wrw->liov); -} - -unsigned -WRW_Flush(const struct worker *wrk) -{ - ssize_t i; - struct wrw *wrw; - char cbuf[32]; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - wrw = wrk->wrw; - CHECK_OBJ_NOTNULL(wrw, WRW_MAGIC); - AN(wrw->wfd); - - /* For chunked, there must be one slot reserved for the chunked tail */ - if (wrw->ciov < wrw->siov) - assert(wrw->niov < wrw->siov); - - if (*wrw->wfd >= 0 && wrw->liov > 0 && wrw->werr == 0) { - if (wrw->ciov < wrw->siov && wrw->cliov > 0) { - /* Add chunk head & tail */ - bprintf(cbuf, "00%zx\r\n", wrw->cliov); - i = strlen(cbuf); - wrw->iov[wrw->ciov].iov_base = cbuf; - wrw->iov[wrw->ciov].iov_len = i; - wrw->liov += i; - - wrw->iov[wrw->niov].iov_base = cbuf + i - 2; - wrw->iov[wrw->niov++].iov_len = 2; - wrw->liov += 2; - } else if (wrw->ciov < wrw->siov) { - wrw->iov[wrw->ciov].iov_base = cbuf; - wrw->iov[wrw->ciov].iov_len = 0; - } - - i = writev(*wrw->wfd, wrw->iov, wrw->niov); - if (i > 0) - wrw->cnt += i; - while (i != wrw->liov && i > 0) { - /* Remove sent data from start of I/O vector, - * then retry; we hit a timeout, but some data - * was sent. - * - * XXX: Add a "minimum sent data per timeout - * counter to prevent slowlaris attacks - */ - - if (VTIM_real() - wrw->t0 > cache_param->send_timeout) { - VSLb(wrw->vsl, SLT_Debug, - "Hit total send timeout, " - "wrote = %zd/%zd; not retrying", - i, wrw->liov); - i = -1; - break; - } - - VSLb(wrw->vsl, SLT_Debug, - "Hit idle send timeout, wrote = %zd/%zd; retrying", - i, wrw->liov); - - wrw_prune(wrw, i); - i = writev(*wrw->wfd, wrw->iov, wrw->niov); - if (i > 0) - wrw->cnt += i; - } - if (i <= 0) { - wrw->werr++; - VSLb(wrw->vsl, SLT_Debug, - "Write error, retval = %zd, len = %zd, errno = %s", - i, wrw->liov, strerror(errno)); - } - } - wrw->liov = 0; - wrw->cliov = 0; - wrw->niov = 0; - if (wrw->ciov < wrw->siov) - wrw->ciov = wrw->niov++; - return (wrw->werr); -} - -unsigned -WRW_FlushRelease(struct worker *wrk, uint64_t *pacc) -{ - unsigned u; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - AN(wrk->wrw->wfd); - u = WRW_Flush(wrk); - wrw_release(wrk, pacc); - return (u); -} - -unsigned -WRW_Write(const struct worker *wrk, const void *ptr, int len) -{ - struct wrw *wrw; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - wrw = wrk->wrw; - CHECK_OBJ_NOTNULL(wrw, WRW_MAGIC); - AN(wrw->wfd); - if (len == 0 || *wrw->wfd < 0) - return (0); - if (len == -1) - len = strlen(ptr); - if (wrw->niov >= wrw->siov - (wrw->ciov < wrw->siov ? 1 : 0)) - (void)WRW_Flush(wrk); - wrw->iov[wrw->niov].iov_base = TRUST_ME(ptr); - wrw->iov[wrw->niov].iov_len = len; - wrw->liov += len; - wrw->niov++; - if (wrw->ciov < wrw->siov) { - assert(wrw->niov < wrw->siov); - wrw->cliov += len; - } - return (len); -} - -void -WRW_Chunked(const struct worker *wrk) -{ - struct wrw *wrw; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - wrw = wrk->wrw; - CHECK_OBJ_NOTNULL(wrw, WRW_MAGIC); - - assert(wrw->ciov == wrw->siov); - /* - * If there are not space for chunked header, a chunk of data and - * a chunk tail, we might as well flush right away. - */ - if (wrw->niov + 3 >= wrw->siov) - (void)WRW_Flush(wrk); - wrw->ciov = wrw->niov++; - wrw->cliov = 0; - assert(wrw->ciov < wrw->siov); - assert(wrw->niov < wrw->siov); -} - -/* - * XXX: It is not worth the complexity to attempt to get the - * XXX: end of chunk into the WRW_Flush(), because most of the time - * XXX: if not always, that is a no-op anyway, because the calling - * XXX: code already called WRW_Flush() to release local storage. - */ - -void -WRW_EndChunk(const struct worker *wrk) -{ - struct wrw *wrw; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - wrw = wrk->wrw; - CHECK_OBJ_NOTNULL(wrw, WRW_MAGIC); - - assert(wrw->ciov < wrw->siov); - (void)WRW_Flush(wrk); - wrw->ciov = wrw->siov; - wrw->niov = 0; - wrw->cliov = 0; - (void)WRW_Write(wrk, "0\r\n\r\n", -1); -} diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index cde97b5..29c8171 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -50,9 +50,9 @@ v1d_bytes(struct req *req, enum vdp_action act, void **priv, AZ(req->vdp_nxt); /* always at the bottom of the pile */ if (len > 0) - wl = WRW_Write(req->wrk, ptr, len); + wl = V1L_Write(req->wrk, ptr, len); req->acct.resp_bodybytes += len; - if (act > VDP_NULL && WRW_Flush(req->wrk)) + if (act > VDP_NULL && V1L_Flush(req->wrk)) return (-1); if (len != wl) return (-1); @@ -327,7 +327,7 @@ V1D_Deliver(struct req *req, struct busyobj *bo) v1d_dorange(req, bo, r); } - WRW_Reserve(req->wrk, &req->sp->fd, req->vsl, req->t_prev); + V1L_Reserve(req->wrk, &req->sp->fd, req->vsl, req->t_prev); /* * Send HTTP protocol header, unless interior ESI object @@ -337,7 +337,7 @@ V1D_Deliver(struct req *req, struct busyobj *bo) HTTP1_Write(req->wrk, req->resp, HTTP1_Resp); if (req->res_mode & RES_CHUNKED) - WRW_Chunked(req->wrk); + V1L_Chunked(req->wrk); ois = OIS_DONE; if (!req->wantbody) { @@ -379,9 +379,9 @@ V1D_Deliver(struct req *req, struct busyobj *bo) if (ois == OIS_DONE && (req->res_mode & RES_CHUNKED) && !(req->res_mode & RES_ESI_CHILD)) - WRW_EndChunk(req->wrk); + V1L_EndChunk(req->wrk); - if ((WRW_FlushRelease(req->wrk, NULL) || ois != OIS_DONE) && + if ((V1L_FlushRelease(req->wrk, NULL) || ois != OIS_DONE) && req->sp->fd >= 0) SES_Close(req->sp, SC_REM_CLOSE); } diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c index 3289acd..77b3675 100644 --- a/bin/varnishd/http1/cache_http1_fetch.c +++ b/bin/varnishd/http1/cache_http1_fetch.c @@ -56,8 +56,8 @@ vbf_iter_req_body(struct req *req, void *priv, void *ptr, size_t l) CAST_OBJ_NOTNULL(wrk, priv, WORKER_MAGIC); if (l > 0) { - (void)WRW_Write(wrk, ptr, l); - if (WRW_Flush(wrk)) + (void)V1L_Write(wrk, ptr, l); + if (V1L_Flush(wrk)) return (-1); } return (0); @@ -112,7 +112,7 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo) } (void)VTCP_blocking(vc->fd); /* XXX: we should timeout instead */ - WRW_Reserve(wrk, &vc->fd, bo->vsl, bo->t_prev); + V1L_Reserve(wrk, &vc->fd, bo->vsl, bo->t_prev); hdrbytes = HTTP1_Write(wrk, hp, HTTP1_Req); /* Deal with any message-body the request might (still) have */ @@ -120,7 +120,7 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo) if (bo->req != NULL) { if (do_chunked) - WRW_Chunked(wrk); + V1L_Chunked(wrk); i = VRB_Iterate(bo->req, vbf_iter_req_body, wrk); if (bo->req->req_body_status == REQ_BODY_TAKEN) { @@ -133,10 +133,10 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo) retry = -1; } if (do_chunked) - WRW_EndChunk(wrk); + V1L_EndChunk(wrk); } - j = WRW_FlushRelease(wrk, &bo->acct.bereq_hdrbytes); + j = V1L_FlushRelease(wrk, &bo->acct.bereq_hdrbytes); if (bo->acct.bereq_hdrbytes > hdrbytes) { bo->acct.bereq_bodybytes = bo->acct.bereq_hdrbytes - hdrbytes; bo->acct.bereq_hdrbytes = hdrbytes; diff --git a/bin/varnishd/http1/cache_http1_line.c b/bin/varnishd/http1/cache_http1_line.c new file mode 100644 index 0000000..95c668f --- /dev/null +++ b/bin/varnishd/http1/cache_http1_line.c @@ -0,0 +1,295 @@ +/*- + * 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. + * + * Write data to fd + * We try to use writev() if possible in order to minimize number of + * syscalls made and packets sent. It also just might allow the worker + * thread to complete the request without holding stuff locked. + */ + +#include "config.h" + +#include +#include + +#include +#include + +#include "cache/cache.h" +#include "vtim.h" + +/*--------------------------------------------------------------------*/ + +struct v1l { + unsigned magic; +#define V1L_MAGIC 0x2f2142e5 + int *wfd; + unsigned werr; /* valid after V1L_Flush() */ + struct iovec *iov; + unsigned siov; + unsigned niov; + ssize_t liov; + ssize_t cliov; + unsigned ciov; /* Chunked header marker */ + double t0; + struct vsl_log *vsl; + ssize_t cnt; /* Flushed byte count */ +}; + +/*-------------------------------------------------------------------- + */ + +void +V1L_Reserve(struct worker *wrk, int *fd, struct vsl_log *vsl, double t0) +{ + struct v1l *v1l; + unsigned u; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + AZ(wrk->v1l); + v1l = WS_Alloc(wrk->aws, sizeof *v1l); + AN(v1l); + INIT_OBJ(v1l, V1L_MAGIC); + u = WS_Reserve(wrk->aws, 0); + u = PRNDDN(u); + u /= sizeof(struct iovec); + if (u > IOV_MAX) + u = IOV_MAX; + AN(u); + v1l->iov = (void*)PRNDUP(wrk->aws->f); + v1l->siov = u; + v1l->ciov = u; + v1l->werr = 0; + v1l->liov = 0; + v1l->niov = 0; + v1l->wfd = fd; + v1l->t0 = t0; + v1l->vsl = vsl; + wrk->v1l = v1l; +} + +static void +v1l_release(struct worker *wrk, uint64_t *pacc) +{ + struct v1l *v1l; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + v1l = wrk->v1l; + wrk->v1l = NULL; + CHECK_OBJ_NOTNULL(v1l, V1L_MAGIC); + if (pacc != NULL) + *pacc += v1l->cnt; + WS_Release(wrk->aws, 0); + WS_Reset(wrk->aws, NULL); +} + +static void +v1l_prune(struct v1l *v1l, ssize_t bytes) +{ + ssize_t used = 0; + ssize_t j, used_here; + + for (j = 0; j < v1l->niov; j++) { + if (used + v1l->iov[j].iov_len > bytes) { + /* Cutoff is in this iov */ + used_here = bytes - used; + v1l->iov[j].iov_len -= used_here; + v1l->iov[j].iov_base = + (char*)v1l->iov[j].iov_base + used_here; + memmove(v1l->iov, &v1l->iov[j], + (v1l->niov - j) * sizeof(struct iovec)); + v1l->niov -= j; + v1l->liov -= bytes; + return; + } + used += v1l->iov[j].iov_len; + } + AZ(v1l->liov); +} + +unsigned +V1L_Flush(const struct worker *wrk) +{ + ssize_t i; + struct v1l *v1l; + char cbuf[32]; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + v1l = wrk->v1l; + CHECK_OBJ_NOTNULL(v1l, V1L_MAGIC); + AN(v1l->wfd); + + /* For chunked, there must be one slot reserved for the chunked tail */ + if (v1l->ciov < v1l->siov) + assert(v1l->niov < v1l->siov); + + if (*v1l->wfd >= 0 && v1l->liov > 0 && v1l->werr == 0) { + if (v1l->ciov < v1l->siov && v1l->cliov > 0) { + /* Add chunk head & tail */ + bprintf(cbuf, "00%zx\r\n", v1l->cliov); + i = strlen(cbuf); + v1l->iov[v1l->ciov].iov_base = cbuf; + v1l->iov[v1l->ciov].iov_len = i; + v1l->liov += i; + + v1l->iov[v1l->niov].iov_base = cbuf + i - 2; + v1l->iov[v1l->niov++].iov_len = 2; + v1l->liov += 2; + } else if (v1l->ciov < v1l->siov) { + v1l->iov[v1l->ciov].iov_base = cbuf; + v1l->iov[v1l->ciov].iov_len = 0; + } + + i = writev(*v1l->wfd, v1l->iov, v1l->niov); + if (i > 0) + v1l->cnt += i; + while (i != v1l->liov && i > 0) { + /* Remove sent data from start of I/O vector, + * then retry; we hit a timeout, but some data + * was sent. + * + * XXX: Add a "minimum sent data per timeout + * counter to prevent slowlaris attacks + */ + + if (VTIM_real() - v1l->t0 > cache_param->send_timeout) { + VSLb(v1l->vsl, SLT_Debug, + "Hit total send timeout, " + "wrote = %zd/%zd; not retrying", + i, v1l->liov); + i = -1; + break; + } + + VSLb(v1l->vsl, SLT_Debug, + "Hit idle send timeout, wrote = %zd/%zd; retrying", + i, v1l->liov); + + v1l_prune(v1l, i); + i = writev(*v1l->wfd, v1l->iov, v1l->niov); + if (i > 0) + v1l->cnt += i; + } + if (i <= 0) { + v1l->werr++; + VSLb(v1l->vsl, SLT_Debug, + "Write error, retval = %zd, len = %zd, errno = %s", + i, v1l->liov, strerror(errno)); + } + } + v1l->liov = 0; + v1l->cliov = 0; + v1l->niov = 0; + if (v1l->ciov < v1l->siov) + v1l->ciov = v1l->niov++; + return (v1l->werr); +} + +unsigned +V1L_FlushRelease(struct worker *wrk, uint64_t *pacc) +{ + unsigned u; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + AN(wrk->v1l->wfd); + u = V1L_Flush(wrk); + v1l_release(wrk, pacc); + return (u); +} + +unsigned +V1L_Write(const struct worker *wrk, const void *ptr, int len) +{ + struct v1l *v1l; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + v1l = wrk->v1l; + CHECK_OBJ_NOTNULL(v1l, V1L_MAGIC); + AN(v1l->wfd); + if (len == 0 || *v1l->wfd < 0) + return (0); + if (len == -1) + len = strlen(ptr); + if (v1l->niov >= v1l->siov - (v1l->ciov < v1l->siov ? 1 : 0)) + (void)V1L_Flush(wrk); + v1l->iov[v1l->niov].iov_base = TRUST_ME(ptr); + v1l->iov[v1l->niov].iov_len = len; + v1l->liov += len; + v1l->niov++; + if (v1l->ciov < v1l->siov) { + assert(v1l->niov < v1l->siov); + v1l->cliov += len; + } + return (len); +} + +void +V1L_Chunked(const struct worker *wrk) +{ + struct v1l *v1l; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + v1l = wrk->v1l; + CHECK_OBJ_NOTNULL(v1l, V1L_MAGIC); + + assert(v1l->ciov == v1l->siov); + /* + * If there are not space for chunked header, a chunk of data and + * a chunk tail, we might as well flush right away. + */ + if (v1l->niov + 3 >= v1l->siov) + (void)V1L_Flush(wrk); + v1l->ciov = v1l->niov++; + v1l->cliov = 0; + assert(v1l->ciov < v1l->siov); + assert(v1l->niov < v1l->siov); +} + +/* + * XXX: It is not worth the complexity to attempt to get the + * XXX: end of chunk into the V1L_Flush(), because most of the time + * XXX: if not always, that is a no-op anyway, because the calling + * XXX: code already called V1L_Flush() to release local storage. + */ + +void +V1L_EndChunk(const struct worker *wrk) +{ + struct v1l *v1l; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + v1l = wrk->v1l; + CHECK_OBJ_NOTNULL(v1l, V1L_MAGIC); + + assert(v1l->ciov < v1l->siov); + (void)V1L_Flush(wrk); + v1l->ciov = v1l->siov; + v1l->niov = 0; + v1l->cliov = 0; + (void)V1L_Write(wrk, "0\r\n\r\n", -1); +} diff --git a/bin/varnishd/http1/cache_http1_pipe.c b/bin/varnishd/http1/cache_http1_pipe.c index f3fdb6a..c83b6c8 100644 --- a/bin/varnishd/http1/cache_http1_pipe.c +++ b/bin/varnishd/http1/cache_http1_pipe.c @@ -124,14 +124,14 @@ V1P_Process(struct req *req, struct busyobj *bo) bo->director_state = DIR_S_BODY; (void)VTCP_blocking(fd); - WRW_Reserve(wrk, &fd, bo->vsl, req->t_req); + V1L_Reserve(wrk, &fd, bo->vsl, req->t_req); hdrbytes = HTTP1_Write(wrk, bo->bereq, HTTP1_Req); if (req->htc->pipeline_b != NULL) - (void)WRW_Write(wrk, req->htc->pipeline_b, + (void)V1L_Write(wrk, req->htc->pipeline_b, req->htc->pipeline_e - req->htc->pipeline_b); - i = WRW_FlushRelease(wrk, &acct_pipe.bereq); + i = V1L_FlushRelease(wrk, &acct_pipe.bereq); if (acct_pipe.bereq > hdrbytes) { acct_pipe.in = acct_pipe.bereq - hdrbytes; acct_pipe.bereq = hdrbytes; diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index 70a007e..45f4784 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -529,9 +529,9 @@ http1_WrTxt(const struct worker *wrk, const txt *hh, const char *suf) AN(hh); AN(hh->b); AN(hh->e); - u = WRW_Write(wrk, hh->b, hh->e - hh->b); + u = V1L_Write(wrk, hh->b, hh->e - hh->b); if (suf != NULL) - u += WRW_Write(wrk, suf, -1); + u += V1L_Write(wrk, suf, -1); return (u); } @@ -550,6 +550,6 @@ HTTP1_Write(const struct worker *w, const struct http *hp, const int *hf) for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) l += http1_WrTxt(w, &hp->hd[u], "\r\n"); - l += WRW_Write(w, "\r\n", -1); + l += V1L_Write(w, "\r\n", -1); return (l); } From phk at FreeBSD.org Wed Oct 22 21:19:40 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Oct 2014 23:19:40 +0200 Subject: [master] 18c88fb Make statistics a caller task and simply V1L_FlushRelease() Message-ID: commit 18c88fbd6eae4429966aa6f217d4c96f01dfa527 Author: Poul-Henning Kamp Date: Wed Oct 22 21:18:57 2014 +0000 Make statistics a caller task and simply V1L_FlushRelease() diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 6b63de3..e058fed 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -953,7 +953,7 @@ void V1L_Chunked(const struct worker *w); void V1L_EndChunk(const struct worker *w); void V1L_Reserve(struct worker *w, int *fd, struct vsl_log *, double t0); unsigned V1L_Flush(const struct worker *w); -unsigned V1L_FlushRelease(struct worker *w, uint64_t *pacc); +unsigned V1L_FlushRelease(struct worker *w); unsigned V1L_Write(const struct worker *w, const void *ptr, int len); /* cache_session.c [SES] */ diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index 886bec2..5f13e9b 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -56,7 +56,7 @@ ved_include(struct req *preq, const char *src, const char *host) if (preq->esi_level >= cache_param->max_esi_depth) return; - (void)V1L_FlushRelease(preq->wrk, NULL); + (void)V1L_FlushRelease(preq->wrk); /* Take a workspace snapshot */ wrk_ws_wm = WS_Snapshot(wrk->aws); /* XXX ? */ diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 29c8171..2198085 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -381,7 +381,7 @@ V1D_Deliver(struct req *req, struct busyobj *bo) !(req->res_mode & RES_ESI_CHILD)) V1L_EndChunk(req->wrk); - if ((V1L_FlushRelease(req->wrk, NULL) || ois != OIS_DONE) && + if ((V1L_FlushRelease(req->wrk) || ois != OIS_DONE) && req->sp->fd >= 0) SES_Close(req->sp, SC_REM_CLOSE); } diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c index 77b3675..3124812 100644 --- a/bin/varnishd/http1/cache_http1_fetch.c +++ b/bin/varnishd/http1/cache_http1_fetch.c @@ -50,14 +50,14 @@ static int __match_proto__(req_body_iter_f) vbf_iter_req_body(struct req *req, void *priv, void *ptr, size_t l) { - struct worker *wrk; + struct busyobj *bo; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - CAST_OBJ_NOTNULL(wrk, priv, WORKER_MAGIC); + CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC); if (l > 0) { - (void)V1L_Write(wrk, ptr, l); - if (V1L_Flush(wrk)) + bo->acct.bereq_bodybytes += V1L_Write(bo->wrk, ptr, l); + if (V1L_Flush(bo->wrk)) return (-1); } return (0); @@ -82,7 +82,6 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo) int retry = -1; int i, j, first; struct http_conn *htc; - ssize_t hdrbytes; int do_chunked = 0; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); @@ -113,7 +112,7 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo) (void)VTCP_blocking(vc->fd); /* XXX: we should timeout instead */ V1L_Reserve(wrk, &vc->fd, bo->vsl, bo->t_prev); - hdrbytes = HTTP1_Write(wrk, hp, HTTP1_Req); + bo->acct.bereq_hdrbytes = HTTP1_Write(wrk, hp, HTTP1_Req); /* Deal with any message-body the request might (still) have */ i = 0; @@ -121,7 +120,7 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo) if (bo->req != NULL) { if (do_chunked) V1L_Chunked(wrk); - i = VRB_Iterate(bo->req, vbf_iter_req_body, wrk); + i = VRB_Iterate(bo->req, vbf_iter_req_body, bo); if (bo->req->req_body_status == REQ_BODY_TAKEN) { retry = -1; @@ -136,11 +135,7 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo) V1L_EndChunk(wrk); } - j = V1L_FlushRelease(wrk, &bo->acct.bereq_hdrbytes); - if (bo->acct.bereq_hdrbytes > hdrbytes) { - bo->acct.bereq_bodybytes = bo->acct.bereq_hdrbytes - hdrbytes; - bo->acct.bereq_hdrbytes = hdrbytes; - } + j = V1L_FlushRelease(wrk); if (j != 0 || i != 0) { VSLb(bo->vsl, SLT_FetchError, "backend write error: %d (%s)", errno, strerror(errno)); diff --git a/bin/varnishd/http1/cache_http1_line.c b/bin/varnishd/http1/cache_http1_line.c index 95c668f..4e2f027 100644 --- a/bin/varnishd/http1/cache_http1_line.c +++ b/bin/varnishd/http1/cache_http1_line.c @@ -93,19 +93,20 @@ V1L_Reserve(struct worker *wrk, int *fd, struct vsl_log *vsl, double t0) wrk->v1l = v1l; } -static void -v1l_release(struct worker *wrk, uint64_t *pacc) +unsigned +V1L_FlushRelease(struct worker *wrk) { struct v1l *v1l; + unsigned u; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + u = V1L_Flush(wrk); v1l = wrk->v1l; wrk->v1l = NULL; CHECK_OBJ_NOTNULL(v1l, V1L_MAGIC); - if (pacc != NULL) - *pacc += v1l->cnt; WS_Release(wrk->aws, 0); WS_Reset(wrk->aws, NULL); + return (u); } static void @@ -211,18 +212,6 @@ V1L_Flush(const struct worker *wrk) } unsigned -V1L_FlushRelease(struct worker *wrk, uint64_t *pacc) -{ - unsigned u; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - AN(wrk->v1l->wfd); - u = V1L_Flush(wrk); - v1l_release(wrk, pacc); - return (u); -} - -unsigned V1L_Write(const struct worker *wrk, const void *ptr, int len) { struct v1l *v1l; diff --git a/bin/varnishd/http1/cache_http1_pipe.c b/bin/varnishd/http1/cache_http1_pipe.c index c83b6c8..87b7256 100644 --- a/bin/varnishd/http1/cache_http1_pipe.c +++ b/bin/varnishd/http1/cache_http1_pipe.c @@ -99,7 +99,6 @@ V1P_Process(struct req *req, struct busyobj *bo) struct pollfd fds[2]; int i, fd; struct acct_pipe acct_pipe; - ssize_t hdrbytes; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); CHECK_OBJ_NOTNULL(req->sp, SESS_MAGIC); @@ -125,17 +124,13 @@ V1P_Process(struct req *req, struct busyobj *bo) (void)VTCP_blocking(fd); V1L_Reserve(wrk, &fd, bo->vsl, req->t_req); - hdrbytes = HTTP1_Write(wrk, bo->bereq, HTTP1_Req); + acct_pipe.bereq += HTTP1_Write(wrk, bo->bereq, HTTP1_Req); if (req->htc->pipeline_b != NULL) - (void)V1L_Write(wrk, req->htc->pipeline_b, + acct_pipe.in += V1L_Write(wrk, req->htc->pipeline_b, req->htc->pipeline_e - req->htc->pipeline_b); - i = V1L_FlushRelease(wrk, &acct_pipe.bereq); - if (acct_pipe.bereq > hdrbytes) { - acct_pipe.in = acct_pipe.bereq - hdrbytes; - acct_pipe.bereq = hdrbytes; - } + i = V1L_FlushRelease(wrk); VSLb_ts_req(req, "Pipe", W_TIM_real(wrk)); From phk at FreeBSD.org Thu Oct 23 12:46:50 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 23 Oct 2014 14:46:50 +0200 Subject: [master] d378007 Properly give esi_level>0 requests their own VDP stack which passes down to parents VDP stack. Message-ID: commit d37800783d93d7314d0f370cee51a94bb96d40f6 Author: Poul-Henning Kamp Date: Thu Oct 23 12:46:09 2014 +0000 Properly give esi_level>0 requests their own VDP stack which passes down to parents VDP stack. Always close all the VDPs. diff --git a/bin/varnishd/cache/cache_deliver_proc.c b/bin/varnishd/cache/cache_deliver_proc.c index dc0b4f7..5b6e94d 100644 --- a/bin/varnishd/cache/cache_deliver_proc.c +++ b/bin/varnishd/cache/cache_deliver_proc.c @@ -83,3 +83,12 @@ VDP_pop(struct req *req, vdp_bytes *func) AZ(vdp->priv); req->vdp_nxt = VTAILQ_FIRST(&req->vdp); } + +void +VDP_close(struct req *req) +{ + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + while (!VTAILQ_EMPTY(&req->vdp)) + VDP_pop(req, VTAILQ_FIRST(&req->vdp)->func); +} diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index 5f13e9b..9c28ac3 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -43,6 +43,27 @@ /*--------------------------------------------------------------------*/ +static int __match_proto__(vdp_bytes) +ved_vdp_bytes(struct req *req, enum vdp_action act, void **priv, + const void *ptr, ssize_t len) +{ + struct req *preq; + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + if (act == VDP_INIT) + return (0); + if (act == VDP_FINI) { + *priv = NULL; + return (0); + } + CAST_OBJ_NOTNULL(preq, *priv, REQ_MAGIC); + req->acct.resp_bodybytes += len; + return (VDP_bytes(preq, act, ptr, len)); +} + + +/*--------------------------------------------------------------------*/ + static void ved_include(struct req *preq, const char *src, const char *host) { @@ -112,13 +133,16 @@ ved_include(struct req *preq, const char *src, const char *host) req->l_crc = preq->l_crc; - req->vdp = preq->vdp; - req->vdp_nxt = preq->vdp_nxt; + req->vdp_nxt = 0; + VTAILQ_INIT(&req->vdp); + VDP_push(req, ved_vdp_bytes, preq); THR_SetRequest(req); VSLb_ts_req(req, "Start", W_TIM_real(wrk)); + req->ws_req = WS_Snapshot(req->ws); + while (1) { req->wrk = wrk; s = CNT_Request(wrk, req); @@ -132,8 +156,7 @@ ved_include(struct req *preq, const char *src, const char *host) } AN(V1L_IsReleased(wrk)); - /* Charge the transmitted body byte counts also to the parent request */ - preq->acct.resp_bodybytes += req->acct.resp_bodybytes; + VDP_close(req); CNT_AcctLogCharge(wrk->stats, req); VSL_End(req->vsl); diff --git a/bin/varnishd/cache/cache_filter.h b/bin/varnishd/cache/cache_filter.h index 80dc7d2..2912ece 100644 --- a/bin/varnishd/cache/cache_filter.h +++ b/bin/varnishd/cache/cache_filter.h @@ -89,10 +89,10 @@ enum vfp_status VFP_GetStorage(struct vfp_ctx *, ssize_t *sz, uint8_t **ptr); enum vdp_action { VDP_INIT, + VDP_FINI, VDP_NULL, VDP_FLUSH, VDP_FINISH, - VDP_FINI, }; typedef int vdp_bytes(struct req *, enum vdp_action, void **priv, @@ -109,6 +109,7 @@ struct vdp_entry { int VDP_bytes(struct req *, enum vdp_action act, const void *ptr, ssize_t len); void VDP_push(struct req *, vdp_bytes *func, void *priv); void VDP_pop(struct req *, vdp_bytes *func); +void VDP_close(struct req *req); vdp_bytes VDP_gunzip; vdp_bytes VED_pretend_gzip; diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 2198085..d9eae86 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -384,4 +384,6 @@ V1D_Deliver(struct req *req, struct busyobj *bo) if ((V1L_FlushRelease(req->wrk) || ois != OIS_DONE) && req->sp->fd >= 0) SES_Close(req->sp, SC_REM_CLOSE); + if (req->esi_level == 0) + VDP_close(req); } diff --git a/bin/varnishd/http1/cache_http1_line.c b/bin/varnishd/http1/cache_http1_line.c index 4e2f027..a2781d1 100644 --- a/bin/varnishd/http1/cache_http1_line.c +++ b/bin/varnishd/http1/cache_http1_line.c @@ -93,7 +93,7 @@ V1L_Reserve(struct worker *wrk, int *fd, struct vsl_log *vsl, double t0) wrk->v1l = v1l; } -unsigned +unsigned V1L_FlushRelease(struct worker *wrk) { struct v1l *v1l; From lkarsten at varnish-software.com Thu Oct 23 14:05:32 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Thu, 23 Oct 2014 16:05:32 +0200 Subject: [master] a6b6345 Fix spelling. Message-ID: commit a6b63457d3c0db395f13076678ec1f9d90d3de0a Author: Lasse Karstensen Date: Thu Oct 23 14:42:58 2014 +0200 Fix spelling. diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 1bf0934..ceaf931 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -455,7 +455,7 @@ vbf_fetch_body_helper(struct busyobj *bo) do { if (bo->abandon) { /* - * A pass object and delivery was terminted + * A pass object and delivery was terminated * We don't fail the fetch, in order for hit-for-pass * objects to be created. */ @@ -490,7 +490,7 @@ vbf_fetch_body_helper(struct busyobj *bo) if (vfps == VFP_ERROR) { AN(vfc->failed); - (void)VFP_Error(vfc, "Fetch Pipeline failed to process"); + (void)VFP_Error(vfc, "Fetch pipeline failed to process"); bo->doclose = SC_RX_BODY; } @@ -575,7 +575,7 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo) bo->do_stream = 0; if (VFP_Open(bo->vfc)) { - (void)VFP_Error(bo->vfc, "Fetch Pipeline failed to open"); + (void)VFP_Error(bo->vfc, "Fetch pipeline failed to open"); bo->doclose = SC_RX_BODY; VDI_Finish(bo->director_resp, bo->wrk, bo); return (F_STP_ERROR); From phk at FreeBSD.org Thu Oct 23 19:46:32 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 23 Oct 2014 21:46:32 +0200 Subject: [master] a86fd4f Eliminate VDP_FINISH, it's unmanageable and we have VDP_FINI Message-ID: commit a86fd4f671cf4ff00766d0e344c423be004f7abd Author: Poul-Henning Kamp Date: Thu Oct 23 19:46:05 2014 +0000 Eliminate VDP_FINISH, it's unmanageable and we have VDP_FINI diff --git a/bin/varnishd/cache/cache_deliver_proc.c b/bin/varnishd/cache/cache_deliver_proc.c index 5b6e94d..86c9889 100644 --- a/bin/varnishd/cache/cache_deliver_proc.c +++ b/bin/varnishd/cache/cache_deliver_proc.c @@ -39,6 +39,7 @@ VDP_bytes(struct req *req, enum vdp_action act, const void *ptr, ssize_t len) struct vdp_entry *vdp; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + assert(act == VDP_NULL || act == VDP_FLUSH); vdp = req->vdp_nxt; CHECK_OBJ_NOTNULL(vdp, VDP_ENTRY_MAGIC); req->vdp_nxt = VTAILQ_NEXT(vdp, list); diff --git a/bin/varnishd/cache/cache_filter.h b/bin/varnishd/cache/cache_filter.h index 2912ece..fce1c09 100644 --- a/bin/varnishd/cache/cache_filter.h +++ b/bin/varnishd/cache/cache_filter.h @@ -88,11 +88,10 @@ enum vfp_status VFP_GetStorage(struct vfp_ctx *, ssize_t *sz, uint8_t **ptr); /* Deliver processors ------------------------------------------------*/ enum vdp_action { - VDP_INIT, - VDP_FINI, - VDP_NULL, - VDP_FLUSH, - VDP_FINISH, + VDP_INIT, /* Happens on VDP_push() */ + VDP_FINI, /* Happens on VDP_pop() */ + VDP_NULL, /* Input buffer valid after call */ + VDP_FLUSH, /* Input buffer will be invalidated */ }; typedef int vdp_bytes(struct req *, enum vdp_action, void **priv, diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index 93b16dd..c32f760 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -277,11 +277,11 @@ VDP_gunzip(struct req *req, enum vdp_action act, void **priv, const void *dp; struct worker *wrk; struct vgz *vg; - int retval; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); wrk = req->wrk; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + if (act == VDP_INIT) { vg = VGZ_NewUngzip(req->vsl, "U D -"); AN(vg); @@ -291,33 +291,28 @@ VDP_gunzip(struct req *req, enum vdp_action act, void **priv, *priv = vg; return (0); } + CAST_OBJ_NOTNULL(vg, *priv, VGZ_MAGIC); + AN(vg->m_buf); + if (act == VDP_FINI) { + AZ(len); + AZ(vg->m_len); (void)VGZ_Destroy(&vg); *priv = NULL; return (0); } - AN(vg->m_buf); - if (len == 0) { - AN(act > VDP_NULL); - retval = VDP_bytes(req, act, vg->m_buf, vg->m_len); - vg->m_len = 0; - VGZ_Obuf(vg, vg->m_buf, vg->m_sz); - return (retval); - } + if (len == 0) + return (0); VGZ_Ibuf(vg, ptr, len); do { - if (vg->m_len == vg->m_sz) - vr = VGZ_STUCK; - else { - vr = VGZ_Gunzip(vg, &dp, &dl); - vg->m_len += dl; - } + vr = VGZ_Gunzip(vg, &dp, &dl); + vg->m_len += dl; if (vr < VGZ_OK) return (-1); - if (vg->m_len == vg->m_sz || vr == VGZ_STUCK) { + if (vg->m_len == vg->m_sz || vr != VGZ_OK) { if (VDP_bytes(req, VDP_FLUSH, vg->m_buf, vg->m_len)) return (-1); vg->m_len = 0; diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index d9eae86..7d873ed 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -222,7 +222,6 @@ v1d_WriteDirObj(struct req *req) WRONG("Wrong OIS value"); } } while (ois == OIS_DATA || ois == OIS_STREAM); - (void)VDP_bytes(req, VDP_FINISH, NULL, 0); ObjIterEnd(req->objcore, &oi); return (ois); } From phk at FreeBSD.org Thu Oct 23 22:15:00 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Fri, 24 Oct 2014 00:15:00 +0200 Subject: [master] 99fe067 Further untangling of the VDP stack Message-ID: commit 99fe06744222e4235c2ae4971e201d1cc6653275 Author: Poul-Henning Kamp Date: Thu Oct 23 22:14:45 2014 +0000 Further untangling of the VDP stack diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index 9c28ac3..35fdeaa 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -156,8 +156,6 @@ ved_include(struct req *preq, const char *src, const char *host) } AN(V1L_IsReleased(wrk)); - VDP_close(req); - CNT_AcctLogCharge(wrk->stats, req); VSL_End(req->vsl); diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 7d873ed..8d479a9 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -345,14 +345,11 @@ V1D_Deliver(struct req *req, struct busyobj *bo) if (req->esi_level == 0 && req->res_mode & RES_GUNZIP) VDP_push(req, VDP_gunzip, NULL); ESI_Deliver(req); - if (req->esi_level == 0 && req->res_mode & RES_GUNZIP) - VDP_pop(req, VDP_gunzip); } else if (req->res_mode & RES_ESI_CHILD) { if (req->gzip_resp && !ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) { VDP_push(req, VED_pretend_gzip, NULL); ois = v1d_WriteDirObj(req); - VDP_pop(req, VED_pretend_gzip); } else if (req->gzip_resp) { if (bo != NULL) VBO_waitstate(bo, BOS_FINISHED); @@ -361,19 +358,16 @@ V1D_Deliver(struct req *req, struct busyobj *bo) ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) { VDP_push(req, VDP_gunzip, NULL); ois = v1d_WriteDirObj(req); - VDP_pop(req, VDP_gunzip); } else { /* The toplevel will gunzip if needed */ ois = v1d_WriteDirObj(req); } - } else if ((req->res_mode & RES_GUNZIP) && - ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) { - VDP_push(req, VDP_gunzip, NULL); - ois = v1d_WriteDirObj(req); - VDP_pop(req, VDP_gunzip); } else { + if (req->res_mode & RES_GUNZIP) + VDP_push(req, VDP_gunzip, NULL); ois = v1d_WriteDirObj(req); } + (void)VDP_bytes(req, VDP_FLUSH, NULL, 0); if (ois == OIS_DONE && (req->res_mode & RES_CHUNKED) && @@ -383,6 +377,5 @@ V1D_Deliver(struct req *req, struct busyobj *bo) if ((V1L_FlushRelease(req->wrk) || ois != OIS_DONE) && req->sp->fd >= 0) SES_Close(req->sp, SC_REM_CLOSE); - if (req->esi_level == 0) - VDP_close(req); + VDP_close(req); } From phk at FreeBSD.org Thu Oct 23 22:42:01 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Fri, 24 Oct 2014 00:42:01 +0200 Subject: [master] e09ed9d Use the pretend_gzip to simplify delivery of esi objects Message-ID: commit e09ed9d8f404f8c691fa168d04c1601a9709397b Author: Poul-Henning Kamp Date: Thu Oct 23 22:41:35 2014 +0000 Use the pretend_gzip to simplify delivery of esi objects diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index 35fdeaa..9eb10e3 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -362,22 +362,7 @@ ESI_Deliver(struct req *req) sl -= l2; l -= l2; - if (req->gzip_resp && isgzip) { - /* - * We have a gzip'ed VEC and delivers - * a gzip'ed ESI response. - */ - (void)VDP_bytes(req, VDP_NULL, pp, l2); - } else if (req->gzip_resp) { - /* - * A gzip'ed ESI response, but the VEC - * was not gzip'ed. - */ - (void)VED_pretend_gzip(req, VDP_NULL, - NULL, pp, l2); - } else { - (void)VDP_bytes(req, VDP_NULL, pp, l2); - } + (void)VDP_bytes(req, VDP_NULL, pp, l2); pp += l2; if (sl == 0) { ois = ObjIter(req->objcore, oi, diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 8d479a9..26fae72 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -341,31 +341,32 @@ V1D_Deliver(struct req *req, struct busyobj *bo) ois = OIS_DONE; if (!req->wantbody) { /* This was a HEAD or conditional request */ - } else if (req->res_mode & RES_ESI) { - if (req->esi_level == 0 && req->res_mode & RES_GUNZIP) - VDP_push(req, VDP_gunzip, NULL); - ESI_Deliver(req); - } else if (req->res_mode & RES_ESI_CHILD) { + } else if (req->esi_level > 0) { if (req->gzip_resp && - !ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) { - VDP_push(req, VED_pretend_gzip, NULL); - ois = v1d_WriteDirObj(req); - } else if (req->gzip_resp) { + ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) { if (bo != NULL) VBO_waitstate(bo, BOS_FINISHED); ESI_DeliverChild(req); - } else if (!req->gzip_resp && - ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) { - VDP_push(req, VDP_gunzip, NULL); - ois = v1d_WriteDirObj(req); } else { - /* The toplevel will gunzip if needed */ - ois = v1d_WriteDirObj(req); + if (req->gzip_resp && + !ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) + VDP_push(req, VED_pretend_gzip, NULL); + else if (!req->gzip_resp && + ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) + VDP_push(req, VDP_gunzip, NULL); + + if (req->res_mode & RES_ESI) + ESI_Deliver(req); + else + ois = v1d_WriteDirObj(req); } } else { if (req->res_mode & RES_GUNZIP) VDP_push(req, VDP_gunzip, NULL); - ois = v1d_WriteDirObj(req); + if (req->res_mode & RES_ESI) + ESI_Deliver(req); + else + ois = v1d_WriteDirObj(req); } (void)VDP_bytes(req, VDP_FLUSH, NULL, 0); From phk at FreeBSD.org Mon Oct 27 07:52:35 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Oct 2014 08:52:35 +0100 Subject: [master] be77dbc Don't skip ESI processing for included gzip objects Message-ID: commit be77dbcae20678e86e312e2660d4768055e42fcd Author: Poul-Henning Kamp Date: Mon Oct 27 07:52:16 2014 +0000 Don't skip ESI processing for included gzip objects diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 26fae72..746f129 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -343,7 +343,8 @@ V1D_Deliver(struct req *req, struct busyobj *bo) /* This was a HEAD or conditional request */ } else if (req->esi_level > 0) { if (req->gzip_resp && - ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) { + ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED) && + !(req->res_mode & RES_ESI)) { if (bo != NULL) VBO_waitstate(bo, BOS_FINISHED); ESI_DeliverChild(req); From phk at FreeBSD.org Mon Oct 27 08:54:11 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Oct 2014 09:54:11 +0100 Subject: [master] 0350510 Enable Range: for ESI requests Message-ID: commit 03505109dffc5bcb8d9d3d8035e06f2bfa05c152 Author: Poul-Henning Kamp Date: Mon Oct 27 08:54:00 2014 +0000 Enable Range: for ESI requests diff --git a/bin/varnishd/cache/cache_deliver_proc.c b/bin/varnishd/cache/cache_deliver_proc.c index 86c9889..65f90c9 100644 --- a/bin/varnishd/cache/cache_deliver_proc.c +++ b/bin/varnishd/cache/cache_deliver_proc.c @@ -70,8 +70,8 @@ VDP_push(struct req *req, vdp_bytes *func, void *priv) AZ(vdp->func(req, VDP_INIT, &vdp->priv, NULL, 0)); } -void -VDP_pop(struct req *req, vdp_bytes *func) +static void +vdp_pop(struct req *req, vdp_bytes *func) { struct vdp_entry *vdp; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); @@ -91,5 +91,5 @@ VDP_close(struct req *req) CHECK_OBJ_NOTNULL(req, REQ_MAGIC); while (!VTAILQ_EMPTY(&req->vdp)) - VDP_pop(req, VTAILQ_FIRST(&req->vdp)->func); + vdp_pop(req, VTAILQ_FIRST(&req->vdp)->func); } diff --git a/bin/varnishd/cache/cache_filter.h b/bin/varnishd/cache/cache_filter.h index fce1c09..87f240a 100644 --- a/bin/varnishd/cache/cache_filter.h +++ b/bin/varnishd/cache/cache_filter.h @@ -107,7 +107,6 @@ struct vdp_entry { int VDP_bytes(struct req *, enum vdp_action act, const void *ptr, ssize_t len); void VDP_push(struct req *, vdp_bytes *func, void *priv); -void VDP_pop(struct req *, vdp_bytes *func); void VDP_close(struct req *req); vdp_bytes VDP_gunzip; diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 746f129..4122672 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -318,7 +318,7 @@ V1D_Deliver(struct req *req, struct busyobj *bo) if ( req->wantbody && - !(req->res_mode & (RES_ESI|RES_ESI_CHILD)) && + req->esi_level == 0 && cache_param->http_range_support && http_IsStatus(req->resp, 200)) { http_SetHeader(req->resp, "Accept-Ranges: bytes"); diff --git a/bin/varnishtest/tests/e00003.vtc b/bin/varnishtest/tests/e00003.vtc index 935e1f0..a8ab61a 100644 --- a/bin/varnishtest/tests/e00003.vtc +++ b/bin/varnishtest/tests/e00003.vtc @@ -30,7 +30,7 @@ varnish v1 -vcl+backend { logexpect l1 -v v1 -g request { expect 0 1001 Begin "^req .* rxreq" - expect * = ReqAcct "^18 0 18 154 75 229$" + expect * = ReqAcct "^18 0 18 176 75 251$" expect 0 = End expect 0 1002 Begin "^bereq " @@ -44,7 +44,7 @@ logexpect l1 -v v1 -g request { expect * = End expect 0 1005 Begin "^req .* rxreq" - expect * = ReqAcct "^18 0 18 159 75 234$" + expect * = ReqAcct "^18 0 18 181 75 256$" expect 0 = End } -start diff --git a/bin/varnishtest/tests/l00003.vtc b/bin/varnishtest/tests/l00003.vtc index 851073c..4bbb04e 100644 --- a/bin/varnishtest/tests/l00003.vtc +++ b/bin/varnishtest/tests/l00003.vtc @@ -48,7 +48,7 @@ varnish v1 -vcl+backend { logexpect l1 -v v1 -g request { expect 0 1001 Begin "^req .* rxreq" - expect * = ReqAcct "^18 0 18 71 15 86$" + expect * = ReqAcct "^18 0 18 93 15 108$" expect 0 = End expect * 1003 Begin "^req .* esi" expect * = ReqAcct "^0 0 0 0 12 12$" @@ -72,5 +72,5 @@ logexpect l1 -wait varnish v1 -expect s_req_hdrbytes == 18 varnish v1 -expect s_req_bodybytes == 0 -varnish v1 -expect s_resp_hdrbytes == 71 +varnish v1 -expect s_resp_hdrbytes == 93 varnish v1 -expect s_resp_bodybytes == 33 From phk at FreeBSD.org Mon Oct 27 09:14:33 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Oct 2014 10:14:33 +0100 Subject: [master] 72b94e6 We expect the backends to get into trouble Message-ID: commit 72b94e69c1e32bd168a9b29120641bc1934fd87c Author: Poul-Henning Kamp Date: Mon Oct 27 09:14:12 2014 +0000 We expect the backends to get into trouble diff --git a/bin/varnishtest/tests/r00942.vtc b/bin/varnishtest/tests/r00942.vtc index 171ceb3..164234d 100644 --- a/bin/varnishtest/tests/r00942.vtc +++ b/bin/varnishtest/tests/r00942.vtc @@ -21,9 +21,10 @@ server s1 -repeat 2 { chunked "FOOBAR" + non-fatal chunkedlen 0 - expect_close accept + fatal } -start varnish v1 \ diff --git a/bin/varnishtest/tests/r01086.vtc b/bin/varnishtest/tests/r01086.vtc index d861a0d..dc2e0b3 100644 --- a/bin/varnishtest/tests/r01086.vtc +++ b/bin/varnishtest/tests/r01086.vtc @@ -24,9 +24,11 @@ server s1 { chunked "FOOBAR" + non-fatal chunkedlen 0 accept + fatal # This one will not be streamed rxreq From phk at FreeBSD.org Mon Oct 27 09:28:13 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Oct 2014 10:28:13 +0100 Subject: [master] 7944d8d Silence a new FlexeLint 9L false positive Message-ID: commit 7944d8d1ccc89e7525b17286e974321471aef5d5 Author: Poul-Henning Kamp Date: Mon Oct 27 09:27:50 2014 +0000 Silence a new FlexeLint 9L false positive diff --git a/include/vqueue.h b/include/vqueue.h index a8b248d..fc9fb88 100644 --- a/include/vqueue.h +++ b/include/vqueue.h @@ -435,7 +435,7 @@ struct { \ struct type *vtqe_next; /* next element */ \ struct type **vtqe_prev; /* address of previous next element */\ TRACEBUF \ -} +} /*lint -e(18) */ /* * Tail queue functions. From phk at FreeBSD.org Mon Oct 27 10:33:59 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Oct 2014 11:33:59 +0100 Subject: [master] 026e9ed Explictly tell V1L which workspace to use Message-ID: commit 026e9ede4c396107e61d91a11ba37ef9bf4f9136 Author: Poul-Henning Kamp Date: Mon Oct 27 10:33:42 2014 +0000 Explictly tell V1L which workspace to use diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index e058fed..5dc39c0 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -951,7 +951,7 @@ void Pool_PurgeStat(unsigned nobj); #define V1L_IsReleased(w) ((w)->v1l == NULL) void V1L_Chunked(const struct worker *w); void V1L_EndChunk(const struct worker *w); -void V1L_Reserve(struct worker *w, int *fd, struct vsl_log *, double t0); +void V1L_Reserve(struct worker *, struct ws *, int *fd, struct vsl_log *, double t0); unsigned V1L_Flush(const struct worker *w); unsigned V1L_FlushRelease(struct worker *w); unsigned V1L_Write(const struct worker *w, const void *ptr, int len); diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index 9eb10e3..5d4588d 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -162,7 +162,8 @@ ved_include(struct req *preq, const char *src, const char *host) /* Reset the workspace */ WS_Reset(wrk->aws, wrk_ws_wm); /* XXX ? */ - V1L_Reserve(preq->wrk, &preq->sp->fd, preq->vsl, preq->t_prev); + V1L_Reserve(preq->wrk, preq->wrk->aws, &preq->sp->fd, preq->vsl, + preq->t_prev); if (preq->res_mode & RES_CHUNKED) V1L_Chunked(preq->wrk); diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 4122672..9523a2e 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -326,7 +326,8 @@ V1D_Deliver(struct req *req, struct busyobj *bo) v1d_dorange(req, bo, r); } - V1L_Reserve(req->wrk, &req->sp->fd, req->vsl, req->t_prev); + V1L_Reserve(req->wrk, req->wrk->aws, &req->sp->fd, req->vsl, + req->t_prev); /* * Send HTTP protocol header, unless interior ESI object diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c index 3124812..58175b4 100644 --- a/bin/varnishd/http1/cache_http1_fetch.c +++ b/bin/varnishd/http1/cache_http1_fetch.c @@ -111,7 +111,7 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo) } (void)VTCP_blocking(vc->fd); /* XXX: we should timeout instead */ - V1L_Reserve(wrk, &vc->fd, bo->vsl, bo->t_prev); + V1L_Reserve(wrk, wrk->aws, &vc->fd, bo->vsl, bo->t_prev); bo->acct.bereq_hdrbytes = HTTP1_Write(wrk, hp, HTTP1_Req); /* Deal with any message-body the request might (still) have */ diff --git a/bin/varnishd/http1/cache_http1_line.c b/bin/varnishd/http1/cache_http1_line.c index a2781d1..3254691 100644 --- a/bin/varnishd/http1/cache_http1_line.c +++ b/bin/varnishd/http1/cache_http1_line.c @@ -59,29 +59,39 @@ struct v1l { double t0; struct vsl_log *vsl; ssize_t cnt; /* Flushed byte count */ + struct ws *ws; + void *res; }; /*-------------------------------------------------------------------- */ void -V1L_Reserve(struct worker *wrk, int *fd, struct vsl_log *vsl, double t0) +V1L_Reserve(struct worker *wrk, struct ws *ws, int *fd, struct vsl_log *vsl, + double t0) { struct v1l *v1l; unsigned u; + void *res; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); AZ(wrk->v1l); - v1l = WS_Alloc(wrk->aws, sizeof *v1l); + + res = WS_Snapshot(ws); + v1l = WS_Alloc(ws, sizeof *v1l); AN(v1l); INIT_OBJ(v1l, V1L_MAGIC); - u = WS_Reserve(wrk->aws, 0); + + v1l->ws = ws; + v1l->res = res; + + u = WS_Reserve(ws, 0); u = PRNDDN(u); u /= sizeof(struct iovec); if (u > IOV_MAX) u = IOV_MAX; AN(u); - v1l->iov = (void*)PRNDUP(wrk->aws->f); + v1l->iov = (void*)PRNDUP(ws->f); v1l->siov = u; v1l->ciov = u; v1l->werr = 0; @@ -104,8 +114,8 @@ V1L_FlushRelease(struct worker *wrk) v1l = wrk->v1l; wrk->v1l = NULL; CHECK_OBJ_NOTNULL(v1l, V1L_MAGIC); - WS_Release(wrk->aws, 0); - WS_Reset(wrk->aws, NULL); + WS_Release(v1l->ws, 0); + WS_Reset(v1l->ws, v1l->res); return (u); } diff --git a/bin/varnishd/http1/cache_http1_pipe.c b/bin/varnishd/http1/cache_http1_pipe.c index 87b7256..84b45a0 100644 --- a/bin/varnishd/http1/cache_http1_pipe.c +++ b/bin/varnishd/http1/cache_http1_pipe.c @@ -123,7 +123,7 @@ V1P_Process(struct req *req, struct busyobj *bo) bo->director_state = DIR_S_BODY; (void)VTCP_blocking(fd); - V1L_Reserve(wrk, &fd, bo->vsl, req->t_req); + V1L_Reserve(wrk, wrk->aws, &fd, bo->vsl, req->t_req); acct_pipe.bereq += HTTP1_Write(wrk, bo->bereq, HTTP1_Req); if (req->htc->pipeline_b != NULL) From phk at FreeBSD.org Mon Oct 27 11:05:55 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Oct 2014 12:05:55 +0100 Subject: [master] ea25150 Correctly initialize esi-included req->http0 Message-ID: commit ea251504784faab57e0d47941317a7a046ed78a3 Author: Poul-Henning Kamp Date: Mon Oct 27 10:40:53 2014 +0000 Correctly initialize esi-included req->http0 diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index 5d4588d..deca61e 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -92,10 +92,11 @@ ved_include(struct req *preq, const char *src, const char *host) HTTP_Copy(req->http0, preq->http0); + req->http0->ws = req->ws; + req->http0->vsl = req->vsl; + req->http0->logtag = SLT_ReqMethod; req->http0->conds = 0; - HTTP_Setup(req->http, req->ws, req->vsl, SLT_ReqMethod); - http_SetH(req->http0, HTTP_HDR_URL, src); if (host != NULL && *host != '\0') { http_Unset(req->http0, H_Host); diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 9523a2e..65a2bf6 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -356,7 +356,7 @@ V1D_Deliver(struct req *req, struct busyobj *bo) else if (!req->gzip_resp && ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) VDP_push(req, VDP_gunzip, NULL); - + if (req->res_mode & RES_ESI) ESI_Deliver(req); else diff --git a/bin/varnishd/http1/cache_http1_line.c b/bin/varnishd/http1/cache_http1_line.c index 3254691..271a369 100644 --- a/bin/varnishd/http1/cache_http1_line.c +++ b/bin/varnishd/http1/cache_http1_line.c @@ -76,7 +76,7 @@ V1L_Reserve(struct worker *wrk, struct ws *ws, int *fd, struct vsl_log *vsl, CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); AZ(wrk->v1l); - + res = WS_Snapshot(ws); v1l = WS_Alloc(ws, sizeof *v1l); AN(v1l); From phk at FreeBSD.org Mon Oct 27 11:05:55 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Oct 2014 12:05:55 +0100 Subject: [master] 15fd13e Remove sanity-checks on V1L from protocol independent layer Message-ID: commit 15fd13e4018e34ee40b54421d8a0a67184506949 Author: Poul-Henning Kamp Date: Mon Oct 27 10:53:50 2014 +0000 Remove sanity-checks on V1L from protocol independent layer diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 3b5755b..6b7a9db 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -63,7 +63,6 @@ cnt_deliver(struct worker *wrk, struct req *req) CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); CHECK_OBJ_NOTNULL(req->objcore->objhead, OBJHEAD_MAGIC); CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); - assert(V1L_IsReleased(wrk)); assert(req->objcore->refcnt > 0); @@ -159,7 +158,6 @@ cnt_deliver(struct worker *wrk, struct req *req) ObjSlim(wrk, req->objcore); } - assert(V1L_IsReleased(wrk)); (void)HSH_DerefObjCore(wrk, &req->objcore); http_Teardown(req->resp); return (REQ_FSM_DONE); @@ -517,7 +515,6 @@ cnt_pipe(struct worker *wrk, struct req *req) assert(wrk->handling == VCL_RET_PIPE); V1P_Process(req, bo); - assert(V1L_IsReleased(wrk)); http_Teardown(bo->bereq); THR_SetBusyobj(NULL); VBO_DerefBusyObj(wrk, &bo); @@ -794,7 +791,6 @@ CNT_Request(struct worker *wrk, struct req *req) VRB_Free(req); req->wrk = NULL; } - assert(V1L_IsReleased(wrk)); return (nxt); } From phk at FreeBSD.org Mon Oct 27 11:05:55 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Oct 2014 12:05:55 +0100 Subject: [master] 69d4541 Use the req->ws for the V1L in the toplevel requests, so that esi-included requests don't need to know about it. Message-ID: commit 69d45413bb1fca69cb487b0098f1a7323114fdf7 Author: Poul-Henning Kamp Date: Mon Oct 27 11:05:18 2014 +0000 Use the req->ws for the V1L in the toplevel requests, so that esi-included requests don't need to know about it. diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index deca61e..504902c 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -69,7 +69,6 @@ ved_include(struct req *preq, const char *src, const char *host) { struct worker *wrk; struct req *req; - char *wrk_ws_wm; enum req_fsm_nxt s; wrk = preq->wrk; @@ -77,11 +76,6 @@ ved_include(struct req *preq, const char *src, const char *host) if (preq->esi_level >= cache_param->max_esi_depth) return; - (void)V1L_FlushRelease(preq->wrk); - - /* Take a workspace snapshot */ - wrk_ws_wm = WS_Snapshot(wrk->aws); /* XXX ? */ - req = SES_GetReq(wrk, preq->sp); req->req_body_status = REQ_BODY_NONE; AZ(req->vsl->wid); @@ -155,19 +149,10 @@ ved_include(struct req *preq, const char *src, const char *host) AZ(req->wrk); (void)usleep(10000); } - AN(V1L_IsReleased(wrk)); CNT_AcctLogCharge(wrk->stats, req); VSL_End(req->vsl); - /* Reset the workspace */ - WS_Reset(wrk->aws, wrk_ws_wm); /* XXX ? */ - - V1L_Reserve(preq->wrk, preq->wrk->aws, &preq->sp->fd, preq->vsl, - preq->t_prev); - if (preq->res_mode & RES_CHUNKED) - V1L_Chunked(preq->wrk); - preq->vcl = req->vcl; req->vcl = NULL; diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 65a2bf6..eb15df4 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -298,6 +298,31 @@ V1D_Deliver(struct req *req, struct busyobj *bo) } VSLb(req->vsl, SLT_Debug, "RES_MODE %x", req->res_mode); + if (req->esi_level > 0) { + if (req->gzip_resp && + ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED) && + !(req->res_mode & RES_ESI)) { + if (bo != NULL) + VBO_waitstate(bo, BOS_FINISHED); + ESI_DeliverChild(req); + } else { + if (req->gzip_resp && + !ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) + VDP_push(req, VED_pretend_gzip, NULL); + else if (!req->gzip_resp && + ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) + VDP_push(req, VDP_gunzip, NULL); + + if (req->res_mode & RES_ESI) + ESI_Deliver(req); + else + (void)v1d_WriteDirObj(req); + } + (void)VDP_bytes(req, VDP_FLUSH, NULL, 0); + VDP_close(req); + return; + } + if (!(req->res_mode & RES_LEN)) http_Unset(req->resp, H_Content_Length); @@ -310,15 +335,12 @@ V1D_Deliver(struct req *req, struct busyobj *bo) http_SetHeader(req->resp, req->doclose ? "Connection: close" : "Connection: keep-alive"); - if (req->esi_level == 0) { - req->vdp_nxt = 0; - VTAILQ_INIT(&req->vdp); - VDP_push(req, v1d_bytes, NULL); - } + req->vdp_nxt = 0; + VTAILQ_INIT(&req->vdp); + VDP_push(req, v1d_bytes, NULL); if ( req->wantbody && - req->esi_level == 0 && cache_param->http_range_support && http_IsStatus(req->resp, 200)) { http_SetHeader(req->resp, "Accept-Ranges: bytes"); @@ -326,45 +348,18 @@ V1D_Deliver(struct req *req, struct busyobj *bo) v1d_dorange(req, bo, r); } - V1L_Reserve(req->wrk, req->wrk->aws, &req->sp->fd, req->vsl, - req->t_prev); + if (req->res_mode & RES_GUNZIP) + VDP_push(req, VDP_gunzip, NULL); + + V1L_Reserve(req->wrk, req->ws, &req->sp->fd, req->vsl, req->t_prev); - /* - * Send HTTP protocol header, unless interior ESI object - */ - if (!(req->res_mode & RES_ESI_CHILD)) - req->acct.resp_hdrbytes += - HTTP1_Write(req->wrk, req->resp, HTTP1_Resp); + req->acct.resp_hdrbytes += HTTP1_Write(req->wrk, req->resp, HTTP1_Resp); if (req->res_mode & RES_CHUNKED) V1L_Chunked(req->wrk); ois = OIS_DONE; - if (!req->wantbody) { - /* This was a HEAD or conditional request */ - } else if (req->esi_level > 0) { - if (req->gzip_resp && - ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED) && - !(req->res_mode & RES_ESI)) { - if (bo != NULL) - VBO_waitstate(bo, BOS_FINISHED); - ESI_DeliverChild(req); - } else { - if (req->gzip_resp && - !ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) - VDP_push(req, VED_pretend_gzip, NULL); - else if (!req->gzip_resp && - ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) - VDP_push(req, VDP_gunzip, NULL); - - if (req->res_mode & RES_ESI) - ESI_Deliver(req); - else - ois = v1d_WriteDirObj(req); - } - } else { - if (req->res_mode & RES_GUNZIP) - VDP_push(req, VDP_gunzip, NULL); + if (req->wantbody) { if (req->res_mode & RES_ESI) ESI_Deliver(req); else @@ -372,13 +367,10 @@ V1D_Deliver(struct req *req, struct busyobj *bo) } (void)VDP_bytes(req, VDP_FLUSH, NULL, 0); - if (ois == OIS_DONE && - (req->res_mode & RES_CHUNKED) && - !(req->res_mode & RES_ESI_CHILD)) + if (ois == OIS_DONE && (req->res_mode & RES_CHUNKED)) V1L_EndChunk(req->wrk); - if ((V1L_FlushRelease(req->wrk) || ois != OIS_DONE) && - req->sp->fd >= 0) + if ((V1L_FlushRelease(req->wrk) || ois != OIS_DONE) && req->sp->fd >= 0) SES_Close(req->sp, SC_REM_CLOSE); VDP_close(req); } From phk at FreeBSD.org Mon Oct 27 13:17:02 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Oct 2014 14:17:02 +0100 Subject: [master] 94d1d0f Polish VDP stack mgt API Message-ID: commit 94d1d0fd601711d74f3d47dd5f89ed9adc0d732f Author: Poul-Henning Kamp Date: Mon Oct 27 13:16:46 2014 +0000 Polish VDP stack mgt API diff --git a/bin/varnishd/cache/cache_deliver_proc.c b/bin/varnishd/cache/cache_deliver_proc.c index 65f90c9..fda860c 100644 --- a/bin/varnishd/cache/cache_deliver_proc.c +++ b/bin/varnishd/cache/cache_deliver_proc.c @@ -52,7 +52,7 @@ VDP_bytes(struct req *req, enum vdp_action act, const void *ptr, ssize_t len) } void -VDP_push(struct req *req, vdp_bytes *func, void *priv) +VDP_push(struct req *req, vdp_bytes *func, void *priv, int bottom) { struct vdp_entry *vdp; @@ -64,8 +64,11 @@ VDP_push(struct req *req, vdp_bytes *func, void *priv) INIT_OBJ(vdp, VDP_ENTRY_MAGIC); vdp->func = func; vdp->priv = priv; - VTAILQ_INSERT_HEAD(&req->vdp, vdp, list); - req->vdp_nxt = vdp; + if (bottom) + VTAILQ_INSERT_TAIL(&req->vdp, vdp, list); + else + VTAILQ_INSERT_HEAD(&req->vdp, vdp, list); + req->vdp_nxt = VTAILQ_FIRST(&req->vdp); AZ(vdp->func(req, VDP_INIT, &vdp->priv, NULL, 0)); } diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index 504902c..0cb4713 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -127,10 +127,7 @@ ved_include(struct req *preq, const char *src, const char *host) req->crc = preq->crc; req->l_crc = preq->l_crc; - - req->vdp_nxt = 0; - VTAILQ_INIT(&req->vdp); - VDP_push(req, ved_vdp_bytes, preq); + VDP_push(req, ved_vdp_bytes, preq, 0); THR_SetRequest(req); diff --git a/bin/varnishd/cache/cache_filter.h b/bin/varnishd/cache/cache_filter.h index 87f240a..49dda2f 100644 --- a/bin/varnishd/cache/cache_filter.h +++ b/bin/varnishd/cache/cache_filter.h @@ -106,7 +106,7 @@ struct vdp_entry { }; int VDP_bytes(struct req *, enum vdp_action act, const void *ptr, ssize_t len); -void VDP_push(struct req *, vdp_bytes *func, void *priv); +void VDP_push(struct req *, vdp_bytes *func, void *priv, int bottom); void VDP_close(struct req *req); vdp_bytes VDP_gunzip; diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index 024d74f..7749216 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -371,6 +371,9 @@ SES_GetReq(const struct worker *wrk, struct sess *sp) req->t_prev = NAN; req->t_req = NAN; + req->vdp_nxt = 0; + VTAILQ_INIT(&req->vdp); + return (req); } diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index eb15df4..22e8666 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -185,7 +185,7 @@ v1d_dorange(struct req *req, struct busyobj *bo, const char *r) v1rp->range_off = 0; v1rp->range_low = low; v1rp->range_high = high + 1; - VDP_push(req, v1d_range_bytes, v1rp); + VDP_push(req, v1d_range_bytes, v1rp, 0); } /*--------------------------------------------------------------------*/ @@ -308,10 +308,10 @@ V1D_Deliver(struct req *req, struct busyobj *bo) } else { if (req->gzip_resp && !ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) - VDP_push(req, VED_pretend_gzip, NULL); + VDP_push(req, VED_pretend_gzip, NULL, 0); else if (!req->gzip_resp && ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) - VDP_push(req, VDP_gunzip, NULL); + VDP_push(req, VDP_gunzip, NULL, 0); if (req->res_mode & RES_ESI) ESI_Deliver(req); @@ -335,10 +335,6 @@ V1D_Deliver(struct req *req, struct busyobj *bo) http_SetHeader(req->resp, req->doclose ? "Connection: close" : "Connection: keep-alive"); - req->vdp_nxt = 0; - VTAILQ_INIT(&req->vdp); - VDP_push(req, v1d_bytes, NULL); - if ( req->wantbody && cache_param->http_range_support && @@ -349,7 +345,9 @@ V1D_Deliver(struct req *req, struct busyobj *bo) } if (req->res_mode & RES_GUNZIP) - VDP_push(req, VDP_gunzip, NULL); + VDP_push(req, VDP_gunzip, NULL, 0); + + VDP_push(req, v1d_bytes, NULL, 1); V1L_Reserve(req->wrk, req->ws, &req->sp->fd, req->vsl, req->t_prev); From daghf at varnish-software.com Mon Oct 27 13:43:17 2014 From: daghf at varnish-software.com (Dag Haavi Finstad) Date: Mon, 27 Oct 2014 14:43:17 +0100 Subject: [master] e8c604b Move obj.hits to struct objcore. This gives us a separate hits counter per object, in line with the functionality as it was in Varnish 3.0. Message-ID: commit e8c604b03eb61b0663996ebc68439a09af50fa3d Author: Dag Haavi Finstad Date: Mon Oct 27 14:31:08 2014 +0100 Move obj.hits to struct objcore. This gives us a separate hits counter per object, in line with the functionality as it was in Varnish 3.0. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 5dc39c0..e88a4af 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -403,6 +403,7 @@ struct objcore { struct objhead *objhead; struct busyobj *busyobj; double timer_when; + long hits; struct exp exp; diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c index dc18cfe..de35e8a 100644 --- a/bin/varnishd/cache/cache_hash.c +++ b/bin/varnishd/cache/cache_hash.c @@ -434,8 +434,8 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp, assert(oh->refcnt > 1); assert(oc->objhead == oh); oc->refcnt++; - if (oh->hits < LONG_MAX) - oh->hits++; + if (oc->hits < LONG_MAX) + oc->hits++; Lck_Unlock(&oh->mtx); assert(HSH_DerefObjHead(wrk, &oh)); *ocp = oc; @@ -461,8 +461,8 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp, AZ(req->hash_ignore_busy); retval = HSH_EXP; } - if (oh->hits < LONG_MAX) - oh->hits++; + if (exp_oc->hits < LONG_MAX) + exp_oc->hits++; Lck_Unlock(&oh->mtx); if (retval == HSH_EXP) assert(HSH_DerefObjHead(wrk, &oh)); diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index 8448317..07f386b 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -651,8 +651,7 @@ VRT_r_obj_hits(VRT_CTX) CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC); CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC); - CHECK_OBJ_NOTNULL(ctx->req->objcore->objhead, OBJHEAD_MAGIC); - return (ctx->req->objcore->objhead->hits); + return (ctx->req->objcore->hits); } unsigned diff --git a/bin/varnishd/hash/hash_slinger.h b/bin/varnishd/hash/hash_slinger.h index db722da..189f938 100644 --- a/bin/varnishd/hash/hash_slinger.h +++ b/bin/varnishd/hash/hash_slinger.h @@ -94,8 +94,6 @@ struct objhead { uint8_t digest[DIGEST_LEN]; struct waitinglist *waitinglist; - long hits; - /*---------------------------------------------------- * The fields below are for the sole private use of * the hash implementation(s). diff --git a/bin/varnishtest/tests/v00039.vtc b/bin/varnishtest/tests/v00039.vtc index 90bc865..029e114 100644 --- a/bin/varnishtest/tests/v00039.vtc +++ b/bin/varnishtest/tests/v00039.vtc @@ -31,19 +31,19 @@ client c1 { expect resp.bodylen == 6 expect resp.http.hits == 1 - # This is a miss on different vary -> hits still == 1 + # This is a miss on different vary -> hits == 0 txreq -url "/" -hdr "Bar: 2" rxresp expect resp.status == 200 expect resp.bodylen == 4 - expect resp.http.hits == 1 + expect resp.http.hits == 0 - # This is a hit -> hits == 2 + # This is a hit -> hits == 1 txreq -url "/" -hdr "Bar: 2" rxresp expect resp.status == 200 expect resp.bodylen == 4 - expect resp.http.hits == 2 + expect resp.http.hits == 1 } -run diff --git a/lib/libvcc/generate.py b/lib/libvcc/generate.py index ea07a32..4dd6288 100755 --- a/lib/libvcc/generate.py +++ b/lib/libvcc/generate.py @@ -571,13 +571,9 @@ sp_variables = [ 'INT', ( 'hit', 'deliver',), ( ), """ - The count of cache-hits on this hash-key since it was - last instantiated. This counts cache-hits across all - Vary:-ants on this hash-key. - The counter will only be reset to zero if/when all objects - with this hash-key have disappeared from cache. - NB: obj.hits == 0 does *not* indicate a cache miss. - """ + The count of cache-hits on this object. A value of 0 indicates a + cache miss. + """ ), ('obj.http.', 'HEADER', From phk at FreeBSD.org Mon Oct 27 13:44:53 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Oct 2014 14:44:53 +0100 Subject: [master] 7d6878c Make the logexpect stuff robust Message-ID: commit 7d6878cf74c41f82ffe99365e7ef517f75924821 Author: Poul-Henning Kamp Date: Mon Oct 27 13:44:24 2014 +0000 Make the logexpect stuff robust diff --git a/bin/varnishtest/tests/e00003.vtc b/bin/varnishtest/tests/e00003.vtc index a8ab61a..02e6840 100644 --- a/bin/varnishtest/tests/e00003.vtc +++ b/bin/varnishtest/tests/e00003.vtc @@ -32,18 +32,26 @@ logexpect l1 -v v1 -g request { expect 0 1001 Begin "^req .* rxreq" expect * = ReqAcct "^18 0 18 176 75 251$" expect 0 = End +} -start - expect 0 1002 Begin "^bereq " +logexpect l2 -v v1 -g request { + expect * 1002 Begin "^bereq " expect * = End +} -start - expect 0 1003 Begin "^req .* esi" +logexpect l3 -v v1 -g request { + expect * 1003 Begin "^req .* esi" expect * = ReqAcct "^0 0 0 0 18 18$" expect 0 = End +} -start - expect 0 1004 Begin "^bereq " +logexpect l4 -v v1 -g request { + expect * 1004 Begin "^bereq " expect * = End +} -start - expect 0 1005 Begin "^req .* rxreq" +logexpect l5 -v v1 -g request { + expect * 1005 Begin "^req .* rxreq" expect * = ReqAcct "^18 0 18 181 75 256$" expect 0 = End } -start @@ -66,3 +74,7 @@ client c1 -run varnish v1 -expect esi_errors == 0 logexpect l1 -wait +logexpect l2 -wait +logexpect l3 -wait +logexpect l4 -wait +logexpect l5 -wait From phk at FreeBSD.org Mon Oct 27 14:18:50 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Oct 2014 15:18:50 +0100 Subject: [master] 644be66 More V1D/VDP reorg Message-ID: commit 644be66fbec23145bd5caceee00f8fca934274d6 Author: Poul-Henning Kamp Date: Mon Oct 27 14:18:35 2014 +0000 More V1D/VDP reorg diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 22e8666..8012f7c 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -233,23 +233,41 @@ V1D_Deliver(struct req *req, struct busyobj *bo) { const char *r; enum objiter_status ois; + int i; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); req->res_mode = 0; - if (req->esi_level > 0) + if (!req->disable_esi && + ObjGetattr(req->wrk, req->objcore, OA_ESIDATA, NULL) != NULL) + req->res_mode |= RES_ESI; + + if (req->esi_level > 0) { req->res_mode |= RES_ESI_CHILD; + i = ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED); + if (req->gzip_resp && i && !(req->res_mode & RES_ESI)) { + if (bo != NULL) + VBO_waitstate(bo, BOS_FINISHED); + ESI_DeliverChild(req); + } else { + if (req->gzip_resp && !i) + VDP_push(req, VED_pretend_gzip, NULL, 0); + else if (!req->gzip_resp && i) + VDP_push(req, VDP_gunzip, NULL, 0); - if (!req->disable_esi && ObjGetattr(req->wrk, req->objcore, - OA_ESIDATA, NULL) != NULL) { - /* In ESI mode, we can't know the aggregate length */ - req->res_mode |= RES_ESI; - RFC2616_Weaken_Etag(req->resp); + if (req->res_mode & RES_ESI) + ESI_Deliver(req); + else + (void)v1d_WriteDirObj(req); + } + (void)VDP_bytes(req, VDP_FLUSH, NULL, 0); + VDP_close(req); + return; } - if (req->res_mode & (RES_ESI_CHILD|RES_ESI)) { + if (req->res_mode & RES_ESI) { /* nothing */ } else if (http_IsStatus(req->resp, 304)) { req->res_mode &= ~RES_LEN; @@ -298,31 +316,6 @@ V1D_Deliver(struct req *req, struct busyobj *bo) } VSLb(req->vsl, SLT_Debug, "RES_MODE %x", req->res_mode); - if (req->esi_level > 0) { - if (req->gzip_resp && - ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED) && - !(req->res_mode & RES_ESI)) { - if (bo != NULL) - VBO_waitstate(bo, BOS_FINISHED); - ESI_DeliverChild(req); - } else { - if (req->gzip_resp && - !ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) - VDP_push(req, VED_pretend_gzip, NULL, 0); - else if (!req->gzip_resp && - ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED)) - VDP_push(req, VDP_gunzip, NULL, 0); - - if (req->res_mode & RES_ESI) - ESI_Deliver(req); - else - (void)v1d_WriteDirObj(req); - } - (void)VDP_bytes(req, VDP_FLUSH, NULL, 0); - VDP_close(req); - return; - } - if (!(req->res_mode & RES_LEN)) http_Unset(req->resp, H_Content_Length); @@ -332,6 +325,9 @@ V1D_Deliver(struct req *req, struct busyobj *bo) if (req->res_mode & RES_CHUNKED) http_SetHeader(req->resp, "Transfer-Encoding: chunked"); + if (req->res_mode & RES_ESI) + RFC2616_Weaken_Etag(req->resp); + http_SetHeader(req->resp, req->doclose ? "Connection: close" : "Connection: keep-alive"); From fgsch at lodoss.net Mon Oct 27 14:53:24 2014 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Mon, 27 Oct 2014 15:53:24 +0100 Subject: [master] d9f7e92 Merge stale-while-revalidate handling into RFC2616_Ttl Message-ID: commit d9f7e92cacb777410f7fd4e8beb1fe3e6c660799 Author: Federico G. Schwindt Date: Mon Oct 27 13:43:16 2014 +0000 Merge stale-while-revalidate handling into RFC2616_Ttl Log the grace period as part of the SLT_TTL VSL tag. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index e88a4af..dd2f71f 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -1085,7 +1085,6 @@ unsigned RFC2616_Req_Gzip(const struct http *); int RFC2616_Do_Cond(const struct req *sp); void RFC2616_Weaken_Etag(struct http *hp); void RFC2616_Vary_AE(struct http *hp); -void RFC5861_Stale(const struct busyobj *); /* stevedore.c */ int STV_NewObject(struct objcore *, struct worker *, diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index ceaf931..bfbd3c9 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -366,8 +366,6 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo) EXP_Clr(&bo->fetch_objcore->exp); RFC2616_Ttl(bo, now); - RFC5861_Stale(bo); - /* private objects have negative TTL */ if (bo->fetch_objcore->flags & OC_F_PRIVATE) bo->fetch_objcore->exp.ttl = -1.; diff --git a/bin/varnishd/cache/cache_rfc2616.c b/bin/varnishd/cache/cache_rfc2616.c index 4733b56..89949e4 100644 --- a/bin/varnishd/cache/cache_rfc2616.c +++ b/bin/varnishd/cache/cache_rfc2616.c @@ -173,10 +173,22 @@ RFC2616_Ttl(struct busyobj *bo, double now) } - /* calculated TTL, Our time, Date, Expires, max-age, age */ + /* + * RFC5861 outlines a way to control the use of stale responses. + * We use this to initialize the grace period. + */ + if (expp->ttl >= 0 && http_GetHdrField(hp, H_Cache_Control, + "stale-while-revalidate", &p) && p != NULL) { + + if (*p == '-') + expp->grace = 0; + else + expp->grace = strtoul(p, NULL, 0); + } + VSLb(bo->vsl, SLT_TTL, "RFC %.0f %.0f %.0f %.0f %.0f %.0f %.0f %u", - expp->ttl, -1., -1., now, + expp->ttl, expp->grace, -1., now, expp->t_origin, h_date, h_expires, max_age); } @@ -275,35 +287,3 @@ RFC2616_Vary_AE(struct http *hp) http_SetHeader(hp, "Vary: Accept-Encoding"); } } - -/* - * RFC5861 outlines a way to control the use of stale responses. - * We use this to initialize the grace period. - */ - -void -RFC5861_Stale(const struct busyobj *bo) -{ - const char *p; - const struct http *hp; - struct exp *expp; - - expp = &bo->fetch_objcore->exp; - - /* - * If we are not meant to cache this ignore any potential - * stale-while-revalidate values. - */ - if (expp->ttl < 0.) - return; - - hp = bo->beresp; - - if (http_GetHdrField(hp, H_Cache_Control, - "stale-while-revalidate", &p) && p != NULL) { - if (*p == '-') - expp->grace = 0; - else - expp->grace = strtoul(p, NULL, 0); - } -} diff --git a/include/tbl/vsl_tags.h b/include/tbl/vsl_tags.h index b483f2c..7dd918d 100644 --- a/include/tbl/vsl_tags.h +++ b/include/tbl/vsl_tags.h @@ -211,7 +211,7 @@ SLTM(TTL, 0, "TTL set on object", "\n" "The last four fields are only present in \"RFC\" headers.\n\n" "Examples::\n\n" - "\tRFC 60 -1 -1 1312966109 1312966109 1312966109 0 60\n" + "\tRFC 60 10 -1 1312966109 1312966109 1312966109 0 60\n" "\tVCL 120 10 0 1312966111\n" "\n" ) From phk at FreeBSD.org Mon Oct 27 16:39:56 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Oct 2014 17:39:56 +0100 Subject: [master] 1c24449 Move the actual pushing of objects through VDP to a new function: VDP_DeliverObj() Message-ID: commit 1c24449296aa987745ef2e039aa13f5006c77551 Author: Poul-Henning Kamp Date: Mon Oct 27 16:39:21 2014 +0000 Move the actual pushing of objects through VDP to a new function: VDP_DeliverObj() diff --git a/bin/varnishd/cache/cache_deliver_proc.c b/bin/varnishd/cache/cache_deliver_proc.c index fda860c..a3701a9 100644 --- a/bin/varnishd/cache/cache_deliver_proc.c +++ b/bin/varnishd/cache/cache_deliver_proc.c @@ -96,3 +96,47 @@ VDP_close(struct req *req) while (!VTAILQ_EMPTY(&req->vdp)) vdp_pop(req, VTAILQ_FIRST(&req->vdp)->func); } + +/*--------------------------------------------------------------------*/ + +enum objiter_status +VDP_DeliverObj(struct req *req) +{ + enum objiter_status ois; + ssize_t len; + void *oi; + void *ptr; + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + + if (req->res_mode & RES_ESI) { + ESI_Deliver(req); + return (OIS_DONE); + } + + oi = ObjIterBegin(req->wrk, req->objcore); + XXXAN(oi); + AZ(req->synth_body); + + do { + ois = ObjIter(req->objcore, oi, &ptr, &len); + switch(ois) { + case OIS_DONE: + AZ(len); + break; + case OIS_ERROR: + break; + case OIS_DATA: + case OIS_STREAM: + if (VDP_bytes(req, + ois == OIS_DATA ? VDP_NULL : VDP_FLUSH, ptr, len)) + ois = OIS_ERROR; + break; + default: + WRONG("Wrong OIS value"); + } + } while (ois == OIS_DATA || ois == OIS_STREAM); + ObjIterEnd(req->objcore, &oi); + return (ois); +} + diff --git a/bin/varnishd/cache/cache_filter.h b/bin/varnishd/cache/cache_filter.h index 49dda2f..859b1e5 100644 --- a/bin/varnishd/cache/cache_filter.h +++ b/bin/varnishd/cache/cache_filter.h @@ -108,6 +108,7 @@ struct vdp_entry { int VDP_bytes(struct req *, enum vdp_action act, const void *ptr, ssize_t len); void VDP_push(struct req *, vdp_bytes *func, void *priv, int bottom); void VDP_close(struct req *req); +enum objiter_status VDP_DeliverObj(struct req *req); vdp_bytes VDP_gunzip; vdp_bytes VED_pretend_gzip; diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 8012f7c..32bf944 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -188,44 +188,6 @@ v1d_dorange(struct req *req, struct busyobj *bo, const char *r) VDP_push(req, v1d_range_bytes, v1rp, 0); } -/*--------------------------------------------------------------------*/ - -static enum objiter_status -v1d_WriteDirObj(struct req *req) -{ - enum objiter_status ois; - ssize_t len; - void *oi; - void *ptr; - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - - oi = ObjIterBegin(req->wrk, req->objcore); - XXXAN(oi); - AZ(req->synth_body); - - do { - ois = ObjIter(req->objcore, oi, &ptr, &len); - switch(ois) { - case OIS_DONE: - AZ(len); - break; - case OIS_ERROR: - break; - case OIS_DATA: - case OIS_STREAM: - if (VDP_bytes(req, - ois == OIS_DATA ? VDP_NULL : VDP_FLUSH, ptr, len)) - ois = OIS_ERROR; - break; - default: - WRONG("Wrong OIS value"); - } - } while (ois == OIS_DATA || ois == OIS_STREAM); - ObjIterEnd(req->objcore, &oi); - return (ois); -} - /*-------------------------------------------------------------------- */ void @@ -257,10 +219,7 @@ V1D_Deliver(struct req *req, struct busyobj *bo) else if (!req->gzip_resp && i) VDP_push(req, VDP_gunzip, NULL, 0); - if (req->res_mode & RES_ESI) - ESI_Deliver(req); - else - (void)v1d_WriteDirObj(req); + (void)VDP_DeliverObj(req); } (void)VDP_bytes(req, VDP_FLUSH, NULL, 0); VDP_close(req); @@ -353,12 +312,8 @@ V1D_Deliver(struct req *req, struct busyobj *bo) V1L_Chunked(req->wrk); ois = OIS_DONE; - if (req->wantbody) { - if (req->res_mode & RES_ESI) - ESI_Deliver(req); - else - ois = v1d_WriteDirObj(req); - } + if (req->wantbody) + ois = VDP_DeliverObj(req); (void)VDP_bytes(req, VDP_FLUSH, NULL, 0); if (ois == OIS_DONE && (req->res_mode & RES_CHUNKED)) From phk at FreeBSD.org Mon Oct 27 16:58:43 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Oct 2014 17:58:43 +0100 Subject: [master] f87c29b Push magic of ESI child delivery back home to esi_deliver.c Message-ID: commit f87c29bdf69c81dcfc91b82fa8785f0ea0ed02e1 Author: Poul-Henning Kamp Date: Mon Oct 27 16:58:15 2014 +0000 Push magic of ESI child delivery back home to esi_deliver.c diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index dd2f71f..eaea802 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -1046,7 +1046,7 @@ char *VRT_StringList(char *d, unsigned dl, const char *p, va_list ap); void VRTPRIV_dynamic_kill(struct sess *sp, uintptr_t id); void ESI_Deliver(struct req *); -void ESI_DeliverChild(struct req *); +void ESI_DeliverChild(struct req *, struct busyobj *); /* cache_vrt_vmod.c */ void VMOD_Init(void); diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index 0cb4713..deabbf6 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -215,8 +215,8 @@ ved_decode_len(uint8_t **pp) * the stream with a bit more overhead. */ -int __match_proto__(vdp_bytes) -VED_pretend_gzip(struct req *req, enum vdp_action act, void **priv, +static int __match_proto__(vdp_bytes) +ved_pretend_gzip(struct req *req, enum vdp_action act, void **priv, const void *pv, ssize_t l) { uint8_t buf1[5], buf2[5]; @@ -427,8 +427,8 @@ ESI_Deliver(struct req *req) * Include an object in a gzip'ed ESI object delivery */ -void -ESI_DeliverChild(struct req *req) +static void +ved_stripgzip(struct req *req) { ssize_t start, last, stop, lpad; ssize_t l; @@ -616,3 +616,26 @@ ESI_DeliverChild(struct req *req) req->crc = crc32_combine(req->crc, icrc, ilen); req->l_crc += ilen; } + +void +ESI_DeliverChild(struct req *req, struct busyobj *bo) +{ + int i; + + req->res_mode |= RES_ESI_CHILD; + i = ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED); + if (req->gzip_resp && i && !(req->res_mode & RES_ESI)) { + if (bo != NULL) + VBO_waitstate(bo, BOS_FINISHED); + ved_stripgzip(req); + } else { + if (req->gzip_resp && !i) + VDP_push(req, ved_pretend_gzip, NULL, 0); + else if (!req->gzip_resp && i) + VDP_push(req, VDP_gunzip, NULL, 0); + + (void)VDP_DeliverObj(req); + } + (void)VDP_bytes(req, VDP_FLUSH, NULL, 0); + VDP_close(req); +} diff --git a/bin/varnishd/cache/cache_filter.h b/bin/varnishd/cache/cache_filter.h index 859b1e5..e6d9274 100644 --- a/bin/varnishd/cache/cache_filter.h +++ b/bin/varnishd/cache/cache_filter.h @@ -111,5 +111,3 @@ void VDP_close(struct req *req); enum objiter_status VDP_DeliverObj(struct req *req); vdp_bytes VDP_gunzip; -vdp_bytes VED_pretend_gzip; - diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 32bf944..0836f0e 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -195,7 +195,6 @@ V1D_Deliver(struct req *req, struct busyobj *bo) { const char *r; enum objiter_status ois; - int i; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); @@ -207,22 +206,7 @@ V1D_Deliver(struct req *req, struct busyobj *bo) req->res_mode |= RES_ESI; if (req->esi_level > 0) { - req->res_mode |= RES_ESI_CHILD; - i = ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED); - if (req->gzip_resp && i && !(req->res_mode & RES_ESI)) { - if (bo != NULL) - VBO_waitstate(bo, BOS_FINISHED); - ESI_DeliverChild(req); - } else { - if (req->gzip_resp && !i) - VDP_push(req, VED_pretend_gzip, NULL, 0); - else if (!req->gzip_resp && i) - VDP_push(req, VDP_gunzip, NULL, 0); - - (void)VDP_DeliverObj(req); - } - (void)VDP_bytes(req, VDP_FLUSH, NULL, 0); - VDP_close(req); + ESI_DeliverChild(req, bo); return; } From nils.goroll at uplex.de Mon Oct 27 20:03:00 2014 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 27 Oct 2014 21:03:00 +0100 Subject: [master] eeee484 Avoid assertion failure in VCC if the first symbol encountered in VCL is not an ID Message-ID: commit eeee484d56b3c92348e1b1b8ff6db424938b9bec Author: Nils Goroll Date: Mon Oct 27 21:01:55 2014 +0100 Avoid assertion failure in VCC if the first symbol encountered in VCL is not an ID Trivial test VCL: C{ }C; vcl 4.0; diff --git a/lib/libvcc/vcc_parse.c b/lib/libvcc/vcc_parse.c index 9412a58..e235090 100644 --- a/lib/libvcc/vcc_parse.c +++ b/lib/libvcc/vcc_parse.c @@ -338,7 +338,7 @@ vcc_Parse(struct vcc *tl) { struct toplev *tp; - if (!vcc_IdIs(tl->t, "vcl")) { + if (tl->t->tok != ID || !vcc_IdIs(tl->t, "vcl")) { VSB_printf(tl->sb, "VCL version declaration missing\n" "Update your VCL to Version 4 syntax, and add\n" From phk at FreeBSD.org Mon Oct 27 20:21:28 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Oct 2014 21:21:28 +0100 Subject: [master] c42b0d4 Reorder and simplify the logic for determining how we deliver the body (if at all) Message-ID: commit c42b0d41cbf06dd15e79f2c195bcb092a86d255c Author: Poul-Henning Kamp Date: Mon Oct 27 19:56:07 2014 +0000 Reorder and simplify the logic for determining how we deliver the body (if at all) diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 0836f0e..f887a63 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -190,6 +190,7 @@ v1d_dorange(struct req *req, struct busyobj *bo, const char *r) /*-------------------------------------------------------------------- */ + void V1D_Deliver(struct req *req, struct busyobj *bo) { @@ -201,39 +202,41 @@ V1D_Deliver(struct req *req, struct busyobj *bo) req->res_mode = 0; + /* + * Determine ESI status first. Not dependent on wantbody, because + * we want ESI to supress C-L in HEAD too. + */ if (!req->disable_esi && ObjGetattr(req->wrk, req->objcore, OA_ESIDATA, NULL) != NULL) req->res_mode |= RES_ESI; + /* + * ESI-childen don't care about headers -> early escape + */ if (req->esi_level > 0) { ESI_DeliverChild(req, bo); return; } if (req->res_mode & RES_ESI) { - /* nothing */ + RFC2616_Weaken_Etag(req->resp); + http_Unset(req->resp, H_Content_Length); } else if (http_IsStatus(req->resp, 304)) { - req->res_mode &= ~RES_LEN; http_Unset(req->resp, H_Content_Length); req->wantbody = 0; - } else if (bo != NULL) { - /* Streaming, decide CHUNKED/EOF later */ - } else if ((req->objcore->flags & OC_F_PASS) && !req->wantbody) { - /* - * if we pass a HEAD the C-L header may already be in the - * object and it will not match the actual storage length - * which is zero. - * Hand that C-L header back to client. - */ - req->res_mode |= RES_LEN; - } else { - req->res_mode |= RES_LEN; - http_Unset(req->resp, H_Content_Length); + } else if (bo == NULL && + !http_GetHdr(req->resp, H_Content_Length, NULL)) { http_PrintfHeader(req->resp, "Content-Length: %ju", (uintmax_t)ObjGetLen( req->wrk, req->objcore)); } + if (cache_param->http_range_support && http_IsStatus(req->resp, 200)) { + http_SetHeader(req->resp, "Accept-Ranges: bytes"); + if (req->wantbody && http_GetHdr(req->http, H_Range, &r)) + v1d_dorange(req, bo, r); + } + if (cache_param->http_gzip_support && ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED) && !RFC2616_Req_Gzip(req->http)) { @@ -242,66 +245,47 @@ V1D_Deliver(struct req *req, struct busyobj *bo) * XXX: we could cache that, but would still deliver * XXX: with multiple writes because of the gunzip buffer */ - req->res_mode &= ~RES_LEN; req->res_mode |= RES_GUNZIP; + http_Unset(req->resp, H_Content_Length); + http_Unset(req->resp, H_Content_Encoding); + VDP_push(req, VDP_gunzip, NULL, 0); } - if (!(req->res_mode & (RES_LEN|RES_CHUNKED|RES_EOF))) { - /* We havn't chosen yet, do so */ - if (!req->wantbody) { - /* Nothing */ - } else if (req->http->protover >= 11) { + if (http_GetHdr(req->resp, H_Content_Length, NULL)) + req->res_mode |= RES_LEN; + + if (req->wantbody && !(req->res_mode & RES_LEN)) { + if (req->http->protover >= 11) { req->res_mode |= RES_CHUNKED; + http_SetHeader(req->resp, "Transfer-Encoding: chunked"); } else { req->res_mode |= RES_EOF; req->doclose = SC_TX_EOF; } } - VSLb(req->vsl, SLT_Debug, "RES_MODE %x", req->res_mode); - - if (!(req->res_mode & RES_LEN)) - http_Unset(req->resp, H_Content_Length); - - if (req->res_mode & RES_GUNZIP) - http_Unset(req->resp, H_Content_Encoding); - if (req->res_mode & RES_CHUNKED) - http_SetHeader(req->resp, "Transfer-Encoding: chunked"); - - if (req->res_mode & RES_ESI) - RFC2616_Weaken_Etag(req->resp); + VSLb(req->vsl, SLT_Debug, "RES_MODE %x", req->res_mode); http_SetHeader(req->resp, req->doclose ? "Connection: close" : "Connection: keep-alive"); - if ( - req->wantbody && - cache_param->http_range_support && - http_IsStatus(req->resp, 200)) { - http_SetHeader(req->resp, "Accept-Ranges: bytes"); - if (http_GetHdr(req->http, H_Range, &r)) - v1d_dorange(req, bo, r); - } - - if (req->res_mode & RES_GUNZIP) - VDP_push(req, VDP_gunzip, NULL, 0); - VDP_push(req, v1d_bytes, NULL, 1); V1L_Reserve(req->wrk, req->ws, &req->sp->fd, req->vsl, req->t_prev); req->acct.resp_hdrbytes += HTTP1_Write(req->wrk, req->resp, HTTP1_Resp); - if (req->res_mode & RES_CHUNKED) - V1L_Chunked(req->wrk); - ois = OIS_DONE; - if (req->wantbody) + if (req->wantbody) { + if (req->res_mode & RES_CHUNKED) + V1L_Chunked(req->wrk); + ois = VDP_DeliverObj(req); - (void)VDP_bytes(req, VDP_FLUSH, NULL, 0); + (void)VDP_bytes(req, VDP_FLUSH, NULL, 0); - if (ois == OIS_DONE && (req->res_mode & RES_CHUNKED)) - V1L_EndChunk(req->wrk); + if (ois == OIS_DONE && (req->res_mode & RES_CHUNKED)) + V1L_EndChunk(req->wrk); + } if ((V1L_FlushRelease(req->wrk) || ois != OIS_DONE) && req->sp->fd >= 0) SES_Close(req->sp, SC_REM_CLOSE); diff --git a/bin/varnishtest/tests/r00801.vtc b/bin/varnishtest/tests/r00801.vtc index f538d7f..ca1a567 100644 --- a/bin/varnishtest/tests/r00801.vtc +++ b/bin/varnishtest/tests/r00801.vtc @@ -13,6 +13,7 @@ varnish v1 -vcl+backend { sub vcl_recv { return (pass); } sub vcl_backend_response { set beresp.do_stream = false; + unset beresp.http.content-length; } } -start From phk at FreeBSD.org Mon Oct 27 20:21:28 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Oct 2014 21:21:28 +0100 Subject: [master] 6503425 Move Range: processing to its own source file Message-ID: commit 65034251f59181ac35f40ef06926e98951b3cd5b Author: Poul-Henning Kamp Date: Mon Oct 27 20:21:11 2014 +0000 Move Range: processing to its own source file diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index a347119..a71e2a6 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -36,6 +36,7 @@ varnishd_SOURCES = \ cache/cache_req_body.c \ cache/cache_req_fsm.c \ cache/cache_rfc2616.c \ + cache/cache_range.c \ cache/cache_session.c \ cache/cache_shmlog.c \ cache/cache_vary.c \ diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index eaea802..1e0cec2 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -957,6 +957,9 @@ unsigned V1L_Flush(const struct worker *w); unsigned V1L_FlushRelease(struct worker *w); unsigned V1L_Write(const struct worker *w, const void *ptr, int len); +/* cache_range.c [VRG] */ +void VRG_dorange(struct req *req, struct busyobj *bo, const char *r); + /* cache_session.c [SES] */ void SES_Close(struct sess *sp, enum sess_close reason); void SES_Delete(struct sess *sp, enum sess_close reason, double now); diff --git a/bin/varnishd/cache/cache_range.c b/bin/varnishd/cache/cache_range.c new file mode 100644 index 0000000..ed08bf5 --- /dev/null +++ b/bin/varnishd/cache/cache_range.c @@ -0,0 +1,163 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2014 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 "cache/cache.h" +#include "cache/cache_filter.h" + +#include "vct.h" + +/*--------------------------------------------------------------------*/ + +struct vrg_priv { + unsigned magic; +#define VRG_PRIV_MAGIC 0xb886e711 + ssize_t range_low; + ssize_t range_high; + ssize_t range_off; +}; + +static int __match_proto__(vdp_bytes) +vrg_range_bytes(struct req *req, enum vdp_action act, void **priv, + const void *ptr, ssize_t len) +{ + int retval = 0; + ssize_t l; + const char *p = ptr; + struct vrg_priv *vrg_priv; + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + if (act == VDP_INIT) + return (0); + if (act == VDP_FINI) { + *priv = NULL; + return (0); + } + CAST_OBJ_NOTNULL(vrg_priv, *priv, VRG_PRIV_MAGIC); + l = vrg_priv->range_low - vrg_priv->range_off; + if (l > 0) { + if (l > len) + l = len; + vrg_priv->range_off += l; + p += l; + len -= l; + } + l = vrg_priv->range_high - vrg_priv->range_off; + if (l > len) + l = len; + if (l > 0) + retval = VDP_bytes(req, act, p, l); + else if (act > VDP_NULL) + retval = VDP_bytes(req, act, p, 0); + vrg_priv->range_off += len; + return (retval); +} + +/*--------------------------------------------------------------------*/ + +void +VRG_dorange(struct req *req, struct busyobj *bo, const char *r) +{ + ssize_t len, low, high, has_low; + struct vrg_priv *vrg_priv; + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); + assert(http_IsStatus(req->resp, 200)); + + /* We must snapshot the length if we're streaming from the backend */ + if (bo != NULL) + len = VBO_waitlen(req->wrk, bo, -1); + else + len = ObjGetLen(req->wrk, req->objcore); + + if (strncmp(r, "bytes=", 6)) + return; + r += 6; + + /* The low end of range */ + has_low = low = 0; + if (!vct_isdigit(*r) && *r != '-') + return; + while (vct_isdigit(*r)) { + has_low = 1; + low *= 10; + low += *r - '0'; + r++; + } + + if (low >= len) + return; + + if (*r != '-') + return; + r++; + + /* The high end of range */ + if (vct_isdigit(*r)) { + high = 0; + while (vct_isdigit(*r)) { + high *= 10; + high += *r - '0'; + r++; + } + if (!has_low) { + low = len - high; + if (low < 0) + low = 0; + high = len - 1; + } + } else + high = len - 1; + if (*r != '\0') + return; + + if (high >= len) + high = len - 1; + + if (low > high) + return; + + http_PrintfHeader(req->resp, "Content-Range: bytes %jd-%jd/%jd", + (intmax_t)low, (intmax_t)high, (intmax_t)len); + http_Unset(req->resp, H_Content_Length); + if (req->res_mode & RES_LEN) + http_PrintfHeader(req->resp, "Content-Length: %jd", + (intmax_t)(1 + high - low)); + http_PutResponse(req->resp, "HTTP/1.1", 206, NULL); + + vrg_priv = WS_Alloc(req->ws, sizeof *vrg_priv); + XXXAN(vrg_priv); + INIT_OBJ(vrg_priv, VRG_PRIV_MAGIC); + vrg_priv->range_off = 0; + vrg_priv->range_low = low; + vrg_priv->range_high = high + 1; + VDP_push(req, vrg_range_bytes, vrg_priv, 0); +} diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index f887a63..4b09178 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -32,8 +32,6 @@ #include "cache/cache.h" #include "cache/cache_filter.h" -#include "vct.h" - /*--------------------------------------------------------------------*/ static int __match_proto__(vdp_bytes) @@ -59,135 +57,6 @@ v1d_bytes(struct req *req, enum vdp_action act, void **priv, return (0); } -/*--------------------------------------------------------------------*/ - -struct v1rp { - unsigned magic; -#define V1RP_MAGIC 0xb886e711 - ssize_t range_low; - ssize_t range_high; - ssize_t range_off; -}; - -static int __match_proto__(vdp_bytes) -v1d_range_bytes(struct req *req, enum vdp_action act, void **priv, - const void *ptr, ssize_t len) -{ - int retval = 0; - ssize_t l; - const char *p = ptr; - struct v1rp *v1rp; - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - if (act == VDP_INIT) - return (0); - if (act == VDP_FINI) { - *priv = NULL; - return (0); - } - CAST_OBJ_NOTNULL(v1rp, *priv, V1RP_MAGIC); - l = v1rp->range_low - v1rp->range_off; - if (l > 0) { - if (l > len) - l = len; - v1rp->range_off += l; - p += l; - len -= l; - } - l = v1rp->range_high - v1rp->range_off; - if (l > len) - l = len; - if (l > 0) - retval = VDP_bytes(req, act, p, l); - else if (act > VDP_NULL) - retval = VDP_bytes(req, act, p, 0); - v1rp->range_off += len; - return (retval); -} - -/*--------------------------------------------------------------------*/ - - -static void -v1d_dorange(struct req *req, struct busyobj *bo, const char *r) -{ - ssize_t len, low, high, has_low; - struct v1rp *v1rp; - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); - assert(http_IsStatus(req->resp, 200)); - - /* We must snapshot the length if we're streaming from the backend */ - if (bo != NULL) - len = VBO_waitlen(req->wrk, bo, -1); - else - len = ObjGetLen(req->wrk, req->objcore); - - if (strncmp(r, "bytes=", 6)) - return; - r += 6; - - /* The low end of range */ - has_low = low = 0; - if (!vct_isdigit(*r) && *r != '-') - return; - while (vct_isdigit(*r)) { - has_low = 1; - low *= 10; - low += *r - '0'; - r++; - } - - if (low >= len) - return; - - if (*r != '-') - return; - r++; - - /* The high end of range */ - if (vct_isdigit(*r)) { - high = 0; - while (vct_isdigit(*r)) { - high *= 10; - high += *r - '0'; - r++; - } - if (!has_low) { - low = len - high; - if (low < 0) - low = 0; - high = len - 1; - } - } else - high = len - 1; - if (*r != '\0') - return; - - if (high >= len) - high = len - 1; - - if (low > high) - return; - - http_PrintfHeader(req->resp, "Content-Range: bytes %jd-%jd/%jd", - (intmax_t)low, (intmax_t)high, (intmax_t)len); - http_Unset(req->resp, H_Content_Length); - if (req->res_mode & RES_LEN) - http_PrintfHeader(req->resp, "Content-Length: %jd", - (intmax_t)(1 + high - low)); - http_PutResponse(req->resp, "HTTP/1.1", 206, NULL); - - v1rp = WS_Alloc(req->ws, sizeof *v1rp); - XXXAN(v1rp); - INIT_OBJ(v1rp, V1RP_MAGIC); - v1rp->range_off = 0; - v1rp->range_low = low; - v1rp->range_high = high + 1; - VDP_push(req, v1d_range_bytes, v1rp, 0); -} - /*-------------------------------------------------------------------- */ @@ -234,7 +103,7 @@ V1D_Deliver(struct req *req, struct busyobj *bo) if (cache_param->http_range_support && http_IsStatus(req->resp, 200)) { http_SetHeader(req->resp, "Accept-Ranges: bytes"); if (req->wantbody && http_GetHdr(req->http, H_Range, &r)) - v1d_dorange(req, bo, r); + VRG_dorange(req, bo, r); } if (cache_param->http_gzip_support && From phk at FreeBSD.org Tue Oct 28 11:42:18 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 28 Oct 2014 12:42:18 +0100 Subject: [master] 418cea5 Add busyobj as argument to vdir->healthy() Message-ID: commit 418cea5d6c32f14aaa16a7d0b58b8e8a6e287bb9 Author: Poul-Henning Kamp Date: Tue Oct 28 07:21:23 2014 +0000 Add busyobj as argument to vdir->healthy() diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 4ddc3ca..0befb29 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -370,12 +370,14 @@ vbe_dir_getfd(const struct director *d, struct busyobj *bo) } static unsigned __match_proto__(vdi_healthy_f) -vbe_dir_healthy(const struct director *d, double *changed) +vbe_dir_healthy(const struct director *d, const struct busyobj *bo, + double *changed) { struct vbe_dir *vs; struct backend *be; CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); + CHECK_OBJ_ORNULL(bo, BUSYOBJ_MAGIC); CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC); be = vs->backend; CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC); diff --git a/bin/varnishd/cache/cache_director.c b/bin/varnishd/cache/cache_director.c index c79b3a8..0df939e 100644 --- a/bin/varnishd/cache/cache_director.c +++ b/bin/varnishd/cache/cache_director.c @@ -145,12 +145,12 @@ VDI_GetFd(const struct director *d, struct worker *wrk, struct busyobj *bo) */ int -VDI_Healthy(const struct director *d) +VDI_Healthy(const struct director *d, const struct busyobj *bo) { CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); AN(d->healthy); - return (d->healthy(d, NULL)); + return (d->healthy(d, bo, NULL)); } /* Get suckaddr ------------------------------------------------------*/ diff --git a/bin/varnishd/cache/cache_director.h b/bin/varnishd/cache/cache_director.h index cef951d..e904686 100644 --- a/bin/varnishd/cache/cache_director.h +++ b/bin/varnishd/cache/cache_director.h @@ -43,7 +43,8 @@ */ typedef int vdi_getfd_f(const struct director *, struct busyobj *); -typedef unsigned vdi_healthy_f(const struct director *, double *changed); +typedef unsigned vdi_healthy_f(const struct director *, const struct busyobj *, + double *changed); typedef const struct director *vdi_resolve_f(const struct director *, struct worker *, struct busyobj *); typedef int vdi_gethdrs_f(const struct director *, struct worker *, @@ -77,7 +78,7 @@ int VDI_GetBody(const struct director *d, struct worker *wrk, void VDI_Finish(const struct director *d, struct worker *wrk, struct busyobj *bo); int VDI_GetFd(const struct director *d, struct worker *wrk, struct busyobj *); -int VDI_Healthy(const struct director *); +int VDI_Healthy(const struct director *, const struct busyobj *); struct suckaddr *VDI_Suckaddr(const struct director *d, struct worker *wrk, struct busyobj *bo); void VDI_AddHostHeader(struct http *to, const struct vbc *vbc); diff --git a/lib/libvmod_directors/fall_back.c b/lib/libvmod_directors/fall_back.c index a3d2a9c..25b05dd 100644 --- a/lib/libvmod_directors/fall_back.c +++ b/lib/libvmod_directors/fall_back.c @@ -45,12 +45,13 @@ struct vmod_directors_fallback { }; static unsigned __match_proto__(vdi_healthy) -vmod_fallback_healthy(const struct director *dir, double *changed) +vmod_fallback_healthy(const struct director *dir, const struct busyobj *bo, + double *changed) { struct vmod_directors_fallback *rr; CAST_OBJ_NOTNULL(rr, dir->priv, VMOD_DIRECTORS_FALLBACK_MAGIC); - return (vdir_any_healthy(rr->vd, changed)); + return (vdir_any_healthy(rr->vd, bo, changed)); } static const struct director * __match_proto__(vdi_resolve_f) @@ -69,7 +70,7 @@ vmod_fallback_resolve(const struct director *dir, struct worker *wrk, for (u = 0; u < rr->vd->n_backend; u++) { be = rr->vd->backend[u]; CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC); - if (be->healthy(be, NULL)) + if (be->healthy(be, bo, NULL)) break; } vdir_unlock(rr->vd); diff --git a/lib/libvmod_directors/random.c b/lib/libvmod_directors/random.c index a693bc6..c368392 100644 --- a/lib/libvmod_directors/random.c +++ b/lib/libvmod_directors/random.c @@ -50,12 +50,13 @@ struct vmod_directors_random { }; static unsigned __match_proto__(vdi_healthy) -vmod_random_healthy(const struct director *dir, double *changed) +vmod_random_healthy(const struct director *dir, const struct busyobj *bo, + double *changed) { struct vmod_directors_random *rr; CAST_OBJ_NOTNULL(rr, dir->priv, VMOD_DIRECTORS_RANDOM_MAGIC); - return (vdir_any_healthy(rr->vd, changed)); + return (vdir_any_healthy(rr->vd, bo, changed)); } static const struct director * __match_proto__(vdi_resolve_f) diff --git a/lib/libvmod_directors/round_robin.c b/lib/libvmod_directors/round_robin.c index 39f6b3d..26668ec 100644 --- a/lib/libvmod_directors/round_robin.c +++ b/lib/libvmod_directors/round_robin.c @@ -46,12 +46,13 @@ struct vmod_directors_round_robin { }; static unsigned __match_proto__(vdi_healthy) -vmod_rr_healthy(const struct director *dir, double *changed) +vmod_rr_healthy(const struct director *dir, const struct busyobj *bo, + double *changed) { struct vmod_directors_round_robin *rr; CAST_OBJ_NOTNULL(rr, dir->priv, VMOD_DIRECTORS_ROUND_ROBIN_MAGIC); - return (vdir_any_healthy(rr->vd, changed)); + return (vdir_any_healthy(rr->vd, bo, changed)); } static const struct director * __match_proto__(vdi_resolve_f) @@ -72,7 +73,7 @@ vmod_rr_resolve(const struct director *dir, struct worker *wrk, be = rr->vd->backend[rr->nxt]; rr->nxt++; CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC); - if (be->healthy(be, NULL)) + if (be->healthy(be, bo, NULL)) break; } vdir_unlock(rr->vd); diff --git a/lib/libvmod_directors/vdir.c b/lib/libvmod_directors/vdir.c index 3488026..0ed64ec 100644 --- a/lib/libvmod_directors/vdir.c +++ b/lib/libvmod_directors/vdir.c @@ -129,7 +129,7 @@ vdir_add_backend(struct vdir *vd, VCL_BACKEND be, double weight) } unsigned -vdir_any_healthy(struct vdir *vd, double *changed) +vdir_any_healthy(struct vdir *vd, const struct busyobj *bo, double *changed) { unsigned retval = 0; VCL_BACKEND be; @@ -137,13 +137,14 @@ vdir_any_healthy(struct vdir *vd, double *changed) double c; CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC); + CHECK_OBJ_ORNULL(bo, BUSYOBJ_MAGIC); vdir_lock(vd); if (changed != NULL) *changed = 0; for (u = 0; u < vd->n_backend; u++) { be = vd->backend[u]; CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC); - retval = be->healthy(be, &c); + retval = be->healthy(be, bo, &c); if (changed != NULL && c > *changed) *changed = c; if (retval) @@ -190,7 +191,7 @@ vdir_pick_be(struct vdir *vd, double w, unsigned nloops) u = vdir_pick_by_weight(vd, w * tw, vbm); be = vd->backend[u]; CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC); - if (be->healthy(be, NULL)) + if (be->healthy(be, NULL, NULL)) break; if (l == 0) { vbm = vd->vbm; diff --git a/lib/libvmod_directors/vdir.h b/lib/libvmod_directors/vdir.h index 5afb754..0d21e2f 100644 --- a/lib/libvmod_directors/vdir.h +++ b/lib/libvmod_directors/vdir.h @@ -46,6 +46,7 @@ void vdir_new(struct vdir **vdp, const char *vcl_name, vdi_healthy_f *healthy, void vdir_delete(struct vdir **vdp); void vdir_lock(struct vdir *vd); void vdir_unlock(struct vdir *vd); -unsigned vdir_add_backend(struct vdir *vd, VCL_BACKEND be, double weight); -unsigned vdir_any_healthy(struct vdir *vd, double *changed); -VCL_BACKEND vdir_pick_be(struct vdir *vd, double w, unsigned nloops); +unsigned vdir_add_backend(struct vdir *, VCL_BACKEND be, double weight); +unsigned vdir_any_healthy(struct vdir *, const struct busyobj *, + double *changed); +VCL_BACKEND vdir_pick_be(struct vdir *, double w, unsigned nloops); diff --git a/lib/libvmod_std/vmod_std.c b/lib/libvmod_std/vmod_std.c index 792f04b..35c417b 100644 --- a/lib/libvmod_std/vmod_std.c +++ b/lib/libvmod_std/vmod_std.c @@ -193,7 +193,7 @@ vmod_healthy(VRT_CTX, VCL_BACKEND be) if (be == NULL) return (0); CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC); - return (VDI_Healthy(be)); + return (VDI_Healthy(be, ctx->bo)); } VCL_INT __match_proto__(td_std_port) From phk at FreeBSD.org Tue Oct 28 11:42:18 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 28 Oct 2014 12:42:18 +0100 Subject: [master] af1b857 More VDP polishing Message-ID: commit af1b857ce703a58ce769d1fe6c6c991510a98e27 Author: Poul-Henning Kamp Date: Tue Oct 28 07:43:47 2014 +0000 More VDP polishing diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index c32f760..583abc5 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -289,6 +289,8 @@ VDP_gunzip(struct req *req, enum vdp_action act, void **priv, return (-1); VGZ_Obuf(vg, vg->m_buf, vg->m_sz); *priv = vg; + http_Unset(req->resp, H_Content_Length); + http_Unset(req->resp, H_Content_Encoding); return (0); } diff --git a/bin/varnishd/cache/cache_range.c b/bin/varnishd/cache/cache_range.c index ed08bf5..2ba4587 100644 --- a/bin/varnishd/cache/cache_range.c +++ b/bin/varnishd/cache/cache_range.c @@ -148,9 +148,8 @@ VRG_dorange(struct req *req, struct busyobj *bo, const char *r) http_PrintfHeader(req->resp, "Content-Range: bytes %jd-%jd/%jd", (intmax_t)low, (intmax_t)high, (intmax_t)len); http_Unset(req->resp, H_Content_Length); - if (req->res_mode & RES_LEN) - http_PrintfHeader(req->resp, "Content-Length: %jd", - (intmax_t)(1 + high - low)); + http_PrintfHeader(req->resp, "Content-Length: %jd", + (intmax_t)(1 + high - low)); http_PutResponse(req->resp, "HTTP/1.1", 206, NULL); vrg_priv = WS_Alloc(req->ws, sizeof *vrg_priv); @@ -159,5 +158,5 @@ VRG_dorange(struct req *req, struct busyobj *bo, const char *r) vrg_priv->range_off = 0; vrg_priv->range_low = low; vrg_priv->range_high = high + 1; - VDP_push(req, vrg_range_bytes, vrg_priv, 0); + VDP_push(req, vrg_range_bytes, vrg_priv, 1); } diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 4b09178..c1f3b91 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -100,12 +100,6 @@ V1D_Deliver(struct req *req, struct busyobj *bo) req->wrk, req->objcore)); } - if (cache_param->http_range_support && http_IsStatus(req->resp, 200)) { - http_SetHeader(req->resp, "Accept-Ranges: bytes"); - if (req->wantbody && http_GetHdr(req->http, H_Range, &r)) - VRG_dorange(req, bo, r); - } - if (cache_param->http_gzip_support && ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED) && !RFC2616_Req_Gzip(req->http)) { @@ -115,11 +109,20 @@ V1D_Deliver(struct req *req, struct busyobj *bo) * XXX: with multiple writes because of the gunzip buffer */ req->res_mode |= RES_GUNZIP; - http_Unset(req->resp, H_Content_Length); - http_Unset(req->resp, H_Content_Encoding); VDP_push(req, VDP_gunzip, NULL, 0); } + /* + * Range comes after the others and pushes on bottom because it + * can generate a correct C-L header. + */ + if (cache_param->http_range_support && http_IsStatus(req->resp, 200)) { + http_SetHeader(req->resp, "Accept-Ranges: bytes"); + if (req->wantbody && http_GetHdr(req->http, H_Range, &r)) + VRG_dorange(req, bo, r); + } + + if (http_GetHdr(req->resp, H_Content_Length, NULL)) req->res_mode |= RES_LEN; From daghf at varnish-software.com Tue Oct 28 12:39:56 2014 From: daghf at varnish-software.com (Dag Haavi Finstad) Date: Tue, 28 Oct 2014 13:39:56 +0100 Subject: [master] 606906c Prefer exact matches in varnishadm backend.set_health. Message-ID: commit 606906c8d52dd2cc262e1ea0adb11f507d66609f Author: Dag Haavi Finstad Date: Tue Oct 28 13:34:06 2014 +0100 Prefer exact matches in varnishadm backend.set_health. Fixes: #1349 diff --git a/bin/varnishd/cache/cache_backend_cfg.c b/bin/varnishd/cache/cache_backend_cfg.c index dbe07c1..5cf077e 100644 --- a/bin/varnishd/cache/cache_backend_cfg.c +++ b/bin/varnishd/cache/cache_backend_cfg.c @@ -288,7 +288,7 @@ backend_find(struct cli *cli, const char *matcher, bf_func *func, void *priv) const char *port_b = NULL; ssize_t port_l = 0; int found = 0; - int i; + int i, j; name_b = matcher; if (matcher != NULL) { @@ -342,22 +342,33 @@ backend_find(struct cli *cli, const char *matcher, bf_func *func, void *priv) } } } - VTAILQ_FOREACH(b, &backends, list) { - CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); - if (port_b != NULL && strncmp(b->port, port_b, port_l) != 0) - continue; - if (name_b != NULL && strncmp(b->vcl_name, name_b, name_l) != 0) - continue; - if (ip_b != NULL && - (b->ipv4_addr == NULL || - strncmp(b->ipv4_addr, ip_b, ip_l)) && - (b->ipv6_addr == NULL || - strncmp(b->ipv6_addr, ip_b, ip_l))) + + for (j = 0; j < 2; ++j) { + if (j == 0 && name_b == NULL) continue; - found++; - i = func(cli, b, priv); - if (i) - return(i); + VTAILQ_FOREACH(b, &backends, list) { + CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); + if (port_b != NULL && + strncmp(b->port, port_b, port_l) != 0) + continue; + if (name_b != NULL && + strncmp(b->vcl_name, name_b, name_l) != 0) + continue; + if (j == 0 && b->vcl_name[name_l] != '\0') + continue; + if (ip_b != NULL && + (b->ipv4_addr == NULL || + strncmp(b->ipv4_addr, ip_b, ip_l)) && + (b->ipv6_addr == NULL || + strncmp(b->ipv6_addr, ip_b, ip_l))) + continue; + found++; + i = func(cli, b, priv); + if (i) + return(i); + if (j == 0) + return (1); + } } return (found); } diff --git a/bin/varnishtest/tests/r01349.vtc b/bin/varnishtest/tests/r01349.vtc new file mode 100644 index 0000000..78c64ba --- /dev/null +++ b/bin/varnishtest/tests/r01349.vtc @@ -0,0 +1,66 @@ +varnishtest "Exact matching for varnishadm backend.set_health" + +server s1 -repeat 2 { + rxreq + txresp -hdr "Backend: b1" +} -start + +server s2 -repeat 2 { + rxreq + txresp -hdr "Backend: b" +} -start + +varnish v1 -vcl { + backend b1 { + .host = "${s1_addr}"; + .port = "${s1_port}"; + } + + backend b { + .host = "${s2_addr}"; + .port = "${s2_port}"; + } + + sub vcl_recv { + return(pass); + } + + sub vcl_backend_fetch { + if (bereq.http.backend == "b1") { + set bereq.backend = b1; + } + else { + set bereq.backend = b; + } + } + +} -start + +varnish v1 -cliok "backend.list b" + +client c1 { + txreq -hdr "Backend: b1" + rxresp + expect resp.status == 200 + expect resp.http.backend == "b1" + + txreq -hdr "Backend: b" + rxresp + expect resp.status == 200 + expect resp.http.backend == "b" +} -run + +varnish v1 -cliok "backend.set_health b sick" + +client c1 { + txreq -hdr "Backend: b1" + rxresp + expect resp.status == 200 + expect resp.http.backend == "b1" + + txreq -hdr "Backend: b" + rxresp + expect resp.status == 503 +} -run + +varnish v1 -clierr 106 "backend.set_health b(1.2.3.4:) healthy" From daghf at varnish-software.com Tue Oct 28 13:10:51 2014 From: daghf at varnish-software.com (Dag Haavi Finstad) Date: Tue, 28 Oct 2014 14:10:51 +0100 Subject: [master] 2be86e6 Document current behavior of backend.set_health Message-ID: commit 2be86e6e1926763ec23a50465144e58a26a32e59 Author: Dag Haavi Finstad Date: Tue Oct 28 14:05:57 2014 +0100 Document current behavior of backend.set_health diff --git a/doc/sphinx/reference/varnish-cli.rst b/doc/sphinx/reference/varnish-cli.rst index 2e17c2e..ca2fc8c 100644 --- a/doc/sphinx/reference/varnish-cli.rst +++ b/doc/sphinx/reference/varnish-cli.rst @@ -132,7 +132,11 @@ backend.list List all backends backend.set_health matcher state - Set health status on a backend + Set health status on a backend. The matcher expression can be a + backend name or a parenthesized "(IP:port)" expression, or both. All + fields are optional. If no exact matching backend is found, partial + matching will be attempted based on the provided name, IP and port + fields. ban [&& ]... All objects where the all the conditions match will be marked obsolete. From martin at varnish-software.com Tue Oct 28 14:30:19 2014 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 28 Oct 2014 15:30:19 +0100 Subject: [master] 389c050 Don't log logexpect error level from within the callback routine Message-ID: commit 389c05031b7464a99305d2624f811054f3ef7b0f Author: Martin Blix Grydeland Date: Tue Oct 28 15:14:26 2014 +0100 Don't log logexpect error level from within the callback routine vtc_log does a pthread_exit when reporting an error condition. When this happened from within the API callback function for logexpect, the API internal data structures were left in an inconsistent state, causing asserts do be thrown during VSLQ_Delete(). Signal the failed expect back from the callback function and do the vtc_log error level after the API function has returned. diff --git a/bin/varnishtest/vtc_logexp.c b/bin/varnishtest/vtc_logexp.c index 86de1ea..cbf11d6 100644 --- a/bin/varnishtest/vtc_logexp.c +++ b/bin/varnishtest/vtc_logexp.c @@ -183,7 +183,7 @@ logexp_dispatch(struct VSL_data *vsl, struct VSL_transaction * const pt[], struct VSL_transaction *t; int i; int ok, skip; - int vxid, tag, type, len, lvl; + int vxid, tag, type, len; const char *legend, *data; (void)vsl; @@ -228,22 +228,19 @@ logexp_dispatch(struct VSL_data *vsl, struct VSL_transaction * const pt[], le->test->skip_max > le->skip_cnt)) skip = 1; - if (ok) { - lvl = 4; + if (ok) legend = "ok"; - } else if (skip) { - lvl = 4; + else if (skip) legend = NULL; - } else { - lvl = 0; + else legend = "err"; - } type = VSL_CLIENT(t->c->rec.ptr) ? 'c' : VSL_BACKEND(t->c->rec.ptr) ? 'b' : '-'; if (legend != NULL) - vtc_log(le->vl, lvl, "%3s| %10u %-15s %c %.*s", - legend, vxid, VSL_tags[tag], type, len, data); + vtc_log(le->vl, 4, "%3s| %10u %-15s %c %.*s", + legend, vxid, VSL_tags[tag], type, len, + data); if (ok) { le->vxid_last = vxid; @@ -253,9 +250,12 @@ logexp_dispatch(struct VSL_data *vsl, struct VSL_transaction * const pt[], if (le->test == NULL) /* End of test script */ return (1); - } - if (skip) + } else if (skip) le->skip_cnt++; + else { + /* Signal fail */ + return (2); + } } } @@ -281,9 +281,11 @@ logexp_thread(void *priv) logexp_next(le); while (le->test) { i = VSLQ_Dispatch(le->vslq, logexp_dispatch, le); - if (i < 0) - vtc_log(le->vl, 0, "dispatch: %d", i); - if (i == 0 && le->test) + if (i == 2) + vtc_log(le->vl, 0, "bad| expectation failed"); + else if (i < 0) + vtc_log(le->vl, 0, "bad| dispatch failed (%d)", i); + else if (i == 0 && le->test) VTIM_sleep(0.01); } vtc_log(le->vl, 4, "end|"); From phk at FreeBSD.org Wed Oct 29 09:40:54 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 29 Oct 2014 10:40:54 +0100 Subject: [master] 759574a Make space for another 8 bytes of GZIP data Message-ID: commit 759574ac84f9de37f56c5f1740f125d2bf268059 Author: Poul-Henning Kamp Date: Wed Oct 29 09:40:40 2014 +0000 Make space for another 8 bytes of GZIP data diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index deabbf6..3e6e9d3 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -457,7 +457,7 @@ ved_stripgzip(struct req *req) p = ObjGetattr(req->wrk, req->objcore, OA_GZIPBITS, &l); AN(p); - assert(l == 24); + assert(l == 32); start = vbe64dec(p); last = vbe64dec(p + 8); stop = vbe64dec(p + 16); diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index 583abc5..f4e3796 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -333,7 +333,7 @@ VGZ_UpdateObj(const struct vfp_ctx *vc, const struct vgz *vg) char *p; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); - p = ObjSetattr(vc->wrk, vc->oc, OA_GZIPBITS, 24, NULL); + p = ObjSetattr(vc->wrk, vc->oc, OA_GZIPBITS, 32, NULL); AN(p); vbe64enc(p, vg->vz.start_bit); vbe64enc(p + 8, vg->vz.last_bit); diff --git a/bin/varnishd/storage/storage.h b/bin/varnishd/storage/storage.h index 0d162ca..311f6a6 100644 --- a/bin/varnishd/storage/storage.h +++ b/bin/varnishd/storage/storage.h @@ -69,7 +69,7 @@ struct object { uint8_t *oa_vary; uint8_t *oa_http; uint8_t oa_flags[1]; - char oa_gzipbits[24]; + char oa_gzipbits[32]; char oa_lastmodified[8]; struct storagehead list; From lkarsten at varnish-software.com Wed Oct 29 09:46:51 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Wed, 29 Oct 2014 10:46:51 +0100 Subject: [master] 3225543 Copy over additions to changes.rst from 3.0 branch. Message-ID: commit 322554318914466a35e432c1cf83943163090300 Author: Lasse Karstensen Date: Wed Oct 29 10:33:20 2014 +0100 Copy over additions to changes.rst from 3.0 branch. diff --git a/doc/changes.rst b/doc/changes.rst index 846f975..c2be62f 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -334,6 +334,40 @@ Open issues .. _1268: https://www.varnish-cache.org/trac/ticket/1268 +=========================================== +Changes from 3.0.6rc1 to 3.0.6 (2014-10-16) +=========================================== + +- Minor changes to documentation. +- [varnishadm] Add termcap workaround for libedit. Bug 1514_. + +.. _1531: http://varnish-cache.org/trac/ticket/1531 + + +=========================================== +Changes from 3.0.5 to 3.0.6rc1 (2014-06-24) +=========================================== + +- Document storage..* VCL variables. Bug 1514_. +- Fix memory alignment panic when http_max_hdr is not a multiple of 4. Bug 1327_. +- Avoid negative ReqEnd timestamps with ESI. Bug 1297_. +- %D format for varnishncsa is now an integer (as documented) +- Fix compile errors with clang. +- Clear objectcore flags earlier in ban lurker to avoid spinning thread. Bug 1470_. +- Patch embedded jemalloc to avoid segfault. Bug 1448_. +- Allow backend names to start with if, include or else. Bug 1439_. +- Stop handling gzip after gzip body end. Bug 1086_. +- Document %D and %T for varnishncsa. + +.. _1514: http://varnish-cache.org/trac/ticket/1514 +.. _1327: http://varnish-cache.org/trac/ticket/1327 +.. _1297: http://varnish-cache.org/trac/ticket/1297 +.. _1470: http://varnish-cache.org/trac/ticket/1470 +.. _1448: http://varnish-cache.org/trac/ticket/1448 +.. _1439: http://varnish-cache.org/trac/ticket/1439 +.. _1086: http://varnish-cache.org/trac/ticket/1086 + + ================================ Changes from 3.0.5 rc 1 to 3.0.5 ================================ From lkarsten at varnish-software.com Wed Oct 29 09:46:51 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Wed, 29 Oct 2014 10:46:51 +0100 Subject: [master] 307afcf Be consistent in formatting headlines. Message-ID: commit 307afcfdf167414f9dd847714a51926098ad29d6 Author: Lasse Karstensen Date: Wed Oct 29 10:34:22 2014 +0100 Be consistent in formatting headlines. diff --git a/doc/changes.rst b/doc/changes.rst index c2be62f..4c6807f 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -7,6 +7,7 @@ New since 4.0.2-rc1: - [varnishlog] -k argument is back. (exit after n records) - [varnishadm] vcl.show is now listed in help. + ============================================ Changes from 4.0.1 to 4.0.2-rc1 (2014-09-23) ============================================ @@ -193,7 +194,6 @@ Bugs fixed .. _1519: https://www.varnish-cache.org/trac/ticket/1519 - ============================================== Changes from 4.0.0 beta1 to 4.0.0 (2014-04-10) ============================================== @@ -278,7 +278,6 @@ Bugs fixed .. _1405: https://www.varnish-cache.org/trac/ticket/1405 - =================================== Changes from 4.0.0 TP1 to 4.0.0 TP2 =================================== @@ -380,6 +379,7 @@ varnishd .. _bug #1376: http://varnish-cache.org/trac/ticket/1376 + ================================ Changes from 3.0.4 to 3.0.5 rc 1 ================================ @@ -417,6 +417,7 @@ varnishadm .. _bug #1314: http://varnish-cache.org/trac/ticket/1314 + ================================ Changes from 3.0.4 rc 1 to 3.0.4 ================================ @@ -433,6 +434,7 @@ varnishd .. _bug #1285: http://varnish-cache.org/trac/ticket/1285 .. _bug #1312: http://varnish-cache.org/trac/ticket/1312 + ================================ Changes from 3.0.3 to 3.0.4 rc 1 ================================ @@ -491,6 +493,7 @@ Other least on i386. - Make libvarnish prefer exact hits when looking for VSL tags. + =========================== Changes from 3.0.2 to 3.0.3 =========================== @@ -607,6 +610,7 @@ Other .. _bug #1003: http://varnish-cache.org/trac/ticket/1003 + ================================ Changes from 3.0.2 rc 1 to 3.0.2 ================================ @@ -637,6 +641,7 @@ Other - Some Solaris portability updates. + ================================ Changes from 3.0.1 to 3.0.2 rc 1 ================================ @@ -698,6 +703,7 @@ Other - Some Solaris portability updates. + ================================ Changes from 3.0.1 rc 1 to 3.0.1 ================================ @@ -729,6 +735,7 @@ Other - Documentation updates + ================================ Changes from 3.0.0 to 3.0.1 rc 1 ================================ @@ -805,6 +812,7 @@ Other .. _bug #961: http://varnish-cache.org/trac/ticket/961 + ================================ Changes from 3.0 beta 2 to 3.0.0 ================================ @@ -832,6 +840,7 @@ varnishadm .. _bug #935: http://varnish-cache.org/trac/ticket/935 + ===================================== Changes from 3.0 beta 1 to 3.0 beta 2 ===================================== @@ -883,6 +892,7 @@ VMODs - The std module now has proper documentation, including a manual page + ================================ Changes from 2.1.5 to 3.0 beta 1 ================================ @@ -1126,6 +1136,7 @@ Other - The documentation has been improved all over and should now be in much better shape than before + =========================== Changes from 2.1.4 to 2.1.5 =========================== @@ -1200,6 +1211,7 @@ varnishtest - Remove no longer existing -L option. + =========================== Changes from 2.1.3 to 2.1.4 =========================== @@ -1349,6 +1361,7 @@ libvarnishapi - The -X parameter didn't work correctly. This has been fixed. + =========================== Changes from 2.1.1 to 2.1.2 =========================== @@ -1361,6 +1374,7 @@ varnishd by default 128k. Browsers would do the right thing due to Content-Length, but some load balancers would get very confused. + =========================== Changes from 2.1.1 to 2.1.1 =========================== @@ -1592,6 +1606,7 @@ varnishadm - varnishadm now knows how to respond to the secret from a secured varnishd + =========================== Changes from 2.0.5 to 2.0.6 =========================== @@ -1621,6 +1636,7 @@ varnishd - Document the -C option to varnishd. + =========================== Changes from 2.0.4 to 2.0.5 =========================== @@ -1718,6 +1734,7 @@ varnishtop - varnishtop previously did not print the name of the tag, which made it very hard to understand. We now print out the tag name. + =========================== Changes from 2.0.3 to 2.0.4 =========================== @@ -1775,6 +1792,7 @@ varnishtest - Make it possible to send NULL bytes through the testing framework. + =========================== Changes from 2.0.2 to 2.0.3 =========================== @@ -1909,6 +1927,7 @@ varnishreplay - varnishreplay did not work correctly on Linux, due to a too small stack. This has now been fixed. + =========================== Changes from 2.0.1 to 2.0.2 =========================== @@ -1943,6 +1962,7 @@ Red Hat spec file - A typo in the spec file made the .rpm file names wrong. + ========================= Changes from 1.1.2 to 2.0 ========================= @@ -2062,6 +2082,7 @@ Build system - The C compiler invocation is decided by the configure script and can now be overridden by passing VCC\_CC when running configure. + =========================== Changes from 1.1.1 to 1.1.2 =========================== @@ -2165,6 +2186,7 @@ Build system the default state directory would be garbage and a state directory would have to be specified manually with -n. This has been corrected. + ========================= Changes from 1.1 to 1.1.1 ========================= @@ -2249,6 +2271,7 @@ Build system dynamic rather than static. This simplifies the build process and resolves an issue with the Mac OS X linker. + ========================= Changes from 1.0.4 to 1.1 ========================= @@ -2409,6 +2432,7 @@ varnishtop actually works. In addition, the name of the Varnish instance being watched is displayed in the upper right corner in curses mode. + =========================== Changes from 1.0.3 to 1.0.4 =========================== From lkarsten at varnish-software.com Wed Oct 29 09:46:51 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Wed, 29 Oct 2014 10:46:51 +0100 Subject: [master] 6312613 Add release dates. Message-ID: commit 63126139f062d0a05ceab31f48d32eca074d5811 Author: Lasse Karstensen Date: Wed Oct 29 10:41:26 2014 +0100 Add release dates. Source data from file time on repo.varnish-cache.org. diff --git a/doc/changes.rst b/doc/changes.rst index 4c6807f..a603870 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -220,9 +220,9 @@ Bugs fixed .. _1467: https://www.varnish-cache.org/trac/ticket/1467 -===================================== -Changes from 4.0.0 TP2 to 4.0.0 beta1 -===================================== +================================================== +Changes from 4.0.0 TP2 to 4.0.0 beta1 (2014-03-27) +================================================== New since TP2: @@ -278,9 +278,9 @@ Bugs fixed .. _1405: https://www.varnish-cache.org/trac/ticket/1405 -=================================== -Changes from 4.0.0 TP1 to 4.0.0 TP2 -=================================== +================================================ +Changes from 4.0.0 TP1 to 4.0.0 TP2 (2014-01-23) +================================================ New since from 4.0.0 TP1 ------------------------ @@ -367,9 +367,9 @@ Changes from 3.0.5 to 3.0.6rc1 (2014-06-24) .. _1086: http://varnish-cache.org/trac/ticket/1086 -================================ -Changes from 3.0.5 rc 1 to 3.0.5 -================================ +============================================= +Changes from 3.0.5 rc 1 to 3.0.5 (2013-12-02) +============================================= varnishd -------- @@ -418,9 +418,9 @@ varnishadm .. _bug #1314: http://varnish-cache.org/trac/ticket/1314 -================================ -Changes from 3.0.4 rc 1 to 3.0.4 -================================ +============================================= +Changes from 3.0.4 rc 1 to 3.0.4 (2013-06-14) +============================================= varnishd -------- @@ -494,9 +494,9 @@ Other - Make libvarnish prefer exact hits when looking for VSL tags. -=========================== -Changes from 3.0.2 to 3.0.3 -=========================== +======================================== +Changes from 3.0.2 to 3.0.3 (2012-08-20) +======================================== Varnishd -------- @@ -611,9 +611,9 @@ Other .. _bug #1003: http://varnish-cache.org/trac/ticket/1003 -================================ -Changes from 3.0.2 rc 1 to 3.0.2 -================================ +============================================= +Changes from 3.0.2 rc 1 to 3.0.2 (2011-10-26) +============================================= Varnishd -------- @@ -642,9 +642,9 @@ Other - Some Solaris portability updates. -================================ -Changes from 3.0.1 to 3.0.2 rc 1 -================================ +============================================= +Changes from 3.0.1 to 3.0.2 rc 1 (2011-10-06) +============================================= Varnishd -------- @@ -704,9 +704,9 @@ Other - Some Solaris portability updates. -================================ -Changes from 3.0.1 rc 1 to 3.0.1 -================================ +============================================= +Changes from 3.0.1 rc 1 to 3.0.1 (2011-08-30) +============================================= Varnishd -------- @@ -736,9 +736,9 @@ Other - Documentation updates -================================ -Changes from 3.0.0 to 3.0.1 rc 1 -================================ +============================================= +Changes from 3.0.0 to 3.0.1 rc 1 (2011-08-24) +============================================= Varnishd -------- @@ -813,9 +813,9 @@ Other .. _bug #961: http://varnish-cache.org/trac/ticket/961 -================================ -Changes from 3.0 beta 2 to 3.0.0 -================================ +============================================= +Changes from 3.0 beta 2 to 3.0.0 (2011-06-16) +============================================= Varnishd -------- @@ -1137,9 +1137,9 @@ Other much better shape than before -=========================== -Changes from 2.1.4 to 2.1.5 -=========================== +======================================== +Changes from 2.1.4 to 2.1.5 (2011-01-25) +======================================== varnishd -------- From phk at FreeBSD.org Wed Oct 29 10:56:13 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 29 Oct 2014 11:56:13 +0100 Subject: [master] 18e7b5e Store the uncompressed size as part of OA_GZIP data and have VDP_gunzip() emit it as C-L if it looks sane. Message-ID: commit 18e7b5e33c37fb1bc8d97a23aa01db02859bb676 Author: Poul-Henning Kamp Date: Wed Oct 29 10:55:14 2014 +0000 Store the uncompressed size as part of OA_GZIP data and have VDP_gunzip() emit it as C-L if it looks sane. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 1e0cec2..fb17acc 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -788,7 +788,7 @@ enum vgzret_e VGZ_Gzip(struct vgz *, const void **, ssize_t *len, enum vgz_flag); // enum vgzret_e VGZ_Gunzip(struct vgz *, const void **, ssize_t *len); enum vgzret_e VGZ_Destroy(struct vgz **); -void VGZ_UpdateObj(const struct vfp_ctx *, const struct vgz*); +void VGZ_UpdateObj(const struct vfp_ctx *, const struct vgz*, int input); /* cache_http.c */ unsigned HTTP_estimate(unsigned nhttp); diff --git a/bin/varnishd/cache/cache_esi_fetch.c b/bin/varnishd/cache/cache_esi_fetch.c index 9091197..07d5503 100644 --- a/bin/varnishd/cache/cache_esi_fetch.c +++ b/bin/varnishd/cache/cache_esi_fetch.c @@ -130,7 +130,7 @@ vfp_esi_end(struct vfp_ctx *vc, struct vef_priv *vef, } if (vef->vgz != NULL) { - VGZ_UpdateObj(vc, vef->vgz); + VGZ_UpdateObj(vc, vef->vgz, 1); if (VGZ_Destroy(&vef->vgz) != VGZ_END) retval = VFP_Error(vc, "ESI+Gzip Failed at the very end"); diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index f4e3796..1afd3cb 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -45,6 +45,7 @@ #include "cache_filter.h" #include "vend.h" +#include "vend.h" #include "vgz.h" struct vgz { @@ -277,6 +278,8 @@ VDP_gunzip(struct req *req, enum vdp_action act, void **priv, const void *dp; struct worker *wrk; struct vgz *vg; + char *p; + uint64_t u; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); wrk = req->wrk; @@ -289,7 +292,16 @@ VDP_gunzip(struct req *req, enum vdp_action act, void **priv, return (-1); VGZ_Obuf(vg, vg->m_buf, vg->m_sz); *priv = vg; + http_Unset(req->resp, H_Content_Length); + p = ObjGetattr(req->wrk, req->objcore, OA_GZIPBITS, &dl); + if (p != NULL && dl == 32) { + u = vbe64dec(p + 24); + /* XXX: Zero is suspect: OA_GZIPBITS wasn't set */ + if (u != 0) + http_PrintfHeader(req->resp, + "Content-Length: %ju", u); + } http_Unset(req->resp, H_Content_Encoding); return (0); } @@ -328,7 +340,7 @@ VDP_gunzip(struct req *req, enum vdp_action act, void **priv, /*--------------------------------------------------------------------*/ void -VGZ_UpdateObj(const struct vfp_ctx *vc, const struct vgz *vg) +VGZ_UpdateObj(const struct vfp_ctx *vc, const struct vgz *vg, int input) { char *p; @@ -338,6 +350,10 @@ VGZ_UpdateObj(const struct vfp_ctx *vc, const struct vgz *vg) vbe64enc(p, vg->vz.start_bit); vbe64enc(p + 8, vg->vz.last_bit); vbe64enc(p + 16, vg->vz.stop_bit); + if (input) + vbe64enc(p + 24, vg->vz.total_in); + else + vbe64enc(p + 24, vg->vz.total_out); } /*-------------------------------------------------------------------- @@ -539,7 +555,7 @@ vfp_gzip_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, if (vr != VGZ_END) return (VFP_Error(vc, "Gzip failed")); - VGZ_UpdateObj(vc, vg); + VGZ_UpdateObj(vc, vg, 1); return (VFP_END); } @@ -584,7 +600,7 @@ vfp_testgunzip_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, if (vp == VFP_END) { if (vr != VGZ_END) return (VFP_Error(vc, "tGunzip failed")); - VGZ_UpdateObj(vc, vg); + VGZ_UpdateObj(vc, vg, 0); } return (vp); } diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index c1f3b91..84cd582 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -89,7 +89,6 @@ V1D_Deliver(struct req *req, struct busyobj *bo) if (req->res_mode & RES_ESI) { RFC2616_Weaken_Etag(req->resp); - http_Unset(req->resp, H_Content_Length); } else if (http_IsStatus(req->resp, 304)) { http_Unset(req->resp, H_Content_Length); req->wantbody = 0; @@ -112,6 +111,11 @@ V1D_Deliver(struct req *req, struct busyobj *bo) VDP_push(req, VDP_gunzip, NULL, 0); } + if (req->res_mode & RES_ESI) { + /* Gunzip could have added back a C-L */ + http_Unset(req->resp, H_Content_Length); + } + /* * Range comes after the others and pushes on bottom because it * can generate a correct C-L header. From lkarsten at varnish-software.com Wed Oct 29 13:09:47 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Wed, 29 Oct 2014 14:09:47 +0100 Subject: [3.0] a8f2f85 Use correct bug number. Message-ID: commit a8f2f85de3bedee2624c2055a22c47626e0cda3f Author: Lasse Karstensen Date: Wed Oct 29 14:09:16 2014 +0100 Use correct bug number. Found by: Geoff diff --git a/doc/changes.rst b/doc/changes.rst index 56c53d6..8291cee 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -3,7 +3,7 @@ Changes from 3.0.6rc1 to 3.0.6 (2014-10-16) =========================================== - Minor changes to documentation. -- [varnishadm] Add termcap workaround for libedit. Bug 1514_. +- [varnishadm] Add termcap workaround for libedit. Bug 1531_. .. _1531: http://varnish-cache.org/trac/ticket/1531 From lkarsten at varnish-software.com Wed Oct 29 13:11:52 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Wed, 29 Oct 2014 14:11:52 +0100 Subject: [master] 9ee713e Use correct bug number. Message-ID: commit 9ee713e63a24d586c43fa527ba54b23b79b2dbc8 Author: Lasse Karstensen Date: Wed Oct 29 14:11:23 2014 +0100 Use correct bug number. Found by: Geoff diff --git a/doc/changes.rst b/doc/changes.rst index a603870..fd4db1f 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -338,7 +338,7 @@ Changes from 3.0.6rc1 to 3.0.6 (2014-10-16) =========================================== - Minor changes to documentation. -- [varnishadm] Add termcap workaround for libedit. Bug 1514_. +- [varnishadm] Add termcap workaround for libedit. Bug 1531_. .. _1531: http://varnish-cache.org/trac/ticket/1531 From phk at FreeBSD.org Thu Oct 30 10:23:02 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 30 Oct 2014 11:23:02 +0100 Subject: [master] 2053e92 White space nit Message-ID: commit 2053e9206c41ccb1c3c536ac0cab4f68f29aa7bd Author: Poul-Henning Kamp Date: Thu Oct 30 09:14:21 2014 +0000 White space nit diff --git a/bin/varnishtest/tests/e00003.vtc b/bin/varnishtest/tests/e00003.vtc index 02e6840..ba73c14 100644 --- a/bin/varnishtest/tests/e00003.vtc +++ b/bin/varnishtest/tests/e00003.vtc @@ -41,7 +41,7 @@ logexpect l2 -v v1 -g request { logexpect l3 -v v1 -g request { expect * 1003 Begin "^req .* esi" - expect * = ReqAcct "^0 0 0 0 18 18$" + expect * = ReqAcct "^0 0 0 0 18 18$" expect 0 = End } -start From phk at FreeBSD.org Thu Oct 30 10:23:02 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 30 Oct 2014 11:23:02 +0100 Subject: [master] 9e9f3f0 Check for multiple Content-Length headers Message-ID: commit 9e9f3f0281a4d521764c54afa9a47a9cfd51e162 Author: Poul-Henning Kamp Date: Thu Oct 30 09:40:36 2014 +0000 Check for multiple Content-Length headers diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index 1a4b12f..8f70514 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -168,6 +168,25 @@ http_find_header(char * const *hh, const char *hdr) } /********************************************************************** + * count header + */ + +static int +http_count_header(char * const *hh, const char *hdr) +{ + int n, l, r = 0; + + l = strlen(hdr); + + for (n = 3; hh[n] != NULL; n++) { + if (strncasecmp(hdr, hh[n], l) || hh[n][l] != ':') + continue; + r++; + } + return (r); +} + +/********************************************************************** * Expect */ @@ -536,6 +555,9 @@ cmd_http_rxresp(CMD_ARGS) "Unknown http rxresp spec: %s\n", *av); http_rxhdr(hp); http_splitheader(hp, 0); + if (http_count_header(hp->resp, "Content-Length") > 1) + vtc_log(hp->vl, 0, + "Multiple Content-Length headers.\n"); hp->body = hp->rxbuf + hp->prxbuf; if (!has_obj) return; @@ -562,6 +584,9 @@ cmd_http_rxresphdrs(CMD_ARGS) vtc_log(hp->vl, 0, "Unknown http rxreq spec: %s\n", *av); http_rxhdr(hp); http_splitheader(hp, 0); + if (http_count_header(hp->resp, "Content-Length") > 1) + vtc_log(hp->vl, 0, + "Multiple Content-Length headers.\n"); } @@ -820,6 +845,9 @@ cmd_http_rxreq(CMD_ARGS) vtc_log(hp->vl, 0, "Unknown http rxreq spec: %s\n", *av); http_rxhdr(hp); http_splitheader(hp, 1); + if (http_count_header(hp->req, "Content-Length") > 1) + vtc_log(hp->vl, 0, + "Multiple Content-Length headers.\n"); hp->body = hp->rxbuf + hp->prxbuf; http_swallow_body(hp, hp->req, 0); vtc_log(hp->vl, 4, "bodylen = %s", hp->bodylen); @@ -840,6 +868,9 @@ cmd_http_rxreqhdrs(CMD_ARGS) vtc_log(hp->vl, 0, "Unknown http rxreq spec: %s\n", *av); http_rxhdr(hp); http_splitheader(hp, 1); + if (http_count_header(hp->req, "Content-Length") > 1) + vtc_log(hp->vl, 0, + "Multiple Content-Length headers.\n"); } static void From phk at FreeBSD.org Thu Oct 30 10:23:02 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 30 Oct 2014 11:23:02 +0100 Subject: [master] b7d414c Make it possible to receive resphdrs and respbody separately. Message-ID: commit b7d414c719831f3c56ccbe8f4fea4bcbb25eb903 Author: Poul-Henning Kamp Date: Thu Oct 30 10:10:08 2014 +0000 Make it possible to receive resphdrs and respbody separately. Always interpret C-L in decimal diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index 8f70514..6de14ea 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -469,7 +469,7 @@ http_swallow_body(struct http *hp, char * const *hh, int body) p = http_find_header(hh, "content-length"); if (p != NULL) { hp->body = hp->rxbuf + hp->prxbuf; - l = strtoul(p, NULL, 0); + l = strtoul(p, NULL, 10); (void)http_rxchar(hp, l, 0); vtc_dump(hp->vl, 4, "body", hp->body, l); hp->bodyl = l; @@ -874,7 +874,7 @@ cmd_http_rxreqhdrs(CMD_ARGS) } static void -cmd_http_rxbody(CMD_ARGS) +cmd_http_rxreqbody(CMD_ARGS) { struct http *hp; @@ -882,7 +882,7 @@ cmd_http_rxbody(CMD_ARGS) (void)vl; CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC); ONLY_SERVER(hp, av); - AZ(strcmp(av[0], "rxbody")); + AZ(strcmp(av[0], "rxreqbody")); av++; for(; *av != NULL; av++) @@ -892,6 +892,24 @@ cmd_http_rxbody(CMD_ARGS) } static void +cmd_http_rxrespbody(CMD_ARGS) +{ + struct http *hp; + + (void)cmd; + (void)vl; + CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC); + ONLY_CLIENT(hp, av); + AZ(strcmp(av[0], "rxrespbody")); + av++; + + for(; *av != NULL; av++) + vtc_log(hp->vl, 0, "Unknown http rxreq spec: %s\n", *av); + http_swallow_body(hp, hp->resp, 0); + vtc_log(hp->vl, 4, "bodylen = %s", hp->bodylen); +} + +static void cmd_http_rxchunk(CMD_ARGS) { struct http *hp; @@ -1225,12 +1243,13 @@ static const struct cmds http_cmds[] = { { "rxreq", cmd_http_rxreq }, { "rxreqhdrs", cmd_http_rxreqhdrs }, + { "rxreqbody", cmd_http_rxreqbody }, { "rxchunk", cmd_http_rxchunk }, - { "rxbody", cmd_http_rxbody }, { "txresp", cmd_http_txresp }, { "rxresp", cmd_http_rxresp }, { "rxresphdrs", cmd_http_rxresphdrs }, + { "rxrespbody", cmd_http_rxrespbody }, { "gunzip", cmd_http_gunzip_body }, { "expect", cmd_http_expect }, { "send", cmd_http_send }, From phk at FreeBSD.org Thu Oct 30 10:23:02 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 30 Oct 2014 11:23:02 +0100 Subject: [master] dec75e0 Don't needlessly throw away Content-Length from backend, but assume it is sane and pass it to streaming clients, provided we don't munge the body along the way. Message-ID: commit dec75e06706a0333d15473134ee368300fb42184 Author: Poul-Henning Kamp Date: Thu Oct 30 10:21:27 2014 +0000 Don't needlessly throw away Content-Length from backend, but assume it is sane and pass it to streaming clients, provided we don't munge the body along the way. Fixes: #1506 diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index bfbd3c9..e83d06d 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -382,6 +382,7 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo) http_Unset(bo->beresp, H_Content_Encoding); RFC2616_Weaken_Etag(bo->beresp); } + http_Unset(bo->beresp, H_Content_Length); HTTP_Merge(bo->wrk, bo->ims_oc, bo->beresp); assert(http_IsStatus(bo->beresp, 200)); do_ims = 1; diff --git a/bin/varnishtest/tests/r01506.vtc b/bin/varnishtest/tests/r01506.vtc new file mode 100644 index 0000000..4f0ca76 --- /dev/null +++ b/bin/varnishtest/tests/r01506.vtc @@ -0,0 +1,42 @@ +varnishtest "Streaming of C-L header from backend" + +server s1 { + rxreq + txresp -nolen -hdr "Content-Length: 020" + send "0123456789" + sema r1 sync 2 + send "0123456789" + + rxreq + txresp -nolen -hdr "Content-Length: 010" + send "0123456789" +} -start + +varnish v1 -vcl+backend { + + sub vcl_backend_response { + if (bereq.url == "/2") { + set beresp.do_gzip = true; + } + } +} -start -cliok "param.set debug +syncvsl" + +client c1 { + txreq + rxresphdrs + expect resp.http.content-length == "020" + sema r1 sync 2 + rxrespbody + expect resp.body == "01234567890123456789" + delay .1 + + txreq -url "/2" + rxresp + expect resp.http.content-length == "" + expect resp.body == "0123456789" + + delay .1 + txreq -url "/2" + rxresp + expect resp.http.content-length == "10" +} -run diff --git a/include/tbl/http_headers.h b/include/tbl/http_headers.h index 26443ca..0a5395f 100644 --- a/include/tbl/http_headers.h +++ b/include/tbl/http_headers.h @@ -57,7 +57,7 @@ HTTPH("Cache-Control", H_Cache_Control, HTTPH_R_FETCH ) /* RFC2616 1 HTTPH("Connection", H_Connection, HTTPH_R_PASS | HTTPH_R_FETCH | HTTPH_A_INS) /* RFC2616 14.10 */ HTTPH("Content-Encoding", H_Content_Encoding, 0 ) /* RFC2616 14.11 */ HTTPH("Content-Language", H_Content_Language, 0 ) /* RFC2616 14.12 */ -HTTPH("Content-Length", H_Content_Length, HTTPH_R_FETCH | HTTPH_A_INS) /* RFC2616 14.13 */ +HTTPH("Content-Length", H_Content_Length, HTTPH_R_FETCH ) /* RFC2616 14.13 */ HTTPH("Content-Location", H_Content_Location, 0 ) /* RFC2616 14.14 */ HTTPH("Content-MD5", H_Content_MD5, 0 ) /* RFC2616 14.15 */ HTTPH("Content-Range", H_Content_Range, HTTPH_R_FETCH | HTTPH_A_INS) /* RFC2616 14.16 */ From lkarsten at varnish-software.com Thu Oct 30 10:36:21 2014 From: lkarsten at varnish-software.com (Lasse Karstensen) Date: Thu, 30 Oct 2014 11:36:21 +0100 Subject: [master] 5303dff Remove duplicate target name. Message-ID: commit 5303dff890afd5b21254e474d51e171576bf53ed Author: Lasse Karstensen Date: Thu Oct 30 11:36:02 2014 +0100 Remove duplicate target name. diff --git a/doc/changes.rst b/doc/changes.rst index fd4db1f..a8ab383 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -340,8 +340,6 @@ Changes from 3.0.6rc1 to 3.0.6 (2014-10-16) - Minor changes to documentation. - [varnishadm] Add termcap workaround for libedit. Bug 1531_. -.. _1531: http://varnish-cache.org/trac/ticket/1531 - =========================================== Changes from 3.0.5 to 3.0.6rc1 (2014-06-24) From tfheen at err.no Thu Oct 30 13:24:54 2014 From: tfheen at err.no (Tollef Fog Heen) Date: Thu, 30 Oct 2014 14:24:54 +0100 Subject: [master] 4aa57ab Drop duplicate ref Message-ID: commit 4aa57ab7e53476dfbefb0d65a69d74ff105685d6 Author: Tollef Fog Heen Date: Thu Oct 30 14:24:44 2014 +0100 Drop duplicate ref diff --git a/doc/changes.rst b/doc/changes.rst index a8ab383..c638014 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -189,7 +189,6 @@ Bugs fixed .. _1501: https://www.varnish-cache.org/trac/ticket/1501 .. _1495: https://www.varnish-cache.org/trac/ticket/1495 .. _1510: https://www.varnish-cache.org/trac/ticket/1510 -.. _1514: https://www.varnish-cache.org/trac/ticket/1514 .. _1518: https://www.varnish-cache.org/trac/ticket/1518 .. _1519: https://www.varnish-cache.org/trac/ticket/1519 From phk at FreeBSD.org Thu Oct 30 14:35:15 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 30 Oct 2014 15:35:15 +0100 Subject: [master] 3e34810 Make this test-case more robust Message-ID: commit 3e348103e4bdbb92d672a522ef9682709c2fd0e8 Author: Poul-Henning Kamp Date: Thu Oct 30 14:34:55 2014 +0000 Make this test-case more robust diff --git a/bin/varnishtest/tests/r01506.vtc b/bin/varnishtest/tests/r01506.vtc index 4f0ca76..b8d1e44 100644 --- a/bin/varnishtest/tests/r01506.vtc +++ b/bin/varnishtest/tests/r01506.vtc @@ -9,7 +9,9 @@ server s1 { rxreq txresp -nolen -hdr "Content-Length: 010" - send "0123456789" + send "01234" + delay .5 + send "56789" } -start varnish v1 -vcl+backend { From phk at FreeBSD.org Thu Oct 30 15:50:21 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 30 Oct 2014 16:50:21 +0100 Subject: [master] abefe72 Add a debug facility to force a V1L_Flush after the headers. Message-ID: commit abefe72ece143e7bb5a6575e135c1de1d363c727 Author: Poul-Henning Kamp Date: Thu Oct 30 15:30:12 2014 +0000 Add a debug facility to force a V1L_Flush after the headers. diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 84cd582..bc24ff3 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -150,6 +150,8 @@ V1D_Deliver(struct req *req, struct busyobj *bo) V1L_Reserve(req->wrk, req->ws, &req->sp->fd, req->vsl, req->t_prev); req->acct.resp_hdrbytes += HTTP1_Write(req->wrk, req->resp, HTTP1_Resp); + if (DO_DEBUG(DBG_FLUSH_HEAD)) + (void)V1L_Flush(req->wrk); ois = OIS_DONE; if (req->wantbody) { diff --git a/include/tbl/debug_bits.h b/include/tbl/debug_bits.h index 59bc64e..81d5e38 100644 --- a/include/tbl/debug_bits.h +++ b/include/tbl/debug_bits.h @@ -38,3 +38,4 @@ DEBUG_BIT(HASHEDGE, hashedge, "Edge cases in Hash") DEBUG_BIT(VCLREL, vclrel, "Rapid VCL release") DEBUG_BIT(LURKER, lurker, "VSL Ban lurker") DEBUG_BIT(ESI_CHOP, esi_chop, "Chop ESI fetch to bits") +DEBUG_BIT(FLUSH_HEAD, flush_head, "Flush after http1 head") From phk at FreeBSD.org Thu Oct 30 15:50:21 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 30 Oct 2014 16:50:21 +0100 Subject: [master] deb3ef1 Fix a couple of bugs for the detached rx*body functions. Message-ID: commit deb3ef1029c4388720ee0dc579cdb4e81a0357d3 Author: Poul-Henning Kamp Date: Thu Oct 30 15:49:39 2014 +0000 Fix a couple of bugs for the detached rx*body functions. diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index 6de14ea..a3dbff4 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -465,10 +465,10 @@ http_swallow_body(struct http *hp, char * const *hh, int body) char *p; int i, l, ll; + hp->body = hp->rxbuf + hp->prxbuf; ll = 0; p = http_find_header(hh, "content-length"); if (p != NULL) { - hp->body = hp->rxbuf + hp->prxbuf; l = strtoul(p, NULL, 10); (void)http_rxchar(hp, l, 0); vtc_dump(hp->vl, 4, "body", hp->body, l); @@ -487,7 +487,6 @@ http_swallow_body(struct http *hp, char * const *hh, int body) return; } if (body) { - hp->body = hp->rxbuf + hp->prxbuf; do { i = http_rxchar(hp, 1, 1); ll += i; @@ -558,7 +557,6 @@ cmd_http_rxresp(CMD_ARGS) if (http_count_header(hp->resp, "Content-Length") > 1) vtc_log(hp->vl, 0, "Multiple Content-Length headers.\n"); - hp->body = hp->rxbuf + hp->prxbuf; if (!has_obj) return; else if (!strcmp(hp->resp[1], "200")) @@ -848,7 +846,6 @@ cmd_http_rxreq(CMD_ARGS) if (http_count_header(hp->req, "Content-Length") > 1) vtc_log(hp->vl, 0, "Multiple Content-Length headers.\n"); - hp->body = hp->rxbuf + hp->prxbuf; http_swallow_body(hp, hp->req, 0); vtc_log(hp->vl, 4, "bodylen = %s", hp->bodylen); } From phk at FreeBSD.org Thu Oct 30 15:50:21 2014 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 30 Oct 2014 16:50:21 +0100 Subject: [master] 77849fd Use new debug bit to make this test robust. Message-ID: commit 77849fdaf94f697a6094fb1d19a16fe1ab9b029f Author: Poul-Henning Kamp Date: Thu Oct 30 15:50:03 2014 +0000 Use new debug bit to make this test robust. diff --git a/bin/varnishtest/tests/r01506.vtc b/bin/varnishtest/tests/r01506.vtc index b8d1e44..09a8db0 100644 --- a/bin/varnishtest/tests/r01506.vtc +++ b/bin/varnishtest/tests/r01506.vtc @@ -9,9 +9,8 @@ server s1 { rxreq txresp -nolen -hdr "Content-Length: 010" - send "01234" - delay .5 - send "56789" + sema r2 sync 2 + send "0123456789" } -start varnish v1 -vcl+backend { @@ -21,7 +20,7 @@ varnish v1 -vcl+backend { set beresp.do_gzip = true; } } -} -start -cliok "param.set debug +syncvsl" +} -start -cliok "param.set debug +syncvsl" -cliok "param.set debug +flush_head" client c1 { txreq @@ -33,11 +32,13 @@ client c1 { delay .1 txreq -url "/2" - rxresp + rxresphdrs expect resp.http.content-length == "" + sema r2 sync 2 + rxrespbody expect resp.body == "0123456789" - delay .1 + txreq -url "/2" rxresp expect resp.http.content-length == "10"