]> err.no Git - varnish/commitdiff
Add INCOMPL() macro to mark missing code.
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 1 May 2006 10:55:27 +0000 (10:55 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 1 May 2006 10:55:27 +0000 (10:55 +0000)
Add http_HdrIs() to check if we have a given header and if we do
if it has a given value.

Use it.

Ignore SIGPIPE since SO_NOSIGPIPE doesn't work reliably, (but set
it on accepted TCP connections anyway).

Update passing to match fetching, including a chunked encoding method.

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

varnish-cache/bin/varnishd/cache.h
varnish-cache/bin/varnishd/cache_acceptor.c
varnish-cache/bin/varnishd/cache_fetch.c
varnish-cache/bin/varnishd/cache_http.c
varnish-cache/bin/varnishd/cache_main.c
varnish-cache/bin/varnishd/cache_pass.c
varnish-cache/bin/varnishd/cache_pool.c

index 2b2d306f3abfc8c51729a51755d26d08f5a676c3..a34925a789d06cb7baea101d8d8d9700e5cc1714 100644 (file)
@@ -83,6 +83,7 @@ struct http;
 struct http *http_New(void);
 void http_Delete(struct http *hp);
 int http_GetHdr(struct http *hp, const char *hdr, char **ptr);
+int http_HdrIs(struct http *hp, const char *hdr, const char *val);
 int http_GetTail(struct http *hp, unsigned len, char **b, char **e);
 int http_GetURL(struct http *hp, char **b);
 void http_RecvHead(struct http *hp, int fd, struct event_base *eb, http_callback_f *func, void *arg);
@@ -108,6 +109,10 @@ void VSL_Init(void);
 void VSLR(enum shmlogtag tag, unsigned id, const char *b, const char *e);
 void VSL(enum shmlogtag tag, unsigned id, const char *fmt, ...);
 #define HERE() VSL(SLT_Debug, 0, "HERE: %s(%d)", __func__, __LINE__)
+#define INCOMPL() do {                                                 \
+       VSL(SLT_Debug, 0, "INCOMPLETE AT: %s(%d)", __func__, __LINE__); \
+       assert(__LINE__ == 0);                                          \
+       } while (0)
 #endif
 
 /* cache_vcl.c */
index b05b95e631930a530d1828efa23f90d1f17b769d..fb6fae040d2f65e3ad535023196f5265ee1de44a 100644 (file)
@@ -58,6 +58,7 @@ accept_f(int fd, short event, void *arg)
        struct sockaddr addr;
        struct sess *sp;
        char port[10];
+       int i;
 
        (void)arg;
        sm = calloc(sizeof *sm, 1);
@@ -76,6 +77,8 @@ accept_f(int fd, short event, void *arg)
                free(sp);
                return;
        }
+       i = 1;
+       AZ(setsockopt(sp->fd, SOL_SOCKET, SO_NOSIGPIPE, &i, sizeof i));
        AZ(getnameinfo(&addr, l,
            sp->addr, VCA_ADDRBUFSIZE,
            port, sizeof port, NI_NUMERICHOST | NI_NUMERICSERV));
index 33370305f7b6dc76a42787a612eb0a4e6cb03b51..35c477d2270164527210da5dda8deb257aaf8ccf 100644 (file)
@@ -165,9 +165,7 @@ FetchSession(struct worker *w, struct sess *sp)
        VSL(SLT_Handling, sp->fd, "Fetch fd %d", fd);
 
        hp = http_New();
-HERE();
        http_BuildSbuf(1, w->sb, sp->http);
-HERE();
        i = write(fd, sbuf_data(w->sb), sbuf_len(w->sb));
        assert(i == sbuf_len(w->sb));
 
@@ -190,12 +188,11 @@ HERE();
 
        assert(sp->handling == HND_Insert);
 
