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