From: Kinkie Date: Wed, 2 Jul 2008 00:08:57 +0000 (+0200) Subject: Imported changes from old trees. X-Git-Tag: SQUID_3_1_0_1~49^2~143^2~54 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c83f0bd518f729aac2f7ef0f04fff0b459e6071b;p=thirdparty%2Fsquid.git Imported changes from old trees. --- diff --git a/src/CacheManager.h b/src/CacheManager.h index efc687c08a..db7a9108e1 100644 --- a/src/CacheManager.h +++ b/src/CacheManager.h @@ -41,30 +41,39 @@ \ingroup Components */ -/// \ingroup CacheManagerAPI -extern void cachemgrStart(int fd, HttpRequest * request, StoreEntry * entry); - -/** - \ingroup CacheManagerAPI - * A single menu item in the cache manager - an 'action'. - */ -class CacheManagerAction -{ +class CacheManagerAction { +public: + virtual void run(StoreEntry *sentry) = 0; + char *action; + char *desc; + struct + { + unsigned int pw_req:1; + unsigned int atomic:1; + } flags; + CacheManagerAction *next; + virtual ~CacheManagerAction() { } +}; +class CacheManagerActionLegacy : public CacheManagerAction { public: - char *action; - char *desc; - OBJH *handler; - - struct - { - unsigned int pw_req:1; - unsigned int atomic:1; - } flags; + OBJH *handler; + virtual void run (StoreEntry *sentry); +}; - CacheManagerAction *next; +class CacheManagerShutdownAction : public CacheManagerAction { +public: + virtual void run (StoreEntry *sentry); }; +/// \ingroup CacheManagerInternal +typedef struct +{ + StoreEntry *entry; + char *action; + char *user_name; + char *passwd; +} cachemgrStateData; /** \ingroup CacheManagerAPI @@ -72,12 +81,12 @@ public: * This is currently just an adapter to the global cachemgr* routines to * provide looser coupling between modules, but once fully transitioned, * an instance of this class will represent a single independent manager. + * TODO: update documentation to reflect the new singleton model. */ class CacheManager { public: - CacheManager(); /* the holy trinity - assignment, copy cons, destructor */ /* unimplemented - prevents bugs from synthetic */ CacheManager & operator = (CacheManager &); @@ -86,8 +95,37 @@ public: /* inline so that we dont need to link in cachemgr.cc at all in tests */ virtual ~CacheManager() {} - virtual void registerAction(char const * action, char const * desc, OBJH * handler, int pw_req_flag, int atomic); - virtual CacheManagerAction * findAction(char const * action); + void registerAction(char const * action, char const * desc, OBJH * handler, int pw_req_flag, int atomic); + CacheManagerAction * findAction(char const * action); + + void Start(int fd, HttpRequest * request, StoreEntry * entry); + + static CacheManager* GetInstance(); + const char *ActionProtection(const CacheManagerAction * at); //needs to be called from C + +protected: + CacheManager(); + cachemgrStateData* ParseUrl(const char *url); + void ParseHeaders(cachemgrStateData * mgr, const HttpRequest * request); + int CheckPassword(cachemgrStateData * mgr); + char *PasswdGet(cachemgr_passwd *, const char *); + +private: + static CacheManager* instance; + + //commands need to be static to be able to be referenced as C-style + //functions. Binding to nonstatic members can be done at runtime + //via the singleton, but it's syntactic hackery + //TODO: fix so that ActionTable uses a Command pattern and thus + // function calls are properly object-wrapped + static void ShutdownCommand(StoreEntry *unused); + static void ReconfigureCommand(StoreEntry *sentry); + static void MenuCommand(StoreEntry *sentry); + static void OfflineToggleCommand(StoreEntry *sentry); + + void StateFree(cachemgrStateData * mgr); + + }; #endif /* SQUID_CACHEMANAGER_H */ diff --git a/src/cache_manager.cc b/src/cache_manager.cc index 00f5b38e9a..9a616c7b78 100644 --- a/src/cache_manager.cc +++ b/src/cache_manager.cc @@ -50,62 +50,44 @@ /// \ingroup CacheManagerInternal #define MGR_PASSWD_SZ 128 -/// \ingroup CacheManagerInternal -typedef struct -{ - StoreEntry *entry; - char *action; - char *user_name; - char *passwd; -} cachemgrStateData; - -static CacheManagerAction *cachemgrFindAction(const char *action); -static cachemgrStateData *cachemgrParseUrl(const char *url); -static void cachemgrParseHeaders(cachemgrStateData * mgr, const HttpRequest * request); -static int cachemgrCheckPassword(cachemgrStateData *); -static void cachemgrStateFree(cachemgrStateData * mgr); -static char *cachemgrPasswdGet(cachemgr_passwd *, const char *); -static const char *cachemgrActionProtection(const CacheManagerAction * at); -static OBJH cachemgrShutdown; -static OBJH cachemgrReconfigure; -static OBJH cachemgrMenu; -static OBJH cachemgrOfflineToggle; + /// \ingroup CacheManagerInternal CacheManagerAction *ActionTable = NULL; CacheManager::CacheManager() { - registerAction("menu", "This Cachemanager Menu", cachemgrMenu, 0, 1); + registerAction("menu", "This Cachemanager Menu", MenuCommand, 0, 1); registerAction("shutdown", "Shut Down the Squid Process", - cachemgrShutdown, 1, 1); + ShutdownCommand, 1, 1); registerAction("reconfigure", "Reconfigure the Squid Process", - cachemgrReconfigure, 1, 1); + ReconfigureCommand, 1, 1); registerAction("offline_toggle", "Toggle offline_mode setting", - cachemgrOfflineToggle, 1, 1); + OfflineToggleCommand, 1, 1); } void CacheManager::registerAction(char const * action, char const * desc, OBJH * handler, int pw_req_flag, int atomic) { - CacheManagerAction *a; + CacheManagerActionLegacy *a; CacheManagerAction **A; if (findAction(action) != NULL) { - debugs(16, 3, "CacheManager::registerAction: Duplicate '" << action << "'"); + debugs(16, 3, "CacheManager::registerAction: Duplicate '" << action << "'. Skipping."); return; } assert (strstr (" ", action) == NULL); - a = (CacheManagerAction *)xcalloc(1, sizeof(CacheManagerAction)); + a = new CacheManagerActionLegacy; a->action = xstrdup(action); a->desc = xstrdup(desc); a->handler = handler; a->flags.pw_req = pw_req_flag; a->flags.atomic = atomic; + a->next=0; for (A = &ActionTable; *A; A = &(*A)->next); *A = a; @@ -113,15 +95,13 @@ CacheManager::registerAction(char const * action, char const * desc, OBJH * hand debugs(16, 3, "CacheManager::registerAction: registered " << action); } +/// \ingroup CacheManagerInternal +//TODO: revert those two functions and turn ActionTable into a +// private data member. +// In order to do so ActionTable must be extended to allow using +// function objects rather than C-style functions CacheManagerAction * CacheManager::findAction(char const * action) -{ - return cachemgrFindAction(action); -} - -/// \ingroup CacheManagerInternal -static CacheManagerAction * -cachemgrFindAction(const char *action) { CacheManagerAction *a; @@ -134,8 +114,8 @@ cachemgrFindAction(const char *action) } /// \ingroup CacheManagerInternal -static cachemgrStateData * -cachemgrParseUrl(const char *url) +cachemgrStateData * +CacheManager::ParseUrl(const char *url) { int t; LOCAL_ARRAY(char, host, MAX_URL); @@ -157,14 +137,14 @@ cachemgrParseUrl(const char *url) xstrncpy(request, "menu", MAX_URL); #endif - } else if ((a = cachemgrFindAction(request)) == NULL) { - debugs(16, 1, "cachemgrParseUrl: action '" << request << "' not found"); + } else if ((a = findAction(request)) == NULL) { + debugs(16, 1, "CacheManager::ParseUrl: action '" << request << "' not found"); return NULL; } else { - prot = cachemgrActionProtection(a); + prot = ActionProtection(a); if (!strcmp(prot, "disabled") || !strcmp(prot, "hidden")) { - debugs(16, 1, "cachemgrParseUrl: action '" << request << "' is " << prot); + debugs(16, 1, "CacheManager::ParseUrl: action '" << request << "' is " << prot); return NULL; } } @@ -182,8 +162,8 @@ cachemgrParseUrl(const char *url) } /// \ingroup CacheManagerInternal -static void -cachemgrParseHeaders(cachemgrStateData * mgr, const HttpRequest * request) +void +CacheManager::ParseHeaders(cachemgrStateData * mgr, const HttpRequest * request) { const char *basic_cookie; /* base 64 _decoded_ user:passwd pair */ const char *passwd_del; @@ -194,7 +174,7 @@ cachemgrParseHeaders(cachemgrStateData * mgr, const HttpRequest * request) return; if (!(passwd_del = strchr(basic_cookie, ':'))) { - debugs(16, 1, "cachemgrParseHeaders: unknown basic_cookie format '" << basic_cookie << "'"); + debugs(16, 1, "CacheManager::ParseHeaders: unknown basic_cookie format '" << basic_cookie << "'"); return; } @@ -210,7 +190,7 @@ cachemgrParseHeaders(cachemgrStateData * mgr, const HttpRequest * request) mgr->passwd = xstrdup(passwd_del + 1); /* warning: this prints decoded password which maybe not what you want to do @?@ @?@ */ - debugs(16, 9, "cachemgrParseHeaders: got user: '" << mgr->user_name << "' passwd: '" << mgr->passwd << "'"); + debugs(16, 9, "CacheManager::ParseHeaders: got user: '" << mgr->user_name << "' passwd: '" << mgr->passwd << "'"); } /** @@ -220,11 +200,11 @@ cachemgrParseHeaders(cachemgrStateData * mgr, const HttpRequest * request) \retval 1 if mgr->password is "disable" \retval !0 if mgr->password does not match configured password */ -static int -cachemgrCheckPassword(cachemgrStateData * mgr) +int +CacheManager::CheckPassword(cachemgrStateData * mgr) { - char *pwd = cachemgrPasswdGet(Config.passwd_list, mgr->action); - CacheManagerAction *a = cachemgrFindAction(mgr->action); + char *pwd = PasswdGet(Config.passwd_list, mgr->action); + CacheManagerAction *a = findAction(mgr->action); assert(a != NULL); if (pwd == NULL) @@ -243,8 +223,8 @@ cachemgrCheckPassword(cachemgrStateData * mgr) } /// \ingroup CacheManagerInternal -static void -cachemgrStateFree(cachemgrStateData * mgr) +void +CacheManager::StateFree(cachemgrStateData * mgr) { safe_free(mgr->action); safe_free(mgr->user_name); @@ -255,14 +235,14 @@ cachemgrStateFree(cachemgrStateData * mgr) // API void -cachemgrStart(int fd, HttpRequest * request, StoreEntry * entry) +CacheManager::Start(int fd, HttpRequest * request, StoreEntry * entry) { cachemgrStateData *mgr = NULL; ErrorState *err = NULL; CacheManagerAction *a; debugs(16, 3, "objectcacheStart: '" << entry->url() << "'" ); - if ((mgr = cachemgrParseUrl(entry->url())) == NULL) { + if ((mgr = ParseUrl(entry->url())) == NULL) { err = errorCon(ERR_INVALID_URL, HTTP_NOT_FOUND, request); err->url = xstrdup(entry->url()); errorAppendEntry(entry, err); @@ -278,11 +258,11 @@ cachemgrStart(int fd, HttpRequest * request, StoreEntry * entry) debugs(16, 5, "CACHEMGR: " << fd_table[fd].ipaddr << " requesting '" << mgr->action << "'"); /* get additional info from request headers */ - cachemgrParseHeaders(mgr, request); + ParseHeaders(mgr, request); /* Check password */ - if (cachemgrCheckPassword(mgr) != 0) { + if (CheckPassword(mgr) != 0) { /* build error message */ ErrorState *err; HttpReply *rep; @@ -317,7 +297,7 @@ cachemgrStart(int fd, HttpRequest * request, StoreEntry * entry) entry->complete(); - cachemgrStateFree(mgr); + StateFree(mgr); return; } @@ -327,7 +307,7 @@ cachemgrStart(int fd, HttpRequest * request, StoreEntry * entry) fd_table[fd].ipaddr << " requesting '" << mgr->action << "'" ); /* retrieve object requested */ - a = cachemgrFindAction(mgr->action); + a = findAction(mgr->action); assert(a != NULL); entry->buffer(); @@ -345,27 +325,32 @@ cachemgrStart(int fd, HttpRequest * request, StoreEntry * entry) entry->replaceHttpReply(rep); } - a->handler(entry); + a->run(entry); entry->flush(); if (a->flags.atomic) entry->complete(); - cachemgrStateFree(mgr); + StateFree(mgr); } /// \ingroup CacheManagerInternal -static void -cachemgrShutdown(StoreEntry * entryunused) +void +CacheManager::ShutdownCommand(StoreEntry *unused) +{ + debugs(16, 0, "Shutdown by command."); + shut_down(0); +} +void CacheManagerShutdownAction::run(StoreEntry *sentry) { debugs(16, 0, "Shutdown by command."); shut_down(0); } /// \ingroup CacheManagerInternal -static void -cachemgrReconfigure(StoreEntry * sentry) +void +CacheManager::ReconfigureCommand(StoreEntry * sentry) { debug(16, 0) ("Reconfigure by command.\n"); storeAppendPrintf(sentry, "Reconfiguring Squid Process ...."); @@ -373,8 +358,8 @@ cachemgrReconfigure(StoreEntry * sentry) } /// \ingroup CacheManagerInternal -static void -cachemgrOfflineToggle(StoreEntry * sentry) +void +CacheManager::OfflineToggleCommand(StoreEntry * sentry) { Config.onoff.offline = !Config.onoff.offline; debugs(16, 0, "offline_mode now " << (Config.onoff.offline ? "ON" : "OFF") << "."); @@ -384,12 +369,12 @@ cachemgrOfflineToggle(StoreEntry * sentry) } /// \ingroup CacheManagerInternal -static const char * -cachemgrActionProtection(const CacheManagerAction * at) +const char * +CacheManager::ActionProtection(const CacheManagerAction * at) { char *pwd; assert(at); - pwd = cachemgrPasswdGet(Config.passwd_list, at->action); + pwd = PasswdGet(Config.passwd_list, at->action); if (!pwd) return at->flags.pw_req ? "hidden" : "public"; @@ -404,20 +389,20 @@ cachemgrActionProtection(const CacheManagerAction * at) } /// \ingroup CacheManagerInternal -static void -cachemgrMenu(StoreEntry * sentry) +void +CacheManager::MenuCommand(StoreEntry * sentry) { CacheManagerAction *a; for (a = ActionTable; a != NULL; a = a->next) { storeAppendPrintf(sentry, " %-22s\t%-32s\t%s\n", - a->action, a->desc, cachemgrActionProtection(a)); + a->action, a->desc, CacheManager::GetInstance()->ActionProtection(a)); } } /// \ingroup CacheManagerInternal -static char * -cachemgrPasswdGet(cachemgr_passwd * a, const char *action) +char * +CacheManager::PasswdGet(cachemgr_passwd * a, const char *action) { wordlist *w; @@ -435,3 +420,19 @@ cachemgrPasswdGet(cachemgr_passwd * a, const char *action) return NULL; } + +CacheManager* CacheManager::instance=0; + +CacheManager* +CacheManager::GetInstance() { + if (instance == 0) + instance = new CacheManager; + return instance; +} + + +void CacheManagerActionLegacy::run(StoreEntry *sentry) +{ + handler(sentry); +} + diff --git a/src/forward.cc b/src/forward.cc index 0e615f93c3..4daef3197c 100644 --- a/src/forward.cc +++ b/src/forward.cc @@ -256,7 +256,7 @@ FwdState::fwdStart(int client_fd, StoreEntry *entry, HttpRequest *request) return; case PROTO_CACHEOBJ: - cachemgrStart(client_fd, request, entry); + CacheManager::GetInstance()->Start(client_fd, request, entry); return; case PROTO_URN: diff --git a/src/main.cc b/src/main.cc index 006a9e6e98..84418f348f 100644 --- a/src/main.cc +++ b/src/main.cc @@ -127,7 +127,7 @@ static void SquidShutdown(void); static void mainSetCwd(void); static int checkRunningPid(void); -static CacheManager manager; +static CacheManager *manager=CacheManager::GetInstance(); #ifndef _SQUID_MSWIN_ static const char *squid_start_script = "squid_start"; @@ -693,7 +693,7 @@ mainReconfigure(void) refererCloseLog(); errorClean(); enter_suid(); /* root to read config file */ - parseConfigFile(ConfigFile, manager); + parseConfigFile(ConfigFile, *manager); setUmask(Config.umask); Mem::Report(); setEffectiveUser(); @@ -730,7 +730,7 @@ mainReconfigure(void) serverConnectionsOpen(); neighbors_init(); - neighborsRegisterWithCacheManager(manager); + neighborsRegisterWithCacheManager(*manager); storeDirOpenSwapLogs(); @@ -966,76 +966,76 @@ mainInitialize(void) FwdState::initModule(); /* register the modules in the cache manager menus */ - accessLogRegisterWithCacheManager(manager); - asnRegisterWithCacheManager(manager); - authenticateRegisterWithCacheManager(&Config.authConfiguration, manager); + accessLogRegisterWithCacheManager(*manager); + asnRegisterWithCacheManager(*manager); + authenticateRegisterWithCacheManager(&Config.authConfiguration, *manager); #if USE_CARP - carpRegisterWithCacheManager(manager); + carpRegisterWithCacheManager(*manager); #endif - cbdataRegisterWithCacheManager(manager); + cbdataRegisterWithCacheManager(*manager); /* These use separate calls so that the comm loops can eventually * coexist. */ #ifdef USE_EPOLL - commEPollRegisterWithCacheManager(manager); + commEPollRegisterWithCacheManager(*manager); #endif #ifdef USE_KQUEUE - commKQueueRegisterWithCacheManager(manager); + commKQueueRegisterWithCacheManager(*manager); #endif #ifdef USE_POLL - commPollRegisterWithCacheManager(manager); + commPollRegisterWithCacheManager(*manager); #endif #if defined(USE_SELECT) || defined(USE_SELECT_WIN32) - commSelectRegisterWithCacheManager(manager); + commSelectRegisterWithCacheManager(*manager); #endif - clientdbRegisterWithCacheManager(manager); + clientdbRegisterWithCacheManager(*manager); #if DELAY_POOLS - DelayPools::RegisterWithCacheManager(manager); + DelayPools::RegisterWithCacheManager(*manager); #endif - DiskIOModule::RegisterAllModulesWithCacheManager(manager); + DiskIOModule::RegisterAllModulesWithCacheManager(*manager); #if USE_DNSSERVERS - dnsRegisterWithCacheManager(manager); + dnsRegisterWithCacheManager(*manager); #endif - eventInit(manager); - externalAclRegisterWithCacheManager(manager); - fqdncacheRegisterWithCacheManager(manager); - FwdState::RegisterWithCacheManager(manager); - httpHeaderRegisterWithCacheManager(manager); + eventInit(*manager); + externalAclRegisterWithCacheManager(*manager); + fqdncacheRegisterWithCacheManager(*manager); + FwdState::RegisterWithCacheManager(*manager); + httpHeaderRegisterWithCacheManager(*manager); #if !USE_DNSSERVERS - idnsRegisterWithCacheManager(manager); + idnsRegisterWithCacheManager(*manager); #endif - ipcacheRegisterWithCacheManager(manager); - Mem::RegisterWithCacheManager(manager); - netdbRegisterWitHCacheManager(manager); - PconnModule::GetInstance()->registerWithCacheManager(manager); - redirectRegisterWithCacheManager(manager); - refreshRegisterWithCacheManager(manager); - statRegisterWithCacheManager(manager); - storeDigestRegisterWithCacheManager(manager); - StoreFileSystem::RegisterAllFsWithCacheManager(manager); - storeRegisterWithCacheManager(manager); - storeLogRegisterWithCacheManager(manager); + ipcacheRegisterWithCacheManager(*manager); + Mem::RegisterWithCacheManager(*manager); + netdbRegisterWitHCacheManager(*manager); + PconnModule::GetInstance()->registerWithCacheManager(*manager); + redirectRegisterWithCacheManager(*manager); + refreshRegisterWithCacheManager(*manager); + statRegisterWithCacheManager(*manager); + storeDigestRegisterWithCacheManager(*manager); + StoreFileSystem::RegisterAllFsWithCacheManager(*manager); + storeRegisterWithCacheManager(*manager); + storeLogRegisterWithCacheManager(*manager); #if DEBUGSTRINGS - StringRegistry::Instance().registerWithCacheManager(manager); + StringRegistry::Instance().registerWithCacheManager(*manager); #endif #if USE_XPROF_STATS - xprofRegisterWithCacheManager(manager); + xprofRegisterWithCacheManager(*manager); #endif } @@ -1054,7 +1054,7 @@ mainInitialize(void) neighbors_init(); - neighborsRegisterWithCacheManager(manager); + neighborsRegisterWithCacheManager(*manager); if (Config.chroot_dir) no_suid(); @@ -1262,7 +1262,7 @@ main(int argc, char **argv) /* we may want the parsing process to set this up in the future */ Store::Root(new StoreController); - parse_err = parseConfigFile(ConfigFile, manager); + parse_err = parseConfigFile(ConfigFile, *manager); Mem::Report();