From 90b6b2832db3267ca89f284148d3c5bd21a49bdc Mon Sep 17 00:00:00 2001 From: phk Date: Mon, 3 Apr 2006 09:02:27 +0000 Subject: [PATCH] A little step for humanity but a big step for varnish: Implement pipe-through mode and see the first web-pages actually pass through varnish. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@95 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/Makefile.am | 1 + varnish-cache/bin/varnishd/cache.h | 7 ++ varnish-cache/bin/varnishd/cache_acceptor.c | 9 ++ varnish-cache/bin/varnishd/cache_backend.c | 82 ++++++++++++++--- varnish-cache/bin/varnishd/cache_httpd.c | 12 +-- varnish-cache/bin/varnishd/cache_pipe.c | 97 +++++++++++++++++++++ varnish-cache/bin/varnishd/cache_pool.c | 4 +- varnish-cache/include/http_headers.h | 18 +++- varnish-cache/include/vcl_lang.h | 9 +- varnish-cache/lib/libvcl/vcl_fixed_token.c | 27 ++++-- 10 files changed, 233 insertions(+), 33 deletions(-) create mode 100644 varnish-cache/bin/varnishd/cache_pipe.c diff --git a/varnish-cache/bin/varnishd/Makefile.am b/varnish-cache/bin/varnishd/Makefile.am index ddea6a70..7a0d4a60 100644 --- a/varnish-cache/bin/varnishd/Makefile.am +++ b/varnish-cache/bin/varnishd/Makefile.am @@ -10,6 +10,7 @@ varnishd_SOURCES = \ cache_httpd.c \ cache_main.c \ cache_pool.c \ + cache_pipe.c \ cache_shmlog.c \ cache_vcl.c \ cli_event.c \ diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index e69b631a..3a041bc3 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -4,9 +4,13 @@ /* cache_acceptor.c */ void *vca_main(void *arg); +void vca_retire_session(struct sess *sp); /* cache_backend.c */ void VBE_Init(void); +int VBE_GetFd(struct backend *bp, void **ptr); +void VBE_Pass(struct sess *sp); +void VBE_ClosedFd(void *ptr); /* cache_httpd.c */ void HttpdAnalyze(struct sess *sp); @@ -14,6 +18,9 @@ void HttpdAnalyze(struct sess *sp); /* cache_main.c */ pthread_mutex_t sessmtx; +/* cache_pipe.c */ +void PipeSession(struct sess *sp); + /* cache_pool.c */ void CacheInitPool(void); void DealWithSession(struct sess *sp); diff --git a/varnish-cache/bin/varnishd/cache_acceptor.c b/varnish-cache/bin/varnishd/cache_acceptor.c index c40e0a46..48a19a5b 100644 --- a/varnish-cache/bin/varnishd/cache_acceptor.c +++ b/varnish-cache/bin/varnishd/cache_acceptor.c @@ -137,3 +137,12 @@ vca_main(void *arg) return ("FOOBAR"); } + +void +vca_retire_session(struct sess *sp) +{ + + if (sp->fd >= 0) + close(sp->fd); + free(sp); +} diff --git a/varnish-cache/bin/varnishd/cache_backend.c b/varnish-cache/bin/varnishd/cache_backend.c index 706eab33..d8f1efb6 100644 --- a/varnish-cache/bin/varnishd/cache_backend.c +++ b/varnish-cache/bin/varnishd/cache_backend.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "libvarnish.h" #include "vcl_lang.h" @@ -86,7 +87,7 @@ connect_to_backend(struct vbe_conn *vc, struct backend *bp) /*--------------------------------------------------------------------*/ int -VBE_GetFd(struct backend *bp) +VBE_GetFd(struct backend *bp, void **ptr) { struct vbe *vp; struct vbe_conn *vc; @@ -113,20 +114,81 @@ VBE_GetFd(struct backend *bp) TAILQ_REMOVE(&vp->fconn, vc, list); TAILQ_INSERT_TAIL(&vp->bconn, vc, list); AZ(pthread_mutex_unlock(&vbemtx)); - return (vc->fd); + } else { + vc = calloc(sizeof *vc, 1); + assert(vc != NULL); + vc->vbe = vp; + vc->fd = -1; + TAILQ_INSERT_TAIL(&vp->bconn, vc, list); + AZ(pthread_mutex_unlock(&vbemtx)); + connect_to_backend(vc, bp); } - vc = calloc(sizeof *vc, 1); - assert(vc != NULL); - vc->vbe = vp; - vc->fd = -1; - TAILQ_INSERT_TAIL(&vp->bconn, vc, list); + *ptr = vc; + return (vc->fd); +} + +void +VBE_ClosedFd(void *ptr) +{ + struct vbe_conn *vc; + + vc = ptr; + AZ(pthread_mutex_lock(&vbemtx)); + TAILQ_REMOVE(&vc->vbe->bconn, vc, list); AZ(pthread_mutex_unlock(&vbemtx)); - connect_to_backend(vc, bp); + free(vc); +} + +/*--------------------------------------------------------------------*/ +void +VBE_Pass(struct sess *sp) +{ + int fd, i; + void *fd_token; + struct sbuf *sb; + + fd = VBE_GetFd(sp->backend, &fd_token); + assert(fd != -1); + + sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); + assert(sb != NULL); + sbuf_cat(sb, sp->req); + sbuf_cat(sb, " "); + sbuf_cat(sb, sp->url); + sbuf_cat(sb, " "); + sbuf_cat(sb, sp->proto); + sbuf_cat(sb, "\r\n"); +#define HTTPH(a, b, c, d, e, f, g) \ + do { \ + if (c && sp->b != NULL) { \ + sbuf_cat(sb, a ": "); \ + sbuf_cat(sb, sp->b); \ + sbuf_cat(sb, "\r\n"); \ + } \ + } while (0); +#include "http_headers.h" +#undef HTTPH + sbuf_cat(sb, "\r\n"); + sbuf_finish(sb); + printf("REQ: <%s>\n", sbuf_data(sb)); + i = write(fd, sbuf_data(sb), sbuf_len(sb)); + assert(i == sbuf_len(sb)); + { + char buf[101]; + + for(;;) { + i = read(fd, buf, 100); + if (i > 0) { + buf[i] = '\0'; + printf("RESP: <%s>\n", buf); + } + } - /* XXX */ - return (-1); + } } +/*--------------------------------------------------------------------*/ + void VBE_Init(void) { diff --git a/varnish-cache/bin/varnishd/cache_httpd.c b/varnish-cache/bin/varnishd/cache_httpd.c index cf6f4756..c05cea9f 100644 --- a/varnish-cache/bin/varnishd/cache_httpd.c +++ b/varnish-cache/bin/varnishd/cache_httpd.c @@ -22,30 +22,30 @@ HttpdAnalyze(struct sess *sp) sp->handling = HND_Unclass; /* First, isolate and possibly identify request type */ - sp->req_b = sp->rcv; + sp->req = sp->rcv; for (p = sp->rcv; isalpha(*p); p++) ; - VSLR(SLT_Request, sp->fd, sp->req_b, p); + VSLR(SLT_Request, sp->fd, sp->req, p); *p++ = '\0'; /* Next find the URI */ while (isspace(*p)) p++; - sp->url_b = p; + sp->url = p; while (!isspace(*p)) p++; - VSLR(SLT_URL, sp->fd, sp->url_b, p); + VSLR(SLT_URL, sp->fd, sp->url, p); *p++ = '\0'; /* Finally, look for protocol, if any */ while (isspace(*p) && *p != '\n') p++; - sp->proto_b = p; + sp->proto = p; if (*p != '\n') { while (!isspace(*p)) p++; } - VSLR(SLT_Protocol, sp->fd, sp->proto_b, p); + VSLR(SLT_Protocol, sp->fd, sp->proto, p); *p++ = '\0'; while (isspace(*p) && *p != '\n') diff --git a/varnish-cache/bin/varnishd/cache_pipe.c b/varnish-cache/bin/varnishd/cache_pipe.c new file mode 100644 index 00000000..d15590d5 --- /dev/null +++ b/varnish-cache/bin/varnishd/cache_pipe.c @@ -0,0 +1,97 @@ +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libvarnish.h" +#include "vcl_lang.h" +#include "cache.h" + +struct edir { + int fd; + struct event ev; +}; + +static void +rdf(int fd, short event, void *arg) +{ + int i, j; + struct edir *ep; + char buf[BUFSIZ]; + + ep = arg; + i = read(fd, buf, sizeof buf); + if (i <= 0) { + shutdown(fd, SHUT_RD); + shutdown(ep->fd, SHUT_WR); + event_del(&ep->ev); + } else { + j = write(ep->fd, buf, i); + assert(i == j); + } +} + +void +PipeSession(struct sess *sp) +{ + int fd, i; + void *fd_token; + struct sbuf *sb; + struct event_base *eb; + struct edir e1, e2; + + fd = VBE_GetFd(sp->backend, &fd_token); + assert(fd != -1); + + sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); + assert(sb != NULL); + sbuf_cat(sb, sp->req); + sbuf_cat(sb, " "); + sbuf_cat(sb, sp->url); + if (sp->proto != NULL) { + sbuf_cat(sb, " "); + sbuf_cat(sb, sp->proto); + } + sbuf_cat(sb, "\r\n"); +#define HTTPH(a, b, c, d, e, f, g) \ + do { \ + if (sp->b != NULL) { \ + sbuf_cat(sb, a ": "); \ + sbuf_cat(sb, sp->b); \ + sbuf_cat(sb, "\r\n"); \ + } \ + } while (0); +#include "http_headers.h" +#undef HTTPH + sbuf_cat(sb, "\r\n"); + sbuf_finish(sb); + printf("REQ: <%s>\n", sbuf_data(sb)); + i = write(fd, sbuf_data(sb), sbuf_len(sb)); + assert(i == sbuf_len(sb)); + + e1.fd = fd; + e2.fd = sp->fd; + eb = event_init(); + event_set(&e1.ev, sp->fd, EV_READ | EV_PERSIST, rdf, &e1); + event_base_set(eb, &e1.ev); + event_set(&e2.ev, fd, EV_READ | EV_PERSIST, rdf, &e2); + event_base_set(eb, &e2.ev); + event_add(&e1.ev, NULL); + event_add(&e2.ev, NULL); + event_base_loop(eb, 0); + close (fd); + close (sp->fd); + /* XXX: Delete eb */ + VBE_ClosedFd(fd_token); + sp->fd = -1; +} diff --git a/varnish-cache/bin/varnishd/cache_pool.c b/varnish-cache/bin/varnishd/cache_pool.c index 0e294c45..29baee3d 100644 --- a/varnish-cache/bin/varnishd/cache_pool.c +++ b/varnish-cache/bin/varnishd/cache_pool.c @@ -39,10 +39,12 @@ CacheWorker(void *priv __unused) printf("Handling: %d\n", sp->handling); + PipeSession(sp); + AZ(pthread_mutex_lock(&sessmtx)); RelVCL(sp->vcl); sp->vcl = NULL; - /* XXX send session to acceptor for reuse/disposal */ + vca_retire_session(sp); } } diff --git a/varnish-cache/include/http_headers.h b/varnish-cache/include/http_headers.h index 152c5879..c798ce54 100644 --- a/varnish-cache/include/http_headers.h +++ b/varnish-cache/include/http_headers.h @@ -1,16 +1,26 @@ /* * $Id$ + * + * a Http header name + * b session field name + * c PassThrough handling (0=remove, 1=pass) + * d unused + * e unused + * f unused + * g unused + * + * a b c d e f g + *-------------------------------------------------------------------- */ - HTTPH("Accept-Charset", H_Accept_Charset, 0, 0, 0, 0, 0) HTTPH("Accept-Encoding", H_Accept_Encoding, 0, 0, 0, 0, 0) HTTPH("Accept-Language", H_Accept_Language, 0, 0, 0, 0, 0) HTTPH("Accept", H_Accept, 0, 0, 0, 0, 0) HTTPH("Authorization", H_Authorization, 0, 0, 0, 0, 0) -HTTPH("Connection", H_Connection, 0, 0, 0, 0, 0) +HTTPH("Connection", H_Connection, 1, 0, 0, 0, 0) HTTPH("Expect", H_Expect, 0, 0, 0, 0, 0) HTTPH("From", H_From, 0, 0, 0, 0, 0) -HTTPH("Host", H_Host, 0, 0, 0, 0, 0) +HTTPH("Host", H_Host, 1, 0, 0, 0, 0) HTTPH("If-Match", H_If_Match, 0, 0, 0, 0, 0) HTTPH("If-Modified-Since", H_If_Modified_Since, 0, 0, 0, 0, 0) HTTPH("If-None-Match", H_If_None_Match, 0, 0, 0, 0, 0) @@ -22,4 +32,4 @@ HTTPH("Proxy-Authorization", H_Proxy_Authorization, 0, 0, 0, 0, 0) HTTPH("Range", H_Range, 0, 0, 0, 0, 0) HTTPH("Referer", H_Referer, 0, 0, 0, 0, 0) HTTPH("TE", H_TE, 0, 0, 0, 0, 0) -HTTPH("User-Agent", H_User_Agent, 0, 0, 0, 0, 0) +HTTPH("User-Agent", H_User_Agent, 1, 0, 0, 0, 0) diff --git a/varnish-cache/include/vcl_lang.h b/varnish-cache/include/vcl_lang.h index ee3a3f61..dad14f8b 100644 --- a/varnish-cache/include/vcl_lang.h +++ b/varnish-cache/include/vcl_lang.h @@ -34,9 +34,9 @@ struct sess { unsigned rcv_len; /* HTTP request info, points into rcv */ - const char *req_b; - const char *url_b; - const char *proto_b; + const char *req; + const char *url; + const char *proto; #define HTTPH(a, b, c, d, e, f, g) const char *b; #include #undef HTTPH @@ -44,7 +44,8 @@ struct sess { enum { HND_Unclass, HND_Handle, - HND_Pass + HND_Pass, + HND_Pipe } handling; char done; diff --git a/varnish-cache/lib/libvcl/vcl_fixed_token.c b/varnish-cache/lib/libvcl/vcl_fixed_token.c index 47506cb2..8323fe71 100644 --- a/varnish-cache/lib/libvcl/vcl_fixed_token.c +++ b/varnish-cache/lib/libvcl/vcl_fixed_token.c @@ -415,23 +415,33 @@ vcl_output_lang_h(FILE *f) fputs(" unsigned rcv_len;\n", f); fputs("\n", f); fputs(" /* HTTP request info, points into rcv */\n", f); - fputs(" const char *req_b;\n", f); - fputs(" const char *url_b;\n", f); - fputs(" const char *proto_b;\n", f); + fputs(" const char *req;\n", f); + fputs(" const char *url;\n", f); + fputs(" const char *proto;\n", f); fputs("#define HTTPH(a, b, c, d, e, f, g) const char *b;\n", f); fputs("/*\n", f); fputs(" * $Id$\n", f); + fputs(" *\n", f); + fputs(" * a Http header name\n", f); + fputs(" * b session field name\n", f); + fputs(" * c PassThrough handling (0=remove, 1=pass)\n", f); + fputs(" * d unused\n", f); + fputs(" * e unused\n", f); + fputs(" * f unused\n", f); + fputs(" * g unused\n", f); + fputs(" *\n", f); + fputs(" * a b c d e f g \n", f); + fputs(" *--------------------------------------------------------------------\n", f); fputs(" */\n", f); - fputs("\n", f); fputs("HTTPH(\"Accept-Charset\", H_Accept_Charset, 0, 0, 0, 0, 0)\n", f); fputs("HTTPH(\"Accept-Encoding\", H_Accept_Encoding, 0, 0, 0, 0, 0)\n", f); fputs("HTTPH(\"Accept-Language\", H_Accept_Language, 0, 0, 0, 0, 0)\n", f); fputs("HTTPH(\"Accept\", H_Accept, 0, 0, 0, 0, 0)\n", f); fputs("HTTPH(\"Authorization\", H_Authorization, 0, 0, 0, 0, 0)\n", f); - fputs("HTTPH(\"Connection\", H_Connection, 0, 0, 0, 0, 0)\n", f); + fputs("HTTPH(\"Connection\", H_Connection, 1, 0, 0, 0, 0)\n", f); fputs("HTTPH(\"Expect\", H_Expect, 0, 0, 0, 0, 0)\n", f); fputs("HTTPH(\"From\", H_From, 0, 0, 0, 0, 0)\n", f); - fputs("HTTPH(\"Host\", H_Host, 0, 0, 0, 0, 0)\n", f); + fputs("HTTPH(\"Host\", H_Host, 1, 0, 0, 0, 0)\n", f); fputs("HTTPH(\"If-Match\", H_If_Match, 0, 0, 0, 0, 0)\n", f); fputs("HTTPH(\"If-Modified-Since\", H_If_Modified_Since, 0, 0, 0, 0, 0)\n", f); fputs("HTTPH(\"If-None-Match\", H_If_None_Match, 0, 0, 0, 0, 0)\n", f); @@ -443,13 +453,14 @@ vcl_output_lang_h(FILE *f) fputs("HTTPH(\"Range\", H_Range, 0, 0, 0, 0, 0)\n", f); fputs("HTTPH(\"Referer\", H_Referer, 0, 0, 0, 0, 0)\n", f); fputs("HTTPH(\"TE\", H_TE, 0, 0, 0, 0, 0)\n", f); - fputs("HTTPH(\"User-Agent\", H_User_Agent, 0, 0, 0, 0, 0)\n", f); + fputs("HTTPH(\"User-Agent\", H_User_Agent, 1, 0, 0, 0, 0)\n", f); fputs("#undef HTTPH\n", f); fputs("\n", f); fputs(" enum {\n", f); fputs(" HND_Unclass,\n", f); fputs(" HND_Handle,\n", f); - fputs(" HND_Pass\n", f); + fputs(" HND_Pass,\n", f); + fputs(" HND_Pipe\n", f); fputs(" } handling;\n", f); fputs("\n", f); fputs(" char done;\n", f); -- 2.39.5