Index: squid/src/client_side.c diff -c squid/src/client_side.c:1.561.2.40 squid/src/client_side.c:1.561.2.42 *** squid/src/client_side.c:1.561.2.40 Wed Aug 6 08:09:19 2003 --- squid/src/client_side.c Thu Aug 28 16:00:18 2003 *************** *** 127,132 **** --- 127,133 ---- static int clientReplyBodyTooLarge(clientHttpRequest *, ssize_t clen); static int clientRequestBodyTooLarge(int clen); static void clientProcessBody(ConnStateData * conn); + static void clientEatRequestBody(clientHttpRequest *); static int checkAccelOnly(clientHttpRequest * http) *************** *** 783,789 **** debug(33, 3) ("httpRequestFree: %s\n", storeUrl(http->entry)); if (!clientCheckTransferDone(http)) { if (request && request->body_connection) ! clientAbortBody(request); /* abort body transter */ /* HN: This looks a bit odd.. why should client_side care about * the ICP selection status? */ --- 784,790 ---- debug(33, 3) ("httpRequestFree: %s\n", storeUrl(http->entry)); if (!clientCheckTransferDone(http)) { if (request && request->body_connection) ! clientAbortBody(request); /* abort request body transter */ /* HN: This looks a bit odd.. why should client_side care about * the ICP selection status? */ *************** *** 2198,2203 **** --- 2199,2213 ---- } else if (clientGotNotEnough(http)) { debug(33, 5) ("clientWriteComplete: client didn't get all it expected\n"); comm_close(fd); + } else if (http->request->body_connection) { + debug(33, 5) ("clientWriteComplete: closing, but first we need to read the rest of the request\n"); + /* XXX We assumes the reply does fit in the TCP transmit window. + * If not the connection may stall while sending the reply + * (before reaching here) if the client does not try to read the + * response while sending the request body. As of yet we have + * not received any complaints indicating this may be an issue. + */ + clientEatRequestBody(http); } else if (http->request->flags.proxy_keepalive) { debug(33, 5) ("clientWriteComplete: FD %d Keeping Alive\n", fd); clientKeepaliveNextRequest(http); *************** *** 3141,3146 **** --- 3151,3193 ---- clientProcessBody(conn); } + static void + clientEatRequestBodyHandler(char *buf, ssize_t size, void *data) + { + clientHttpRequest *http = data; + ConnStateData *conn = http->conn; + if (buf && size < 0) { + return; /* Aborted, don't care */ + } + if (conn->body.size_left> 0) { + conn->body.callback = clientEatRequestBodyHandler; + conn->body.cbdata = http; + cbdataLock(conn->body.cbdata); + conn->body.buf = NULL; + conn->body.bufsize = SQUID_TCP_SO_RCVBUF; + clientProcessBody(conn); + } else { + if (http->request->flags.proxy_keepalive) { + debug(33, 5) ("clientWriteComplete: FD %d Keeping Alive\n", conn->fd); + clientKeepaliveNextRequest(http); + } else { + comm_close(conn->fd); + } + } + } + + static void + clientEatRequestBody(clientHttpRequest * http) + { + ConnStateData *conn = http->conn; + cbdataLock(conn); + if (conn->body.request) + clientAbortBody(conn->body.request); + if (cbdataValid(conn)) + clientEatRequestBodyHandler(NULL, -1, http); + cbdataUnlock(conn); + } + /* Called by clientReadRequest to process body content */ static void clientProcessBody(ConnStateData * conn) *************** *** 3150,3171 **** void *cbdata = conn->body.cbdata; CBCB *callback = conn->body.callback; request_t *request = conn->body.request; - int valid; /* Note: request is null while eating "aborted" transfers */ debug(33, 2) ("clientProcessBody: start fd=%d body_size=%lu in.offset=%ld cb=%p req=%p\n", conn->fd, (unsigned long int) conn->body.size_left, (long int) conn->in.offset, callback, request); if (conn->in.offset) { /* Some sanity checks... */ assert(conn->body.size_left> 0); assert(conn->in.offset> 0); assert(callback != NULL); ! assert(buf != NULL); /* How much do we have to process? */ size = conn->in.offset; if (size> conn->body.size_left) /* only process the body part */ size = conn->body.size_left; if (size> conn->body.bufsize) /* don't copy more than requested */ size = conn->body.bufsize; ! xmemcpy(buf, conn->in.buf, size); conn->body.size_left -= size; /* Move any remaining data */ conn->in.offset -= size; --- 3197,3223 ---- void *cbdata = conn->body.cbdata; CBCB *callback = conn->body.callback; request_t *request = conn->body.request; /* Note: request is null while eating "aborted" transfers */ debug(33, 2) ("clientProcessBody: start fd=%d body_size=%lu in.offset=%ld cb=%p req=%p\n", conn->fd, (unsigned long int) conn->body.size_left, (long int) conn->in.offset, callback, request); if (conn->in.offset) { + int valid = cbdataValid(conn->body.cbdata); + if (!valid) { + comm_close(conn->fd); + return; + } /* Some sanity checks... */ assert(conn->body.size_left> 0); assert(conn->in.offset> 0); assert(callback != NULL); ! assert(buf != NULL || !conn->body.request); /* How much do we have to process? */ size = conn->in.offset; if (size> conn->body.size_left) /* only process the body part */ size = conn->body.size_left; if (size> conn->body.bufsize) /* don't copy more than requested */ size = conn->body.bufsize; ! if (valid && buf) ! xmemcpy(buf, conn->in.buf, size); conn->body.size_left -= size; /* Move any remaining data */ conn->in.offset -= size; *************** *** 3176,3182 **** if (conn->body.size_left <= 0 && request != NULL) request->body_connection = NULL; /* Remove clientReadBody arguments (the call is completed) */ - valid = cbdataValid(conn->body.cbdata); conn->body.request = NULL; conn->body.callback = NULL; cbdataUnlock(conn->body.cbdata); --- 3228,3233 ---- *************** *** 3195,3219 **** } } - /* A dummy handler that throws away a request-body */ - static char bodyAbortBuf[SQUID_TCP_SO_RCVBUF]; - static void - clientReadBodyAbortHandler(char *buf, ssize_t size, void *data) - { - ConnStateData *conn = (ConnStateData *) data; - debug(33, 2) ("clientReadBodyAbortHandler: fd=%d body_size=%lu in.offset=%ld\n", conn->fd, (unsigned long int) conn->body.size_left, (long int) conn->in.offset); - if (size != 0 && conn->body.size_left != 0) { - debug(33, 3) ("clientReadBodyAbortHandler: fd=%d shedule next read\n", conn->fd); - conn->body.callback = clientReadBodyAbortHandler; - conn->body.buf = bodyAbortBuf; - conn->body.bufsize = sizeof(bodyAbortBuf); - conn->body.cbdata = data; - cbdataLock(conn->body.cbdata); - } - } - /* Abort a body request */ ! int clientAbortBody(request_t * request) { ConnStateData *conn = request->body_connection; --- 3246,3253 ---- } } /* Abort a body request */ ! void clientAbortBody(request_t * request) { ConnStateData *conn = request->body_connection; *************** *** 3222,3247 **** void *cbdata; int valid; request->body_connection = NULL; ! if (!conn || conn->body.size_left <= 0) ! return 0; /* No body to abort */ ! if (conn->body.callback != NULL) { ! buf = conn->body.buf; ! callback = conn->body.callback; ! cbdata = conn->body.cbdata; ! valid = cbdataValid(cbdata); ! assert(request == conn->body.request); ! conn->body.buf = NULL; ! conn->body.callback = NULL; ! cbdataUnlock(conn->body.cbdata); ! conn->body.cbdata = NULL; ! conn->body.request = NULL; ! if (valid) ! callback(buf, -1, cbdata); /* Signal abort to clientReadBody caller */ ! requestUnlink(request); ! } ! clientReadBodyAbortHandler(NULL, -1, conn); /* Install abort handler */ ! /* clientProcessBody() */ ! return 1; /* Aborted */ } /* general lifetime handler for HTTP requests */ --- 3256,3278 ---- void *cbdata; int valid; request->body_connection = NULL; ! if (!conn->body.callback || !conn->body.request) ! return; ! buf = conn->body.buf; ! callback = conn->body.callback; ! cbdata = conn->body.cbdata; ! valid = cbdataValid(cbdata); ! assert(request == conn->body.request); ! conn->body.buf = NULL; ! conn->body.callback = NULL; ! cbdataUnlock(conn->body.cbdata); ! conn->body.cbdata = NULL; ! conn->body.request = NULL; ! if (valid) ! callback(buf, -1, cbdata); /* Signal abort to clientReadBody caller to allow them to clean up */ ! else ! debug(33, 1) ("NOTICE: A request body was aborted with cancelled callback: %p, possible memory leak\n", callback); ! requestUnlink(request); /* Linked in clientReadBody */ } /* general lifetime handler for HTTP requests */ Index: squid/src/protos.h diff -c squid/src/protos.h:1.420.2.19 squid/src/protos.h:1.420.2.20 *** squid/src/protos.h:1.420.2.19 Wed Aug 6 07:49:02 2003 --- squid/src/protos.h Sun Aug 10 15:04:47 2003 *************** *** 142,148 **** extern StoreEntry *clientCreateStoreEntry(clientHttpRequest *, method_t, request_flags); extern int isTcpHit(log_type); extern void clientReadBody(request_t * req, char *buf, size_t size, CBCB * callback, void *data); ! extern int clientAbortBody(request_t * req); extern int commSetNonBlocking(int fd); extern int commUnsetNonBlocking(int fd); --- 142,148 ---- extern StoreEntry *clientCreateStoreEntry(clientHttpRequest *, method_t, request_flags); extern int isTcpHit(log_type); extern void clientReadBody(request_t * req, char *buf, size_t size, CBCB * callback, void *data); ! extern void clientAbortBody(request_t * req); extern int commSetNonBlocking(int fd); extern int commUnsetNonBlocking(int fd);

AltStyle によって変換されたページ (->オリジナル) /