]> err.no Git - varnish/commitdiff
Get a fair bit further in parsing HTTP stuff.
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Sun, 15 Jun 2008 16:11:17 +0000 (16:11 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Sun, 15 Jun 2008 16:11:17 +0000 (16:11 +0000)
git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2686 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishtest/t000.vtc
varnish-cache/bin/varnishtest/vtc.c
varnish-cache/bin/varnishtest/vtc.h
varnish-cache/bin/varnishtest/vtc_client.c
varnish-cache/bin/varnishtest/vtc_http.c
varnish-cache/bin/varnishtest/vtc_server.c

index 492873ad30db08c02c0c3ebdfe4083bfb42c9c09..d766663bb7092c353e332185b6e111ea28464382 100644 (file)
@@ -5,7 +5,7 @@
 server s1 -listen :9080 -repeat 2 {
        rxreq
        expect req.url == "/"
-       txresp -body "0123456789"
+       txresp -hdr "Foobar: barf" -body "0123456789"
 }
 
 server s1 -start 
index 593614e3e393647cf316e650a8ba98a7b482cabb..30acac712a9ffe774852dda04be8c2ea58f9f13e 100644 (file)
 #include <err.h>
 
 #include "libvarnish.h"
+#include "vsb.h"
 
 #include "vtc.h"
 
 #define                MAX_FILESIZE            (1024 * 1024)
 #define                MAX_TOKENS              20
 
+/**********************************************************************
+ * Dump a string
+ */
+void
+vct_dump(const char *ident, const char *pfx, const char *str)
+{
+       int nl = 1;
+       struct vsb *vsb;
+
+       if (pfx == NULL)
+               pfx = "";
+       vsb = vsb_new(NULL, NULL, 0, VSB_AUTOEXTEND);
+       if (str == NULL) 
+               vsb_printf(vsb, "#### %-4s %s(null)\n", ident, pfx);
+       for(; *str; str++) {
+               if (nl) {
+                       vsb_printf(vsb, "#### %-4s %s| ", ident, pfx);
+                       nl = 0;
+               }
+               if (*str == '\r')
+                       vsb_printf(vsb, "\\r");
+               else if (*str == '\t')
+                       vsb_printf(vsb, "\\t");
+               else if (*str == '\n') {
+                       vsb_printf(vsb, "\\n\n");
+                       nl = 1;
+               } else if (*str < 0x20 || *str > 0x7e)
+                       vsb_printf(vsb, "\\x%02x", *str);
+               else
+                       vsb_printf(vsb, "%c", *str);
+       }
+       if (!nl)
+               vsb_printf(vsb, "\n");
+       vsb_finish(vsb);
+       AZ(vsb_overflowed(vsb));
+       fputs(vsb_data(vsb), stdout);
+       vsb_delete(vsb);
+}
+
+
 /**********************************************************************
  * Read a file into memory
  */
index facb12bbfff655d81453ecb480f9189c699fedaa..23d383161c9529423fcc097987705ed39999ab8c 100644 (file)
@@ -42,4 +42,6 @@ void cmd_vcl(char **av, void *priv);
 void cmd_stats(char **av, void *priv);
 void cmd_varnish(char **av, void *priv);
 
-void http_process(const char *spec, int sock, int client);
+void http_process(const char *ident, const char *spec, int sock, int client);
+
+void vct_dump(const char *ident, const char *pfx, const char *str);
index d29c1e0607f1d3f91921c1af06fed09740b1c118..50bd1fb0b6938798e8c1dd1cd5eb6b430062318a 100644 (file)
@@ -76,19 +76,19 @@ client_thread(void *priv)
        CAST_OBJ_NOTNULL(c, priv, CLIENT_MAGIC);
        assert(c->naddr > 0);
 
-       printf("### Client %s started\n", c->name);
-       printf("#### Client %s connect to %s\n", c->name, c->connect);
+       printf("##   %-4s started\n", c->name);
+       printf("###  %-4s connect to %s\n", c->name, c->connect);
        for (i = 0; i < c->naddr; i++) {
                fd = VSS_connect(c->vss_addr[i]);
                if (fd >= 0)
                        break;
        }
        assert(fd >= 0);
-       printf("#### Client %s connected to %s fd is %d\n",
+       printf("###  %-4s connected to %s fd is %d\n",
            c->name, c->connect, fd);
-       http_process(c->spec, fd, 1);
+       http_process(c->name, c->spec, fd, 1);
        AZ(close(fd));
-       printf("### Client %s ending\n", c->name);
+       printf("##   %-4s ending\n", c->name);
 
        return (NULL);
 }
@@ -133,7 +133,7 @@ client_wait(struct client *c)
        void *res;
 
        CHECK_OBJ_NOTNULL(c, CLIENT_MAGIC);
-       printf("Waiting for client %s\n", c->name);
+       printf("##   %-4s Waiting for client\n", c->name);
        AZ(pthread_join(c->tp, &res));
        if (res != NULL) {
                fprintf(stderr, "Server %s returned \"%s\"\n",
index a1f4b4ca893290c0aae671e83c544579151333fb..4c2b0a691945bf2831cc16a2caeb5e001a8b9e68 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <ctype.h>
 
 #include "libvarnish.h"
+#include "vct.h"
 #include "miniobj.h"
 #include "vsb.h"
 
 #include "vtc.h"
 
+#define MAX_HDR                50
 
 struct http {
        unsigned                magic;
@@ -46,14 +49,113 @@ struct http {
        int                     fd;
        int                     client;
        int                     timeout;
+       const char              *ident;
 
        int                     nrxbuf;
        char                    *rxbuf;
 
-       char                    *req;
-       char                    *resp;
+       char                    *req[MAX_HDR];
+       char                    *resp[MAX_HDR];
 };
 
+/**********************************************************************
+ * Expect
+ */
+
+static void
+cmd_http_expect(char **av, void *priv)
+{
+       struct http *hp;
+
+       CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC);
+       assert(!strcmp(av[0], "expect"));
+       av++;
+
+       for(; *av != NULL; av++) {
+               fprintf(stderr, "Unknown http expect spec: %s\n", *av);
+               // exit (1);
+       }
+}
+
+/**********************************************************************
+ * Split a HTTP protocol header
+ */
+
+static void
+http_splitheader(struct http *hp, int req)
+{
+       char *p, *q, **hh;
+       int n;
+       char buf[20];
+
+       CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
+       if (req) {
+               memset(hp->req, 0, sizeof hp->req);
+               hh = hp->req;
+       } else {
+               memset(hp->resp, 0, sizeof hp->resp);
+               hh = hp->resp;
+       }
+
+       n = 0;
+       p = hp->rxbuf;
+
+       /* REQ/PROTO */
+       while (vct_islws(*p))
+               p++;
+       hh[n++] = p;
+       while (!vct_islws(*p))
+               p++;
+       assert(!vct_iscrlf(*p));
+       *p++ = '\0';
+
+       /* URL/STATUS */
+       while (vct_issp(*p))            /* XXX: H space only */
+               p++;
+       assert(!vct_iscrlf(*p));
+       hh[n++] = p;
+       while (!vct_islws(*p))
+               p++;
+       if (vct_iscrlf(*p)) {
+               hh[n++] = NULL;
+               q = p;
+               p += vct_skipcrlf(p);
+               *q = '\0';
+       } else {
+               *p++ = '\0';
+               /* PROTO/MSG */
+               while (vct_issp(*p))            /* XXX: H space only */
+                       p++;
+               hh[n++] = p;
+               while (!vct_iscrlf(*p))
+                       p++;
+               q = p;
+               p += vct_skipcrlf(p);
+               *q = '\0';
+       }
+       assert(n == 3);
+
+       while (*p != '\0') {
+               assert(n < MAX_HDR);
+               if (vct_iscrlf(*p))
+                       break;
+               hh[n++] = p++;
+               while (*p != '\0' && !vct_iscrlf(*p))
+                       p++;
+               q = p;
+               p += vct_skipcrlf(p);
+               *q = '\0';
+       }
+       p += vct_skipcrlf(p);
+       assert(*p == '\0');
+
+       for (n = 0; n < 3 || hh[n] != NULL; n++) {
+               sprintf(buf, "http[%2d] ", n);
+               vct_dump(hp->ident, buf, hh[n]);
+       }
+}
+
+
 /**********************************************************************
  * Receive a HTTP protocol header
  */
@@ -94,7 +196,7 @@ http_rxhdr(struct http *hp)
                if (i == 2)
                        break;
        }
-printf("<<<%s>>>\n", hp->rxbuf);
+       vct_dump(hp->ident, NULL, hp->rxbuf);
 }
 
 
@@ -116,8 +218,9 @@ cmd_http_rxresp(char **av, void *priv)
                fprintf(stderr, "Unknown http rxresp spec: %s\n", *av);
                exit (1);
        }
