]> err.no Git - varnish/commitdiff
Change the logic that decides when we attempt EOF fetches from the
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 18 Dec 2008 11:30:02 +0000 (11:30 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 18 Dec 2008 11:30:02 +0000 (11:30 +0000)
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

varnish-cache/bin/varnishd/cache_fetch.c
varnish-cache/bin/varnishd/cache_http.c

index 7d90c5f1c488ca08a87152b7cc86c6eac233c93d..fed310034fb164092a614ae2c6a78618dd4f85c1 100644 (file)
@@ -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)
index baf1e6f752871940616a17b80dce1bcae3aa9293..868b656d6ea63a9a7b34f02457a4abc67fcff6b3 100644 (file)
@@ -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 */