From: phk Date: Thu, 18 Dec 2008 11:30:02 +0000 (+0000) Subject: Change the logic that decides when we attempt EOF fetches from the X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=32e049596c01cd42b07b00784908774c27930fb0;p=varnish Change the logic that decides when we attempt EOF fetches from the backend. The new logic is: If (HEAD) /* happens only on pass */ do not fetch body. else if (Content-Length) fetch body according to length else if (chunked) fetch body as chunked else if (other transfer-encoding) fail else if (Connection: keep-alive) fetch no body, set Length = 0 else if (Connection: close) fetch body until EOF else if (HTTP < 1.1) fetch body until EOF else fetch no body, set Length = 0 let me know if this breaks anything that should work. Fixes #400 git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@3470 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/bin/varnishd/cache_fetch.c b/varnish-cache/bin/varnishd/cache_fetch.c index 7d90c5f1..fed31003 100644 --- a/varnish-cache/bin/varnishd/cache_fetch.c +++ b/varnish-cache/bin/varnishd/cache_fetch.c @@ -414,15 +414,31 @@ Fetch(struct sess *sp) WSL(sp->wrk, SLT_Debug, vc->fd, "Invalid Transfer-Encoding"); VBE_ClosedFd(sp); return (__LINE__); + } else if (http_HdrIs(hp, H_Connection, "keep-alive")) { + /* + * If we have Connection: keep-alive, it cannot possibly be + * EOF encoded, and since it is neither length nor chunked + * it must be zero length. + */ + mklen = 1; + } else if (http_HdrIs(hp, H_Connection, "close")) { + /* + * If we have connection closed, it is safe to read what + * comes in any case. + */ + cls = fetch_eof(sp, htc); + mklen = 1; + } else if (hp->protover < 1.1) { + /* + * With no Connection header, assume EOF + */ + cls = fetch_eof(sp, htc); + mklen = 1; } else { - switch (http_GetStatus(hp)) { - case 200: - cls = fetch_eof(sp, htc); - mklen = 1; - break; - default: - break; - } + /* + * Assume zero length + */ + mklen = 1; } if (cls < 0) { @@ -451,7 +467,7 @@ Fetch(struct sess *sp) http_PrintfHeader(sp->wrk, sp->fd, hp2, "Content-Length: %u", sp->obj->len); - if (http_GetHdr(hp, H_Connection, &b) && !strcasecmp(b, "close")) + if (http_HdrIs(hp, H_Connection, "close")) cls = 1; if (cls) diff --git a/varnish-cache/bin/varnishd/cache_http.c b/varnish-cache/bin/varnishd/cache_http.c index baf1e6f7..868b656d 100644 --- a/varnish-cache/bin/varnishd/cache_http.c +++ b/varnish-cache/bin/varnishd/cache_http.c @@ -251,7 +251,7 @@ http_DoConnection(struct http *hp) unsigned u; if (!http_GetHdr(hp, H_Connection, &p)) { - if (strcmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.1")) + if (hp->protover < 1.1) return ("not HTTP/1.1"); return (NULL); } @@ -440,6 +440,21 @@ http_splitline(struct worker *w, int fd, struct http *hp, return (http_dissect_hdrs(w, hp, fd, p, htc->rxbuf)); } +/*--------------------------------------------------------------------*/ + +static void +http_ProtoVer(struct http *hp) +{ + + if (!strcmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.0")) + hp->protover = 1.0; + else if (!strcmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.1")) + hp->protover = 1.1; + else + hp->protover = 0.9; +} + + /*--------------------------------------------------------------------*/ int @@ -463,13 +478,7 @@ http_DissectRequest(struct sess *sp) WSPR(sp, SLT_HttpGarbage, htc->rxbuf); return (i); } - - if (!strcmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.0")) - hp->protover = 1.0; - else if (!strcmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.1")) - hp->protover = 1.1; - else - hp->protover = 0.9; + http_ProtoVer(hp); return (i); } @@ -497,6 +506,7 @@ http_DissectResponse(struct worker *w, const struct http_conn *htc, hp->status = strtoul(hp->hd[HTTP_HDR_STATUS].b, NULL /* XXX */, 10); } + http_ProtoVer(hp); if (hp->hd[HTTP_HDR_RESPONSE].b == NULL || !Tlen(hp->hd[HTTP_HDR_RESPONSE])) { /* Backend didn't send a response string, use the standard */