From: Christos Tsantilas Date: Sat, 25 May 2013 07:13:09 +0000 (+0300) Subject: note ACL X-Git-Tag: SQUID_3_4_0_1~110 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=39baccc;p=thirdparty%2Fsquid.git note ACL This patch investigates the new note ACL type, to match transaction annotation. Syntax: acl aclname note name [value ...] Without values, matches any annotation with a given name. With value(s), matches any annotation with a given name that also has one of the given values. Annotation sources include note and adaptation_meta directives as well as helper and eCAP responses. This is a Measurement Factory project --- diff --git a/src/AclRegs.cc b/src/AclRegs.cc index fb112f18ba..ff65937df2 100644 --- a/src/AclRegs.cc +++ b/src/AclRegs.cc @@ -37,6 +37,8 @@ #include "acl/MethodData.h" #include "acl/Method.h" #include "acl/MyPortName.h" +#include "acl/Note.h" +#include "acl/NoteData.h" #include "acl/PeerName.h" #include "acl/ProtocolData.h" #include "acl/Protocol.h" @@ -181,3 +183,6 @@ ACLMaxUserIP ACLMaxUserIP::RegistryEntry_("max_user_ip"); ACL::Prototype ACLTag::RegistryProtoype(&ACLTag::RegistryEntry_, "tag"); ACLStrategised ACLTag::RegistryEntry_(new ACLStringData, ACLTagStrategy::Instance(), "tag"); + +ACL::Prototype ACLNote::RegistryProtoype(&ACLNote::RegistryEntry_, "note"); +ACLStrategised ACLNote::RegistryEntry_(new ACLNoteData, ACLNoteStrategy::Instance(), "note"); diff --git a/src/acl/Makefile.am b/src/acl/Makefile.am index 3a1d122766..430b34e23c 100644 --- a/src/acl/Makefile.am +++ b/src/acl/Makefile.am @@ -73,6 +73,10 @@ libacls_la_SOURCES = \ Method.h \ MyPortName.cc \ MyPortName.h \ + Note.h \ + Note.cc \ + NoteData.h \ + NoteData.cc \ PeerName.cc \ PeerName.h \ Protocol.cc \ diff --git a/src/acl/Note.cc b/src/acl/Note.cc new file mode 100644 index 0000000000..a5d8a85a25 --- /dev/null +++ b/src/acl/Note.cc @@ -0,0 +1,24 @@ +#include "squid.h" +#include "acl/Note.h" +#include "acl/HttpHeaderData.h" +#include "acl/Checklist.h" +#include "HttpRequest.h" +#include "Notes.h" + +int +ACLNoteStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +{ + if (checklist->request != NULL) + return data->match(checklist->request); + + return 0; +} + +ACLNoteStrategy * +ACLNoteStrategy::Instance() +{ + return &Instance_; +} + +ACLNoteStrategy ACLNoteStrategy::Instance_; + diff --git a/src/acl/Note.h b/src/acl/Note.h new file mode 100644 index 0000000000..972cd65429 --- /dev/null +++ b/src/acl/Note.h @@ -0,0 +1,39 @@ +#ifndef SQUID_ACLNOTE_H +#define SQUID_ACLNOTE_H + +#include "acl/Strategy.h" +#include "acl/Strategised.h" + +class HttpRequest; + +/// \ingroup ACLAPI +class ACLNoteStrategy : public ACLStrategy +{ + +public: + virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual bool requiresRequest() const { return true; } + + static ACLNoteStrategy *Instance(); + /* Not implemented to prevent copies of the instance. */ + /* Not private to prevent brain dead g+++ warnings about + * private constructors with no friends */ + ACLNoteStrategy(ACLNoteStrategy const &); + +private: + static ACLNoteStrategy Instance_; + ACLNoteStrategy() { } + + ACLNoteStrategy& operator = (ACLNoteStrategy const &); +}; + +/// \ingroup ACLAPI +class ACLNote +{ + +private: + static ACL::Prototype RegistryProtoype; + static ACLStrategised RegistryEntry_; +}; + +#endif /* SQUID_ACLNOTE_H */ diff --git a/src/acl/NoteData.cc b/src/acl/NoteData.cc new file mode 100644 index 0000000000..3195971ee3 --- /dev/null +++ b/src/acl/NoteData.cc @@ -0,0 +1,87 @@ +#include "squid.h" +#include "acl/Acl.h" +#include "acl/Checklist.h" +#include "acl/NoteData.h" +#include "acl/StringData.h" +#include "cache_cf.h" +#include "ConfigParser.h" +#include "Debug.h" +#include "HttpRequest.h" +#include "Notes.h" +#include "wordlist.h" + +ACLNoteData::ACLNoteData() : values(new ACLStringData) +{} + +ACLNoteData::~ACLNoteData() +{ + delete values; +} + +bool +ACLNoteData::matchNotes(NotePairs *note) +{ + if (note == NULL) + return false; + + debugs(28, 3, "Checking " << name); + + if (values->empty()) + return (note->findFirst(name.termedBuf()) != NULL); + + for (Vector::iterator i = note->entries.begin(); i!= note->entries.end(); ++i) { + if ((*i)->name.cmp(name.termedBuf()) == 0) { + if (values->match((*i)->value.termedBuf())) + return true; + } + } + return false; +} + +bool +ACLNoteData::match(HttpRequest *request) +{ + if (request->notes != NULL && matchNotes(request->notes.getRaw())) + return true; +#if USE_ADAPTATION + const Adaptation::History::Pointer ah = request->adaptLogHistory(); + if (ah != NULL && ah->metaHeaders != NULL && matchNotes(ah->metaHeaders.getRaw())) + return true; +#endif + return false; +} + +wordlist * +ACLNoteData::dump() +{ + wordlist *W = NULL; + wordlistAdd(&W, name.termedBuf()); + wordlist * dumpR = values->dump(); + wordlistAddWl(&W, dumpR); + wordlistDestroy(&dumpR); + return W; +} + +void +ACLNoteData::parse() +{ + char* t = strtokFile(); + assert (t != NULL); + name = t; + values->parse(); +} + +bool +ACLNoteData::empty() const +{ + return name.undefined(); +} + +ACLData * +ACLNoteData::clone() const +{ + ACLNoteData * result = new ACLNoteData; + result->values = values->clone(); + result->name = name; + return result; +} diff --git a/src/acl/NoteData.h b/src/acl/NoteData.h new file mode 100644 index 0000000000..b62031072e --- /dev/null +++ b/src/acl/NoteData.h @@ -0,0 +1,33 @@ +#ifndef SQUID_ACLNOTEDATA_H +#define SQUID_ACLNOTEDATA_H + +#include "acl/Data.h" +#include "SquidString.h" +#include "MemPool.h" + +class HttpRequest; +class NotePairs; + +/// \ingroup ACLAPI +class ACLNoteData : public ACLData +{ +public: + MEMPROXY_CLASS(ACLNoteData); + + ACLNoteData(); + virtual ~ACLNoteData(); + virtual bool match(HttpRequest* request); + virtual wordlist *dump(); + virtual void parse(); + virtual bool empty() const; + virtual ACLData *clone() const; + +private: + bool matchNotes(NotePairs *note); + String name; ///< Note name to check. It is always set + ACLData *values; ///< if set, at least one value must match +}; + +MEMPROXY_CLASS_INLINE(ACLNoteData); + +#endif /* SQUID_ACLNOTEDATA_H */ diff --git a/src/cf.data.pre b/src/cf.data.pre index f5b794a907..c4d7626849 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -1052,6 +1052,15 @@ DOC_START # effect in rules that affect the reply data stream such as # http_reply_access. + acl aclname note name [value ...] + # match transaction annotation [fast] + # Without values, matches any annotation with a given name. + # With value(s), matches any annotation with a given name that + # also has one of the given values. + # Names and values are compared using a string equality test. + # Annotation sources include note and adaptation_meta directives + # as well as helper and eCAP responses. + IF USE_SSL acl aclname ssl_error errorname # match against SSL certificate validation error [fast]