From efb9218c3b9665cb27d24275356f04cca8882b40 Mon Sep 17 00:00:00 2001 From: wessels <> Date: Tue, 17 Mar 1998 00:03:25 +0000 Subject: [PATCH] More pconn/restart/pump fixes. - Try sending keepalives for all request methods, not just GET - Only restart a failed PUT/POST if we still have the start of the request body in memory. - If we do restart a PUT/POST, then we need to re-register with storeClientListAdd. --- src/client_side.cc | 24 ++++++++++------------- src/http.cc | 49 +++++++++++++++++++++++++++++----------------- src/protos.h | 2 ++ 3 files changed, 43 insertions(+), 32 deletions(-) diff --git a/src/client_side.cc b/src/client_side.cc index bd97e534da..cabdd1481c 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.226 1998/03/15 04:25:27 rousskov Exp $ + * $Id: client_side.cc,v 1.227 1998/03/16 17:03:25 wessels Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -67,7 +67,7 @@ static HttpReply *clientConstructProxyAuthReply(clientHttpRequest * http); static int clientCachable(clientHttpRequest * http); static int clientHierarchical(clientHttpRequest * http); static int isTcpHit(log_type code); -static int clientCheckContentLength(request_t *r); +static int clientCheckContentLength(request_t * r); static int checkAccelOnly(clientHttpRequest * http) @@ -690,23 +690,17 @@ clientParseRequestHeaders(clientHttpRequest * http) } static int -clientCheckContentLength(request_t *r) +clientCheckContentLength(request_t * r) { char *t; int len; /* - * We only require a request content-length for POST and PUT + * We only require a content-length for "upload" methods */ - switch(r->method) { - case METHOD_POST: - case METHOD_PUT: - break; - default: + if (0 == pumpMethod(r->method)) return 1; - break; - } t = mime_get_header(r->headers, "Content-Length"); - if (t == NULL) + if (NULL == t) return 0; len = atoi(t); if (len < 0) @@ -826,6 +820,8 @@ clientBuildReplyHeader(clientHttpRequest * http, size_t len = 0; size_t hdr_len = 0; size_t l; + if (0 != strncmp(hdr_in, "HTTP/", 5)) + return 0; end = mime_headers_end(hdr_in); if (end == NULL) { debug(33, 3) ("clientBuildReplyHeader: DIDN'T FIND END-OF-HEADERS\n"); @@ -1285,12 +1281,12 @@ clientProcessRequest(clientHttpRequest * http) return; } /* yes, continue */ - } else if (r->method == METHOD_PUT || r->method == METHOD_POST) { + } else if (pumpMethod(r->method)) { http->log_type = LOG_TCP_MISS; /* XXX oof, POST can be cached! */ pumpInit(fd, r, http->uri); } else { - http->log_type = clientProcessRequest2(http); + http->log_type = clientProcessRequest2(http); } http->log_type = clientProcessRequest2(http); debug(33, 4) ("clientProcessRequest: %s for '%s'\n", diff --git a/src/http.cc b/src/http.cc index b823654637..bf4c6c4a33 100644 --- a/src/http.cc +++ b/src/http.cc @@ -1,6 +1,6 @@ /* - * $Id: http.cc,v 1.252 1998/03/13 06:37:40 wessels Exp $ + * $Id: http.cc,v 1.253 1998/03/16 17:03:26 wessels Exp $ * * DEBUG: section 11 Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived @@ -140,6 +140,7 @@ static STABH httpAbort; static HttpStateData *httpBuildState(int, StoreEntry *, request_t *, peer *); static int httpSocketOpen(StoreEntry *, request_t *); static void httpRestart(HttpStateData *); +static int httpTryRestart(HttpStateData *); static int httpCachableReply(HttpStateData *); static void @@ -471,7 +472,7 @@ httpReadReply(int fd, void *data) debug(50, 2) ("httpReadReply: FD %d: read failure: %s.\n", fd, xstrerror()); } else if (len == 0 && entry->mem_obj->inmem_hi == 0) { - if (fd_table[fd].uses > 1) { + if (httpTryRestart(httpState)) { httpRestart(httpState); } else { httpState->eof = 1; @@ -728,7 +729,7 @@ httpSendRequest(int fd, void *data) buflen += req->headers_sz + 1; buflen += 512; /* lots of extra */ - if ((req->method == METHOD_POST || req->method == METHOD_PUT)) + if (pumpMethod(req->method)) sendHeaderDone = httpSendRequestEntry; else sendHeaderDone = httpSendComplete; @@ -749,14 +750,15 @@ httpSendRequest(int fd, void *data) cfd = entry->mem_obj->fd; if (p != NULL) EBIT_SET(httpState->flags, HTTP_PROXYING); - if (req->method == METHOD_GET) { - if (p == NULL) - EBIT_SET(httpState->flags, HTTP_KEEPALIVE); - else if (p->stats.n_keepalives_sent < 10) - EBIT_SET(httpState->flags, HTTP_KEEPALIVE); - else if ((double) p->stats.n_keepalives_recv / (double) p->stats.n_keepalives_sent > 0.50) - EBIT_SET(httpState->flags, HTTP_KEEPALIVE); - } + /* + * Is Keepalive okay for all request methods? + */ + if (p == NULL) + EBIT_SET(httpState->flags, HTTP_KEEPALIVE); + else if (p->stats.n_keepalives_sent < 10) + EBIT_SET(httpState->flags, HTTP_KEEPALIVE); + else if ((double) p->stats.n_keepalives_recv / (double) p->stats.n_keepalives_sent > 0.50) + EBIT_SET(httpState->flags, HTTP_KEEPALIVE); len = httpBuildRequestHeader(req, httpState->orig_request, entry, @@ -772,10 +774,6 @@ httpSendRequest(int fd, void *data) sendHeaderDone, httpState, buftype == BUF_TYPE_8K ? memFree8K : xfree); -#ifdef BREAKS_PCONN_RESTART - requestUnlink(httpState->orig_request); - httpState->orig_request = NULL; -#endif } static int @@ -876,15 +874,30 @@ httpStart(request_t * request, StoreEntry * entry, peer * e) httpState); } +static int +httpTryRestart(HttpStateData * httpState) +{ + /* + * We only retry the request if it looks like it was + * on a persistent/pipelined connection + */ + if (fd_table[httpState->fd].uses < 2) + return 0; + if (pumpMethod(httpState->orig_request->method)) + if (0 == pumpRestart(httpState->orig_request)) + return 0; + return 1; +} + static void httpRestart(HttpStateData * httpState) { /* restart a botched request from a persistent connection */ debug(11, 2) ("Retrying HTTP request for %s\n", storeUrl(httpState->entry)); if (httpState->orig_request->method != METHOD_GET) { - debug(11, 1)("Potential Coredump: httpRestart %s %s\n", - RequestMethodStr[httpState->orig_request->method], - storeUrl(httpState->entry)); + debug(11, 1) ("Potential Coredump: httpRestart %s %s\n", + RequestMethodStr[httpState->orig_request->method], + storeUrl(httpState->entry)); } if (httpState->fd >= 0) { comm_remove_close_handler(httpState->fd, httpStateFree, httpState); diff --git a/src/protos.h b/src/protos.h index e9a8f45c0e..988f056ef3 100644 --- a/src/protos.h +++ b/src/protos.h @@ -803,6 +803,8 @@ extern void dumpMallocStats(void); extern void pumpInit(int fd, request_t * r, char *uri); extern void pumpStart(int, StoreEntry *, request_t *, CWCB *callback, void *); +extern int pumpMethod(method_t method); +extern int pumpRestart(request_t *); extern void unlinkdInit(void); extern void unlinkdClose(void); -- 2.47.3