\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
* 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 &);
/* 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 */
/// \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;
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;
}
/// \ingroup CacheManagerInternal
-static cachemgrStateData *
-cachemgrParseUrl(const char *url)
+cachemgrStateData *
+CacheManager::ParseUrl(const char *url)
{
int t;
LOCAL_ARRAY(char, host, MAX_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;
}
}
}
/// \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;
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;
}
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 << "'");
}
/**
\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)
}
/// \ingroup CacheManagerInternal
-static void
-cachemgrStateFree(cachemgrStateData * mgr)
+void
+CacheManager::StateFree(cachemgrStateData * mgr)
{
safe_free(mgr->action);
safe_free(mgr->user_name);
// 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);
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;
entry->complete();
- cachemgrStateFree(mgr);
+ StateFree(mgr);
return;
}
fd_table[fd].ipaddr << " requesting '" <<
mgr->action << "'" );
/* retrieve object requested */
- a = cachemgrFindAction(mgr->action);
+ a = findAction(mgr->action);
assert(a != NULL);
entry->buffer();
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 ....");
}
/// \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") << ".");
}
/// \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";
}
/// \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;
return NULL;
}
+
+CacheManager* CacheManager::instance=0;
+
+CacheManager*
+CacheManager::GetInstance() {
+ if (instance == 0)
+ instance = new CacheManager;
+ return instance;
+}
+
+
+void CacheManagerActionLegacy::run(StoreEntry *sentry)
+{
+ handler(sentry);
+}
+
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";
refererCloseLog();
errorClean();
enter_suid(); /* root to read config file */
- parseConfigFile(ConfigFile, manager);
+ parseConfigFile(ConfigFile, *manager);
setUmask(Config.umask);
Mem::Report();
setEffectiveUser();
serverConnectionsOpen();
neighbors_init();
- neighborsRegisterWithCacheManager(manager);
+ neighborsRegisterWithCacheManager(*manager);
storeDirOpenSwapLogs();
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
}
neighbors_init();
- neighborsRegisterWithCacheManager(manager);
+ neighborsRegisterWithCacheManager(*manager);
if (Config.chroot_dir)
no_suid();
/* 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();