-       if (http_GetHdr(hp, "Content-Length", &b)) {
+       if (http_GetHdr(hp, "Content-Length", &b))
                cls = fetch_straight(w, sp, fd, hp, b);
-       } else if (http_GetHdr(hp, "Transfer-Encoding", &b) &&
-           !strcasecmp(b, "chunked")) {
+       else if (http_HdrIs(hp, "Transfer-Encoding", "chunked"))
                cls = fetch_chunked(w, sp, fd, hp);
-       else {
+       else {
                VSL(SLT_Debug, fd, "No transfer");
                cls = 0;
        }
index 718980cece4a0eda88bfb47538cf431f55d69b2c..ba45148711a0ecd6d99ae9a217e2158c1f99cee9 100644 (file)
@@ -101,6 +101,19 @@ http_GetHdr(struct http *hp, const char *hdr, char **ptr)
        return (0);
 }
 
+int
+http_HdrIs(struct http *hp, const char *hdr, const char *val)
+{
+       char *p;
+
+       if (!http_GetHdr(hp, hdr, &p))
+               return (0);
+       assert(p != NULL);
+       if (!strcasecmp(p, val))
+               return (1);
+       return (0);
+}
+
 int
 http_GetURL(struct http *hp, char **b)
 {
@@ -346,6 +359,7 @@ http_BuildSbuf(int resp, struct sbuf *sb, struct http *hp)
                sbuf_cat(sb, " ");
                sbuf_cat(sb, hp->proto);
        } else {
+               printf("resp = %d\n", resp);
                assert(resp == 1 || resp == 2);
        }
        sbuf_cat(sb, "\r\n");
index 224cbf9c4b65259535354e915eb1e18221e6c2ba..c5e3e56e5608a69e2b24bb87dfc97a2f6933d989 100644 (file)
@@ -6,6 +6,7 @@
 #include <unistd.h>
 #include <assert.h>
 #include <stdlib.h>
+#include <signal.h>
 #include <sys/time.h>
 
 #include <pthread.h>
@@ -103,6 +104,9 @@ child_main(void)
        struct cli *cli;
        int i;
 
+       /* XXX: SO_NOSIGPIPE does not work reliably :-( */
+       signal(SIGPIPE, SIG_IGN);
+
        setbuf(stdout, NULL);
        setbuf(stderr, NULL);
        printf("Child starts\n");
index 6dce02b2d6e578ac9e871532d22bfc939460a11f..72e02bf2d7ac564850775722ab58dddb8411fbce 100644 (file)
 #include "vcl_lang.h"
 #include "cache.h"
 
+
+/*--------------------------------------------------------------------*/
+
+static int
+pass_straight(struct worker *w, struct sess *sp, int fd, struct http *hp, char *bi)
+{
+       int i, j;
+       char *b, *e;
+       off_t   cl;
+       unsigned c;
+       char buf[BUFSIZ];
+
+       if (bi != NULL)
+               cl = strtoumax(bi, NULL, 0);
+       else
+               cl = (1<<30);           /* XXX */
+
+       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;
+               if (http_GetTail(hp, c, &b, &e)) {
+                       i = e - b;
+                       j = write(sp->fd, b, i);
+                       assert(i == j);
+                       cl -= i;
+                       continue;
+               }
+               i = read(fd, buf, c);
+               if (i == 0 && bi == NULL)
+                       return (1);
+               assert(i > 0);
+               j = write(sp->fd, buf, i);
+               assert(i == j);
+               cl -= i;
+       }
+       return (0);
+}
+
+
+/*--------------------------------------------------------------------*/
+
+static int
+pass_chunked(struct worker *w, struct sess *sp, int fd, struct http *hp)
+{
+       int i, j;
+       char *b, *q, *e;
+       char *p;
+       unsigned u;
+       char buf[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) {
+               if (http_GetTail(hp, be - bp, &b, &e)) {
+                       memcpy(bp, b, e - b);
+                       bp += e - b;
+               } else {
+                       /* XXX: must be safe from backend */
+                       i = read(fd, bp, be - bp);
+                       assert(i > 0);
+                       bp += i;
+               }
+               /* buffer valid from p to bp */
+
+               u = strtoul(p, &q, 16);
+               if (q == NULL || (*q != '\n' && *q != '\r')) {
+                       INCOMPL();
+                       /* XXX: move bp to buf start, get more */
+               }
+               if (*q == '\r')
+                       q++;
+               assert(*q == '\n');
+               q++;
+               if (u == 0)
+                       break;
+
+               j = q - p;
+               i = write(sp->fd, q, j);
+               assert(i == j);
+
+               p = q;
+
+               while (u > 0) {
+                       j = u;
+                       if (bp == p) {
+                               bp = p = buf;
+                               break;
+                       }
+                       if (bp - p < j)
+                               j = bp - p;
+                       i = write(sp->fd, p, j);
+                       assert(i == j);
+                       p += j;
+                       u -= i;
+               }
+               while (u > 0) {
+                       if (http_GetTail(hp, u, &b, &e)) {
+                               j = e - b;
+                               i = write(sp->fd, q, j);
+                               assert(i == j);
+                               u -= j;
+                       } else
+                               break;
+               }
+               while (u > 0) {
+                       j = u;
+                       if (j > sizeof buf)
+                               j = sizeof buf;
+                       i = read(fd, buf, j);
+                       assert(i > 0);
+                       j = write(sp->fd, buf, i);
+                       assert(j == i);
+                       u -= i;
+               }
+       }
+       return (0);
+}
+
+
 /*--------------------------------------------------------------------*/
 void
 PassSession(struct worker *w, struct sess *sp)
 {
-       int fd, i, j;
+       int fd, i;
        void *fd_token;
-       struct sess sp2;
-       char buf[BUFSIZ];
-       off_t   cl;
+       struct http *hp;
        char *b;
+       int cls;
 
-       if (http_GetHdr(sp->http, "Connection", &b) && !strcmp(b, "close")) {
-               /*
-                * If client wants only this one request, piping is safer
-                * and cheaper
-                */
-               PipeSession(w, sp);
-               return;
-       }
        fd = VBE_GetFd(sp->backend, &fd_token);
        assert(fd != -1);
 
@@ -50,69 +171,35 @@ PassSession(struct worker *w, struct sess *sp)
 
        /* XXX: copy any contents */
 
-       memset(&sp2, 0, sizeof sp2);
-       sp2.rd_e = &w->e1;
-       sp2.fd = fd;
        /*
         * XXX: It might be cheaper to avoid the event_engine and simply
         * XXX: read(2) the header
         */
-       http_RecvHead(sp2.http, sp2.fd, w->eb, NULL, NULL);
+       hp = http_New();
+       http_RecvHead(hp, fd, w->eb, NULL, NULL);
        event_base_loop(w->eb, 0);
-       http_Dissect(sp2.http, sp2.fd, 2);
+       http_Dissect(hp, fd, 2);
 
-       http_BuildSbuf(2, w->sb, sp2.http);
+       http_BuildSbuf(2, w->sb, hp);
        i = write(sp->fd, sbuf_data(w->sb), sbuf_len(w->sb));
        assert(i == sbuf_len(w->sb));
 
-       assert(__LINE__ == 0);
-       cl = j = 0;
-       *buf = 0;
-
-#if 0
-       if (sp2.http.H_Content_Length != NULL) {
-               cl = strtoumax(sp2.http.H_Content_Length, NULL, 0);
-               i = fcntl(sp2.fd, F_GETFL);
-               i &= ~O_NONBLOCK;
-               i = fcntl(sp2.fd, F_SETFL, i);
-               assert(i != -1);
-               i = sp2.rcv_len - sp2.rcv_ptr;
-               if (i > 0) {
-                       j = write(sp->fd, sp2.rcv + sp2.rcv_ptr, i);
-                       assert(j == i);
-                       cl -= i;
-                       sp2.rcv_ptr += i;
-               }
-               while (cl > 0) {
-                       j = sizeof buf;
-                       if (j > cl)
-                               j = cl;
-                       i = recv(sp2.fd, buf, j, 0);
-                       assert(i >= 0);
-                       if (i > 0) {
-                               cl -= i;
-                               j = write(sp->fd, buf, i);
-                               assert(j == i);
-                       } else if (i == 0) {
-                               break;
-                       }
-               }
-               assert(cl == 0);
+       if (http_GetHdr(hp, "Content-Length", &b))
+               cls = pass_straight(w, sp, fd, hp, b);
+       else if (http_HdrIs(hp, "Connection", "close"))
+               cls = pass_straight(w, sp, fd, hp, NULL);
+       else if (http_HdrIs(hp, "Transfer-Encoding", "chunked"))
+               cls = pass_chunked(w, sp, fd, hp);
+       else {
+               INCOMPL();
+               cls = 1;
        }
 
-       if (sp2.http.H_Connection != NULL &&
-           !strcmp(sp2.http.H_Connection, "close")) {
-               close(fd);
+       if (http_GetHdr(hp, "Connection", &b) && !strcasecmp(b, "close"))
+               cls = 1;
+
+       if (cls)
                VBE_ClosedFd(fd_token);
-       } else {
+       else
                VBE_RecycleFd(fd_token);
-       }
-
-       /* XXX: this really belongs in the acceptor */
-       if (sp->rcv_len > sp->rcv_ptr)
-               memmove(sp->rcv, sp->rcv + sp->rcv_ptr,
-                   sp->rcv_len - sp->rcv_ptr);
-       sp->rcv_len -= sp->rcv_ptr;
-       sp->rcv_ptr = 0;
-#endif
 }
index 0cfe5df7659546662caa3859fb65040700a46728..57425cba3b235cda125e27a1b542b6e402d172e1 100644 (file)
@@ -126,6 +126,7 @@ CacheWorker(void *priv)
                sp->handling = HND_Lookup;
                
                sp->vcl->recv_func(sp);
+               sp->handling = HND_Pass;
 
                for (done = 0; !done; ) {
                        switch(sp->handling) {