--------------------- PatchSet 1900 Date: 2005/09/29 18:00:44 Author: dwsquid Branch: squid3-icap Tag: (none) Log: Starting to make ICAP service selection work with icap_access configuration Members: src/ICAPAnchor.cc:1.1.2.28->1.1.2.29 src/ICAPAnchor.h:1.1.2.8->1.1.2.9 src/ICAPClient.cc:1.1.2.7->1.1.2.8 src/ICAPClient.h:1.1.2.6->1.1.2.7 src/ICAPClientSideHook.cc:1.1.2.6->1.1.2.7 src/ICAPConfig.cc:1.1.2.3->1.1.2.4 src/ICAPConfig.h:1.1.2.3->1.1.2.4 src/ICAPServiceRep.cc:1.1.2.4->1.1.2.5 src/ICAPServiceRep.h:1.1.2.4->1.1.2.5 src/ICAPXaction.cc:1.1.2.33->1.1.2.34 src/ICAPXaction.h:1.1.2.18->1.1.2.19 src/client_side_request.cc:1.34.4.7->1.34.4.8 src/http.cc:1.49.2.32->1.49.2.33 src/http.h:1.11.4.11->1.11.4.12 Index: squid3/src/ICAPAnchor.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/Attic/ICAPAnchor.cc,v retrieving revision 1.1.2.28 retrieving revision 1.1.2.29 diff -u -r1.1.2.28 -r1.1.2.29 --- squid3/src/ICAPAnchor.cc 18 Sep 2005 04:12:42 -0000 1.1.2.28 +++ squid3/src/ICAPAnchor.cc 29 Sep 2005 18:00:44 -0000 1.1.2.29 @@ -8,6 +8,7 @@ #include "HttpReply.h" #include "ICAPAnchor.h" #include "ICAPClient.h" +#include "ICAPServiceRep.h" #include "LeakFinder.h" @@ -15,9 +16,10 @@ extern LeakFinder *leaky; -ICAPAnchor::ICAPAnchor(): httpState(NULL), virgin(NULL), adapted(NULL) +ICAPAnchor::ICAPAnchor(ICAPServiceRep::Pointer aService): service(aService), httpState(NULL), virgin(NULL), adapted(NULL) { debug(93,5)("ICAPAnchor constructed, this=%p\n", this); + debug(0,0)("ICAPAnchor constructed, service=%p\n", service.getRaw()); } ICAPAnchor::~ICAPAnchor() @@ -31,6 +33,10 @@ if (adapted != NULL) freeAdapted(); + + debug(0,0)("NULLing ICAPAnchor:service\n"); + + service = NULL; } void ICAPAnchor::startRespMod(HttpStateData *anHttpState, HttpRequest *request, HttpReply *reply) @@ -55,7 +61,7 @@ adapted->data->cause = request; // should not hurt #else - ICAPInitXaction(virgin, adapted); + ICAPInitXaction(service, virgin, adapted); #endif virgin->sendSourceStart(); // we may have virgin data to provide Index: squid3/src/ICAPAnchor.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/Attic/ICAPAnchor.h,v retrieving revision 1.1.2.8 retrieving revision 1.1.2.9 diff -u -r1.1.2.8 -r1.1.2.9 --- squid3/src/ICAPAnchor.h 31 Aug 2005 20:03:39 -0000 1.1.2.8 +++ squid3/src/ICAPAnchor.h 29 Sep 2005 18:00:44 -0000 1.1.2.9 @@ -1,6 +1,6 @@ /* - * $Id: ICAPAnchor.h,v 1.1.2.8 2005/08/31 20:03:39 dwsquid Exp $ + * $Id: ICAPAnchor.h,v 1.1.2.9 2005/09/29 18:00:44 dwsquid Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -37,6 +37,7 @@ #include "MsgPipe.h" #include "MsgPipeSource.h" #include "MsgPipeSink.h" +#include "ICAPServiceRep.h" /* The ICAP Anchor implements message pipe sink and source interfaces. It * helps HttpStateData to marshall the incoming/virgin HTTP message (being @@ -54,7 +55,7 @@ { public: - ICAPAnchor(); + ICAPAnchor(ICAPServiceRep::Pointer); virtual ~ICAPAnchor(); // synchronous calls called by HttpStateData @@ -75,6 +76,7 @@ virtual void noteSourceAbort(MsgPipe *p); public: + ICAPServiceRep::Pointer service; HttpStateData *httpState; MsgPipe::Pointer virgin; MsgPipe::Pointer adapted; Index: squid3/src/ICAPClient.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/Attic/ICAPClient.cc,v retrieving revision 1.1.2.7 retrieving revision 1.1.2.8 diff -u -r1.1.2.7 -r1.1.2.8 --- squid3/src/ICAPClient.cc 31 Aug 2005 20:03:39 -0000 1.1.2.7 +++ squid3/src/ICAPClient.cc 29 Sep 2005 18:00:44 -0000 1.1.2.8 @@ -18,11 +18,11 @@ {} // initialize ICAP-specific ends of message pipes -void ICAPInitXaction(MsgPipe::Pointer virgin, MsgPipe::Pointer adapted) +void ICAPInitXaction(ICAPServiceRep::Pointer service, MsgPipe::Pointer virgin, MsgPipe::Pointer adapted) { ICAPXaction::Pointer x = new ICAPXaction; debugs(93,5, "ICAPInitXaction: " << x.getRaw()); - x->init(virgin, adapted, x); + x->init(service, virgin, adapted, x); // if we want to do something to the transaction after it is done, // we need to keep a pointer to it } Index: squid3/src/ICAPClient.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/Attic/ICAPClient.h,v retrieving revision 1.1.2.6 retrieving revision 1.1.2.7 diff -u -r1.1.2.6 -r1.1.2.7 --- squid3/src/ICAPClient.h 31 Aug 2005 20:03:39 -0000 1.1.2.6 +++ squid3/src/ICAPClient.h 29 Sep 2005 18:00:44 -0000 1.1.2.7 @@ -1,6 +1,6 @@ /* - * $Id: ICAPClient.h,v 1.1.2.6 2005/08/31 20:03:39 dwsquid Exp $ + * $Id: ICAPClient.h,v 1.1.2.7 2005/09/29 18:00:44 dwsquid Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -45,7 +45,7 @@ // let ICAP initialize ICAP-specific ends of message pipes class MsgPipe; -extern void ICAPInitXaction(MsgPipe::Pointer virgin, MsgPipe::Pointer adapted); +extern void ICAPInitXaction(ICAPServiceRep::Pointer, MsgPipe::Pointer virgin, MsgPipe::Pointer adapted); // recommended initial size and max capacity for MsgPipe buffer enum { ICAPMsgPipeBufSizeMin = (4*1024), ICAPMsgPipeBufSizeMax = SQUID_TCP_SO_RCVBUF }; Index: squid3/src/ICAPClientSideHook.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/Attic/ICAPClientSideHook.cc,v retrieving revision 1.1.2.6 retrieving revision 1.1.2.7 diff -u -r1.1.2.6 -r1.1.2.7 --- squid3/src/ICAPClientSideHook.cc 21 Sep 2005 20:36:07 -0000 1.1.2.6 +++ squid3/src/ICAPClientSideHook.cc 29 Sep 2005 18:00:44 -0000 1.1.2.7 @@ -7,6 +7,7 @@ #include "MsgPipeSink.h" #include "HttpRequest.h" #include "ICAPClientSideHook.h" +#include "ICAPServiceRep.h" #include "ICAPClient.h" #include "LeakFinder.h" @@ -51,7 +52,8 @@ leakTouch(adapted.getRaw(), leaky); adapted->sink = this; - ICAPInitXaction(virgin, adapted); + fatal("fix following ICAPInitXaction() call"); + ICAPInitXaction(NULL, virgin, adapted); virgin->sendSourceStart(); // we may have virgin data to provide adapted->sendSinkNeed(); // we want adapted response, eventially Index: squid3/src/ICAPConfig.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/Attic/ICAPConfig.cc,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -u -r1.1.2.3 -r1.1.2.4 --- squid3/src/ICAPConfig.cc 27 Sep 2005 20:40:57 -0000 1.1.2.3 +++ squid3/src/ICAPConfig.cc 29 Sep 2005 18:00:44 -0000 1.1.2.4 @@ -1,6 +1,6 @@ /* - * $Id: ICAPConfig.cc,v 1.1.2.3 2005/09/27 20:40:57 dwsquid Exp $ + * $Id: ICAPConfig.cc,v 1.1.2.4 2005/09/29 18:00:44 dwsquid Exp $ * * SQUID Web Proxy Cache http://www.squid-cache.org/ * ---------------------------------------------------------- @@ -38,34 +38,43 @@ #include "ACL.h" #include "Store.h" #include "List.h" +#include "Array.h" // really Vector #include "ICAPConfig.h" #include "ICAPServiceRep.h" +#include "HttpRequest.h" ICAPConfig TheICAPConfig; +ICAPServiceRep::Pointer +ICAPConfig::findService(const String& key) +{ + Vector::iterator iter = services.begin(); + + while (iter != TheICAPConfig.services.end()) { + if (iter->getRaw()->key == key) + return *iter; + + ++iter; + } + + return NULL; +} + int ICAPClass::prepare() { int found = 0; - List **Tail; - List *service_iter; wordlist *iter; ConfigParser::ParseString(&key); ConfigParser::ParseWordList(&service_names); for (iter = service_names; iter; iter = iter->next) { - for (service_iter = TheICAPConfig.services; service_iter; service_iter = service_iter->next) { - if (!service_iter->element.key.cmp(iter->key)) { - for (Tail = &services; *Tail; Tail = &((*Tail)->next)) - - ; - List * q = new List(service_iter->element); - - *(Tail) = q; + ICAPServiceRep::Pointer match = TheICAPConfig.findService(iter->key); - found = 1; - } + if (match != NULL) { + found = 1; + services += match; } } @@ -98,19 +107,83 @@ return found; }; +// ================================================================================ // + +CBDATA_CLASS_INIT(ICAPAccessCheck); + +ICAPAccessCheck::ICAPAccessCheck(ICAPServiceRep::IcapMethod aMethod, + ICAPServiceRep::IcapVectPoint aPoint, + HttpRequest *aReq, + HttpReply *aRep, + ICAPAccessCheckCallback *aCallback, + void *aCallbackData) +{ + method = aMethod; + point = aPoint; + req = requestLink(aReq); + rep = aRep; + callback = aCallback; + callback_data = aCallbackData; + match = NULL; +} + +ICAPAccessCheck::~ICAPAccessCheck() +{ + requestUnlink(req); +} + +void +ICAPAccessCheck::check() +{ + debug(0,0)("ICAPAccessCheck::check\n"); + Vector::iterator i; + + for (i = TheICAPConfig.services.begin(); i != TheICAPConfig.services.end(); ++i) { + if (method != i->getRaw()->method) + continue; + + if (point != i->getRaw()->point) + continue; + + debug(0,0)("ICAPAccessCheck::check: found a matching service\n"); + + match = *i; + + eventAdd("ICAPAccessCheckCallbackWrapper", + ICAPAccessCheckCallbackWrapper, + this, + 0.0, + 0, + 1); + } +} + +void +ICAPAccessCheck::ICAPAccessCheckCallbackWrapper(void *data) +{ + debug(0,0)("ICAPAccessCheckCallbackWrapper\n"); + ICAPAccessCheck *ac = (ICAPAccessCheck*)data; + ac->do_callback(); +} + +void +ICAPAccessCheck::do_callback() +{ + debug(0,0)("ICAPAccessCheck::do_callback\n"); + callback(match, callback_data); + match = NULL; +} + + +// ================================================================================ // + void ICAPConfig::parseICAPService() { - List **Tail; ICAPServiceRep *S = new ICAPServiceRep(); if (S->parseConfigLine()) { - for (Tail = &services; *Tail; Tail = &((*Tail)->next)) - - ; - List * q = new List(*S); - - *(Tail) = q; + services += S; } else { delete S; } @@ -121,18 +194,18 @@ void ICAPConfig::freeICAPService() { - delete services; + services.clean(); }; void ICAPConfig::dumpICAPService(StoreEntry *entry, const char *name) { - List *data = services; + Vector::iterator i = services.begin(); - while (data != NULL) { - ICAPServiceRep *r = &data->element; + while (i != services.end()) { + ICAPServiceRep *r = i->getRaw(); storeAppendPrintf(entry, "%s %s_%s %s %d %s\n", name, r->key.buf(), r->methodStr(), r->vectPointStr(), r->bypass, r->uri.buf()); - data = data->next; + ++i; } }; @@ -223,6 +296,6 @@ ICAPConfig::~ICAPConfig() { delete classes; - delete services; + services.clean(); delete accesses; }; Index: squid3/src/ICAPConfig.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/Attic/ICAPConfig.h,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -u -r1.1.2.3 -r1.1.2.4 --- squid3/src/ICAPConfig.h 27 Sep 2005 20:40:57 -0000 1.1.2.3 +++ squid3/src/ICAPConfig.h 29 Sep 2005 18:00:44 -0000 1.1.2.4 @@ -1,6 +1,6 @@ /* - * $Id: ICAPConfig.h,v 1.1.2.3 2005/09/27 20:40:57 dwsquid Exp $ + * $Id: ICAPConfig.h,v 1.1.2.4 2005/09/29 18:00:44 dwsquid Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -37,13 +37,12 @@ #define SQUID_ICAPCONFIG_H #include "List.h" +#include "ICAPServiceRep.h" class acl_access; class ICAPConfig; -class ICAPServiceRep; - class ICAPClass { @@ -51,9 +50,9 @@ char *key; wordlist *service_names; - List *services; + Vector services; - ICAPClass() : key(NULL), service_names(NULL), services(NULL) {}; + ICAPClass() : key(NULL), service_names(NULL) {}; int prepare(); }; @@ -78,6 +77,33 @@ }; +class ICAPAccessCheck +{ + +public: + typedef void ICAPAccessCheckCallback(ICAPServiceRep::Pointer match, void *data); + ICAPAccessCheck(ICAPServiceRep::IcapMethod, ICAPServiceRep::IcapVectPoint, HttpRequest *, HttpReply *, ICAPAccessCheckCallback *, void *); + ~ICAPAccessCheck(); + +private: + ICAPServiceRep::IcapMethod method; + ICAPServiceRep::IcapVectPoint point; + HttpRequest *req; + HttpReply *rep; + ICAPAccessCheckCallback *callback; + void *callback_data; + + ICAPServiceRep::Pointer match; + void do_callback(); + +public: + void check(); + static void ICAPAccessCheckCallbackWrapper(void*); + +private: + CBDATA_CLASS2(ICAPAccessCheck); +}; + class ICAPConfig { @@ -91,17 +117,18 @@ int auth_user; char *auth_scheme; - List *services; + Vector services; List *classes; List *accesses; - ICAPConfig() : services(NULL), classes(NULL), accesses(NULL) {}; + ICAPConfig() : classes(NULL), accesses(NULL) {}; ~ICAPConfig(); void parseICAPService(void); void freeICAPService(void); void dumpICAPService(StoreEntry *, const char *); + ICAPServiceRep::Pointer findService(const String&); void parseICAPClass(void); void freeICAPClass(void); Index: squid3/src/ICAPServiceRep.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/Attic/ICAPServiceRep.cc,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -u -r1.1.2.4 -r1.1.2.5 --- squid3/src/ICAPServiceRep.cc 27 Sep 2005 20:40:57 -0000 1.1.2.4 +++ squid3/src/ICAPServiceRep.cc 29 Sep 2005 18:00:44 -0000 1.1.2.5 @@ -9,7 +9,10 @@ ICAPServiceRep::~ICAPServiceRep() { + debug(0,0)("~ICAPServiceRep destructor called\n"); + debug(0,0)("~ICAPServiceRep deleting opts\n"); delete opts; + debug(0,0)("~ICAPServiceRep done\n"); } const char * @@ -124,7 +127,7 @@ } int len = e - s; - host.limitInit(s, len + 1); + host.limitInit(s, len); s = e; if (have_port) { Index: squid3/src/ICAPServiceRep.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/Attic/ICAPServiceRep.h,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -u -r1.1.2.4 -r1.1.2.5 --- squid3/src/ICAPServiceRep.h 27 Sep 2005 20:40:57 -0000 1.1.2.4 +++ squid3/src/ICAPServiceRep.h 29 Sep 2005 18:00:44 -0000 1.1.2.5 @@ -1,6 +1,6 @@ /* - * $Id: ICAPServiceRep.h,v 1.1.2.4 2005/09/27 20:40:57 dwsquid Exp $ + * $Id: ICAPServiceRep.h,v 1.1.2.5 2005/09/29 18:00:44 dwsquid Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -43,10 +43,12 @@ class ICAPOptions; -class ICAPServiceRep +class ICAPServiceRep : public RefCountable { public: + typedef RefCount Pointer; + ICAPServiceRep(); ~ICAPServiceRep(); bool parseConfigLine(); Index: squid3/src/ICAPXaction.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/Attic/ICAPXaction.cc,v retrieving revision 1.1.2.33 retrieving revision 1.1.2.34 diff -u -r1.1.2.33 -r1.1.2.34 --- squid3/src/ICAPXaction.cc 29 Sep 2005 05:17:21 -0000 1.1.2.33 +++ squid3/src/ICAPXaction.cc 29 Sep 2005 18:00:44 -0000 1.1.2.34 @@ -104,8 +104,8 @@ memset(this, sizeof(*this), 0); } -ICAPXaction::ICAPXaction(): self(NULL), virgin(NULL), adapted(NULL), - icapReply(NULL), service(NULL), connection(-1), +ICAPXaction::ICAPXaction(): self(NULL), service(NULL), virgin(NULL), adapted(NULL), + icapReply(NULL), connection(-1), commBuf(NULL), reader(NULL), writer(NULL), closer(NULL), bodyParser(NULL), notify(notifyUnknown) @@ -117,12 +117,13 @@ doStop(); } -void ICAPXaction::init(MsgPipe::Pointer aVirgin, MsgPipe::Pointer anAdapted, Pointer &aSelf) +void ICAPXaction::init(ICAPServiceRep::Pointer aService, MsgPipe::Pointer aVirgin, MsgPipe::Pointer anAdapted, Pointer &aSelf) { assert(!self.getRaw() && !virgin.getRaw() && !adapted.getRaw()); assert(aSelf.getRaw() && aVirgin.getRaw() && anAdapted.getRaw()); self = aSelf; + service = aService; virgin = aVirgin; adapted = anAdapted; @@ -159,7 +160,6 @@ { ICAPXaction_Enter(noteSourceStart); - pickService(); openConnection(); // put nothing here as openConnection calls commConnectStart // and that may call us back without waiting for the next select loop @@ -188,6 +188,7 @@ &ICAPXaction_noteCommTimeout, this); closer = &ICAPXaction_noteCommClose; comm_add_close_handler(connection, closer, this); +debug(0,0)("ICAPXaction::openConnection() to %s %d\n", service->host.buf(), service->port); commConnectStart(connection, service->host.buf(), service->port, &ICAPXaction_noteCommConnected, this); } @@ -602,11 +603,6 @@ ICAPXaction_Exit(noteSinkAbort); } -void ICAPXaction::pickService() -{ - assert(false); -} - void ICAPXaction::mustStop(Notify who) { Must(state.inCall); // otherwise nobody will call doStop() Index: squid3/src/ICAPXaction.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/Attic/ICAPXaction.h,v retrieving revision 1.1.2.18 retrieving revision 1.1.2.19 diff -u -r1.1.2.18 -r1.1.2.19 --- squid3/src/ICAPXaction.h 29 Sep 2005 05:17:21 -0000 1.1.2.18 +++ squid3/src/ICAPXaction.h 29 Sep 2005 18:00:44 -0000 1.1.2.19 @@ -1,6 +1,6 @@ /* - * $Id: ICAPXaction.h,v 1.1.2.18 2005/09/29 05:17:21 rousskov Exp $ + * $Id: ICAPXaction.h,v 1.1.2.19 2005/09/29 18:00:44 dwsquid Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -64,7 +64,7 @@ virtual ~ICAPXaction(); // called by ICAPClient - void init(MsgPipe::Pointer aVirgin, MsgPipe::Pointer anAdapted, Pointer &aSelf); + void init(ICAPServiceRep::Pointer, MsgPipe::Pointer aVirgin, MsgPipe::Pointer anAdapted, Pointer &aSelf); void ownerAbort(); // pipe source methods; called by Anchor while receiving the adapted msg @@ -103,8 +103,6 @@ void maybeAllocateHttpMsg(); bool expectVirginBody() const; - void pickService(); - bool done() const; typedef enum { notifyUnknown, notifyNone, notifyService, notifyHttp, @@ -129,12 +127,12 @@ bool gotEncapsulated(const char *section) const; Pointer self; + ICAPServiceRep::Pointer service; MsgPipe::Pointer virgin; MsgPipe::Pointer adapted; HttpReply *icapReply; - ICAPServiceRep *service; int connection; // FD of the ICAP server connection /* Index: squid3/src/client_side_request.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/client_side_request.cc,v retrieving revision 1.34.4.7 retrieving revision 1.34.4.8 diff -u -r1.34.4.7 -r1.34.4.8 --- squid3/src/client_side_request.cc 21 Sep 2005 20:33:38 -0000 1.34.4.7 +++ squid3/src/client_side_request.cc 29 Sep 2005 18:00:44 -0000 1.34.4.8 @@ -1,6 +1,6 @@ /* - * $Id: client_side_request.cc,v 1.34.4.7 2005/09/21 20:33:38 dwsquid Exp $ + * $Id: client_side_request.cc,v 1.34.4.8 2005/09/29 18:00:44 dwsquid Exp $ * * DEBUG: section 85 Client-side Request Routines * AUTHOR: Robert Collins (Originally Duane Wessels in client_side.c) @@ -985,7 +985,7 @@ return; } -#if ICAP_CLIENT +#if ICAP_CLIENT && 0 if (!calloutContext->icap_reqmod_done) { calloutContext->icap_reqmod_done = 1; Index: squid3/src/http.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/http.cc,v retrieving revision 1.49.2.32 retrieving revision 1.49.2.33 diff -u -r1.49.2.32 -r1.49.2.33 --- squid3/src/http.cc 28 Sep 2005 21:47:23 -0000 1.49.2.32 +++ squid3/src/http.cc 29 Sep 2005 18:00:44 -0000 1.49.2.33 @@ -1,6 +1,6 @@ /* - * $Id: http.cc,v 1.49.2.32 2005/09/28 21:47:23 dwsquid Exp $ + * $Id: http.cc,v 1.49.2.33 2005/09/29 18:00:44 dwsquid Exp $ * * DEBUG: section 11 Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived @@ -54,6 +54,7 @@ #endif #if ICAP_CLIENT #include "ICAPAnchor.h" +#include "ICAPConfig.h" #endif CBDATA_TYPE(HttpStateData); @@ -73,6 +74,9 @@ static void copyOneHeaderFromClientsideRequestToUpstreamRequest(const HttpHeaderEntry *e, String strConnection, HttpRequest * request, HttpRequest * orig_request, HttpHeader * hdr_out, int we_do_ranges, http_state_flags); static int decideIfWeDoRanges (HttpRequest * orig_request); +#if ICAP_CLIENT +static void icapAclCheckDoneWrapper(ICAPServiceRep::Pointer service, void *data); +#endif static void httpStateFree(int fd, void *data) @@ -740,26 +744,10 @@ */ #if ICAP_CLIENT - /* - * One reason to start ICAP here is so that we know the size - * of the ICAP pipe buffer for the first HTTP reply read - * from the network. - */ - if (doIcap() < 0) { - /* - * XXX Maybe instead of an error page we should - * handle the reply normally (without ICAP). - */ - ErrorState *err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR); - err->xerrno = errno; - err->request = requestLink(orig_request); - errorAppendEntry(entry, err); - comm_close(fd); - ctx_exit(ctx); - return; - } else { - icap->startRespMod(this, request, reply); + if (icap_access_check = new ICAPAccessCheck(ICAPServiceRep::respmod, ICAPServiceRep::precache, request, reply, icapAclCheckDoneWrapper, this)) { + icap_access_check->check(); + icapAccessCheckPending = true; ctx_exit(ctx); return; } @@ -1111,9 +1099,11 @@ void HttpStateData::writeReplyBody(const char *data, int len) { +debug(0,0)("HttpStateData::writeReplyBody() called\n"); #if ICAP_CLIENT if (icap) { +debug(0,0)("HttpStateData::writeReplyBody sending %d bytes to ICAP\n", len); icap->sendMoreData (StoreIOBuffer(len, 0, (char*)data)); return; } @@ -1137,12 +1127,16 @@ void HttpStateData::processReplyBody() { +debug(0,0)("HttpStateData::processReplyBody() called\n"); if (!flags.headers_parsed) { flags.do_next_read = 1; maybeReadData(); return; } + if (icapAccessCheckPending) + return; + /* * At this point the reply headers have been parsed and consumed. * That means header content has been removed from readBuf and @@ -1982,17 +1976,54 @@ } #if ICAP_CLIENT + +static void +icapAclCheckDoneWrapper(ICAPServiceRep::Pointer service, void *data) +{ + HttpStateData *http = (HttpStateData *)data; + http->icapAclCheckDone(service); +} + +void +HttpStateData::icapAclCheckDone(ICAPServiceRep::Pointer service) +{ + icapAccessCheckPending = false; + if (service == NULL) { + // handle case where no service is selected; + assert(false); + return; + } + + debug(0,0)("icapAclCheckDone: service=%p\n", service.getRaw()); + + if (doIcap(service) < 0) { + /* + * XXX Maybe instead of an error page we should + * handle the reply normally (without ICAP). + */ + ErrorState *err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR); + err->xerrno = errno; + err->request = requestLink(orig_request); + errorAppendEntry(entry, err); + comm_close(fd); + return; + } + + icap->startRespMod(this, request, reply); + processReplyBody(); +} + /* * Initiate an ICAP transaction. Return 0 if all is well, or -1 upon error. * Caller will handle error condition by generating a Squid error message * or take other action. */ int -HttpStateData::doIcap() +HttpStateData::doIcap(ICAPServiceRep::Pointer service) { debug(11,5)("HttpStateData::doIcap() called\n"); assert(NULL == icap); - icap = new ICAPAnchor; + icap = new ICAPAnchor(service); (void) cbdataReference(icap); return 0; } Index: squid3/src/http.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/http.h,v retrieving revision 1.11.4.11 retrieving revision 1.11.4.12 diff -u -r1.11.4.11 -r1.11.4.12 --- squid3/src/http.h 28 Sep 2005 21:47:23 -0000 1.11.4.11 +++ squid3/src/http.h 29 Sep 2005 18:00:44 -0000 1.11.4.12 @@ -1,6 +1,6 @@ /* - * $Id: http.h,v 1.11.4.11 2005/09/28 21:47:23 dwsquid Exp $ + * $Id: http.h,v 1.11.4.12 2005/09/29 18:00:44 dwsquid Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -36,9 +36,12 @@ #include "StoreIOBuffer.h" #include "comm.h" +#include "ICAPServiceRep.h" class ICAPAnchor; +class ICAPAccessCheck; + class HttpStateData { @@ -76,10 +79,13 @@ MemBuf *readBuf; bool ignoreCacheControl; bool surrogateNoStore; + bool icapAccessCheckPending; void processSurrogateControl(HttpReply *); #if ICAP_CLIENT ICAPAnchor *icap; + ICAPAccessCheck *icap_access_check; + void icapAclCheckDone(ICAPServiceRep::Pointer); #endif /* @@ -111,7 +117,7 @@ void writeReplyBody(const char *data, int len); #if ICAP_CLIENT - int doIcap(); + int doIcap(ICAPServiceRep::Pointer); #endif };