From a68cf07608b99295dd4df1726bc24faedb462702 Mon Sep 17 00:00:00 2001 From: Alex Rousskov Date: Sun, 23 Mar 2008 22:40:39 -0600 Subject: [PATCH] Moving common adaptation code from ICAP/ to adaptation/. --- src/ICAP/ICAPElements.cc | 3 + src/ICAP/ICAPElements.h | 26 ++++--- src/ICAP/ICAPServiceRep.cc | 121 ++----------------------------- src/ICAP/ICAPServiceRep.h | 21 +----- src/adaptation/Elements.cc | 51 +++++++++++++ src/adaptation/Elements.h | 18 +++++ src/adaptation/Makefile.am | 23 ++++++ src/adaptation/Service.cc | 144 +++++++++++++++++++++++++++++++++++++ src/adaptation/Service.h | 41 +++++++++++ 9 files changed, 305 insertions(+), 143 deletions(-) create mode 100644 src/adaptation/Elements.cc create mode 100644 src/adaptation/Elements.h create mode 100644 src/adaptation/Makefile.am create mode 100644 src/adaptation/Service.cc create mode 100644 src/adaptation/Service.h diff --git a/src/ICAP/ICAPElements.cc b/src/ICAP/ICAPElements.cc index 50f3c40b68..7aa5968c25 100644 --- a/src/ICAP/ICAPElements.cc +++ b/src/ICAP/ICAPElements.cc @@ -1,6 +1,8 @@ #include "squid.h" #include "ICAPElements.h" +#if 0 /* XXX: remove this file */ + const char *ICAP::crlf = "\r\n"; @@ -50,3 +52,4 @@ ICAP::vectPointStr(ICAP::VectPoint point) } +#endif /* if 0 -- remove this file */ diff --git a/src/ICAP/ICAPElements.h b/src/ICAP/ICAPElements.h index 75e18ac427..9cdfca1769 100644 --- a/src/ICAP/ICAPElements.h +++ b/src/ICAP/ICAPElements.h @@ -34,19 +34,25 @@ #ifndef SQUID_ICAPELEMENTS_H #define SQUID_ICAPELEMENTS_H -// ICAP-related things shared by many ICAP classes +#include "adaptation/Elements.h" -// A "fake" class to encapsulate ICAP-related declarations without -// adding namespaces to Squid. Eventually, namespaces should be added. +// ICAP-related things shared by many ICAP classes -struct ICAP +namespace ICAP { - typedef enum { methodNone, methodReqmod, methodRespmod, methodOptions } Method; - typedef enum { pointNone, pointPreCache, pointPostCache } VectPoint; + using Adaptation::Method; + using Adaptation::methodNone; + using Adaptation::methodRespmod; + using Adaptation::methodReqmod; + + using Adaptation::VectPoint; + using Adaptation::pointNone; + using Adaptation::pointPreCache; + using Adaptation::pointPostCache; - static const char *crlf; - static const char *methodStr(ICAP::Method); - static const char *vectPointStr(ICAP::VectPoint); -}; + using Adaptation::crlf; + using Adaptation::methodStr; + using Adaptation::vectPointStr; +} #endif /* SQUID_ICAPCLIENT_H */ diff --git a/src/ICAP/ICAPServiceRep.cc b/src/ICAP/ICAPServiceRep.cc index 224abea48a..36dc0fef4f 100644 --- a/src/ICAP/ICAPServiceRep.cc +++ b/src/ICAP/ICAPServiceRep.cc @@ -14,8 +14,7 @@ CBDATA_CLASS_INIT(ICAPServiceRep); -ICAPServiceRep::ICAPServiceRep(): AsyncJob("ICAPServiceRep"), method(ICAP::methodNone), - point(ICAP::pointNone), port(-1), bypass(false), +ICAPServiceRep::ICAPServiceRep(): AsyncJob("ICAPServiceRep"), theOptions(NULL), theOptionsFetcher(0), theLastUpdate(0), theSessionFailures(0), isSuspended(0), notifying(false), updateScheduled(false), self(NULL), @@ -28,111 +27,18 @@ ICAPServiceRep::~ICAPServiceRep() changeOptions(0); } -const char * -ICAPServiceRep::methodStr() const -{ - return ICAP::methodStr(method); -} - -ICAP::Method -ICAPServiceRep::parseMethod(const char *str) const -{ - if (!strncasecmp(str, "REQMOD", 6)) - return ICAP::methodReqmod; - - if (!strncasecmp(str, "RESPMOD", 7)) - return ICAP::methodRespmod; - - return ICAP::methodNone; -} - - -const char * -ICAPServiceRep::vectPointStr() const -{ - return ICAP::vectPointStr(point); -} - -ICAP::VectPoint -ICAPServiceRep::parseVectPoint(const char *service) const -{ - const char *t = service; - const char *q = strchr(t, '_'); - - if (q) - t = q + 1; - - if (!strcasecmp(t, "precache")) - return ICAP::pointPreCache; - - if (!strcasecmp(t, "postcache")) - return ICAP::pointPostCache; - - return ICAP::pointNone; -} - bool ICAPServiceRep::configure(Pointer &aSelf) { assert(!self && aSelf != NULL); self = aSelf; - char *service_type = NULL; - - ConfigParser::ParseString(&key); - ConfigParser::ParseString(&service_type); - ConfigParser::ParseBool(&bypass); - ConfigParser::ParseString(&uri); - - debugs(3, 5, "ICAPService::parseConfigLine (line " << config_lineno << "): " << key.buf() << " " << service_type << " " << bypass); - - method = parseMethod(service_type); - point = parseVectPoint(service_type); - - debugs(3, 5, "ICAPService::parseConfigLine (line " << config_lineno << "): service is " << methodStr() << "_" << vectPointStr()); - - if (uri.cmp("icap://", 7) != 0) { - debugs(3, 0, "ICAPService::parseConfigLine (line " << config_lineno << "): wrong uri: " << uri.buf()); + if (!Adaptation::Service::configure()) return false; - } - - const char *s = uri.buf() + 7; - - const char *e; - - bool have_port = false; - - if ((e = strchr(s, ':')) != NULL) { - have_port = true; - } else if ((e = strchr(s, '/')) != NULL) { - have_port = false; - } else { - return false; - } - - int len = e - s; - host.limitInit(s, len); - s = e; - - if (have_port) { - s++; - - if ((e = strchr(s, '/')) != NULL) { - char *t; - port = strtoul(s, &t, 0) % 65536; - - if (t != e) { - return false; - } - - s = e; - - if (s[0] != '/') { - return false; - } - } - } else { + // use /etc/services or default port if needed + const bool have_port = port >= 0; + if (!have_port) { struct servent *serv = getservbyname("icap", "tcp"); if (serv) { @@ -142,23 +48,8 @@ ICAPServiceRep::configure(Pointer &aSelf) } } - s++; - e = strchr(s, '\0'); - len = e - s; - - if (len > 1024) { - debugs(3, 0, "icap_service_process (line " << config_lineno << "): long resource name (>1024), probably wrong"); - } - - resource.limitInit(s, len + 1); - - if ((bypass != 0) && (bypass != 1)) { - return false; - } - return true; - -}; +} void ICAPServiceRep::invalidate() { diff --git a/src/ICAP/ICAPServiceRep.h b/src/ICAP/ICAPServiceRep.h index 7def2c59dd..e0f045ffe4 100644 --- a/src/ICAP/ICAPServiceRep.h +++ b/src/ICAP/ICAPServiceRep.h @@ -35,6 +35,7 @@ #define SQUID_ICAPSERVICEREP_H #include "cbdata.h" +#include "adaptation/Service.h" #include "ICAPInitiator.h" #include "ICAPElements.h" @@ -70,7 +71,8 @@ class ICAPOptXact; */ -class ICAPServiceRep : public RefCountable, public ICAPInitiator +class ICAPServiceRep : public RefCountable, public Adaptation::Service, + public ICAPInitiator { public: @@ -83,9 +85,6 @@ public: bool configure(Pointer &aSelf); // needs self pointer for ICAPOptXact void invalidate(); // call when the service is no longer needed or valid - const char *methodStr() const; - const char *vectPointStr() const; - bool probed() const; // see comments above bool broken() const; // see comments above bool up() const; // see comments above @@ -102,20 +101,6 @@ public: //AsyncJob virtual methods virtual bool doneAll() const { return ICAPInitiator::doneAll() && false;} -public: - String key; - ICAP::Method method; - ICAP::VectPoint point; - String uri; // service URI - - // URI components - String host; - int port; - String resource; - - // XXX: use it when selecting a service and handling ICAP errors! - bool bypass; - public: // treat these as private, they are for callbacks only void noteTimeToUpdate(); void noteTimeToNotify(); diff --git a/src/adaptation/Elements.cc b/src/adaptation/Elements.cc new file mode 100644 index 0000000000..42cb5676e5 --- /dev/null +++ b/src/adaptation/Elements.cc @@ -0,0 +1,51 @@ +#include "squid.h" +#include "adaptation/Elements.h" + +const char *Adaptation::crlf = "\r\n"; + +const char * +Adaptation::methodStr(Adaptation::Method method) +{ + switch(method) { + + case Adaptation::methodReqmod: + return "REQMOD"; + break; + + case Adaptation::methodRespmod: + return "RESPMOD"; + break; + + case Adaptation::methodOptions: + return "OPTIONS"; + break; + + default: + break; + } + + return "NONE"; +} + + +const char * +Adaptation::vectPointStr(Adaptation::VectPoint point) +{ + switch(point) { + + case Adaptation::pointPreCache: + return "PRECACHE"; + break; + + case Adaptation::pointPostCache: + return "POSTCACHE"; + break; + + default: + break; + } + + return "NONE"; +} + + diff --git a/src/adaptation/Elements.h b/src/adaptation/Elements.h new file mode 100644 index 0000000000..1dbd089d8d --- /dev/null +++ b/src/adaptation/Elements.h @@ -0,0 +1,18 @@ +#ifndef SQUID_ADAPTATION__ELEMENTS_H +#define SQUID_ADAPTATION__ELEMENTS_H + +// widely used adaptation primitives + +namespace Adaptation +{ + +typedef enum { methodNone, methodReqmod, methodRespmod, methodOptions } Method; +typedef enum { pointNone, pointPreCache, pointPostCache } VectPoint; + +extern const char *crlf; +extern const char *methodStr(Method); // TODO: make into a stream operator? +extern const char *vectPointStr(VectPoint); // TODO: make into a stream op? + +} // namespace Adaptation + +#endif /* SQUID_ADAPTATION_ELEMENTS_H */ diff --git a/src/adaptation/Makefile.am b/src/adaptation/Makefile.am new file mode 100644 index 0000000000..132c0f074c --- /dev/null +++ b/src/adaptation/Makefile.am @@ -0,0 +1,23 @@ +AM_CFLAGS = @SQUID_CFLAGS@ +AM_CXXFLAGS = @SQUID_CXXFLAGS@ + +INCLUDES = \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src + +noinst_LTLIBRARIES = libadaptation.la + +libadaptation_la_SOURCES = \ + Elements.cc \ + Elements.h \ + Service.cc \ + Service.h \ + Xaction.cc \ + Xaction.h + +check_PROGRAMS = testHeaders + +## test .h correctness +testHeaders: *.h + $(top_srcdir)/test-suite/testheaders.sh "$(CXXCOMPILE)" "." || exit 1 diff --git a/src/adaptation/Service.cc b/src/adaptation/Service.cc new file mode 100644 index 0000000000..f41ad14e48 --- /dev/null +++ b/src/adaptation/Service.cc @@ -0,0 +1,144 @@ +/* + * DEBUG: section XXX + */ + +#include "squid.h" +#include "ConfigParser.h" +#include "adaptation/Service.h" + +Adaptation::Service::Service(): + port(-1), method(methodNone), point(pointNone), bypass(false) +{} + +Adaptation::Service::~Service() +{} + +const char * +Adaptation::Service::methodStr() const +{ + return Adaptation::methodStr(method); +} + +const char * +Adaptation::Service::vectPointStr() const +{ + return Adaptation::vectPointStr(point); +} + +Adaptation::Method +Adaptation::Service::parseMethod(const char *str) const +{ + if (!strncasecmp(str, "REQMOD", 6)) + return Adaptation::methodReqmod; + + if (!strncasecmp(str, "RESPMOD", 7)) + return Adaptation::methodRespmod; + + return Adaptation::methodNone; +} + +Adaptation::VectPoint +Adaptation::Service::parseVectPoint(const char *service) const +{ + const char *t = service; + const char *q = strchr(t, '_'); + + if (q) + t = q + 1; + + if (!strcasecmp(t, "precache")) + return Adaptation::pointPreCache; + + if (!strcasecmp(t, "postcache")) + return Adaptation::pointPostCache; + + return Adaptation::pointNone; +} + +bool +Adaptation::Service::configure() +{ + char *service_type = NULL; + + ConfigParser::ParseString(&key); + ConfigParser::ParseString(&service_type); + ConfigParser::ParseBool(&bypass); + ConfigParser::ParseString(&uri); + + debugs(3, 5, HERE << cfg_filename << ':' << config_lineno << ": " << + key.buf() << " " << service_type << " " << bypass); + + method = parseMethod(service_type); + point = parseVectPoint(service_type); + + debugs(3, 5, HERE << cfg_filename << ':' << config_lineno << ": " << + "service is " << methodStr() << "_" << vectPointStr()); + + if (false && uri.cmp("icap://", 7) != 0) { // XXX: parametrize and enable + debugs(3, 0, HERE << cfg_filename << ':' << config_lineno << ": " << + "wrong service URI protocol: " << uri.buf()); + return false; + } + + const char *s = uri.buf() + 7; + + const char *e; + + bool have_port = false; + + if ((e = strchr(s, ':')) != NULL) { + have_port = true; + } else if ((e = strchr(s, '/')) != NULL) { + have_port = false; + } else { + return false; + } + + int len = e - s; + host.limitInit(s, len); + s = e; + + port = -1; + if (have_port) { + s++; + + if ((e = strchr(s, '/')) != NULL) { + char *t; + const unsigned long p = strtoul(s, &t, 0); + + if (p > 65535) // port value is too high + return false; + + port = static_cast(p); + + if (t != e) // extras after the port + return false; + + s = e; + + if (s[0] != '/') + return false; + } + } + + // if no port, the caller may use services or supply the default if neeeded + + s++; + e = strchr(s, '\0'); + len = e - s; + + if (len > 1024) { + debugs(3, 0, HERE << cfg_filename << ':' << config_lineno << ": " << + "long resource name (>1024), probably wrong"); + } + + resource.limitInit(s, len + 1); + + if ((bypass != 0) && (bypass != 1)) { + debugs(3, 0, HERE << cfg_filename << ':' << config_lineno << ": " << + "wrong bypass value; 0 or 1 expected: " << bypass); + return false; + } + + return true; +} diff --git a/src/adaptation/Service.h b/src/adaptation/Service.h new file mode 100644 index 0000000000..8cd77dc73c --- /dev/null +++ b/src/adaptation/Service.h @@ -0,0 +1,41 @@ +#ifndef SQUID_ADAPTATION__SERVICE_H +#define SQUID_ADAPTATION__SERVICE_H + +#include "SquidString.h" +#include "adaptation/Elements.h" + +namespace Adaptation { + +// manages adaptation service configuration in squid.conf +// specific adaptation mechanisms extend this class +class Service +{ +public: + Service(); + virtual ~Service(); + + const char *methodStr() const; + const char *vectPointStr() const; + +public: + String key; // service name in the configuration file + String uri; // service URI + + // service URI components + String host; + String resource; + int port; + + Method method; // what is being adapted (REQMOD vs RESPMOD) + VectPoint point; // where the adaptation happens (pre- or post-cache) + bool bypass; + +protected: + bool configure(); + Method parseMethod(const char *str) const; + VectPoint parseVectPoint(const char *service) const; +}; + +} // namespace Adaptation + +#endif /* SQUID_ADAPTATION__SERVICE_H */ -- 2.47.2