--------------------- PatchSet 2484 Date: 2006/01/22 07:11:16 Author: nlewycky Branch: prefetching Tag: (none) Log: Taking copy from HEAD. Not sure why it didn't merge. Members: src/client_side.cc:1.66.2.3->1.66.2.4 Index: squid3/src/client_side.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/client_side.cc,v retrieving revision 1.66.2.3 retrieving revision 1.66.2.4 diff -u -r1.66.2.3 -r1.66.2.4 --- squid3/src/client_side.cc 5 Nov 2005 14:21:35 -0000 1.66.2.3 +++ squid3/src/client_side.cc 22 Jan 2006 07:11:16 -0000 1.66.2.4 @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.66.2.3 2005/11/05 14:21:35 nlewycky Exp $ + * $Id: client_side.cc,v 1.66.2.4 2006/01/22 07:11:16 nlewycky Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -70,7 +70,9 @@ #include "ACLChecklist.h" #include "ConnectionDetail.h" #include "client_side_reply.h" +#include "ClientRequestContext.h" #include "MemBuf.h" +#include "ClientBody.h" #if LINGERING_CLOSE #define comm_close comm_lingering_close @@ -158,7 +160,6 @@ static void trimTrailingSpaces(char *aString, size_t len); #endif static ClientSocketContext *parseURIandHTTPVersion(char **url_p, HttpVersion * http_ver_p, ConnStateData::Pointer& conn, char *http_version_str); -static void setLogUri(ClientHttpRequest * http, char const *uri); static int connReadWasError(ConnStateData::Pointer& conn, comm_err_t, int size, int xerrno); static int connFinishedWithConn(ConnStateData::Pointer& conn, int size); static void connNoteUseOfBuffer(ConnStateData::Pointer & conn, size_t byteCount); @@ -603,6 +604,18 @@ auth_user_request,this); auth_user_request->onConnectionClose(this); } + + /* + * This is awkward: body has a RefCount::Pointer to this. We must + * destroy body so that our own reference count will go to zero. + * Furthermore, there currently exists a potential loop because + * ~ConnStateData() will delete body if it is not NULL. + */ + if (body) { + ClientBody *tmp = body; + body = NULL; + delete tmp; + } } bool @@ -624,9 +637,10 @@ auth_user_request = NULL; - pconnHistCount(0, nrequests); - cbdataReferenceDone(port); + + if (body) + delete body; } /* @@ -1168,7 +1182,7 @@ { prepareReply(rep); assert (rep); - MemBuf *mb = httpReplyPack(rep); + MemBuf *mb = rep->pack(); /* Save length of headers for persistent conn checks */ http->out.headers_sz = mb->contentSize(); #if HEADERS_LOG @@ -1503,7 +1517,7 @@ return; } - if (http->getConn()->body.size_left > 0) { + if (http->getConn()->body_size_left > 0) { debug(33, 5) ("ClientSocketContext::initiateClose: 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 @@ -2157,7 +2171,7 @@ /* Check if a half-closed connection was aborted in the middle */ if (F->flags.socket_eof) { - if (conn->in.notYetUsed != conn->body.size_left) { + if (conn->in.notYetUsed != conn->body_size_left) { /* != 0 when no request body */ /* Partial request received. Abort client connection! */ debug(33, 3) ("clientAfterReadingRequests: FD %d aborted, partial request\n", fd); @@ -2285,7 +2299,8 @@ /* Do we expect a request-body? */ if (request->content_length > 0) { - conn->body.size_left = request->content_length; + conn->body = new ClientBody(conn, request); + conn->body_size_left = request->content_length; request->body_connection = conn; /* Is it too large? */ @@ -2310,7 +2325,9 @@ if (http->request->method == METHOD_CONNECT) context->mayUseConnection(true); - clientAccessCheck(http); + http->calloutContext = new ClientRequestContext(http); + + http->doCallouts(); } static void @@ -2355,7 +2372,7 @@ debug(33, 5) ("clientParseRequest: FD %d: attempting to parse\n", conn->fd); - while (conn->in.notYetUsed > 0 && conn->body.size_left == 0) { + while (conn->in.notYetUsed > 0 && conn->body_size_left == 0) { size_t req_line_sz; connStripBufferWhitespace (conn); @@ -2404,9 +2421,9 @@ break; } - continue; /* while offset > 0 && body.size_left == 0 */ + continue; /* while offset > 0 && body_size_left == 0 */ } - } /* while offset > 0 && conn->body.size_left == 0 */ + } /* while offset > 0 && conn->body_size_left == 0 */ return parsed_req; } @@ -2477,9 +2494,8 @@ /* Process request body if any */ - if (conn->in.notYetUsed > 0 && conn->body.callback != NULL) { - ClientBody body(conn); - body.process(); + if (conn->in.notYetUsed > 0 && conn->body && conn->body->hasCallback()) { + conn->body->process(); } /* Process next request */ @@ -2517,105 +2533,11 @@ return; } - debug(33, 2) ("clientReadBody: start fd=%d body_size=%lu in.notYetUsed=%ld cb=%p req=%p\n", - conn->fd, (unsigned long int) conn->body.size_left, - (unsigned long int) conn->in.notYetUsed, callback, request); - conn->body.callback = callback; - conn->body.cbdata = cbdataReference(cbdata); - conn->body.buf = buf; - conn->body.bufsize = size; - conn->body.request = requestLink(request); - ClientBody body (conn); - body.process(); -} - -ClientBody::ClientBody(ConnStateData::Pointer &aConn) : conn(aConn), buf (NULL), callback(NULL), request(NULL) -{} - -void -ClientBody::preProcessing() -{ - callback = conn->body.callback; - request = conn->body.request; - /* Note: request is null while eating "aborted" transfers */ - debug(33, 2) ("clientBody::process: start fd=%d body_size=%lu in.notYetUsed=%lu cb=%p req=%p\n", - conn->fd, (unsigned long int) conn->body.size_left, + debug(33, 2) ("clientReadBody: start FD %d body_size=%lu in.notYetUsed=%ld cb=%p req=%p\n", + conn->fd, (unsigned long int) conn->body_size_left, (unsigned long int) conn->in.notYetUsed, callback, request); -} - -/* Called by clientReadRequest to process body content */ -void -ClientBody::process() -{ - preProcessing(); - - if (conn->in.notYetUsed) - processBuffer(); - else - conn->readSomeData(); -} - -void -ClientBody::processBuffer() -{ - /* Some sanity checks... */ - assert(conn->body.size_left > 0); - assert(conn->in.notYetUsed > 0); - assert(callback != NULL); - buf = conn->body.buf; - assert(buf != NULL); - /* How much do we have to process? */ - size_t size = conn->in.notYetUsed; - - 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.notYetUsed -= size; - - if (conn->in.notYetUsed > 0) - xmemmove(conn->in.buf, conn->in.buf + size, conn->in.notYetUsed); - - /* Remove request link if this is the last part of the body, as - * clientReadRequest automatically continues to process next request */ - if (conn->body.size_left <= 0 && request != NULL) - request->body_connection = NULL; - - /* Remove clientReadBody arguments (the call is completed) */ - conn->body.request = NULL; - - conn->body.callback = NULL; - - conn->body.buf = NULL; - - conn->body.bufsize = 0; - - /* Remember that we have touched the body, not restartable */ - if (request != NULL) { - request->flags.body_sent = 1; - conn->body.request = NULL; - } - - /* Invoke callback function */ - void *cbdata; - - if (cbdataReferenceValidDone(conn->body.cbdata, &cbdata)) - callback(buf, size, cbdata); - - if (request != NULL) { - requestUnlink(request); /* Linked in clientReadBody */ - } - - debug(33, 2) ("ClientBody::process: end fd=%d size=%lu body_size=%lu in.notYetUsed=%lu cb=%p req=%p\n", - conn->fd, (unsigned long int)size, (unsigned long int) conn->body.size_left, - (unsigned long) conn->in.notYetUsed, callback, request); + conn->body->init(buf, size, callback, cbdata); + conn->body->process(); } /* A dummy handler that throws away a request-body */ @@ -2624,17 +2546,14 @@ { static char bodyAbortBuf[SQUID_TCP_SO_RCVBUF]; ConnStateData *conn = (ConnStateData *) data; - debug(33, 2) ("clientReadBodyAbortHandler: fd=%d body_size=%lu in.notYetUsed=%lu\n", - conn->fd, (unsigned long int) conn->body.size_left, + debug(33, 2) ("clientReadBodyAbortHandler: FD %d body_size=%lu in.notYetUsed=%lu\n", + conn->fd, (unsigned long int) conn->body_size_left, (unsigned long) conn->in.notYetUsed); - if (size != 0 && conn->body.size_left != 0) { - debug(33, 3) ("clientReadBodyAbortHandler: fd=%d shedule next read\n", + 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 = cbdataReference(data); + conn->body->init(bodyAbortBuf, sizeof(bodyAbortBuf), clientReadBodyAbortHandler, data); } if (conn->closing()) @@ -2646,30 +2565,15 @@ clientAbortBody(HttpRequest * request) { ConnStateData::Pointer conn = request->body_connection; - char *buf; - CBCB *callback; - if (conn.getRaw() == NULL || conn->body.size_left <= 0 || conn->body.request != request) + if (conn.getRaw() == NULL || conn->body_size_left <= 0 || conn->body->getRequest() != request) return 0; /* No body to abort */ - if (conn->body.callback != NULL) { - buf = conn->body.buf; - callback = conn->body.callback; - assert(request == conn->body.request); - conn->body.buf = NULL; - conn->body.callback = NULL; - conn->body.request = NULL; - void *cbdata; - - if (cbdataReferenceValidDone(conn->body.cbdata, &cbdata)) - callback(buf, -1, cbdata); /* Signal abort to clientReadBody caller */ - - conn->body.cbdata = NULL; - - requestUnlink(request); - } + if (conn->body->hasCallback()) + conn->body->negativeCallback(); clientReadBodyAbortHandler(NULL, -1, conn.getRaw()); /* Install abort handler */ + /* ClientBody::process() */ return 1; /* Aborted */ } @@ -2869,12 +2773,11 @@ identChecklist.accessList = cbdataReference(Config.accessList.identLookup); + /* cbdataReferenceDone() happens in either fastCheck() or ~ACLCheckList */ + if (identChecklist.fastCheck()) identStart(&details->me, &details->peer, clientIdentDone, connState); - cbdataReferenceDone(identChecklist.accessList); - - identChecklist.accessList = NULL; #endif @@ -2953,6 +2856,11 @@ /* PEM_write_SSL_SESSION(debug_log, SSL_get_session(ssl)); */ #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x0090708FL PEM_ASN1_write((i2d_of_void *)i2d_SSL_SESSION, PEM_STRING_SSL_SESSION, debug_log, (char *)SSL_get_session(ssl), NULL,NULL,0,NULL,NULL); + +#elif defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER == 0x0090704fL + + PEM_ASN1_write((int(*)(...))i2d_SSL_SESSION, PEM_STRING_SSL_SESSION, debug_log, (char *)SSL_get_session(ssl), NULL,NULL,0,NULL,NULL); + #else PEM_ASN1_write((int(*)())i2d_SSL_SESSION, PEM_STRING_SSL_SESSION, debug_log, (char *)SSL_get_session(ssl), NULL,NULL,0,NULL,NULL); @@ -3047,11 +2955,11 @@ identChecklist.accessList = cbdataReference(Config.accessList.identLookup); + /* cbdataReferenceDone() happens in either fastCheck() or ~ACLCheckList */ + if (identChecklist.fastCheck()) identStart(&details->me, &details->peer, clientIdentDone, connState); - identChecklist.accessList = NULL; - #endif commSetSelect(newfd, COMM_SELECT_READ, clientNegotiateSSL, connState, 0); @@ -3279,7 +3187,7 @@ cbdataFree(t); } -ConnStateData::ConnStateData() : transparent_ (false), reading_ (false), closing_ (false) +ConnStateData::ConnStateData() : body_size_left(0), transparent_ (false), reading_ (false), closing_ (false) { openReference = this; }