From: wessels <> Date: Sun, 7 Dec 1997 07:48:12 +0000 (+0000) Subject: Henrik Nordstrom X-Git-Tag: SQUID_3_0_PRE1~4371 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b34ed72;p=thirdparty%2Fsquid.git Henrik Nordstrom When we detect an entry with bad content length in store.c, set a flags bit so we know to close the client connection. --- diff --git a/src/client_side.cc b/src/client_side.cc index ff5af04d9d..ee11ea6133 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.176 1997/12/06 19:38:36 wessels Exp $ + * $Id: client_side.cc,v 1.177 1997/12/07 00:48:12 wessels Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -974,6 +974,7 @@ clientWriteComplete(int fd, char *bufnotused, size_t size, int errflag, void *da clientHttpRequest *http = data; ConnStateData *conn; StoreEntry *entry = http->entry; + int done; http->out.size += size; debug(12, 5) ("clientWriteComplete: FD %d, sz %d, err %d, off %d, len %d\n", fd, size, errflag, http->out.offset, entry->object_len); @@ -989,17 +990,24 @@ clientWriteComplete(int fd, char *bufnotused, size_t size, int errflag, void *da urlParseProtocol(storeUrl(entry)), http->out.size); comm_close(fd); - } else if (icpCheckTransferDone(http) || size == 0) { + } else if ((done = icpCheckTransferDone(http)) || size == 0) { debug(12, 5) ("clientWriteComplete: FD %d transfer is DONE\n", fd); /* We're finished case */ HTTPCacheInfo->proto_touchobject(HTTPCacheInfo, http->request->protocol, http->out.size); - if (http->entry->mem_obj->reply->content_length < 0) { + if (http->entry->mem_obj->reply->content_length < 0 || !done || + EBIT_TEST(entry->flag, ENTRY_BAD_LENGTH)) { + /* + * Client connection closed due to unknown or invalid + * content length. Persistent connection is not possible. + * This catches most cases, but probably not all. + */ comm_close(fd); } else if (EBIT_TEST(http->request->flags, REQ_PROXY_KEEPALIVE)) { debug(12, 5) ("clientWriteComplete: FD %d Keeping Alive\n", fd); conn = http->conn; + conn->defer.until = 0; /* Kick it to read a new request */ httpRequestFree(http); if ((http = conn->chr) != NULL) { debug(12, 1) ("clientWriteComplete: FD %d Sending next request\n", fd); @@ -1851,17 +1859,17 @@ icpCheckTransferDone(clientHttpRequest * http) assert(http->request != NULL); reply = mem->reply; if (reply->hdr_sz == 0) - return 0; /* haven't found end of headers yet */ + return 0; /* haven't found end of headers yet */ else if (reply->code == HTTP_OK) - sending = SENDING_BODY; + sending = SENDING_BODY; else if (reply->content_length < 0) sending = SENDING_HDRSONLY; else if (reply->code == HTTP_NO_CONTENT) - sending = SENDING_HDRSONLY; + sending = SENDING_HDRSONLY; else if (reply->code == HTTP_NOT_MODIFIED) - sending = SENDING_HDRSONLY; + sending = SENDING_HDRSONLY; else if (http->request->method == METHOD_HEAD) - sending = SENDING_HDRSONLY; + sending = SENDING_HDRSONLY; else sending = SENDING_BODY; /* @@ -1882,7 +1890,7 @@ icpCheckTransferDone(clientHttpRequest * http) if (http->out.offset < sendlen) return 0; else - return 1; + return 1; } static char * diff --git a/src/enums.h b/src/enums.h index 63079f394d..70c65502d2 100644 --- a/src/enums.h +++ b/src/enums.h @@ -309,7 +309,8 @@ enum { KEY_PRIVATE, HIERARCHICAL, ENTRY_NEGCACHED, - ENTRY_VALIDATED + ENTRY_VALIDATED, + ENTRY_BAD_LENGTH }; enum { diff --git a/src/http.cc b/src/http.cc index 4ec5f712f7..8973e7ff14 100644 --- a/src/http.cc +++ b/src/http.cc @@ -1,6 +1,6 @@ /* - * $Id: http.cc,v 1.229 1997/12/06 01:26:16 wessels Exp $ + * $Id: http.cc,v 1.230 1997/12/07 00:48:14 wessels Exp $ * * DEBUG: section 11 Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived @@ -258,7 +258,7 @@ httpTimeout(int fd, void *data) err->request = requestLink(httpState->orig_request); errorAppendEntry(entry, err); } else { - storeAbort(entry, 0); + storeAbort(entry, 0); } comm_close(fd); } @@ -612,7 +612,7 @@ httpPconnTransferDone(HttpStateData * httpState) else if (mem->inmem_hi < reply->content_length + reply->hdr_sz) return 0; else - return 1; + return 1; } /* This will be called when data is ready to be read from fd. Read until @@ -657,7 +657,7 @@ httpReadReply(int fd, void *data) err->request = requestLink(httpState->orig_request); errorAppendEntry(entry, err); } else { - storeAbort(entry, 0); + storeAbort(entry, 0); } comm_close(fd); } @@ -678,6 +678,12 @@ httpReadReply(int fd, void *data) /* Connection closed; retrieval done. */ httpState->eof = 1; if (httpState->reply_hdr_state < 2) + /* + * Yes Henrik, there is a point to doing this. When we + * called httpProcessReplyHeader() before, we didn't find + * the end of headers, but now we are definately at EOF, so + * we want to process the reply headers. + */ httpProcessReplyHeader(httpState, buf, len); storeComplete(entry); /* deallocates mem_obj->request */ comm_close(fd); diff --git a/src/store.cc b/src/store.cc index 9d2e471c5c..d0dfc7d313 100644 --- a/src/store.cc +++ b/src/store.cc @@ -1,5 +1,5 @@ /* - * $Id: store.cc,v 1.355 1997/12/06 05:17:01 wessels Exp $ + * $Id: store.cc,v 1.356 1997/12/07 00:48:15 wessels Exp $ * * DEBUG: section 20 Storeage Manager * AUTHOR: Harvest Derived @@ -1133,7 +1133,7 @@ storeDoRebuildFromDisk(void *data) key = storeKeyScan(keytext); if (key == NULL) { - debug(20,1)("storeDoRebuildFromDisk: bad key: '%s'\n", keytext); + debug(20, 1) ("storeDoRebuildFromDisk: bad key: '%s'\n", keytext); continue; } e = storeGet(key); @@ -1398,7 +1398,7 @@ storeCheckCachable(StoreEntry * e) debug(20, 2) ("storeCheckCachable: NO: not cachable\n"); } else if (EBIT_TEST(e->flag, RELEASE_REQUEST)) { debug(20, 2) ("storeCheckCachable: NO: release requested\n"); - } else if (e->store_status == STORE_OK && !storeEntryValidLength(e)) { + } else if (e->store_status == STORE_OK && EBIT_TEST(e->flag, ENTRY_BAD_LENGTH)) { debug(20, 2) ("storeCheckCachable: NO: wrong content-length\n"); } else if (EBIT_TEST(e->flag, ENTRY_NEGCACHED)) { debug(20, 2) ("storeCheckCachable: NO: negative cached\n"); @@ -1423,6 +1423,8 @@ storeComplete(StoreEntry * e) e->object_len = e->mem_obj->inmem_hi; e->store_status = STORE_OK; assert(e->mem_status == NOT_IN_MEMORY); + if (!storeEntryValidLength(e)) + EBIT_SET(e->flag, ENTRY_BAD_LENGTH); InvokeHandlers(e); storeCheckSwapOut(e); }