+       printf("###  %-4s rxresp\n", hp->ident);
        http_rxhdr(hp);
-       hp->resp = hp->rxbuf;
+       http_splitheader(hp, 0);
 }
 
 /**********************************************************************
@@ -193,6 +296,7 @@ cmd_http_txresp(char **av, void *priv)
        }
        vsb_finish(vsb);
        AZ(vsb_overflowed(vsb));
+       vct_dump(hp->ident, NULL, vsb_data(vsb));
        l = write(hp->fd, vsb_data(vsb), vsb_len(vsb));
        assert(l == vsb_len(vsb));
        vsb_delete(vsb);
@@ -216,8 +320,9 @@ cmd_http_rxreq(char **av, void *priv)
                fprintf(stderr, "Unknown http rxreq spec: %s\n", *av);
                exit (1);
        }
+       printf("###  %-4s rxreq\n", hp->ident);
        http_rxhdr(hp);
-       hp->req = hp->rxbuf;
+       http_splitheader(hp, 1);
 }
 
 /**********************************************************************
@@ -283,6 +388,7 @@ cmd_http_txreq(char **av, void *priv)
        vsb_cat(vsb, nl);
        vsb_finish(vsb);
        AZ(vsb_overflowed(vsb));
+       vct_dump(hp->ident, NULL, vsb_data(vsb));
        l = write(hp->fd, vsb_data(vsb), vsb_len(vsb));
        assert(l == vsb_len(vsb));
        vsb_delete(vsb);
@@ -297,12 +403,12 @@ static struct cmds http_cmds[] = {
        { "rxreq",      cmd_http_rxreq },
        { "txresp",     cmd_http_txresp },
        { "rxresp",     cmd_http_rxresp },
-       { "expect",     cmd_dump },
+       { "expect",     cmd_http_expect },
        { NULL,         NULL }
 };
 
 void
-http_process(const char *spec, int sock, int client)
+http_process(const char *ident, const char *spec, int sock, int client)
 {
        struct http *hp;
        char *s, *q;
@@ -310,6 +416,7 @@ http_process(const char *spec, int sock, int client)
        ALLOC_OBJ(hp, HTTP_MAGIC);
        AN(hp);
        hp->fd = sock;
+       hp->ident = ident;
        hp->client = client;
        hp->timeout = 1000;
        hp->nrxbuf = 8192;
index 9b99f59546ea39b78ba5ca24786bb0e0bd761398..efdf0820f242c3f2b705756fb4c788dbe4b48650 100644 (file)
@@ -82,18 +82,18 @@ server_thread(void *priv)
        CAST_OBJ_NOTNULL(s, priv, SERVER_MAGIC);
        assert(s->sock >= 0);
 
-       printf("### Server %s started\n", s->name);
+       printf("##   %-4s started\n", s->name);
        for (i = 0; i < s->repeat; i++) {
                if (s->repeat > 1)
-                       printf("#### Server %s iteration %d\n", s->name, i);
+                       printf("###  %-4s iteration %d\n", s->name, i);
                addr = (void*)&addr_s;
                l = sizeof addr_s;
                fd = accept(s->sock, addr, &l);
-               printf("#### Accepted socket %d\n", fd);
-               http_process(s->spec, fd, 0);
+               printf("#### %-4s Accepted socket %d\n", s->name, fd);
+               http_process(s->name, s->spec, fd, 0);
                AZ(close(fd));
        }
-       printf("### Server %s ending\n", s->name);
+       printf("##   %-4s ending\n", s->name);
 
        return (NULL);
 }
@@ -157,7 +157,7 @@ server_wait(struct server *s)
        void *res;
 
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
-       printf("Waiting for server %s\n", s->name);
+       printf("##   %-4s Waiting for server\n", s->name);
        AZ(pthread_join(s->tp, &res));
        if (res != NULL) {
                fprintf(stderr, "Server %s returned \"%s\"\n",