]> err.no Git - varnish/commitdiff
Having thought long and hard about this, commit what I think is the
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Tue, 6 Mar 2007 22:40:06 +0000 (22:40 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Tue, 6 Mar 2007 22:40:06 +0000 (22:40 +0000)
new and simpler flow for version2.

Pass is now handled like a miss where the object will not be cached.

The main result of this is that we drag the entire object, header
and body, from the backend before transmitting it to the client,
thus isolating the backend from slow clients.

From a software engineering point of view it is a big improvement,
because it eliminates the need for all of cache_pass.c and we therefore
end up with less HTTP protocol implementations.

A side effect of this is that ticket #56 should be fixed now.

If the object is pass'ed before vcl_fetch{} that is, in vcl_recv{},
vcl_hit{} or vcl_miss{}, no "pass this" object is inserted in the
cache.  The confusion between "pass", "insert" and "insert_pass"
has been cleaned up, by the removal of the latter.

Pipe and Pass calls vcl_pipe{} and vcl_pass{} respectively, before
contacting the backend.  I havn't quite decided if they should
operate on the request header from the client or the one to the
backend, or both.

One possible use is to inject a "Connection: close" header to limit
pipe to one transaction.

A new vcl_hash{} has been added, it will allow customization of
which fields we hash on, instead of the default "url + Host:" but
this is not yet implemented.

vcl_fetch{} is now called after both the headers and body have been
picked up from the backend.  This will allow us to do more comprehensive
handling of backend errors later on.

A disadvantage to this is that if the object ends up as a "pass
this" object in the cache, we could possibly have released any
queued requests already after the headers were received.  If this
is transpires as a real-world problem, we can add a vcl_fetchhdr{}
which can do an early release (ie: "pass").

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@1277 d4fa192b-c00b-0410-8231-f00ffab90ce4

14 files changed:
varnish-cache/bin/varnishd/Makefile.am
varnish-cache/bin/varnishd/cache.h
varnish-cache/bin/varnishd/cache_center.c
varnish-cache/bin/varnishd/cache_fetch.c
varnish-cache/bin/varnishd/cache_hash.c
varnish-cache/bin/varnishd/cache_pass.c [deleted file]
varnish-cache/bin/varnishd/cache_vrt.c
varnish-cache/bin/varnishd/mgt_vcc.c
varnish-cache/bin/varnishd/steps.h
varnish-cache/include/vcl.h
varnish-cache/include/vcl_returns.h
varnish-cache/lib/libvcl/vcc_fixed_token.c
varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl
varnish-cache/lib/libvcl/vcc_token_defs.h

index 53ca42496e15b1772b0a253a4fb338d4067abe6b..e11bbdc4f18b48e9d9efd4a5d2ac0ab7bfb13497 100644 (file)
@@ -21,7 +21,6 @@ varnishd_SOURCES = \
        cache_http.c \
        cache_main.c \
        cache_pool.c \
-       cache_pass.c \
        cache_pipe.c \
        cache_response.c \
        cache_session.c \
index 112354dd04b18ba129543f934681cd6fc6efa71f..5090ecd21a1b811fcfa42b6f0ee55f0bd0177a4e 100644 (file)
@@ -279,7 +279,6 @@ struct sess {
 
        TAILQ_ENTRY(sess)       list;
 
-       struct vbe_conn         *vbc;
        struct backend          *backend;
        struct object           *obj;
        struct VCL_conf         *vcl;
@@ -348,10 +347,10 @@ void EXP_Init(void);
 void EXP_TTLchange(struct object *o);
 
 /* cache_fetch.c */
-int FetchBody(struct sess *sp);
-int FetchHeaders(struct sess *sp);
+int Fetch(struct sess *sp);
 
 /* cache_hash.c */
+void HSH_Prealloc(struct sess *sp);
 struct object *HSH_Lookup(struct sess *sp);
 void HSH_Unbusy(struct object *o);
 void HSH_Ref(struct object *o);
@@ -390,10 +389,6 @@ void http_DoConnection(struct sess *sp);
 #include "http_headers.h"
 #undef HTTPH
 
-/* cache_pass.c */
-int PassSession(struct sess *sp);
-void PassBody(struct sess *sp);
-
 /* cache_pipe.c */
 void PipeSession(struct sess *sp);
 
index 0714599f40c09c3f33e2e4458f099be76767d35b..2e0107d38d1eab5bd0aea15a29f19672d4f9aceb 100644 (file)
 
 /*
 DOT digraph vcl_center {
-DOT    page="8.2,11.7"
-DOT    size="6.3,9.7"
-DOT    margin="1.0"
+xDOT   page="8.2,11.5"
+DOT    size="7.2,10.5"
+DOT    margin="0.5"
+DOT    center="1"
 DOT start [
 DOT    shape=hexagon
-DOT    label="Start"
+DOT    label="Request received"
 DOT ]
-DOT start -> RECV
+DOT RECV [shape=plaintext]
+DOT PIPE [shape=plaintext]
+DOT LOOKUP [shape=plaintext]
+DOT HIT [shape=plaintext]
+DOT MISS [shape=plaintext]
+DOT PASS [shape=plaintext]
+DOT FETCH [shape=plaintext]
+DOT DELIVER [shape=plaintext]
+DOT ERROR [shape=plaintext]
+DOT start -> RECV [style=bold,color=green,weight=4]
  */
 
 #include <stdio.h>
@@ -71,8 +81,13 @@ DOT start -> RECV
 static unsigned xids;
 
 /*--------------------------------------------------------------------
- * The very first request
+ * AGAIN
+ * We come here when we just completed a request and already have
+ * received (part of) the next one.  Instead taking the detour
+ * around the acceptor and then back to a worker, just stay in this
+ * worker and do what it takes.
  */
+
 static int
 cnt_again(struct sess *sp)
 {
@@ -101,19 +116,19 @@ cnt_again(struct sess *sp)
 /*--------------------------------------------------------------------
  * We have a refcounted object on the session, now deliver it.
  *
-DOT subgraph cluster_deliver {
+DOT subgraph xcluster_deliver {
 DOT    deliver [
 DOT            shape=ellipse
 DOT            label="Build & send header"
 DOT    ]
-DOT    DELIVER -> deliver [style=bold]
+DOT    DELIVER -> deliver [style=bold,color=green,weight=4]
 DOT    deliver2 [
 DOT            shape=ellipse
 DOT            label="Send object"
 DOT    ]
-DOT    deliver -> deliver2 [style=bold]
+DOT    deliver -> deliver2 [style=bold,color=green,weight=4]
 DOT }
-DOT deliver2 -> DONE [style=bold]
+DOT deliver2 -> DONE [style=bold,color=green,weight=4]
  */
 
 static int
@@ -154,7 +169,6 @@ cnt_done(struct sess *sp)
        double dh, dp, da;
 
        AZ(sp->obj);
-       AZ(sp->vbc);
        sp->backend = NULL;
        if (sp->vcl != NULL) {
                if (sp->wrk->vcl != NULL)
@@ -211,7 +225,7 @@ cnt_done(struct sess *sp)
 /*--------------------------------------------------------------------
  * Emit an error
  *
-DOT subgraph cluster_error {
+DOT subgraph xcluster_error {
 DOT    error [
 DOT            shape=ellipse
 DOT            label="Issue HTTP error"
@@ -237,99 +251,61 @@ cnt_error(struct sess *sp)
  * We have fetched the headers from the backend, ask the VCL code what
  * to do next, then head off in that direction.
  *
-DOT subgraph cluster_fetch {
+DOT subgraph xcluster_fetch {
 DOT    fetch [
 DOT            shape=ellipse
-DOT            label="find obj.ttl\nobj.cacheable"
+DOT            label="fetch from backend\n(find obj.ttl)"
 DOT    ]
-DOT    FETCH -> fetch [style=bold]
+DOT    FETCH -> fetch [style=bold,color=blue,weight=2]
 DOT    vcl_fetch [
 DOT            shape=box
 DOT            label="vcl_fetch()"
 DOT    ]
-DOT    fetch -> vcl_fetch [style=bold]
-DOT    fetch_lookup [
-DOT            shape=ellipse
-DOT            label="obj.cacheable=false\nunbusy obj\ndiscard body\n"
-DOT    ]
-DOT    vcl_fetch -> fetch_lookup [label="lookup", style=dotted, weight=0]
+DOT    fetch -> vcl_fetch [style=bold,color=blue,weight=2]
 DOT    fetch_pass [
 DOT            shape=ellipse
-DOT            label="obj.cacheable=false\nunbusy obj"
+DOT            label="obj.pass=true"
 DOT    ]
 DOT    vcl_fetch -> fetch_pass [label="pass"]
-DOT    fetch_ipass [
-DOT            shape=ellipse
-DOT            label="obj.cacheable=true\nobj.pass=true\nunbusy obj"
-DOT    ]
-DOT    vcl_fetch -> fetch_ipass [label="insert_pass"]
-DOT    fetch_insert [
-DOT            shape=ellipse
-DOT            label="rcv body\nobj.cacheable=true\nunbusy"
-DOT    ]
-DOT    vcl_fetch -> fetch_insert [label="insert", style=bold]
-DOT    fetch_error [
-DOT            shape=ellipse
-DOT            label="disc body\nobj.cacheable=false\nunbusy"
-DOT    ]
-DOT    vcl_fetch -> fetch_error [label="error"]
 DOT }
-DOT fetch_lookup -> LOOKUP [style=dotted, weight=0]
-DOT fetch_pass -> PASSBODY
-DOT fetch_ipass -> PASSBODY
-DOT fetch_insert -> DELIVER [style=bold]
-DOT fetch_error -> ERROR
+DOT fetch_pass -> DELIVER
+DOT vcl_fetch -> DELIVER [label="insert",style=bold,color=blue,weight=2]
+DOT vcl_fetch -> errfetch [label="error"]
+DOT errfetch [label="ERROR",shape=plaintext]
  */
 
 static int
 cnt_fetch(struct sess *sp)
 {
 
-       CHECK_OBJ_NOTNULL(sp->vbc, VBE_CONN_MAGIC);
-       RFC2616_cache_policy(sp, sp->vbc->http);
-
-       VCL_fetch_method(sp);
 
-       if (sp->handling == VCL_RET_LOOKUP)
-               INCOMPL();
-       if (sp->handling == VCL_RET_PASS) {
+       if (Fetch(sp)) {
                sp->obj->cacheable = 0;
                HSH_Unbusy(sp->obj);
                HSH_Deref(sp->obj);
                sp->obj = NULL;
-               sp->step = STP_PASSBODY;
-               return (0);
-       }
-       if (sp->handling == VCL_RET_INSERT_PASS) {
-               sp->obj->pass = 1;
-               sp->obj->cacheable = 1;
-               HSH_Unbusy(sp->obj);
-               /* Don't HSH_Deref(sp->obj); we need the ref for storage */
-               sp->obj = NULL;
-               sp->step = STP_PASSBODY;
-               return (0);
-       }
-       if (sp->handling == VCL_RET_INSERT) {
-               if (FetchBody(sp)) {
-                       sp->obj->cacheable = 0;
-                       HSH_Unbusy(sp->obj);
-                       HSH_Deref(sp->obj);
-                       sp->obj = NULL;
-                       RES_Error(sp, 503, NULL);
-                       sp->step = STP_DONE;
-                       return (0);
-               }
-               sp->obj->cacheable = 1;
-               AZ(sp->vbc);
-               HSH_Ref(sp->obj); /* get another, STP_DELIVER will deref */
-               HSH_Unbusy(sp->obj);
-               sp->wrk->acct.fetch++;
-               sp->step = STP_DELIVER;
+               sp->step = STP_DONE;
+               RES_Error(sp, 503, NULL);
                return (0);
        }
+
+       RFC2616_cache_policy(sp, &sp->obj->http);       /* XXX -> VCL */
+
+       VCL_fetch_method(sp);
+
        if (sp->handling == VCL_RET_ERROR)
                INCOMPL();
-       INCOMPL();
+
+       if (sp->handling == VCL_RET_PASS)
+               sp->obj->pass = 1;
+
+       sp->obj->cacheable = 1;
+       HSH_Ref(sp->obj); /* get another, STP_DELIVER will deref */
+       if (sp->obj->objhead != NULL)
+               HSH_Unbusy(sp->obj);
+       sp->wrk->acct.fetch++;
+       sp->step = STP_DELIVER;
+       return (0);
 }
 
 /*--------------------------------------------------------------------
@@ -370,120 +346,96 @@ cnt_first(struct sess *sp)
 }
 
 /*--------------------------------------------------------------------
+ * HIT
  * We had a cache hit.  Ask VCL, then march off as instructed.
  *
-DOT subgraph cluster_hit {
+DOT subgraph xcluster_hit {
 DOT    hit [
 DOT            shape=box
 DOT            label="vcl_hit()"
 DOT    ]
-DOT    HIT -> hit [style=bold]
-DOT    hit2 [
-DOT            shape=diamond
-DOT            label="obj.pass ?"
-DOT    ]
-DOT    hit -> hit2 [label=deliver, style=bold]
-DOT    hit_lookup [
-DOT            shape=ellipse
-DOT            label="unbusy"
-DOT    ]
-DOT    hit -> hit_lookup [label="lookup", style=dotted, weight=0]
-DOT    hit_error [
-DOT            shape=ellipse
-DOT            label="unbusy"
-DOT    ]
-DOT    hit -> hit_error [label="error", weight=0]
-DOT    hit_pass [
-DOT            shape=ellipse
-DOT            label="unbusy"
-DOT    ]
-DOT    hit -> hit_pass [label=pass]
-DOT    hit2 -> hit_pass
+DOT    HIT -> hit [style=bold,color=green,weight=4]
 DOT }
-DOT hit_error -> ERROR
-DOT hit_pass -> PASS
-DOT hit_lookup -> LOOKUP [style=dotted, weight=0]
-DOT hit2 -> DELIVER [style=bold]
+DOT hit -> err_hit [label="error"]
+DOT err_hit [label="ERROR",shape=plaintext]
+DOT hit -> PASS [label=pass]
+DOT hit -> DELIVER [label="deliver",style=bold,color=green,weight=4]
  */
 
 static int
 cnt_hit(struct sess *sp)
 {
 
-       VCL_hit_method(sp);
+       assert(!sp->obj->pass);
 
-       if (sp->handling == VCL_RET_DELIVER && sp->obj->pass)
-               sp->handling = VCL_RET_PASS;
+       VCL_hit_method(sp);
 
        if (sp->handling == VCL_RET_DELIVER) {
                sp->step = STP_DELIVER;
                return (0);
        }
+
+       /* Drop our object, we won't need it */
+       HSH_Deref(sp->obj);
+       sp->obj = NULL;
+
        if (sp->handling == VCL_RET_PASS) {
-               HSH_Deref(sp->obj);
-               sp->obj = NULL;
                sp->step = STP_PASS;
                return (0);
        }
 
        if (sp->handling == VCL_RET_ERROR) {
-               HSH_Deref(sp->obj);
-               sp->obj = NULL;
                sp->step = STP_ERROR;
                return (0);
        }
 
-       if (sp->handling == VCL_RET_LOOKUP)
-               INCOMPL();
 
        INCOMPL();
 }
 
 
 /*--------------------------------------------------------------------
- * Look up request in hash table
+ * LOOKUP
+ * Hash things together and look object up in hash-table.
  *
  * LOOKUP consists of two substates so that we can reenter if we
  * encounter a busy object.
  *
-DOT subgraph cluster_lookup {
+DOT subgraph xcluster_lookup {
+DOT    hash [
+DOT            shape=box
+DOT            label="vcl_hash()"
+DOT    ]
 DOT    lookup [
 DOT            shape=ellipse
-DOT            label="find obj in cache"
+DOT            label="obj in cache ?"
 DOT    ]
-DOT    LOOKUP -> lookup [style=bold]
-DOT    lookup3 [
+DOT    lookup2 [
 DOT            shape=ellipse
-DOT            label="Insert new busy object"
+DOT            label="obj.pass ?"
 DOT    ]
-DOT    lookup -> lookup3 [style=bold]
+DOT    LOOKUP -> hash [style=bold,color=green,weight=4]
+DOT    hash -> lookup [label="hash",style=bold,color=green,weight=4]
+DOT    lookup -> lookup2 [label="yes",style=bold,color=green,weight=4]
 DOT }
-DOT lookup -> HIT [label="hit", style=bold]
-DOT lookup3 -> MISS [label="miss", style=bold]
+DOT lookup2 -> HIT [label="no", style=bold,color=green,weight=4]
+DOT lookup2 -> PASS [label="yes"]
+DOT lookup -> MISS [label="no",style=bold,color=blue,weight=2]
  */
 
 static int
 cnt_lookup(struct sess *sp)
-{
-
-       AZ(sp->obj);
-       sp->step = STP_LOOKUP2;
-       return (0);
-}
-
-static int
-cnt_lookup2(struct sess *sp)
 {
        struct object *o;
 
-       /*
-        * We don't assign to sp->obj directly because it is used
-        * to cache state when we encounter a busy object.
-        */
-       o = HSH_Lookup(sp);
+       VCL_hash_method(sp);            /* XXX: no-op for now */
 
-       /* If we encountered busy-object, disembark worker thread */
+       o = HSH_Lookup(sp);
        if (o == NULL) {
+               /*
+                * We hit a busy object, disembark worker thread and expect
+                * hash code to restart us, still in STP_LOOKUP, later.
+                */
                WSL(sp->wrk, SLT_Debug, sp->fd,
                    "on waiting list on obj %u", sp->obj->xid);
                SES_Charge(sp);
@@ -499,14 +451,17 @@ cnt_lookup2(struct sess *sp)
                return (0);
        }
 
-       /* Account separately for pass and cache objects */
        if (sp->obj->pass) {
                VSL_stats->cache_hitpass++;
                WSL(sp->wrk, SLT_HitPass, sp->fd, "%u", sp->obj->xid);
-       } else {
-               VSL_stats->cache_hit++;
-               WSL(sp->wrk, SLT_Hit, sp->fd, "%u", sp->obj->xid);
-       }
+               HSH_Deref(sp->obj);
+               sp->obj = NULL;
+               sp->step = STP_PASS;
+               return (0);
+       } 
+
+       VSL_stats->cache_hit++;
+       WSL(sp->wrk, SLT_Hit, sp->fd, "%u", sp->obj->xid);
        sp->step = STP_HIT;
        return (0);
 }
@@ -515,37 +470,21 @@ cnt_lookup2(struct sess *sp)
 /*--------------------------------------------------------------------
  * We had a miss, ask VCL, proceed as instructed
  *
-DOT subgraph cluster_miss {
+DOT subgraph xcluster_miss {
 DOT    miss [
 DOT            shape=box
 DOT            label="vcl_miss()"
 DOT    ]
-DOT    MISS -> miss [style=bold]
-DOT    miss_error [
-DOT            shape=ellipse
-DOT            label="obj.cacheable=false\nunbusy"
-DOT    ]
-DOT    miss -> miss_error [label="error"]
-DOT    miss_pass [
-DOT            shape=ellipse
-DOT            label="obj.cacheable=false\nunbusy"
+DOT    MISS -> miss [style=bold,color=blue,weight=2]
+DOT    miss_ins [
+DOT            label="insert new object"
 DOT    ]
-DOT    miss -> miss_pass [label="pass"]
-DOT    miss_lookup [
-DOT            shape=ellipse
-DOT            label="obj.cacheable=false\nunbusy"
-DOT    ]
-DOT    miss -> miss_lookup [label="lookup", style=dotted, weight=0]
-DOT    miss_fetch [
-DOT            shape=ellipse
-DOT            label="fetch obj headers\nfrom backend"
-DOT    ]
-DOT    miss -> miss_fetch [label="fetch", style=bold]
+DOT    miss -> miss_ins [label="fetch",style=bold,color=blue,weight=2]
 DOT }
-DOT miss_error -> ERROR
-DOT miss_pass -> PASS
-DOT miss_fetch -> FETCH [style=bold]
-DOT miss_lookup -> LOOKUP [style=dotted, weight=0]
+DOT miss -> err_miss [label="error"]
+DOT err_miss [label="ERROR",shape=plaintext]
+DOT miss_ins -> FETCH [style=bold,color=blue,weight=2]
+DOT miss -> PASS [label="pass"]
 DOT
  */
 
@@ -570,21 +509,8 @@ cnt_miss(struct sess *sp)
                sp->step = STP_PASS;
                return (0);
        }
-       if (sp->handling == VCL_RET_LOOKUP)
-               INCOMPL();
        if (sp->handling == VCL_RET_FETCH) {
-               AZ(sp->vbc);
-               if (FetchHeaders(sp)) {
-                       sp->obj->cacheable = 0;
-                       HSH_Unbusy(sp->obj);
-                       HSH_Deref(sp->obj);
-                       sp->obj = NULL;
-                       sp->step = STP_DONE;
-                       RES_Error(sp, 503, NULL);
-                       return (0);
-               }
                sp->step = STP_FETCH;
-               AN(sp->vbc);
                return (0);
        }
        INCOMPL();
@@ -595,69 +521,61 @@ cnt_miss(struct sess *sp)
  * Start pass processing by getting headers from backend, then
  * continue in passbody.
  *
-DOT subgraph cluster_pass {
+DOT subgraph xcluster_pass {
 DOT    pass [
+DOT            shape=box
+DOT            label="vcl_pass()"
+DOT    ]
+DOT    pass_do [
 DOT            shape=ellipse
-DOT            label="send to bke\nrx bkehdr"
+DOT            label="create new object\n"
 DOT    ]
 DOT    PASS -> pass
+DOT    pass -> pass_do [label="pass"]
 DOT }
-DOT pass -> PASSBODY
+DOT pass_do -> FETCH
+DOT pass -> err_pass [label="error"]
+DOT err_pass [label="ERROR",shape=plaintext]
  */
 
 static int
 cnt_pass(struct sess *sp)
 {
 
-       AZ(sp->vbc);
-       if (!PassSession(sp)) {
-               AN(sp->vbc);
-               sp->step = STP_PASSBODY;
-       } else
-               sp->step = STP_DONE;
-       return (0);
-}
-
-
-/*--------------------------------------------------------------------
- * We get here when we have the backends headers, send them to client
- * and pass any body the backend may have on as well.
- *
-DOT subgraph cluster_passbody {
-DOT    passbody [
-DOT            shape=ellipse
-DOT            label="send hdrs\npass body\n"
-DOT    ]
-DOT    PASSBODY -> passbody
-DOT }
-DOT passbody -> DONE
- */
-
-static int
-cnt_passbody(struct sess *sp)
-{
+       AZ(sp->obj);
 
-       sp->wrk->acct.pass++;
-       AN(sp->vbc);
-       PassBody(sp);
-       AZ(sp->vbc);
-       sp->step = STP_DONE;
+       VCL_pass_method(sp);
+       if (sp->handling == VCL_RET_ERROR) {
+               sp->step = STP_ERROR;
+               return (0);
+       }
+       HSH_Prealloc(sp);
+       sp->obj = sp->wrk->nobj;
+       sp->wrk->nobj = NULL;
+       sp->obj->busy = 1;
+       sp->step = STP_FETCH;
        return (0);
 }
 
-
 /*--------------------------------------------------------------------
  * Ship the request header to the backend unchanged, then pipe
  * until one of the ends close the connection.
  *
-DOT subgraph cluster_pipe {
+DOT subgraph xcluster_pipe {
 DOT    pipe [
+DOT            shape=box
+DOT            label="vcl_pipe()"
+DOT    ]
+DOT    pipe_do [
 DOT            shape=ellipse
 DOT            label="build&send hdr\npipe until close"
 DOT    ]
 DOT    PIPE -> pipe
+DOT    pipe -> pipe_do [label="pipe"]
 DOT }
-DOT pipe -> DONE
+DOT pipe_do -> DONE
+DOT pipe -> err_pipe [label="error"]
+DOT err_pipe [label="ERROR",shape=plaintext]
  */
 
 static int
@@ -672,29 +590,22 @@ cnt_pipe(struct sess *sp)
 
 
 /*--------------------------------------------------------------------
- * Dispatch the request as instructed by VCL
+ * RECV
+ * We have a complete request, get a VCL reference and dispatch it
+ * as instructed by vcl_recv{}
  *
-DOT subgraph cluster_recv {
+DOT subgraph xcluster_recv {
 DOT    recv [
 DOT            shape=box
 DOT            label="vcl_recv()"
 DOT    ]
-DOT    RECV -> recv
-DOT    recv_lookup [
-DOT            shape=ellipse
-DOT            label="discard any body"
-DOT    ]
-DOT    recv -> recv_lookup [label="lookup"]
-DOT    recv_error [
-DOT            shape=ellipse
-DOT            label="discard any body"
-DOT    ]
-DOT    recv -> recv_error [label="error"]
+DOT    RECV -> recv [style=bold,color=green,weight=4]
 DOT }
 DOT recv -> PIPE [label="pipe"]
 DOT recv -> PASS [label="pass"]
-DOT recv_lookup -> LOOKUP
-DOT recv_error -> ERROR
+DOT recv -> err_recv [label="error"]
+DOT err_recv [label="ERROR",shape=plaintext]
+DOT recv -> LOOKUP [label="lookup",style=bold,color=green,weight=4]
  */
 
 static int
@@ -702,43 +613,45 @@ cnt_recv(struct sess *sp)
 {
        int done;
 
-       VSL_stats->client_req++;
+       AZ(sp->vcl);
+       AZ(sp->obj);
+
+       /* Update stats of various sorts */
+       VSL_stats->client_req++;                        /* XXX not locked */
        clock_gettime(CLOCK_REALTIME, &sp->t_req);
        sp->wrk->idle = sp->t_req.tv_sec;
-       sp->xid = ++xids;
+       sp->wrk->acct.req++;
+
+       /* Assign XID and log */
+       sp->xid = ++xids;                               /* XXX not locked */
        WSL(sp->wrk, SLT_ReqStart, sp->fd,
            "%s %s %u", sp->addr, sp->port,  sp->xid);
 
-       AZ(sp->vcl);
+       /* Borrow VCL reference from worker thread */
        VCL_Refresh(&sp->wrk->vcl);
        sp->vcl = sp->wrk->vcl;
        sp->wrk->vcl = NULL;
 
-       AZ(sp->obj);
-       AZ(sp->vbc);
-
-       sp->wrk->acct.req++;
        done = http_DissectRequest(sp->wrk, sp->http, sp->fd);
        if (done != 0) {
-               RES_Error(sp, done, NULL);
+               RES_Error(sp, done, NULL);              /* XXX: STP_ERROR ? */
                sp->step = STP_DONE;
                return (0);
        }
 
        http_DoConnection(sp);
 
+       /* By default we use the first backend */
        sp->backend = sp->vcl->backend[0];
 
        /* XXX: Handle TRACE & OPTIONS of Max-Forwards = 0 */
 
-       /* XXX: determine if request comes with body */
-
        VCL_recv_method(sp);
 
+       sp->wantbody = !strcmp(sp->http->hd[HTTP_HDR_REQ].b, "GET");
        switch(sp->handling) {
        case VCL_RET_LOOKUP:
                /* XXX: discard req body, if any */
-               sp->wantbody = !strcmp(sp->http->hd[HTTP_HDR_REQ].b, "GET");
                sp->step = STP_LOOKUP;
                return (0);
        case VCL_RET_PIPE:
@@ -760,8 +673,7 @@ cnt_recv(struct sess *sp)
 /*--------------------------------------------------------------------
  * Central state engine dispatcher.
  *
- * We grab a VCL reference, and keeps kicking the session around until
- * it has had enough.
+ * Kick the session around until it has had enough.
  *
  */
 
@@ -776,6 +688,10 @@ CNT_Session(struct sess *sp)
        CHECK_OBJ_NOTNULL(w, WORKER_MAGIC);
 
        for (done = 0; !done; ) {
+               /*
+                * This is a good place to be paranoid about the various
+                * pointers still pointing to the things we expect.
+                */
                CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
                if (sp->obj != NULL)
                        CHECK_OBJ(sp->obj, OBJECT_MAGIC);
@@ -784,11 +700,9 @@ CNT_Session(struct sess *sp)
                        CHECK_OBJ(w->nobj, OBJECT_MAGIC);
                if (w->nobjhead != NULL)
                        CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
+
                switch (sp->step) {
-#define STEP(l,u) \
-               case STP_##u: \
-                       done = cnt_##l(sp); \
-                       break;
+#define STEP(l,u) case STP_##u: done = cnt_##l(sp); break;
 #include "steps.h"
 #undef STEP
                default:        INCOMPL();
index 1a96b31abc90d0dc2a8230b401bc5c14f178f257..15d913e3282efd30a59e94e065e60566c1fa7e7e 100644 (file)
@@ -243,11 +243,12 @@ fetch_eof(const struct sess *sp, int fd, struct http *hp)
 /*--------------------------------------------------------------------*/
 
 int
-FetchBody(struct sess *sp)
+Fetch(struct sess *sp)
 {
-       int cls;
        struct vbe_conn *vc;
+       struct worker *w;
        char *b;
+       int cls;
        int body = 1;           /* XXX */
        struct http *hp;
        struct storage *st;
@@ -256,9 +257,53 @@ FetchBody(struct sess *sp)
        CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
        CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
        assert(sp->obj->busy != 0);
+       w = sp->wrk;
+
+       sp->obj->xid = sp->xid;
+
+       vc = VBE_GetFd(sp);
+       if (vc == NULL)
+               return (1);
+
+       http_ClrHeader(vc->http);
+       vc->http->logtag = HTTP_Tx;
+       http_GetReq(w, vc->fd, vc->http, sp->http);
+       http_FilterHeader(w, vc->fd, vc->http, sp->http, HTTPH_R_FETCH);
+       http_PrintfHeader(w, vc->fd, vc->http, "X-Varnish: %u", sp->xid);
+       http_PrintfHeader(w, vc->fd, vc->http,
+           "X-Forwarded-for: %s", sp->addr);
+       if (!http_GetHdr(vc->http, H_Host, &b)) {
+               http_PrintfHeader(w, vc->fd, vc->http, "Host: %s",
+                   sp->backend->hostname);
+       }
 
-       vc = sp->vbc;
-       sp->vbc = NULL;
+       WRK_Reset(w, &vc->fd);
+       http_Write(w, vc->http, 0);
+       if (WRK_Flush(w)) {
+               /* XXX: cleanup */
+               return (1);
+       }
+
+       CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+       CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
+       CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
+
+       if (http_RecvHead(vc->http, vc->fd)) {
+               /* XXX: cleanup */
+               return (1);
+       }
+       if (http_DissectResponse(sp->wrk, vc->http, vc->fd)) {
+               /* XXX: cleanup */
+               return (1);
+       }
+       CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+       CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
+       CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
+
+       sp->obj->entered = time(NULL);
+
+
+       assert(sp->obj->busy != 0);
 
        if (http_GetHdr(vc->http, H_Last_Modified, &b))
                sp->obj->last_modified = TIM_parse(b);
@@ -314,66 +359,3 @@ FetchBody(struct sess *sp)
 
        return (0);
 }
-
-/*--------------------------------------------------------------------*/
-
-int
-FetchHeaders(struct sess *sp)
-{
-       struct vbe_conn *vc;
-       struct worker *w;
-       char *b;
-
-       CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
-       CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
-       CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
-       assert(sp->obj->busy != 0);
-       w = sp->wrk;
-
-       sp->obj->xid = sp->xid;
-
-       vc = VBE_GetFd(sp);
-       if (vc == NULL)
-               return (1);
-
-       http_ClrHeader(vc->http);
-       vc->http->logtag = HTTP_Tx;
-       http_GetReq(w, vc->fd, vc->http, sp->http);
-       http_FilterHeader(w, vc->fd, vc->http, sp->http, HTTPH_R_FETCH);
-       http_PrintfHeader(w, vc->fd, vc->http, "X-Varnish: %u", sp->xid);
-       http_PrintfHeader(w, vc->fd, vc->http,
-           "X-Forwarded-for: %s", sp->addr);
-       if (!http_GetHdr(vc->http, H_Host, &b)) {
-               http_PrintfHeader(w, vc->fd, vc->http, "Host: %s",
-                   sp->backend->hostname);
-       }
-
-       WRK_Reset(w, &vc->fd);
-       http_Write(w, vc->http, 0);
-       if (WRK_Flush(w)) {
-               /* XXX: cleanup */
-               return (1);
-       }
-
-       CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
-       CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
-       CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
-
-       if (http_RecvHead(vc->http, vc->fd)) {
-               /* XXX: cleanup */
-               return (1);
-       }
-       if (http_DissectResponse(sp->wrk, vc->http, vc->fd)) {
-               /* XXX: cleanup */
-               return (1);
-       }
-       CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
-       CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
-       CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
-       AZ(sp->vbc);
-       sp->vbc = vc;
-
-       sp->obj->entered = time(NULL);
-
-       return (0);
-}
index 711a878ae972679f04f3306ae7cf767618faae19..d19474626d39322934b621ff594474fc991d334b 100644 (file)
 
 static struct hash_slinger      *hash;
 
-struct object *
-HSH_Lookup(struct sess *sp)
+/* Precreate an objhead and object for later use */
+void
+HSH_Prealloc(struct sess *sp)
 {
        struct worker *w;
-       struct http *h;
-       struct objhead *oh;
-       struct object *o;
-       char *url, *host;
 
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
-       CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
-       CHECK_OBJ_NOTNULL(sp->http, HTTP_MAGIC);
-       AN(hash);
        w = sp->wrk;
-       h = sp->http;
 
-       /* Precreate an objhead and object in case we need them */
        if (w->nobjhead == NULL) {
                w->nobjhead = calloc(sizeof *w->nobjhead, 1);
                XXXAN(w->nobjhead);
@@ -102,7 +94,25 @@ HSH_Lookup(struct sess *sp)
                VSL_stats->n_object++;
        } else
                CHECK_OBJ_NOTNULL(w->nobj, OBJECT_MAGIC);
+}
+
+struct object *
+HSH_Lookup(struct sess *sp)
+{
+       struct worker *w;
+       struct http *h;
+       struct objhead *oh;
+       struct object *o;
+       char *url, *host;
+
+       CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+       CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
+       CHECK_OBJ_NOTNULL(sp->http, HTTP_MAGIC);
+       AN(hash);
+       w = sp->wrk;
+       h = sp->http;
 
+       HSH_Prealloc(sp);
        url = h->hd[HTTP_HDR_URL].b;
        if (!http_GetHdr(h, H_Host, &host))
                host = url;
@@ -189,11 +199,14 @@ HSH_Ref(struct object *o)
 
        CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
        oh = o->objhead;
-       CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
-       LOCK(&oh->mtx);
+       if (oh != NULL) {
+               CHECK_OBJ(oh, OBJHEAD_MAGIC);
+               LOCK(&oh->mtx);
+       }
        assert(o->refcnt > 0);
        o->refcnt++;
-       UNLOCK(&oh->mtx);
+       if (oh != NULL)
+               UNLOCK(&oh->mtx);
 }
 
 void
@@ -205,7 +218,13 @@ HSH_Deref(struct object *o)
 
        CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
        oh = o->objhead;
-       CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
+       if (oh == NULL) {
+               /* Pass object, not referenced anywhere */
+               free(o);
+               return;
+       }
+
+       CHECK_OBJ(oh, OBJHEAD_MAGIC);
 
        /* drop ref on object */
        LOCK(&oh->mtx);
diff --git a/varnish-cache/bin/varnishd/cache_pass.c b/varnish-cache/bin/varnishd/cache_pass.c
deleted file mode 100644 (file)
index a7293b7..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-/*-
- * Copyright (c) 2006 Verdens Gang AS
- * Copyright (c) 2006 Linpro AS
- * All rights reserved.
- *
- * Author: Poul-Henning Kamp <phk@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 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.
- *
- * $Id$
- *
- * XXX: charge bytes to srcaddr
- * XXX: buffer to relieve backed ASAP.
- * XXX: Check if response has any body
- * XXX: Don't pass chunked to HTTP/1.0 client
- */
-
-#include <stdio.h>
-#include <inttypes.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-
-#ifndef HAVE_CLOCK_GETTIME
-#include "compat/clock_gettime.h"
-#endif
-
-#include "shmlog.h"
-#include "cache.h"
-
-#define                        PASS_BUFSIZ             8192
-
-/*--------------------------------------------------------------------*/
-
-static int
-pass_straight(struct sess *sp, int fd, struct http *hp, char *bi)
-{
-       int i;
-       off_t   cl;
-       unsigned c;
-       char buf[PASS_BUFSIZ];
-
-       if (bi != NULL)
-               cl = strtoumax(bi, NULL, 0);
-       else
-               cl = (1 << 30);
-
-       i = fcntl(fd, F_GETFL);         /* XXX ? */
-       i &= ~O_NONBLOCK;
-       i = fcntl(fd, F_SETFL, i);
-
-       while (cl != 0) {
-               c = cl;
-               if (c > sizeof buf)
-                       c = sizeof buf;
-               i = http_Read(hp, fd, buf, c);
-               if (i == 0 && bi == NULL)
-                       return (1);
-               if (i <= 0) {
-                       vca_close_session(sp, "backend closed");
-                       return (1);
-               }
-               sp->wrk->acct.bodybytes += WRK_Write(sp->wrk, buf, i);
-               if (WRK_Flush(sp->wrk))
-                       vca_close_session(sp, "remote closed");
-               cl -= i;
-       }
-       return (0);
-}
-
-
-/*--------------------------------------------------------------------*/
-
-static int
-pass_chunked(struct sess *sp, int fd, struct http *hp)
-{
-       int i, j;
-       char *p, *q;
-       unsigned u;
-       char buf[PASS_BUFSIZ];
-       char *bp, *be;
-
-       i = fcntl(fd, F_GETFL);         /* XXX ? */
-       i &= ~O_NONBLOCK;
-       i = fcntl(fd, F_SETFL, i);
-
-       bp = buf;
-       be = buf + sizeof buf;
-       p = buf;
-       while (1) {
-               i = http_Read(hp, fd, bp, be - bp);
-               xxxassert(i >= 0);
-               if (i == 0 && p == bp)
-                       break;
-               bp += i;
-               /* buffer valid from p to bp */
-               assert(bp >= p);
-
-               /* chunk starts with f("%x\r\n", len) */
-               u = strtoul(p, &q, 16);
-               while (q && q < bp && *q == ' ')
-                       /* shouldn't happen - but sometimes it does */
-                       q++;
-               if (q == NULL || q > bp - 2 /* want \r\n in same buffer */) {
-                       /* short - move to start of buffer and extend */
-                       memmove(buf, p, bp - p);
-                       bp -= p - buf;
-                       p = buf;
-                       continue;
-               }
-               assert(*q == '\r');
-               q++;
-               assert(*q == '\n');
-               q++;
-
-               /* we just received the final zero-length chunk */
-               if (u == 0) {
-                       sp->wrk->acct.bodybytes += WRK_Write(sp->wrk, p, q - p);
-                       break;
-               }
-
-               /* include chunk header */
-               u += q - p;
-
-               /* include trailing \r\n with chunk */
-               u += 2;
-
-               for (;;) {
-                       j = u;
-                       if (bp - p < j)
-                               j = bp - p;
-                       sp->wrk->acct.bodybytes += WRK_Write(sp->wrk, p, j);
-                       WRK_Flush(sp->wrk);
-                       p += j;
-                       assert(u >= j);
-                       u -= j;
-                       if (u == 0)
-                               break;
-                       p = bp = buf;
-                       j = u;
-                       if (j > be - bp)
-                               j = be - bp;
-                       i = http_Read(hp, fd, bp, j);
-                       xxxassert(i > 0);
-                       bp += i;
-               }
-       }
-       if (WRK_Flush(sp->wrk))
-               vca_close_session(sp, "remote closed");
-       return (0);
-}
-
-
-/*--------------------------------------------------------------------*/
-
-void
-PassBody(struct sess *sp)
-{
-       struct vbe_conn *vc;
-       char *b;
-       int cls;
-
-       CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
-       CHECK_OBJ_NOTNULL(sp->vbc, VBE_CONN_MAGIC);
-       vc = sp->vbc;
-       sp->vbc = NULL;
-
-       clock_gettime(CLOCK_REALTIME, &sp->t_resp);
-
-       http_ClrHeader(sp->http);
-       http_CopyResp(sp->wrk, sp->fd, sp->http, vc->http);
-       http_FilterHeader(sp->wrk, sp->fd, sp->http, vc->http, HTTPH_A_PASS);
-       http_PrintfHeader(sp->wrk, sp->fd, sp->http, "X-Varnish: %u", sp->xid);
-       http_PrintfHeader(sp->wrk, sp->fd, sp->http,
-           "X-Forwarded-for: %s", sp->addr);
-       /* XXX */
-       if (http_HdrIs(vc->http, H_Transfer_Encoding, "chunked"))
-               http_PrintfHeader(sp->wrk, sp->fd, sp->http, "Transfer-Encoding: chunked");
-       WRK_Reset(sp->wrk, &sp->fd);
-       sp->wrk->acct.hdrbytes += http_Write(sp->wrk, sp->http, 1);
-
-       if (http_GetHdr(vc->http, H_Content_Length, &b))
-               cls = pass_straight(sp, vc->fd, vc->http, b);
-       else if (http_HdrIs(vc->http, H_Connection, "close"))
-               cls = pass_straight(sp, vc->fd, vc->http, NULL);
-       else if (http_HdrIs(vc->http, H_Transfer_Encoding, "chunked"))
-               cls = pass_chunked(sp, vc->fd, vc->http);
-       else if (http_IsBodyless(vc->http))
-               cls = 0;
-       else {
-               cls = pass_straight(sp, vc->fd, vc->http, NULL);
-       }
-
-       if (WRK_Flush(sp->wrk))
-               vca_close_session(sp, "remote closed");
-
-       if (http_GetHdr(vc->http, H_Connection, &b) && !strcasecmp(b, "close"))
-               cls = 1;
-
-       if (cls)
-               VBE_ClosedFd(sp->wrk, vc, 0);
-       else
-               VBE_RecycleFd(sp->wrk, vc);
-}
-
-
-/*--------------------------------------------------------------------*/
-
-int
-PassSession(struct sess *sp)
-{
-       int i;
-       struct vbe_conn *vc;
-       struct worker *w;
-       char *b;
-
-       CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
-       CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
-       w = sp->wrk;
-
-       vc = VBE_GetFd(sp);
-       if (vc == NULL)
-               return (1);
-
-       http_CopyReq(w, vc->fd, vc->http, sp->http);
-       http_FilterHeader(w, vc->fd, vc->http, sp->http, HTTPH_R_PASS);
-       http_PrintfHeader(w, vc->fd, vc->http, "X-Varnish: %u", sp->xid);
-       if (!http_GetHdr(vc->http, H_Host, &b)) {
-               http_PrintfHeader(w, vc->fd, vc->http, "Host: %s",
-                   sp->backend->hostname);
-       }
-       WRK_Reset(w, &vc->fd);
-       http_Write(w, vc->http, 0);
-       i = WRK_Flush(w);
-       xxxassert(i == 0);
-
-       /* XXX: copy any contents */
-
-       i = http_RecvHead(vc->http, vc->fd);
-       xxxassert(i == 0);
-       http_DissectResponse(w, vc->http, vc->fd);
-
-       assert(sp->vbc == NULL);
-       sp->vbc = vc;
-       return (0);
-}
index cc4432564dfb5327f49a8a6f23184b4f601f0b1d..5e52f421c8cbf1dd664d29e7f6c20543dd6d4f82 100644 (file)
@@ -82,7 +82,7 @@ VRT_GetHdr(struct sess *sp, int where, const char *n)
                hp = sp->http;
                break;
        case 2:
-               hp = sp->vbc->http;
+               hp = &sp->obj->http;
                break;
        default:
                INCOMPL();
index 324c6afaa511084da0173160e9fc91746c0c848c..301c0147044fd22607278ad99ca2a548658be584 100644 (file)
@@ -79,6 +79,18 @@ static const char *default_vcl =
     "    lookup;\n"
     "}\n"
     "\n"
+    "sub default_vcl_pipe {\n"
+    "    pipe;\n"
+    "}\n"
+    "\n"
+    "sub default_vcl_pass {\n"
+    "    pass;\n"
+    "}\n"
+    "\n"
+    "sub default_vcl_hash {\n"
+    "    hash;\n"
+    "}\n"
+    "\n"
     "sub default_vcl_hit {\n"
     "    if (!obj.cacheable) {\n"
     "        pass;\n"
@@ -95,10 +107,10 @@ static const char *default_vcl =
     "        error;\n"
     "    }\n"
     "    if (!obj.cacheable) {\n"
-    "        insert_pass;\n"
+    "        pass;\n"
     "    }\n"
     "    if (resp.http.Set-Cookie) {\n"
-    "        insert_pass;\n"
+    "        pass;\n"
     "    }\n"
     "    insert;\n"
     "}\n"
index 5649cda2184ffbbe6033d519d30344590ef3425a..d07febb812e0e3de6a59e9eac6ce5560638b02ed 100644 (file)
@@ -34,9 +34,7 @@ STEP(first,   FIRST)
 STEP(recv,     RECV)
 STEP(pipe,     PIPE)
 STEP(pass,     PASS)
-STEP(passbody, PASSBODY)
 STEP(lookup,   LOOKUP)
-STEP(lookup2,  LOOKUP2)
 STEP(miss,     MISS)
 STEP(hit,      HIT)
 STEP(fetch,    FETCH)
index fa281c26c654068eefc7133af1bd89751e781962..4bd7b70dc2e7f8432a6c758c830acb2b880cc0a3 100644 (file)
@@ -28,6 +28,9 @@ struct VCL_conf {
         vcl_fini_f      *fini_func;
 
        vcl_func_f      *recv_func;
+       vcl_func_f      *pipe_func;
+       vcl_func_f      *pass_func;
+       vcl_func_f      *hash_func;
        vcl_func_f      *miss_func;
        vcl_func_f      *hit_func;
        vcl_func_f      *fetch_func;
index fa086117cdeb50fc68e9ac8f0c6d0d10eb0d7638..59fcc65761ac9c010c12d077b2f2ad5daa4fea12 100644 (file)
@@ -11,9 +11,9 @@
 VCL_RET_MAC_E(error, ERROR, (1 << 0), 0)
 #endif
 VCL_RET_MAC(lookup, LOOKUP, (1 << 1), 1)
-VCL_RET_MAC(pipe, PIPE, (1 << 2), 2)
-VCL_RET_MAC(pass, PASS, (1 << 3), 3)
-VCL_RET_MAC(insert_pass, INSERT_PASS, (1 << 4), 4)
+VCL_RET_MAC(hash, HASH, (1 << 2), 2)
+VCL_RET_MAC(pipe, PIPE, (1 << 3), 3)
+VCL_RET_MAC(pass, PASS, (1 << 4), 4)
 VCL_RET_MAC(fetch, FETCH, (1 << 5), 5)
 VCL_RET_MAC(insert, INSERT, (1 << 6), 6)
 VCL_RET_MAC(deliver, DELIVER, (1 << 7), 7)
@@ -21,9 +21,9 @@ VCL_RET_MAC(discard, DISCARD, (1 << 8), 8)
 #else
 #define VCL_RET_ERROR  (1 << 0)
 #define VCL_RET_LOOKUP  (1 << 1)
-#define VCL_RET_PIPE  (1 << 2)
-#define VCL_RET_PASS  (1 << 3)
-#define VCL_RET_INSERT_PASS  (1 << 4)
+#define VCL_RET_HASH  (1 << 2)
+#define VCL_RET_PIPE  (1 << 3)
+#define VCL_RET_PASS  (1 << 4)
 #define VCL_RET_FETCH  (1 << 5)
 #define VCL_RET_INSERT  (1 << 6)
 #define VCL_RET_DELIVER  (1 << 7)
@@ -33,8 +33,11 @@ VCL_RET_MAC(discard, DISCARD, (1 << 8), 8)
 
 #ifdef VCL_MET_MAC
 VCL_MET_MAC(recv,RECV,(VCL_RET_ERROR|VCL_RET_PASS|VCL_RET_PIPE|VCL_RET_LOOKUP))
-VCL_MET_MAC(miss,MISS,(VCL_RET_ERROR|VCL_RET_PASS|VCL_RET_PIPE|VCL_RET_FETCH))
-VCL_MET_MAC(hit,HIT,(VCL_RET_ERROR|VCL_RET_PASS|VCL_RET_PIPE|VCL_RET_DELIVER))
-VCL_MET_MAC(fetch,FETCH,(VCL_RET_ERROR|VCL_RET_PASS|VCL_RET_PIPE|VCL_RET_INSERT|VCL_RET_INSERT_PASS))
+VCL_MET_MAC(pipe,PIPE,(VCL_RET_ERROR|VCL_RET_PIPE))
+VCL_MET_MAC(pass,PASS,(VCL_RET_ERROR|VCL_RET_PASS))
+VCL_MET_MAC(hash,HASH,(VCL_RET_HASH))
+VCL_MET_MAC(miss,MISS,(VCL_RET_ERROR|VCL_RET_PASS|VCL_RET_FETCH))
+VCL_MET_MAC(hit,HIT,(VCL_RET_ERROR|VCL_RET_PASS|VCL_RET_DELIVER))
+VCL_MET_MAC(fetch,FETCH,(VCL_RET_ERROR|VCL_RET_PASS|VCL_RET_INSERT))
 VCL_MET_MAC(timeout,TIMEOUT,(VCL_RET_FETCH|VCL_RET_DISCARD))
 #endif
index d7fd8ed6354e1c1936bad12e8c668f15e492b359..8701a0c5b627fb6a3007fe9277567a69bda4d828 100644 (file)
@@ -228,14 +228,14 @@ vcl_fixed_token(const char *p, const char **q)
                        return (T_FETCH);
                }
                return (0);
-       case 'i':
-               if (p[0] == 'i' && p[1] == 'n' && p[2] == 's' && 
-                   p[3] == 'e' && p[4] == 'r' && p[5] == 't' && 
-                   p[6] == '_' && p[7] == 'p' && p[8] == 'a' && 
-                   p[9] == 's' && p[10] == 's' && !isvar(p[11])) {
-                       *q = p + 11;
-                       return (T_INSERT_PASS);
+       case 'h':
+               if (p[0] == 'h' && p[1] == 'a' && p[2] == 's' && 
+                   p[3] == 'h' && !isvar(p[4])) {
+                       *q = p + 4;
+                       return (T_HASH);
                }
+               return (0);
+       case 'i':
                if (p[0] == 'i' && p[1] == 'n' && p[2] == 's' && 
                    p[3] == 'e' && p[4] == 'r' && p[5] == 't'
                     && !isvar(p[6])) {
@@ -396,11 +396,11 @@ vcl_init_tnames(void)
        vcl_tnames[T_FETCH] = "fetch";
        vcl_tnames[T_FUNC] = "func";
        vcl_tnames[T_GEQ] = ">=";
+       vcl_tnames[T_HASH] = "hash";
        vcl_tnames[T_IF] = "if";
        vcl_tnames[T_INC] = "++";
        vcl_tnames[T_INCR] = "+=";
        vcl_tnames[T_INSERT] = "insert";
-       vcl_tnames[T_INSERT_PASS] = "insert_pass";
        vcl_tnames[T_LEQ] = "<=";
        vcl_tnames[T_LOOKUP] = "lookup";
        vcl_tnames[T_MUL] = "*=";
@@ -424,9 +424,9 @@ vcl_output_lang_h(FILE *f)
 {
        fputs("#define VCL_RET_ERROR  (1 << 0)\n", f);
        fputs("#define VCL_RET_LOOKUP  (1 << 1)\n", f);
-       fputs("#define VCL_RET_PIPE  (1 << 2)\n", f);
-       fputs("#define VCL_RET_PASS  (1 << 3)\n", f);
-       fputs("#define VCL_RET_INSERT_PASS  (1 << 4)\n", f);
+       fputs("#define VCL_RET_HASH  (1 << 2)\n", f);
+       fputs("#define VCL_RET_PIPE  (1 << 3)\n", f);
+       fputs("#define VCL_RET_PASS  (1 << 4)\n", f);
        fputs("#define VCL_RET_FETCH  (1 << 5)\n", f);
        fputs("#define VCL_RET_INSERT  (1 << 6)\n", f);
        fputs("#define VCL_RET_DELIVER  (1 << 7)\n", f);
@@ -461,6 +461,9 @@ vcl_output_lang_h(FILE *f)
        fputs("        vcl_fini_f      *fini_func;\n", f);
        fputs("\n", f);
        fputs(" vcl_func_f      *recv_func;\n", f);
+       fputs(" vcl_func_f      *pipe_func;\n", f);
+       fputs(" vcl_func_f      *pass_func;\n", f);
+       fputs(" vcl_func_f      *hash_func;\n", f);
        fputs(" vcl_func_f      *miss_func;\n", f);
        fputs(" vcl_func_f      *hit_func;\n", f);
        fputs(" vcl_func_f      *fetch_func;\n", f);
index 80618bc0af2fa760b410fa18c1076f68363d3097..d081c7c954bc863e8c4486c825b4b18fad3c4a8b 100755 (executable)
 #
 set methods {
        {recv           {error pass pipe lookup}}
-       {miss           {error pass pipe fetch}}
-       {hit            {error pass pipe deliver}}
-       {fetch          {error pass pipe insert insert_pass}}
+       {pipe           {error pipe}}
+       {pass           {error pass}}
+       {hash           {hash}}
+       {miss           {error pass fetch}}
+       {hit            {error pass deliver}}
+       {fetch          {error pass insert}}
        {timeout        {fetch discard}}
 }
 
@@ -46,9 +49,9 @@ set methods {
 set returns {
        error
        lookup
+       hash
        pipe
        pass
-       insert_pass
        fetch
        insert
        deliver
index 93b77827afb1b9c871b439e793db25cd187e2633..8d954761d3d1631141b75438676cfce1b2cbe5dd 100644 (file)
@@ -24,9 +24,9 @@
 #define T_SWITCH_CONFIG 142
 #define T_ERROR 143
 #define T_LOOKUP 144
-#define T_PIPE 145
-#define T_PASS 146
-#define T_INSERT_PASS 147
+#define T_HASH 145
+#define T_PIPE 146
+#define T_PASS 147
 #define T_FETCH 148
 #define T_INSERT 149
 #define T_DELIVER 150