#include "squid.h"
#include "ICAPElements.h"
+#if 0 /* XXX: remove this file */
+
const char *ICAP::crlf = "\r\n";
}
+#endif /* if 0 -- remove this file */
#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 */
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),
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) {
}
}
- 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()
{
#define SQUID_ICAPSERVICEREP_H
#include "cbdata.h"
+#include "adaptation/Service.h"
#include "ICAPInitiator.h"
#include "ICAPElements.h"
*/
-class ICAPServiceRep : public RefCountable, public ICAPInitiator
+class ICAPServiceRep : public RefCountable, public Adaptation::Service,
+ public ICAPInitiator
{
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
//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();
--- /dev/null
+#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";
+}
+
+
--- /dev/null
+#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 */
--- /dev/null
+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
--- /dev/null
+/*
+ * 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<int>(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;
+}
--- /dev/null
+#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 */