]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
note ACL
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Sat, 25 May 2013 07:13:09 +0000 (10:13 +0300)
committerChristos Tsantilas <chtsanti@users.sourceforge.net>
Sat, 25 May 2013 07:13:09 +0000 (10:13 +0300)
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

src/AclRegs.cc
src/acl/Makefile.am
src/acl/Note.cc [new file with mode: 0644]
src/acl/Note.h [new file with mode: 0644]
src/acl/NoteData.cc [new file with mode: 0644]
src/acl/NoteData.h [new file with mode: 0644]
src/cf.data.pre

index fb112f18bae6638bbca82ce45753be2c92deb481..ff65937df219659284b5e728a9f761c7eb88b108 100644 (file)
@@ -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<const char *> ACLTag::RegistryEntry_(new ACLStringData, ACLTagStrategy::Instance(), "tag");
+
+ACL::Prototype ACLNote::RegistryProtoype(&ACLNote::RegistryEntry_, "note");
+ACLStrategised<HttpRequest *> ACLNote::RegistryEntry_(new ACLNoteData, ACLNoteStrategy::Instance(), "note");
index 3a1d122766049ac4c8fe37fc0d2d3bbe22b4b173..430b34e23cf5844766e006bb88945a292cc50118 100644 (file)
@@ -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 (file)
index 0000000..a5d8a85
--- /dev/null
@@ -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<MatchType> * &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 (file)
index 0000000..972cd65
--- /dev/null
@@ -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<HttpRequest *>
+{
+
+public:
+    virtual int match (ACLData<MatchType> * &, 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<HttpRequest *> RegistryEntry_;
+};
+
+#endif /* SQUID_ACLNOTE_H */
diff --git a/src/acl/NoteData.cc b/src/acl/NoteData.cc
new file mode 100644 (file)
index 0000000..3195971
--- /dev/null
@@ -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<NotePairs::Entry *>::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<HttpRequest *> *
+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 (file)
index 0000000..b620310
--- /dev/null
@@ -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<HttpRequest *>
+{
+public:
+    MEMPROXY_CLASS(ACLNoteData);
+
+    ACLNoteData();
+    virtual ~ACLNoteData();
+    virtual bool match(HttpRequest* request);
+    virtual wordlist *dump();
+    virtual void parse();
+    virtual bool empty() const;
+    virtual ACLData<HttpRequest *> *clone() const;
+
+private:
+    bool matchNotes(NotePairs *note);
+    String name;                   ///< Note name to check. It is always set
+    ACLData<char const *> *values; ///< if set, at least one value must match
+};
+
+MEMPROXY_CLASS_INLINE(ACLNoteData);
+
+#endif /* SQUID_ACLNOTEDATA_H */
index f5b794a90756d83fa77e736a03b69a9da2e59f2a..c4d7626849f3b8650ae920d7d53c3891a7645ff7 100644 (file)
@@ -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]