Commit 3ad49e77 authored by Dag Erling Smørgrav's avatar Dag Erling Smørgrav

r37053@cat (orig r1277): phk | 2007-03-06 23:40:06 +0100

 
 Having thought long and hard about this, commit what I think is the
 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: http://www.varnish-cache.org/svn/branches/1.0@1320 d4fa192b-c00b-0410-8231-f00ffab90ce4
parents fbfc0868 0dd910f6
......@@ -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 \
......
......@@ -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);
......
This diff is collapsed.
......@@ -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);
}
......@@ -64,23 +64,15 @@
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);
......
/*-
* 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);
}
......@@ -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();
......
......@@ -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"
......
......@@ -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)
......
......@@ -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;
......
......@@ -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
......@@ -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);
......
......@@ -35,9 +35,12 @@
#
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
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment