From 8b912dee592a35bc3516718c71e5b7964c5ca730 Mon Sep 17 00:00:00 2001 From: phk Date: Tue, 4 Jul 2006 19:36:00 +0000 Subject: [PATCH] Fix pipelining. A braino in http_Dissect() resulted in an off-by-one error (protected with assert now) Move any remaning bytes in buffer to front and check for a complete header before arming the eventloop on the session. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@302 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/cache_http.c | 53 +++++++++++++++++-------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/varnish-cache/bin/varnishd/cache_http.c b/varnish-cache/bin/varnishd/cache_http.c index 9b8ba126..906d4d92 100644 --- a/varnish-cache/bin/varnishd/cache_http.c +++ b/varnish-cache/bin/varnishd/cache_http.c @@ -291,11 +291,34 @@ http_Dissect(struct http *hp, int fd, int rr) VSLR(SLT_LostHeader, fd, p, q); } } - if (*++p == '\r') + assert(hp->t == r); +} + +/*--------------------------------------------------------------------*/ + +static int +http_header_complete(struct http *hp) +{ + char *p; + + p = hp->s; + while (1) { + /* XXX: we could save location of all linebreaks for later */ + p = strchr(p, '\n'); + if (p == NULL) + return (0); p++; + if (*p == '\r') + p++; + if (*p != '\n') + continue; + break; + } hp->t = ++p; + return (1); } + /*--------------------------------------------------------------------*/ #include @@ -330,21 +353,8 @@ http_read_f(int fd, short event, void *arg) hp->v += i; *hp->v = '\0'; - - p = hp->s; - while (1) { - /* XXX: we could save location of all linebreaks for later */ - p = strchr(p, '\n'); - if (p == NULL) - return; - p++; - if (*p == '\r') - p++; - if (*p != '\n') - continue; - break; - } - hp->t = ++p; + if (!http_header_complete(hp)) + return; event_del(&hp->ev); if (hp->callback != NULL) @@ -356,9 +366,18 @@ http_read_f(int fd, short event, void *arg) void http_RecvHead(struct http *hp, int fd, struct event_base *eb, http_callback_f *func, void *arg) { + unsigned l; assert(hp != NULL); - assert(hp->t == hp->s || hp->t == hp->v); /* XXX pipelining */ + if (hp->t > hp->s && hp->t < hp->v) { + l = hp->v - hp->t; + memmove(hp->s, hp->t, l); + hp->v = hp->s + l; + if (http_header_complete(hp)) { + func(arg, 1); + return; + } + } hp->callback = func; hp->arg = arg; hp->v = hp->s; -- 2.39.5