]> err.no Git - varnish/commitdiff
A little step for humanity but a big step for varnish:
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 3 Apr 2006 09:02:27 +0000 (09:02 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 3 Apr 2006 09:02:27 +0000 (09:02 +0000)
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
varnish-cache/bin/varnishd/cache.h
varnish-cache/bin/varnishd/cache_acceptor.c
varnish-cache/bin/varnishd/cache_backend.c
varnish-cache/bin/varnishd/cache_httpd.c
varnish-cache/bin/varnishd/cache_pipe.c [new file with mode: 0644]
varnish-cache/bin/varnishd/cache_pool.c
varnish-cache/include/http_headers.h
varnish-cache/include/vcl_lang.h
varnish-cache/lib/libvcl/vcl_fixed_token.c

index ddea6a705200befc0b04b5625053687d9c7ccf4d..7a0d4a6078d9ced8ce9ea91884892951cf159ab3 100644 (file)
@@ -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 \
index e69b631aaa6952ccb2ce5df2ed67aa0cc8a19ee8..3a041bc3e79b163b69d79993e8acc075d08fa5bf 100644 (file)
@@ -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);
index c40e0a46f8b367ea3279fb2e9210c1c611f76bba..48a19a5b95245a5a3957d4e1fcffabd84ffdb2a6 100644 (file)
@@ -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);
+}
index 706eab334c13f89b4b7ec6b16ce8335f7c1aa1d7..d8f1efb63020830443cde8cbbc39a18a8f570384 100644 (file)
@@ -12,6 +12,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netdb.h>
+#include <sbuf.h>
 
 #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)
 {
index cf6f47566b722e8bf27c78c22e9b4c74befee35d..c05cea9faa578188992d9a7b8547b6d13140c10d 100644 (file)
@@ -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 (file)
index 0000000..d15590d
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * $Id$
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sbuf.h>
+#include <event.h>
+
+#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;
+}
index 0e294c45ad15ab6389261e1c52d422cff5b48836..29baee3d9b619b59d2a63c7dd597d02dd4202d38 100644 (file)
@@ -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);
        }
 }
 
index 152c5879ecfcb38b175fda79f7cfffa7eb67011c..c798ce5446499cd344d015de983d0118829a4161 100644 (file)
@@ -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)
index ee3a3f61b44283db38c75b4a2e5e51069cbd6405..dad14f8b8c3656931b5df9d323d30ca3aa50c6bd 100644 (file)
@@ -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 <http_headers.h>
 #undef HTTPH
@@ -44,7 +44,8 @@ struct sess {
        enum {
                HND_Unclass,
                HND_Handle,
-               HND_Pass
+               HND_Pass,
+               HND_Pipe
        }                       handling;
 
        char                    done;
index 47506cb260fa1add36c79e293e294d3f90b6e92d..8323fe718aa72ab1b09c7e0001be986e9beebd77 100644 (file)
@@ -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);