From: phk Date: Sun, 15 Jun 2008 16:11:17 +0000 (+0000) Subject: Get a fair bit further in parsing HTTP stuff. X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bdeb00fc886c04302c9c832c009db39a40243794;p=varnish Get a fair bit further in parsing HTTP stuff. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2686 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/bin/varnishtest/t000.vtc b/varnish-cache/bin/varnishtest/t000.vtc index 492873ad..d766663b 100644 --- a/varnish-cache/bin/varnishtest/t000.vtc +++ b/varnish-cache/bin/varnishtest/t000.vtc @@ -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 diff --git a/varnish-cache/bin/varnishtest/vtc.c b/varnish-cache/bin/varnishtest/vtc.c index 593614e3..30acac71 100644 --- a/varnish-cache/bin/varnishtest/vtc.c +++ b/varnish-cache/bin/varnishtest/vtc.c @@ -35,12 +35,53 @@ #include #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 */ diff --git a/varnish-cache/bin/varnishtest/vtc.h b/varnish-cache/bin/varnishtest/vtc.h index facb12bb..23d38316 100644 --- a/varnish-cache/bin/varnishtest/vtc.h +++ b/varnish-cache/bin/varnishtest/vtc.h @@ -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); diff --git a/varnish-cache/bin/varnishtest/vtc_client.c b/varnish-cache/bin/varnishtest/vtc_client.c index d29c1e06..50bd1fb0 100644 --- a/varnish-cache/bin/varnishtest/vtc_client.c +++ b/varnish-cache/bin/varnishtest/vtc_client.c @@ -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", diff --git a/varnish-cache/bin/varnishtest/vtc_http.c b/varnish-cache/bin/varnishtest/vtc_http.c index a1f4b4ca..4c2b0a69 100644 --- a/varnish-cache/bin/varnishtest/vtc_http.c +++ b/varnish-cache/bin/varnishtest/vtc_http.c @@ -32,13 +32,16 @@ #include #include #include +#include #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; diff --git a/varnish-cache/bin/varnishtest/vtc_server.c b/varnish-cache/bin/varnishtest/vtc_server.c index 9b99f595..efdf0820 100644 --- a/varnish-cache/bin/varnishtest/vtc_server.c +++ b/varnish-cache/bin/varnishtest/vtc_server.c @@ -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",