On 05/21/2013 09:14 AM, Amos Jeffries wrote:
> On 17/05/2013 4:41 a.m., Tsantilas Christos wrote:
>> Hi all,
>
> Sorry for the slow reply..
>
>> I am attaching two patches here:
>>
>> 1) Merge AccessLogEntry 'helperNotes' and 'configNotes' members to
>> 'notes' member (trunk-merge-cfg-helper-notes-v2.patch)
>>
>> There is not any need to store notes added using Note cfg option and
>> notes added from helper to separated member. This patch merge them to
>> the same AccessLogEntry::note member.
>
> +1. Looks fine as-is.
I will apply this patch to trunk if there are no objections.
>
> PS. When you apply this please prefix the commit subject with "Cleanup: "
OK.
I am attaching a new version for the note ACL patch.
>
>> 2) note acl ( trunk-note-ACL-v5.patch )
>> 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.
>
> audit results for the second patch:
>
> * please do not cut-n-paste the (partially wrong) copyright from other
> files into new ones.
> NOTE: a default Squid copyright blurb is planned to be automatically
> pre-pended somehow. So for now only add one if you want one different
> from the main Squid COPYRIGHT file. To mark the copyright as yours for
> this file under the default, add your name in an AUTHOR: line instead
> for now.
I removed any copyright comment from these files.
>
> * please also add a "note_regex" ACL which takes regex patterns as the
> value (and/or key) details.
> NP: that will allow removing "Names and values are compared using a
> string equality test." statement in cf.data.pre
I prefer to avoid it for now. We spent a lot of time for this project,
so even the few hours required to add this feature looks long time.
It is easy for someone to add it if needed.
>
> in: src/acl/NoteData.h:
> * please be consistent about doxygen comments:
> + "///" for one-liners before the member definition
> + "///<" for one-liners after the member definition.
> + "/**" for multi-liners before the member definition
> + _no_ multi-liners after the member definition.
OK. I hope it is OK now.
>
> * you don't need to document each #include.
> We are only using that to document why the files like
> globals.h/enums.h/defines.h/structs.h which are scheduled for removal
> are still being included.
OK, this comments removed.
Regards,
Christos
>
> Amos
>
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
=== modified file 'src/AclRegs.cc'
--- src/AclRegs.cc 2013-01-27 17:35:07 +0000
+++ src/AclRegs.cc 2013-05-02 10:21:29 +0000
@@ -20,40 +20,42 @@
#include "acl/DomainData.h"
#if USE_AUTH
#include "acl/ExtUser.h"
#endif
#include "acl/FilledChecklist.h"
#include "acl/Gadgets.h"
#include "acl/HierCodeData.h"
#include "acl/HierCode.h"
#include "acl/HttpHeaderData.h"
#include "acl/HttpRepHeader.h"
#include "acl/HttpReqHeader.h"
#include "acl/HttpStatus.h"
#include "acl/IntRange.h"
#include "acl/Ip.h"
#include "acl/LocalIp.h"
#include "acl/LocalPort.h"
#include "acl/MaxConnection.h"
#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"
#include "acl/Random.h"
#include "acl/Referer.h"
#include "acl/RegexData.h"
#include "acl/ReplyHeaderStrategy.h"
#include "acl/ReplyMimeType.h"
#include "acl/RequestHeaderStrategy.h"
#include "acl/RequestMimeType.h"
#include "acl/SourceAsn.h"
#include "acl/SourceDomain.h"
#include "acl/SourceIp.h"
#if USE_SSL
#include "acl/SslErrorData.h"
#include "acl/SslError.h"
#include "acl/CertificateData.h"
#include "acl/Certificate.h"
#endif
#include "acl/Strategised.h"
@@ -164,20 +166,23 @@
#if USE_IDENT
ACL::Prototype ACLIdent::UserRegistryProtoype(&ACLIdent::UserRegistryEntry_, "ident");
ACLIdent ACLIdent::UserRegistryEntry_(new ACLUserData, "ident");
ACL::Prototype ACLIdent::RegexRegistryProtoype(&ACLIdent::RegexRegistryEntry_, "ident_regex" );
ACLIdent ACLIdent::RegexRegistryEntry_(new ACLRegexData, "ident_regex");
#endif
#if USE_AUTH
ACL::Prototype ACLProxyAuth::UserRegistryProtoype(&ACLProxyAuth::UserRegistryEntry_, "proxy_auth");
ACLProxyAuth ACLProxyAuth::UserRegistryEntry_(new ACLUserData, "proxy_auth");
ACL::Prototype ACLProxyAuth::RegexRegistryProtoype(&ACLProxyAuth::RegexRegistryEntry_, "proxy_auth_regex" );
ACLProxyAuth ACLProxyAuth::RegexRegistryEntry_(new ACLRegexData, "proxy_auth_regex");
ACL::Prototype ACLMaxUserIP::RegistryProtoype(&ACLMaxUserIP::RegistryEntry_, "max_user_ip");
ACLMaxUserIP ACLMaxUserIP::RegistryEntry_("max_user_ip");
#endif
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");
=== modified file 'src/acl/Makefile.am'
--- src/acl/Makefile.am 2012-11-13 18:19:17 +0000
+++ src/acl/Makefile.am 2013-01-25 20:18:48 +0000
@@ -56,40 +56,44 @@
HttpRepHeader.cc \
HttpRepHeader.h \
HttpReqHeader.cc \
HttpReqHeader.h \
HttpStatus.cc \
HttpStatus.h \
Ip.cc \
Ip.h \
LocalIp.cc \
LocalIp.h \
LocalPort.cc \
LocalPort.h \
MaxConnection.cc \
MaxConnection.h \
Method.cc \
MethodData.cc \
MethodData.h \
Method.h \
MyPortName.cc \
MyPortName.h \
+ Note.h \
+ Note.cc \
+ NoteData.h \
+ NoteData.cc \
PeerName.cc \
PeerName.h \
Protocol.cc \
ProtocolData.cc \
ProtocolData.h \
Protocol.h \
Random.cc \
Random.h \
Referer.cc \
Referer.h \
ReplyHeaderStrategy.h \
ReplyMimeType.cc \
ReplyMimeType.h \
RequestHeaderStrategy.h \
RequestMimeType.cc \
RequestMimeType.h \
SourceAsn.h \
SourceDomain.cc \
SourceDomain.h \
SourceIp.cc \
=== added file 'src/acl/Note.cc'
--- src/acl/Note.cc 1970-01-01 00:00:00 +0000
+++ src/acl/Note.cc 2013-05-22 17:02:25 +0000
@@ -0,0 +1,27 @@
+/*
+ */
+
+#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_;
+
=== added file 'src/acl/Note.h'
--- src/acl/Note.h 1970-01-01 00:00:00 +0000
+++ src/acl/Note.h 2013-05-22 17:02:09 +0000
@@ -0,0 +1,42 @@
+/*
+ */
+
+#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 */
=== added file 'src/acl/NoteData.cc'
--- src/acl/NoteData.cc 1970-01-01 00:00:00 +0000
+++ src/acl/NoteData.cc 2013-05-22 17:02:53 +0000
@@ -0,0 +1,91 @@
+/*
+ */
+
+#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;
+}
=== added file 'src/acl/NoteData.h'
--- src/acl/NoteData.h 1970-01-01 00:00:00 +0000
+++ src/acl/NoteData.h 2013-05-22 17:11:30 +0000
@@ -0,0 +1,36 @@
+/*
+ */
+
+#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 */
=== modified file 'src/cf.data.pre'
--- src/cf.data.pre 2013-04-23 14:22:51 +0000
+++ src/cf.data.pre 2013-05-02 09:57:12 +0000
@@ -1028,40 +1028,49 @@
acl aclname ca_cert attribute values...
# match against attributes a users issuing CA SSL certificate
# attribute is one of DN/C/O/CN/L/ST [fast]
acl aclname ext_user username ...
acl aclname ext_user_regex [-i] pattern ...
# string match on username returned by external acl helper [slow]
# use REQUIRED to accept any non-null user name.
acl aclname tag tagvalue ...
# string match on tag returned by external acl helper [slow]
acl aclname hier_code codename ...
# string match against squid hierarchy code(s); [fast]
# e.g., DIRECT, PARENT_HIT, NONE, etc.
#
# NOTE: This has no effect in http_access rules. It only has
# 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]
#
# For valid error names see in @DEFAULT_ERROR_DIR@/templates/error-details.txt
# template file.
#
# The following can be used as shortcuts for certificate properties:
# [ssl::]certHasExpired: the "not after" field is in the past
# [ssl::]certNotYetValid: the "not before" field is in the future
# [ssl::]certUntrusted: The certificate issuer is not to be trusted.
# [ssl::]certSelfSigned: The certificate is self signed.
# [ssl::]certDomainMismatch: The certificate CN domain does not
# match the name the name of the host we are connecting to.
#
# The ssl::certHasExpired, ssl::certNotYetValid, ssl::certDomainMismatch,
# ssl::certUntrusted, and ssl::certSelfSigned can also be used as
# predefined ACLs, just like the 'all' ACL.
#
# NOTE: The ssl_error ACL is only supported with sslproxy_cert_error,