r5381 - in trunk/varnish-cache: bin/varnishd include lib/libvcl
phk at varnish-cache.org
phk at varnish-cache.org
Fri Oct 1 12:02:54 CEST 2010
Author: phk
Date: 2010-10-01 12:02:54 +0200 (Fri, 01 Oct 2010)
New Revision: 5381
Added:
trunk/varnish-cache/bin/varnishd/cache_vrt_var.c
Modified:
trunk/varnish-cache/bin/varnishd/Makefile.am
trunk/varnish-cache/bin/varnishd/cache.h
trunk/varnish-cache/bin/varnishd/cache_vrt.c
trunk/varnish-cache/include/vrt.h
trunk/varnish-cache/lib/libvcl/vcc_expr.c
Log:
Split vrt functions for variables into a separate source file
Modified: trunk/varnish-cache/bin/varnishd/Makefile.am
===================================================================
--- trunk/varnish-cache/bin/varnishd/Makefile.am 2010-10-01 10:01:30 UTC (rev 5380)
+++ trunk/varnish-cache/bin/varnishd/Makefile.am 2010-10-01 10:02:54 UTC (rev 5381)
@@ -42,6 +42,7 @@
cache_vcl.c \
cache_vrt.c \
cache_vrt_re.c \
+ cache_vrt_var.c \
cache_vrt_vmod.c \
cache_wrw.c \
cache_ws.c \
Modified: trunk/varnish-cache/bin/varnishd/cache.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache.h 2010-10-01 10:01:30 UTC (rev 5380)
+++ trunk/varnish-cache/bin/varnishd/cache.h 2010-10-01 10:02:54 UTC (rev 5381)
@@ -43,6 +43,7 @@
#ifdef HAVE_PTHREAD_NP_H
#include <pthread_np.h>
#endif
+#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#include <limits.h>
@@ -708,6 +709,10 @@
#include "vcl_returns.h"
#undef VCL_MET_MAC
+/* cache_vrt.c */
+
+char *VRT_String(struct ws *ws, const char *h, const char *p, va_list ap);
+
/* cache_vrt_esi.c */
void ESI_Deliver(struct sess *);
Modified: trunk/varnish-cache/bin/varnishd/cache_vrt.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_vrt.c 2010-10-01 10:01:30 UTC (rev 5380)
+++ trunk/varnish-cache/bin/varnishd/cache_vrt.c 2010-10-01 10:02:54 UTC (rev 5381)
@@ -57,7 +57,6 @@
/*lint -save -esym(818,sp) */
const void * const vrt_magic_string_end = &vrt_magic_string_end;
-static char vrt_hostname[255] = "";
/*--------------------------------------------------------------------*/
@@ -142,8 +141,8 @@
*/
/*lint -e{818} ap,hp could be const */
-static char *
-vrt_build_string(struct ws *ws, const char *h, const char *p, va_list ap)
+char *
+VRT_String(struct ws *ws, const char *h, const char *p, va_list ap)
{
char *b, *e;
unsigned u, x;
@@ -192,7 +191,7 @@
vrt_assemble_string(struct http *hp, const char *h, const char *p, va_list ap)
{
- return (vrt_build_string(hp->ws, h, p, ap));
+ return (VRT_String(hp->ws, h, p, ap));
}
/*--------------------------------------------------------------------
@@ -200,14 +199,14 @@
*/
const char *
-VRT_String(const struct sess *sp, const char *p, ...)
+VRT_WrkString(const struct sess *sp, const char *p, ...)
{
va_list ap;
char *b;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
va_start(ap, p);
- b = vrt_build_string(sp->wrk->ws, NULL, p, ap);
+ b = VRT_String(sp->wrk->ws, NULL, p, ap);
va_end(ap);
return (b);
}
@@ -241,269 +240,7 @@
/*--------------------------------------------------------------------*/
-static void
-vrt_do_string(struct worker *w, int fd, struct http *hp, int fld,
- const char *err, const char *p, va_list ap)
-{
- char *b;
-
- // AN(p);
- AN(hp);
- b = vrt_assemble_string(hp, NULL, p, ap);
- if (b == NULL || *b == '\0') {
- WSL(w, SLT_LostHeader, fd, err);
- } else {
- http_SetH(hp, fld, b);
- }
- va_end(ap);
-}
-
-#define VRT_DO_HDR(obj, hdr, http, fld) \
-void \
-VRT_l_##obj##_##hdr(const struct sess *sp, const char *p, ...) \
-{ \
- va_list ap; \
- \
- va_start(ap, p); \
- vrt_do_string(sp->wrk, sp->fd, \
- http, fld, #obj "." #hdr, p, ap); \
- va_end(ap); \
-} \
- \
-const char * \
-VRT_r_##obj##_##hdr(const struct sess *sp) \
-{ \
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
- CHECK_OBJ_NOTNULL(http, HTTP_MAGIC); \
- return (http->hd[fld].b); \
-}
-
-VRT_DO_HDR(req, request, sp->http, HTTP_HDR_REQ)
-VRT_DO_HDR(req, url, sp->http, HTTP_HDR_URL)
-VRT_DO_HDR(req, proto, sp->http, HTTP_HDR_PROTO)
-VRT_DO_HDR(bereq, request, sp->wrk->bereq, HTTP_HDR_REQ)
-VRT_DO_HDR(bereq, url, sp->wrk->bereq, HTTP_HDR_URL)
-VRT_DO_HDR(bereq, proto, sp->wrk->bereq, HTTP_HDR_PROTO)
-VRT_DO_HDR(obj, proto, sp->obj->http, HTTP_HDR_PROTO)
-VRT_DO_HDR(obj, response, sp->obj->http, HTTP_HDR_RESPONSE)
-VRT_DO_HDR(resp, proto, sp->wrk->resp, HTTP_HDR_PROTO)
-VRT_DO_HDR(resp, response, sp->wrk->resp, HTTP_HDR_RESPONSE)
-VRT_DO_HDR(beresp, proto, sp->wrk->beresp, HTTP_HDR_PROTO)
-VRT_DO_HDR(beresp, response, sp->wrk->beresp, HTTP_HDR_RESPONSE)
-
-/*--------------------------------------------------------------------*/
-
-#define VRT_DO_STATUS(obj, http) \
-void \
-VRT_l_##obj##_status(const struct sess *sp, int num) \
-{ \
- \
- assert(num >= 100 && num <= 999); \
- http->status = num; \
-} \
- \
-int \
-VRT_r_##obj##_status(const struct sess *sp) \
-{ \
- \
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
- return(http->status); \
-}
-
-VRT_DO_STATUS(obj, sp->obj->http);
-VRT_DO_STATUS(beresp, sp->wrk->beresp);
-VRT_DO_STATUS(resp, sp->wrk->resp);
-
-/*--------------------------------------------------------------------*/
-
-/* XXX: review this */
-/* Add an objecthead to the saintmode list for the (hopefully) relevant
- * backend. Some double-up asserting here to avoid assert-errors when there
- * is no object.
- */
void
-VRT_l_beresp_saintmode(const struct sess *sp, double a)
-{
- struct trouble *new;
- struct trouble *tr;
- struct trouble *tr2;
-
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- if (!sp->vbc)
- return;
- CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC);
- if (!sp->vbc->backend)
- return;
- CHECK_OBJ_NOTNULL(sp->vbc->backend, BACKEND_MAGIC);
- if (!sp->objhead)
- return;
- CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC);
-
- /* Setting a negative holdoff period is a mistake. Detecting this
- * when compiling the VCL would be better.
- */
- assert(a > 0);
-
- ALLOC_OBJ(new, TROUBLE_MAGIC);
- AN(new);
- new->target = (uintptr_t)sp->objhead;
- new->timeout = sp->t_req + a;
-
- /* Insert the new item on the list before the first item with a
- * timeout at a later date (ie: sort by which entry will time out
- * from the list
- */
- Lck_Lock(&sp->vbc->backend->mtx);
- VTAILQ_FOREACH_SAFE(tr, &sp->vbc->backend->troublelist, list, tr2) {
- if (tr->timeout < new->timeout) {
- VTAILQ_INSERT_BEFORE(tr, new, list);
- new = NULL;
- break;
- }
- }
-
- /* Insert the item at the end if the list is empty or all other
- * items have a longer timeout.
- */
- if (new)
- VTAILQ_INSERT_TAIL(&sp->vbc->backend->troublelist, new, list);
-
- Lck_Unlock(&sp->vbc->backend->mtx);
-}
-/*--------------------------------------------------------------------*/
-
-#define VBERESP(dir, type, onm, field) \
-void \
-VRT_l_##dir##_##onm(const struct sess *sp, type a) \
-{ \
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
- sp->wrk->field = a; \
-} \
- \
-type \
-VRT_r_##dir##_##onm(const struct sess *sp) \
-{ \
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
- return (sp->wrk->field); \
-}
-
-VBERESP(beresp, unsigned, cacheable, cacheable)
-
-/*--------------------------------------------------------------------*/
-
-const char *
-VRT_r_client_identity(struct sess *sp)
-{
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- if (sp->client_identity != NULL)
- return (sp->client_identity);
- else
- return (sp->addr);
-}
-
-void
-VRT_l_client_identity(struct sess *sp, const char *str, ...)
-{
- va_list ap;
- char *b;
-
- va_start(ap, str);
- b = vrt_assemble_string(sp->http, NULL, str, ap);
- va_end(ap);
- sp->client_identity = b;
-}
-
-/*--------------------------------------------------------------------
- * XXX: Working relative to t_req is maybe not the right thing, we could
- * XXX: have spent a long time talking to the backend since then.
- * XXX: It might make sense to cache a timestamp as "current time"
- * XXX: before vcl_recv (== t_req) and vcl_fetch.
- * XXX: On the other hand, that might lead to inconsistent behaviour
- * XXX: where an object expires while we are running VCL code, and
- * XXX: and that may not be a good idea either.
- * XXX: See also related t_req use in cache_hash.c
- */
-
-void
-VRT_l_beresp_ttl(const struct sess *sp, double a)
-{
-
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- WSP(sp, SLT_TTL, "%u VCL %.0f %.0f", sp->xid, a, sp->t_req);
- /*
- * If people set obj.ttl = 0s, they don't expect it to be cacheable
- * any longer, but it will still be for up to 1s - epsilon because
- * of the rounding to seconds.
- * We special case and make sure that rounding does not surprise.
- */
- if (a <= 0)
- sp->wrk->ttl = sp->t_req - 1;
- else
- sp->wrk->ttl = sp->t_req + a;
-}
-
-double
-VRT_r_beresp_ttl(const struct sess *sp)
-{
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- return (sp->wrk->ttl - sp->t_req);
-}
-
-/*--------------------------------------------------------------------*/
-
-#define BEREQ_TIMEOUT(which) \
-void \
-VRT_l_bereq_##which(struct sess *sp, double num) \
-{ \
- \
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
- sp->wrk->which = (num > 0.0 ? num : 0.0); \
-} \
- \
-double \
-VRT_r_bereq_##which(struct sess *sp) \
-{ \
- \
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
- return(sp->wrk->which); \
-}
-
-BEREQ_TIMEOUT(connect_timeout)
-BEREQ_TIMEOUT(first_byte_timeout)
-BEREQ_TIMEOUT(between_bytes_timeout)
-
-/*--------------------------------------------------------------------*/
-
-const char *
-VRT_r_beresp_backend_name(const struct sess *sp)
-{
-
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC);
- return(sp->vbc->backend->vcl_name);
-}
-
-struct sockaddr *
-VRT_r_beresp_backend_ip(const struct sess *sp)
-{
-
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC);
- return(sp->vbc->addr);
-}
-
-int
-VRT_r_beresp_backend_port(const struct sess *sp)
-{
-
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC);
- return (TCP_port(sp->vbc->addr));
-}
-
-/*--------------------------------------------------------------------*/
-
-void
VRT_handling(struct sess *sp, unsigned hand)
{
@@ -513,244 +250,6 @@
}
/*--------------------------------------------------------------------
- * XXX: Working relative to t_req is maybe not the right thing, we could
- * XXX: have spent a long time talking to the backend since then.
- * XXX: It might make sense to cache a timestamp as "current time"
- * XXX: before vcl_recv (== t_req) and vcl_fetch.
- * XXX: On the other hand, that might lead to inconsistent behaviour
- * XXX: where an object expires while we are running VCL code, and
- * XXX: and that may not be a good idea either.
- * XXX: See also related t_req use in cache_hash.c
- */
-
-void
-VRT_l_obj_ttl(const struct sess *sp, double a)
-{
-
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); /* XXX */
- if (sp->obj->objcore == NULL)
- return;
- WSP(sp, SLT_TTL, "%u VCL %.0f %.0f",
- sp->obj->xid, a, sp->t_req);
- /*
- * If people set obj.ttl = 0s, they don't expect it to be cacheable
- * any longer, but it will still be for up to 1s - epsilon because
- * of the rounding to seconds.
- * We special case and make sure that rounding does not surprise.
- */
- if (a <= 0)
- sp->obj->ttl = sp->t_req - 1;
- else
- sp->obj->ttl = sp->t_req + a;
- EXP_Rearm(sp->obj);
-}
-
-double
-VRT_r_obj_ttl(const struct sess *sp)
-{
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); /* XXX */
- if (sp->obj->objcore == NULL)
- return (0.0);
- return (sp->obj->ttl - sp->t_req);
-}
-
-
-/*--------------------------------------------------------------------*/
-
-#define VOBJ(type,onm,field) \
-void \
-VRT_l_obj_##onm(const struct sess *sp, type a) \
-{ \
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
- CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); /* XXX */ \
- sp->obj->field = a; \
-} \
- \
-type \
-VRT_r_obj_##onm(const struct sess *sp) \
-{ \
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
- CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); /* XXX */ \
- return (sp->obj->field); \
-}
-
-VOBJ(unsigned, cacheable, cacheable)
-
-/*--------------------------------------------------------------------*/
-
-void
-VRT_l_req_backend(struct sess *sp, struct director *be)
-{
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- sp->director = be;
-}
-
-/*lint -e{818} sp could be const */
-struct director *
-VRT_r_req_backend(struct sess *sp)
-{
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- return (sp->director);
-}
-
-/*--------------------------------------------------------------------*/
-
-void
-VRT_l_req_esi(struct sess *sp, unsigned process_esi)
-{
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- /*
- * Only allow you to turn of esi in the main request
- * else everything gets confused
- */
- if(sp->esis == 0)
- sp->disable_esi = !process_esi;
-}
-
-unsigned
-VRT_r_req_esi(struct sess *sp)
-{
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- return (!sp->disable_esi);
-}
-
-/*--------------------------------------------------------------------*/
-
-int
-VRT_r_req_restarts(const struct sess *sp)
-{
-
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- return (sp->restarts);
-}
-
-/*--------------------------------------------------------------------*/
-
-#define VRT_DO_GRACE(which, fld, extra) \
-void \
-VRT_l_##which##_grace(struct sess *sp, double a) \
-{ \
- \
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
- fld = a >= 0.0 ? a : NAN; \
- extra; \
-} \
- \
-double \
-VRT_r_##which##_grace(struct sess *sp) \
-{ \
- \
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
- if (isnan(fld)) \
- return ((double)params->default_grace); \
- return(fld); \
-}
-
-VRT_DO_GRACE(req, sp->grace, )
-VRT_DO_GRACE(obj, sp->obj->grace, EXP_Rearm(sp->obj))
-VRT_DO_GRACE(beresp, sp->wrk->grace, )
-
-/*--------------------------------------------------------------------
- * req.xid
- */
-
-/*lint -e{818} sp could be const */
-const char *
-VRT_r_req_xid(struct sess *sp)
-{
- char *p;
- int size;
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
-
- size = snprintf(NULL, 0, "%u", sp->xid) + 1;
- AN(p = WS_Alloc(sp->http->ws, size));
- assert(snprintf(p, size, "%u", sp->xid) < size);
- return (p);
-}
-
-/*--------------------------------------------------------------------*/
-
-#define REQ_BOOL(which) \
-void \
-VRT_l_req_##which(struct sess *sp, unsigned val) \
-{ \
- \
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
- sp->which = val ? 1 : 0; \
-} \
- \
-unsigned \
-VRT_r_req_##which(struct sess *sp) \
-{ \
- \
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
- return(sp->which); \
-}
-
-REQ_BOOL(hash_ignore_busy)
-REQ_BOOL(hash_always_miss)
-
-/*--------------------------------------------------------------------*/
-
-struct sockaddr *
-VRT_r_client_ip(const struct sess *sp)
-{
-
- return (sp->sockaddr);
-}
-
-struct sockaddr *
-VRT_r_server_ip(struct sess *sp)
-{
- int i;
-
- if (sp->mysockaddr->sa_family == AF_UNSPEC) {
- i = getsockname(sp->fd, sp->mysockaddr, &sp->mysockaddrlen);
- assert(TCP_Check(i));
- }
-
- return (sp->mysockaddr);
-}
-
-const char*
-VRT_r_server_identity(struct sess *sp)
-{
- (void)sp;
-
- if (heritage.identity[0] != '\0')
- return heritage.identity;
- else
- return heritage.name;
-}
-
-
-const char*
-VRT_r_server_hostname(struct sess *sp)
-{
- (void)sp;
-
- if (vrt_hostname[0] == '\0')
- AZ(gethostname(vrt_hostname, sizeof(vrt_hostname)));
-
- return (vrt_hostname);
-}
-
-/*--------------------------------------------------------------------
- * XXX: This is pessimistically silly
- */
-
-int
-VRT_r_server_port(struct sess *sp)
-{
-
- if (sp->mysockaddr->sa_family == AF_UNSPEC)
- AZ(getsockname(sp->fd, sp->mysockaddr, &sp->mysockaddrlen));
- return (TCP_port(sp->mysockaddr));
-}
-
-/*--------------------------------------------------------------------
* Add an element to the array/list of hash bits.
*/
@@ -780,32 +279,6 @@
return (TIM_real());
}
-int
-VRT_r_obj_hits(const struct sess *sp)
-{
-
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); /* XXX */
- return (sp->obj->hits);
-}
-
-double
-VRT_r_obj_lastuse(const struct sess *sp)
-{
-
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); /* XXX */
- return (TIM_real() - sp->obj->last_use);
-}
-
-unsigned
-VRT_r_req_backend_healthy(const struct sess *sp)
-{
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
- return (VDI_Healthy_sp(sp, sp->director));
-}
-
/*--------------------------------------------------------------------*/
char *
Copied: trunk/varnish-cache/bin/varnishd/cache_vrt_var.c (from rev 5379, trunk/varnish-cache/bin/varnishd/cache_vrt.c)
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_vrt_var.c (rev 0)
+++ trunk/varnish-cache/bin/varnishd/cache_vrt_var.c 2010-10-01 10:02:54 UTC (rev 5381)
@@ -0,0 +1,566 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2009 Linpro AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * 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.
+ *
+ * Runtime support for compiled VCL programs
+ */
+#include "config.h"
+
+#include "svnid.h"
+SVNID("$Id$")
+
+#include <stdio.h>
+#include <math.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include "vrt.h"
+#include "vrt_obj.h"
+#include "cache.h"
+#include "cache_backend.h"
+#include "hash_slinger.h"
+
+static char vrt_hostname[255] = "";
+
+/*--------------------------------------------------------------------*/
+
+static void
+vrt_do_string(struct worker *w, int fd, struct http *hp, int fld,
+ const char *err, const char *p, va_list ap)
+{
+ char *b;
+
+ // AN(p);
+ AN(hp);
+ b = VRT_String(hp->ws, NULL, p, ap);
+ if (b == NULL || *b == '\0') {
+ WSL(w, SLT_LostHeader, fd, err);
+ } else {
+ http_SetH(hp, fld, b);
+ }
+ va_end(ap);
+}
+
+#define VRT_DO_HDR(obj, hdr, http, fld) \
+void \
+VRT_l_##obj##_##hdr(const struct sess *sp, const char *p, ...) \
+{ \
+ va_list ap; \
+ \
+ va_start(ap, p); \
+ vrt_do_string(sp->wrk, sp->fd, \
+ http, fld, #obj "." #hdr, p, ap); \
+ va_end(ap); \
+} \
+ \
+const char * \
+VRT_r_##obj##_##hdr(const struct sess *sp) \
+{ \
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
+ CHECK_OBJ_NOTNULL(http, HTTP_MAGIC); \
+ return (http->hd[fld].b); \
+}
+
+VRT_DO_HDR(req, request, sp->http, HTTP_HDR_REQ)
+VRT_DO_HDR(req, url, sp->http, HTTP_HDR_URL)
+VRT_DO_HDR(req, proto, sp->http, HTTP_HDR_PROTO)
+VRT_DO_HDR(bereq, request, sp->wrk->bereq, HTTP_HDR_REQ)
+VRT_DO_HDR(bereq, url, sp->wrk->bereq, HTTP_HDR_URL)
+VRT_DO_HDR(bereq, proto, sp->wrk->bereq, HTTP_HDR_PROTO)
+VRT_DO_HDR(obj, proto, sp->obj->http, HTTP_HDR_PROTO)
+VRT_DO_HDR(obj, response, sp->obj->http, HTTP_HDR_RESPONSE)
+VRT_DO_HDR(resp, proto, sp->wrk->resp, HTTP_HDR_PROTO)
+VRT_DO_HDR(resp, response, sp->wrk->resp, HTTP_HDR_RESPONSE)
+VRT_DO_HDR(beresp, proto, sp->wrk->beresp, HTTP_HDR_PROTO)
+VRT_DO_HDR(beresp, response, sp->wrk->beresp, HTTP_HDR_RESPONSE)
+
+/*--------------------------------------------------------------------*/
+
+#define VRT_DO_STATUS(obj, http) \
+void \
+VRT_l_##obj##_status(const struct sess *sp, int num) \
+{ \
+ \
+ assert(num >= 100 && num <= 999); \
+ http->status = num; \
+} \
+ \
+int \
+VRT_r_##obj##_status(const struct sess *sp) \
+{ \
+ \
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
+ return(http->status); \
+}
+
+VRT_DO_STATUS(obj, sp->obj->http);
+VRT_DO_STATUS(beresp, sp->wrk->beresp);
+VRT_DO_STATUS(resp, sp->wrk->resp);
+
+/*--------------------------------------------------------------------*/
+
+/* XXX: review this */
+/* Add an objecthead to the saintmode list for the (hopefully) relevant
+ * backend. Some double-up asserting here to avoid assert-errors when there
+ * is no object.
+ */
+void
+VRT_l_beresp_saintmode(const struct sess *sp, double a)
+{
+ struct trouble *new;
+ struct trouble *tr;
+ struct trouble *tr2;
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ if (!sp->vbc)
+ return;
+ CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC);
+ if (!sp->vbc->backend)
+ return;
+ CHECK_OBJ_NOTNULL(sp->vbc->backend, BACKEND_MAGIC);
+ if (!sp->objhead)
+ return;
+ CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC);
+
+ /* Setting a negative holdoff period is a mistake. Detecting this
+ * when compiling the VCL would be better.
+ */
+ assert(a > 0);
+
+ ALLOC_OBJ(new, TROUBLE_MAGIC);
+ AN(new);
+ new->target = (uintptr_t)sp->objhead;
+ new->timeout = sp->t_req + a;
+
+ /* Insert the new item on the list before the first item with a
+ * timeout at a later date (ie: sort by which entry will time out
+ * from the list
+ */
+ Lck_Lock(&sp->vbc->backend->mtx);
+ VTAILQ_FOREACH_SAFE(tr, &sp->vbc->backend->troublelist, list, tr2) {
+ if (tr->timeout < new->timeout) {
+ VTAILQ_INSERT_BEFORE(tr, new, list);
+ new = NULL;
+ break;
+ }
+ }
+
+ /* Insert the item at the end if the list is empty or all other
+ * items have a longer timeout.
+ */
+ if (new)
+ VTAILQ_INSERT_TAIL(&sp->vbc->backend->troublelist, new, list);
+
+ Lck_Unlock(&sp->vbc->backend->mtx);
+}
+
+/*--------------------------------------------------------------------*/
+
+#define VBERESP(dir, type, onm, field) \
+void \
+VRT_l_##dir##_##onm(const struct sess *sp, type a) \
+{ \
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
+ sp->wrk->field = a; \
+} \
+ \
+type \
+VRT_r_##dir##_##onm(const struct sess *sp) \
+{ \
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
+ return (sp->wrk->field); \
+}
+
+VBERESP(beresp, unsigned, cacheable, cacheable)
+
+/*--------------------------------------------------------------------*/
+
+const char *
+VRT_r_client_identity(struct sess *sp)
+{
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ if (sp->client_identity != NULL)
+ return (sp->client_identity);
+ else
+ return (sp->addr);
+}
+
+void
+VRT_l_client_identity(struct sess *sp, const char *str, ...)
+{
+ va_list ap;
+ char *b;
+
+ va_start(ap, str);
+ b = VRT_String(sp->http->ws, NULL, str, ap);
+ va_end(ap);
+ sp->client_identity = b;
+}
+
+/*--------------------------------------------------------------------
+ * XXX: Working relative to t_req is maybe not the right thing, we could
+ * XXX: have spent a long time talking to the backend since then.
+ * XXX: It might make sense to cache a timestamp as "current time"
+ * XXX: before vcl_recv (== t_req) and vcl_fetch.
+ * XXX: On the other hand, that might lead to inconsistent behaviour
+ * XXX: where an object expires while we are running VCL code, and
+ * XXX: and that may not be a good idea either.
+ * XXX: See also related t_req use in cache_hash.c
+ */
+
+void
+VRT_l_beresp_ttl(const struct sess *sp, double a)
+{
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ WSP(sp, SLT_TTL, "%u VCL %.0f %.0f", sp->xid, a, sp->t_req);
+ /*
+ * If people set obj.ttl = 0s, they don't expect it to be cacheable
+ * any longer, but it will still be for up to 1s - epsilon because
+ * of the rounding to seconds.
+ * We special case and make sure that rounding does not surprise.
+ */
+ if (a <= 0)
+ sp->wrk->ttl = sp->t_req - 1;
+ else
+ sp->wrk->ttl = sp->t_req + a;
+}
+
+double
+VRT_r_beresp_ttl(const struct sess *sp)
+{
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ return (sp->wrk->ttl - sp->t_req);
+}
+
+/*--------------------------------------------------------------------*/
+
+#define BEREQ_TIMEOUT(which) \
+void \
+VRT_l_bereq_##which(struct sess *sp, double num) \
+{ \
+ \
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
+ sp->wrk->which = (num > 0.0 ? num : 0.0); \
+} \
+ \
+double \
+VRT_r_bereq_##which(struct sess *sp) \
+{ \
+ \
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
+ return(sp->wrk->which); \
+}
+
+BEREQ_TIMEOUT(connect_timeout)
+BEREQ_TIMEOUT(first_byte_timeout)
+BEREQ_TIMEOUT(between_bytes_timeout)
+
+/*--------------------------------------------------------------------*/
+
+const char *
+VRT_r_beresp_backend_name(const struct sess *sp)
+{
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC);
+ return(sp->vbc->backend->vcl_name);
+}
+
+struct sockaddr *
+VRT_r_beresp_backend_ip(const struct sess *sp)
+{
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC);
+ return(sp->vbc->addr);
+}
+
+int
+VRT_r_beresp_backend_port(const struct sess *sp)
+{
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC);
+ return (TCP_port(sp->vbc->addr));
+}
+
+void
+VRT_l_obj_ttl(const struct sess *sp, double a)
+{
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); /* XXX */
+ if (sp->obj->objcore == NULL)
+ return;
+ WSP(sp, SLT_TTL, "%u VCL %.0f %.0f",
+ sp->obj->xid, a, sp->t_req);
+ /*
+ * If people set obj.ttl = 0s, they don't expect it to be cacheable
+ * any longer, but it will still be for up to 1s - epsilon because
+ * of the rounding to seconds.
+ * We special case and make sure that rounding does not surprise.
+ */
+ if (a <= 0)
+ sp->obj->ttl = sp->t_req - 1;
+ else
+ sp->obj->ttl = sp->t_req + a;
+ EXP_Rearm(sp->obj);
+}
+
+double
+VRT_r_obj_ttl(const struct sess *sp)
+{
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); /* XXX */
+ if (sp->obj->objcore == NULL)
+ return (0.0);
+ return (sp->obj->ttl - sp->t_req);
+}
+
+
+/*--------------------------------------------------------------------*/
+
+#define VOBJ(type,onm,field) \
+void \
+VRT_l_obj_##onm(const struct sess *sp, type a) \
+{ \
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
+ CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); /* XXX */ \
+ sp->obj->field = a; \
+} \
+ \
+type \
+VRT_r_obj_##onm(const struct sess *sp) \
+{ \
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
+ CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); /* XXX */ \
+ return (sp->obj->field); \
+}
+
+VOBJ(unsigned, cacheable, cacheable)
+
+/*--------------------------------------------------------------------*/
+
+void
+VRT_l_req_backend(struct sess *sp, struct director *be)
+{
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ sp->director = be;
+}
+
+/*lint -e{818} sp could be const */
+struct director *
+VRT_r_req_backend(struct sess *sp)
+{
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ return (sp->director);
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+VRT_l_req_esi(struct sess *sp, unsigned process_esi)
+{
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ /*
+ * Only allow you to turn of esi in the main request
+ * else everything gets confused
+ */
+ if(sp->esis == 0)
+ sp->disable_esi = !process_esi;
+}
+
+unsigned
+VRT_r_req_esi(struct sess *sp)
+{
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ return (!sp->disable_esi);
+}
+
+/*--------------------------------------------------------------------*/
+
+int
+VRT_r_req_restarts(const struct sess *sp)
+{
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ return (sp->restarts);
+}
+
+/*--------------------------------------------------------------------*/
+
+#define VRT_DO_GRACE(which, fld, extra) \
+void \
+VRT_l_##which##_grace(struct sess *sp, double a) \
+{ \
+ \
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
+ fld = a >= 0.0 ? a : NAN; \
+ extra; \
+} \
+ \
+double \
+VRT_r_##which##_grace(struct sess *sp) \
+{ \
+ \
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
+ if (isnan(fld)) \
+ return ((double)params->default_grace); \
+ return(fld); \
+}
+
+VRT_DO_GRACE(req, sp->grace, )
+VRT_DO_GRACE(obj, sp->obj->grace, EXP_Rearm(sp->obj))
+VRT_DO_GRACE(beresp, sp->wrk->grace, )
+
+/*--------------------------------------------------------------------
+ * req.xid
+ */
+
+/*lint -e{818} sp could be const */
+const char *
+VRT_r_req_xid(struct sess *sp)
+{
+ char *p;
+ int size;
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+
+ size = snprintf(NULL, 0, "%u", sp->xid) + 1;
+ AN(p = WS_Alloc(sp->http->ws, size));
+ assert(snprintf(p, size, "%u", sp->xid) < size);
+ return (p);
+}
+
+/*--------------------------------------------------------------------*/
+
+#define REQ_BOOL(which) \
+void \
+VRT_l_req_##which(struct sess *sp, unsigned val) \
+{ \
+ \
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
+ sp->which = val ? 1 : 0; \
+} \
+ \
+unsigned \
+VRT_r_req_##which(struct sess *sp) \
+{ \
+ \
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
+ return(sp->which); \
+}
+
+REQ_BOOL(hash_ignore_busy)
+REQ_BOOL(hash_always_miss)
+
+/*--------------------------------------------------------------------*/
+
+struct sockaddr *
+VRT_r_client_ip(const struct sess *sp)
+{
+
+ return (sp->sockaddr);
+}
+
+struct sockaddr *
+VRT_r_server_ip(struct sess *sp)
+{
+ int i;
+
+ if (sp->mysockaddr->sa_family == AF_UNSPEC) {
+ i = getsockname(sp->fd, sp->mysockaddr, &sp->mysockaddrlen);
+ assert(TCP_Check(i));
+ }
+
+ return (sp->mysockaddr);
+}
+
+const char*
+VRT_r_server_identity(struct sess *sp)
+{
+ (void)sp;
+
+ if (heritage.identity[0] != '\0')
+ return heritage.identity;
+ else
+ return heritage.name;
+}
+
+
+const char*
+VRT_r_server_hostname(struct sess *sp)
+{
+ (void)sp;
+
+ if (vrt_hostname[0] == '\0')
+ AZ(gethostname(vrt_hostname, sizeof(vrt_hostname)));
+
+ return (vrt_hostname);
+}
+
+/*--------------------------------------------------------------------
+ * XXX: This is pessimistically silly
+ */
+
+int
+VRT_r_server_port(struct sess *sp)
+{
+
+ if (sp->mysockaddr->sa_family == AF_UNSPEC)
+ AZ(getsockname(sp->fd, sp->mysockaddr, &sp->mysockaddrlen));
+ return (TCP_port(sp->mysockaddr));
+}
+
+/*--------------------------------------------------------------------*/
+
+int
+VRT_r_obj_hits(const struct sess *sp)
+{
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); /* XXX */
+ return (sp->obj->hits);
+}
+
+double
+VRT_r_obj_lastuse(const struct sess *sp)
+{
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); /* XXX */
+ return (TIM_real() - sp->obj->last_use);
+}
+
+unsigned
+VRT_r_req_backend_healthy(const struct sess *sp)
+{
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
+ return (VDI_Healthy_sp(sp, sp->director));
+}
+
Modified: trunk/varnish-cache/include/vrt.h
===================================================================
--- trunk/varnish-cache/include/vrt.h 2010-10-01 10:01:30 UTC (rev 5380)
+++ trunk/varnish-cache/include/vrt.h 2010-10-01 10:02:54 UTC (rev 5381)
@@ -221,4 +221,4 @@
return (1); \
} while (0)
-const char *VRT_String(const struct sess *sp, const char *p, ...);
+const char *VRT_WrkString(const struct sess *sp, const char *p, ...);
Modified: trunk/varnish-cache/lib/libvcl/vcc_expr.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-10-01 10:01:30 UTC (rev 5380)
+++ trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-10-01 10:02:54 UTC (rev 5381)
@@ -702,7 +702,7 @@
}
if (fmt != STRING_LIST && (*e)->fmt == STRING_LIST)
*e = vcc_expr_edit(STRING,
- "\v+VRT_String(sp,\n\v1,\nvrt_magic_string_end)", *e, NULL);
+ "\v+VRT_WrkString(sp,\n\v1,\nvrt_magic_string_end)", *e, NULL);
if (fmt == STRING_LIST && (*e)->fmt == STRING)
(*e)->fmt = STRING_LIST;
More information about the varnish-commit
mailing list