]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Support for --long-acl-options
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Mon, 12 Jun 2017 14:48:28 +0000 (17:48 +0300)
committerChristos Tsantilas <chtsanti@users.sourceforge.net>
Mon, 12 Jun 2017 14:48:28 +0000 (17:48 +0300)
The old single-letter ACL "flags" code was refactored to support long option
names (with option-specific value types) without significant
per-ACL-object performance/RAM overheads and without creating a global
registry for all possible options. This refactoring (unexpectedly)
resulted in removal of a lot of unreliable static initialization code.

Refactoring fixed ACL flags parsing code that was dangerously misinterpreting
-i and +i flags in several contexts. For example, each of the three cases
below was misinterpreted as if three domains were configured (e.g., "+i",
"-z", and "example.com") on each line instead of one domain ("example.com"):

        acl parsedAsThreeDomains dstdomain +i -i .example.com
        acl parsedAsThreeDomains dstdomain -i +i .example.com
        acl parsedAsThreeDomains dstdomain +i -z .example.com

TODO: Finish ACL::clone() removal. Then consider removing any unused
ACLData::clone() and associated ACL/ACLData copying methods.

This is a Measurement Factory project.

116 files changed:
src/AclRegs.cc
src/ExternalACL.h
src/MessageDelayPools.h
src/acl/Acl.cc
src/acl/Acl.h
src/acl/AdaptationService.cc
src/acl/AdaptationService.h
src/acl/AllOf.h
src/acl/AnnotateClient.cc
src/acl/AnnotateClient.h
src/acl/AnnotateTransaction.cc
src/acl/AnnotateTransaction.h
src/acl/AnyOf.h
src/acl/Arp.h
src/acl/Asn.cc
src/acl/Asn.h
src/acl/AtStep.cc
src/acl/AtStep.h
src/acl/BoolOps.cc
src/acl/Browser.cc [deleted file]
src/acl/Browser.h [deleted file]
src/acl/Certificate.cc
src/acl/Certificate.h
src/acl/CharacterSetOption.h [new file with mode: 0644]
src/acl/ConnectionsEncrypted.h
src/acl/Data.h
src/acl/DestinationAsn.h
src/acl/DestinationDomain.cc
src/acl/DestinationDomain.h
src/acl/DestinationIp.cc
src/acl/DestinationIp.h
src/acl/Eui64.h
src/acl/ExtUser.cc
src/acl/ExtUser.h
src/acl/HasComponent.cc
src/acl/HasComponent.h
src/acl/HierCode.cc
src/acl/HierCode.h
src/acl/HttpRepHeader.cc
src/acl/HttpRepHeader.h
src/acl/HttpReqHeader.cc
src/acl/HttpReqHeader.h
src/acl/HttpStatus.h
src/acl/Ip.cc
src/acl/Ip.h
src/acl/LocalIp.h
src/acl/LocalPort.cc
src/acl/LocalPort.h
src/acl/Makefile.am
src/acl/MaxConnection.h
src/acl/Method.cc
src/acl/Method.h
src/acl/MyPortName.cc
src/acl/MyPortName.h
src/acl/Note.cc
src/acl/Note.h
src/acl/Options.cc [new file with mode: 0644]
src/acl/Options.h [new file with mode: 0644]
src/acl/PeerName.cc
src/acl/PeerName.h
src/acl/Protocol.cc
src/acl/Protocol.h
src/acl/Random.h
src/acl/Referer.cc [deleted file]
src/acl/Referer.h [deleted file]
src/acl/RegexData.cc
src/acl/RegexData.h
src/acl/ReplyHeaderStrategy.h
src/acl/ReplyMimeType.cc [deleted file]
src/acl/ReplyMimeType.h
src/acl/RequestHeaderStrategy.h
src/acl/RequestMimeType.cc [deleted file]
src/acl/RequestMimeType.h
src/acl/ServerCertificate.cc
src/acl/ServerCertificate.h
src/acl/ServerName.cc
src/acl/ServerName.h
src/acl/SourceAsn.h
src/acl/SourceDomain.cc
src/acl/SourceDomain.h
src/acl/SourceIp.h
src/acl/SquidError.cc
src/acl/SquidError.h
src/acl/SslError.cc
src/acl/SslError.h
src/acl/Strategised.h
src/acl/Strategy.h
src/acl/Tag.cc
src/acl/Tag.h
src/acl/Time.cc
src/acl/Time.h
src/acl/Url.cc
src/acl/Url.h
src/acl/UrlLogin.cc
src/acl/UrlLogin.h
src/acl/UrlPath.cc
src/acl/UrlPath.h
src/acl/UrlPort.cc
src/acl/UrlPort.h
src/acl/forward.h
src/auth/AclMaxUserIp.cc
src/auth/AclMaxUserIp.h
src/auth/AclProxyAuth.cc
src/auth/AclProxyAuth.h
src/base/CharacterSet.cc
src/base/CharacterSet.h
src/cache_cf.cc
src/external_acl.cc
src/ident/AclIdent.cc
src/ident/AclIdent.h
src/main.cc
src/snmp_core.cc
src/snmp_core.h
src/tests/stub_libauth_acls.cc
src/tests/testACLMaxUserIP.cc
src/tests/testACLMaxUserIP.h

index bbf2995c2b6cb17143c00160192bf6aad3b09ce4..48dd65c451dce1a598fc33ae32302b5a5a16c98c 100644 (file)
@@ -8,11 +8,6 @@
 
 #include "squid.h"
 
-/** This file exists to provide satic registration code to executables
-    that need ACLs. We cannot place this code in acl/lib*.la because it
-    does not get linked in, because nobody is using these classes by name.
-*/
-
 #if USE_ADAPTATION
 #include "acl/AdaptationService.h"
 #include "acl/AdaptationServiceData.h"
@@ -31,7 +26,6 @@
 #include "acl/AtStepData.h"
 #endif
 #include "acl/Asn.h"
-#include "acl/Browser.h"
 #include "acl/Checklist.h"
 #include "acl/ConnectionsEncrypted.h"
 #include "acl/Data.h"
@@ -43,6 +37,7 @@
 #include "acl/ExtUser.h"
 #endif
 #include "acl/FilledChecklist.h"
+#include "acl/forward.h"
 #include "acl/Gadgets.h"
 #include "acl/HasComponent.h"
 #include "acl/HasComponentData.h"
@@ -66,7 +61,6 @@
 #include "acl/Protocol.h"
 #include "acl/ProtocolData.h"
 #include "acl/Random.h"
-#include "acl/Referer.h"
 #include "acl/RegexData.h"
 #include "acl/ReplyHeaderStrategy.h"
 #include "acl/ReplyMimeType.h"
 #include "auth/AclProxyAuth.h"
 #endif
 #include "base/RegexPattern.h"
+#include "ExternalACL.h"
 #if USE_IDENT
 #include "ident/AclIdent.h"
 #endif
-
-ACL::Prototype ACLBrowser::RegistryProtoype(&ACLBrowser::RegistryEntry_, "browser");
-ACLStrategised<char const *> ACLBrowser::RegistryEntry_(new ACLRegexData, ACLRequestHeaderStrategy<Http::HdrType::USER_AGENT>::Instance(), "browser");
-ACLFlag  DestinationDomainFlags[] = {ACL_F_NO_LOOKUP, ACL_F_END};
-ACL::Prototype ACLDestinationDomain::LiteralRegistryProtoype(&ACLDestinationDomain::LiteralRegistryEntry_, "dstdomain");
-ACLStrategised<char const *> ACLDestinationDomain::LiteralRegistryEntry_(new ACLDomainData, ACLDestinationDomainStrategy::Instance(), "dstdomain", DestinationDomainFlags);
-ACL::Prototype ACLDestinationDomain::RegexRegistryProtoype(&ACLDestinationDomain::RegexRegistryEntry_, "dstdom_regex");
-ACLFlag  DestinationDomainRegexFlags[] = {ACL_F_NO_LOOKUP, ACL_F_REGEX_CASE, ACL_F_END};
-ACLStrategised<char const *> ACLDestinationDomain::RegexRegistryEntry_(new ACLRegexData,ACLDestinationDomainStrategy::Instance() ,"dstdom_regex", DestinationDomainRegexFlags);
-ACL::Prototype ACLDestinationIP::RegistryProtoype(&ACLDestinationIP::RegistryEntry_, "dst");
-ACLDestinationIP ACLDestinationIP::RegistryEntry_;
-#if USE_AUTH
-ACL::Prototype ACLExtUser::UserRegistryProtoype(&ACLExtUser::UserRegistryEntry_, "ext_user");
-ACLExtUser ACLExtUser::UserRegistryEntry_(new ACLUserData, "ext_user");
-ACL::Prototype ACLExtUser::RegexRegistryProtoype(&ACLExtUser::RegexRegistryEntry_, "ext_user_regex" );
-ACLExtUser ACLExtUser::RegexRegistryEntry_(new ACLRegexData, "ext_user_regex");
+#if SQUID_SNMP
+#include "snmp_core.h"
 #endif
-ACL::Prototype ACLHierCode::RegistryProtoype(&ACLHierCode::RegistryEntry_, "hier_code");
-ACLStrategised<hier_code> ACLHierCode::RegistryEntry_(new ACLHierCodeData, ACLHierCodeStrategy::Instance(), "hier_code");
-ACL::Prototype ACLHTTPRepHeader::RegistryProtoype(&ACLHTTPRepHeader::RegistryEntry_, "rep_header");
-ACLStrategised<HttpHeader*> ACLHTTPRepHeader::RegistryEntry_(new ACLHTTPHeaderData, ACLHTTPRepHeaderStrategy::Instance(), "rep_header");
-ACL::Prototype ACLHTTPReqHeader::RegistryProtoype(&ACLHTTPReqHeader::RegistryEntry_, "req_header");
-ACLStrategised<HttpHeader*> ACLHTTPReqHeader::RegistryEntry_(new ACLHTTPHeaderData, ACLHTTPReqHeaderStrategy::Instance(), "req_header");
-ACL::Prototype ACLHTTPStatus::RegistryProtoype(&ACLHTTPStatus::RegistryEntry_, "http_status");
-ACLHTTPStatus ACLHTTPStatus::RegistryEntry_("http_status");
-ACL::Prototype ACLMaxConnection::RegistryProtoype(&ACLMaxConnection::RegistryEntry_, "maxconn");
-ACLMaxConnection ACLMaxConnection::RegistryEntry_("maxconn");
-ACL::Prototype ACLMethod::RegistryProtoype(&ACLMethod::RegistryEntry_, "method");
-ACLStrategised<HttpRequestMethod> ACLMethod::RegistryEntry_(new ACLMethodData, ACLMethodStrategy::Instance(), "method");
-ACL::Prototype ACLLocalIP::RegistryProtoype(&ACLLocalIP::RegistryEntry_, "localip");
-ACLLocalIP ACLLocalIP::RegistryEntry_;
-ACL::Prototype ACLLocalPort::RegistryProtoype(&ACLLocalPort::RegistryEntry_, "localport");
-ACLStrategised<int> ACLLocalPort::RegistryEntry_(new ACLIntRange, ACLLocalPortStrategy::Instance(), "localport");
-ACL::Prototype ACLMyPortName::RegistryProtoype(&ACLMyPortName::RegistryEntry_, "myportname");
-ACLStrategised<const char *> ACLMyPortName::RegistryEntry_(new ACLStringData, ACLMyPortNameStrategy::Instance(), "myportname");
-ACL::Prototype ACLPeerName::RegistryProtoype(&ACLPeerName::RegistryEntry_, "peername");
-ACLStrategised<const char *> ACLPeerName::RegistryEntry_(new ACLStringData, ACLPeerNameStrategy::Instance(), "peername");
-ACL::Prototype ACLPeerName::RegexRegistryProtoype(&ACLPeerName::RegexRegistryEntry_, "peername_regex");
-ACLStrategised<char const *> ACLPeerName::RegexRegistryEntry_(new ACLRegexData, ACLPeerNameStrategy::Instance(), "peername_regex");
-ACL::Prototype ACLProtocol::RegistryProtoype(&ACLProtocol::RegistryEntry_, "proto");
-ACLStrategised<AnyP::ProtocolType> ACLProtocol::RegistryEntry_(new ACLProtocolData, ACLProtocolStrategy::Instance(), "proto");
-ACL::Prototype ACLRandom::RegistryProtoype(&ACLRandom::RegistryEntry_, "random");
-ACLRandom ACLRandom::RegistryEntry_("random");
-ACL::Prototype ACLReferer::RegistryProtoype(&ACLReferer::RegistryEntry_, "referer_regex");
-ACLStrategised<char const *> ACLReferer::RegistryEntry_(new ACLRegexData, ACLRequestHeaderStrategy<Http::HdrType::REFERER>::Instance(), "referer_regex");
-ACL::Prototype ACLReplyMIMEType::RegistryProtoype(&ACLReplyMIMEType::RegistryEntry_, "rep_mime_type");
-ACLStrategised<char const *> ACLReplyMIMEType::RegistryEntry_(new ACLRegexData, ACLReplyHeaderStrategy<Http::HdrType::CONTENT_TYPE>::Instance(), "rep_mime_type");
-ACL::Prototype ACLRequestMIMEType::RegistryProtoype(&ACLRequestMIMEType::RegistryEntry_, "req_mime_type");
-ACLStrategised<char const *> ACLRequestMIMEType::RegistryEntry_(new ACLRegexData, ACLRequestHeaderStrategy<Http::HdrType::CONTENT_TYPE>::Instance(), "req_mime_type");
-ACL::Prototype ACLSourceDomain::LiteralRegistryProtoype(&ACLSourceDomain::LiteralRegistryEntry_, "srcdomain");
-ACLStrategised<char const *> ACLSourceDomain::LiteralRegistryEntry_(new ACLDomainData, ACLSourceDomainStrategy::Instance(), "srcdomain");
-ACL::Prototype ACLSourceDomain::RegexRegistryProtoype(&ACLSourceDomain::RegexRegistryEntry_, "srcdom_regex");
-ACLStrategised<char const *> ACLSourceDomain::RegexRegistryEntry_(new ACLRegexData,ACLSourceDomainStrategy::Instance() ,"srcdom_regex");
-ACL::Prototype ACLSourceIP::RegistryProtoype(&ACLSourceIP::RegistryEntry_, "src");
-ACLSourceIP ACLSourceIP::RegistryEntry_;
-ACL::Prototype ACLTime::RegistryProtoype(&ACLTime::RegistryEntry_, "time");
-ACLStrategised<time_t> ACLTime::RegistryEntry_(new ACLTimeData, ACLTimeStrategy::Instance(), "time");
-ACL::Prototype ACLUrl::RegistryProtoype(&ACLUrl::RegistryEntry_, "url_regex");
-ACLStrategised<char const *> ACLUrl::RegistryEntry_(new ACLRegexData, ACLUrlStrategy::Instance(), "url_regex");
-ACL::Prototype ACLUrlLogin::RegistryProtoype(&ACLUrlLogin::RegistryEntry_, "urllogin");
-ACLStrategised<char const *> ACLUrlLogin::RegistryEntry_(new ACLRegexData, ACLUrlLoginStrategy::Instance(), "urllogin");
-ACL::Prototype ACLUrlPath::LegacyRegistryProtoype(&ACLUrlPath::RegistryEntry_, "pattern");
-ACL::Prototype ACLUrlPath::RegistryProtoype(&ACLUrlPath::RegistryEntry_, "urlpath_regex");
-ACLStrategised<char const *> ACLUrlPath::RegistryEntry_(new ACLRegexData, ACLUrlPathStrategy::Instance(), "urlpath_regex");
-ACL::Prototype ACLUrlPort::RegistryProtoype(&ACLUrlPort::RegistryEntry_, "port");
-ACLStrategised<int> ACLUrlPort::RegistryEntry_(new ACLIntRange, ACLUrlPortStrategy::Instance(), "port");
-
-#if USE_OPENSSL
-ACL::Prototype ACLSslError::RegistryProtoype(&ACLSslError::RegistryEntry_, "ssl_error");
-ACLStrategised<const Security::CertErrors *> ACLSslError::RegistryEntry_(new ACLSslErrorData, ACLSslErrorStrategy::Instance(), "ssl_error");
-ACL::Prototype ACLCertificate::UserRegistryProtoype(&ACLCertificate::UserRegistryEntry_, "user_cert");
-ACLStrategised<X509 *> ACLCertificate::UserRegistryEntry_(new ACLCertificateData (Ssl::GetX509UserAttribute, "*"), ACLCertificateStrategy::Instance(), "user_cert");
-ACL::Prototype ACLCertificate::CARegistryProtoype(&ACLCertificate::CARegistryEntry_, "ca_cert");
-ACLStrategised<X509 *> ACLCertificate::CARegistryEntry_(new ACLCertificateData (Ssl::GetX509CAAttribute, "*"), ACLCertificateStrategy::Instance(), "ca_cert");
-ACL::Prototype ACLServerCertificate::X509FingerprintRegistryProtoype(&ACLServerCertificate::X509FingerprintRegistryEntry_, "server_cert_fingerprint");
-ACLStrategised<X509 *> ACLServerCertificate::X509FingerprintRegistryEntry_(new ACLCertificateData(Ssl::GetX509Fingerprint, "-sha1", true), ACLServerCertificateStrategy::Instance(), "server_cert_fingerprint");
 
-ACL::Prototype ACLAtStep::RegistryProtoype(&ACLAtStep::RegistryEntry_, "at_step");
-ACLStrategised<Ssl::BumpStep> ACLAtStep::RegistryEntry_(new ACLAtStepData, ACLAtStepStrategy::Instance(), "at_step");
+// Not in src/acl/ because some of the ACLs it registers are not in src/acl/.
+void
+Acl::Init()
+{
+    /* the registration order does not matter */
+
+    // The explicit return type (ACL*) for lambdas is needed because the type
+    // of the return expression inside lambda is not ACL* but AclFoo* while
+    // Acl::Maker is defined to return ACL*.
+
+    RegisterMaker("all-of", [](TypeName)->ACL* { return new Acl::AllOf; }); // XXX: Add name parameter to ctor
+    RegisterMaker("any-of", [](TypeName)->ACL* { return new Acl::AnyOf; }); // XXX: Add name parameter to ctor
+    RegisterMaker("random", [](TypeName name)->ACL* { return new ACLRandom(name); });
+    RegisterMaker("time", [](TypeName name)->ACL* { return new ACLStrategised<time_t>(new ACLTimeData, new ACLTimeStrategy, name); });
+    RegisterMaker("src_as", [](TypeName name)->ACL* { return new ACLStrategised<Ip::Address>(new ACLASN, new ACLSourceASNStrategy, name); });
+    RegisterMaker("dst_as", [](TypeName name)->ACL* { return new ACLStrategised<Ip::Address>(new ACLASN, new ACLDestinationASNStrategy, name); });
+    RegisterMaker("browser", [](TypeName name)->ACL* { return new ACLStrategised<char const *>(new ACLRegexData, new ACLRequestHeaderStrategy<Http::HdrType::USER_AGENT>, name); });
+    RegisterMaker("dstdomain", [](TypeName name)->ACL* { return new ACLStrategised<char const *>(new ACLDomainData, new ACLDestinationDomainStrategy, name); });
+    RegisterMaker("dstdom_regex", [](TypeName name)->ACL* { return new ACLStrategised<char const *>(new ACLRegexData, new ACLDestinationDomainStrategy , name); });
+    RegisterMaker("dst", [](TypeName)->ACL* { return new ACLDestinationIP; }); // XXX: Add name parameter to ctor
+    RegisterMaker("hier_code", [](TypeName name)->ACL* { return new ACLStrategised<hier_code>(new ACLHierCodeData, new ACLHierCodeStrategy, name); });
+    RegisterMaker("rep_header", [](TypeName name)->ACL* { return new ACLStrategised<HttpHeader*>(new ACLHTTPHeaderData, new ACLHTTPRepHeaderStrategy, name); });
+    RegisterMaker("req_header", [](TypeName name)->ACL* { return new ACLStrategised<HttpHeader*>(new ACLHTTPHeaderData, new ACLHTTPReqHeaderStrategy, name); });
+    RegisterMaker("http_status", [](TypeName name)->ACL* { return new ACLHTTPStatus(name); });
+    RegisterMaker("maxconn", [](TypeName name)->ACL* { return new ACLMaxConnection(name); });
+    RegisterMaker("method", [](TypeName name)->ACL* { return new ACLStrategised<HttpRequestMethod>(new ACLMethodData, new ACLMethodStrategy, name); });
+    RegisterMaker("localip", [](TypeName)->ACL* { return new ACLLocalIP; }); // XXX: Add name parameter to ctor
+    RegisterMaker("localport", [](TypeName name)->ACL* { return new ACLStrategised<int>(new ACLIntRange, new ACLLocalPortStrategy, name); });
+    RegisterMaker("myportname", [](TypeName name)->ACL* { return new ACLStrategised<const char *>(new ACLStringData, new ACLMyPortNameStrategy, name); });
+    RegisterMaker("peername", [](TypeName name)->ACL* { return new ACLStrategised<const char *>(new ACLStringData, new ACLPeerNameStrategy, name); });
+    RegisterMaker("peername_regex", [](TypeName name)->ACL* { return new ACLStrategised<char const *>(new ACLRegexData, new ACLPeerNameStrategy, name); });
+    RegisterMaker("proto", [](TypeName name)->ACL* { return new ACLStrategised<AnyP::ProtocolType>(new ACLProtocolData, new ACLProtocolStrategy, name); });
+    RegisterMaker("referer_regex", [](TypeName name)->ACL* { return new ACLStrategised<char const *>(new ACLRegexData, new ACLRequestHeaderStrategy<Http::HdrType::REFERER>, name); });
+    RegisterMaker("rep_mime_type", [](TypeName name)->ACL* { return new ACLStrategised<char const *>(new ACLRegexData, new ACLReplyHeaderStrategy<Http::HdrType::CONTENT_TYPE>, name); });
+    RegisterMaker("req_mime_type", [](TypeName name)->ACL* { return new ACLStrategised<char const *>(new ACLRegexData, new ACLRequestHeaderStrategy<Http::HdrType::CONTENT_TYPE>, name); });
+    RegisterMaker("srcdomain", [](TypeName name)->ACL* { return new ACLStrategised<char const *>(new ACLDomainData, new ACLSourceDomainStrategy, name); });
+    RegisterMaker("srcdom_regex", [](TypeName name)->ACL* { return new ACLStrategised<char const *>(new ACLRegexData, new ACLSourceDomainStrategy, name); });
+    RegisterMaker("src", [](TypeName)->ACL* { return new ACLSourceIP; }); // XXX: Add name parameter to ctor
+    RegisterMaker("url_regex", [](TypeName name)->ACL* { return new ACLStrategised<char const *>(new ACLRegexData, new ACLUrlStrategy, name); });
+    RegisterMaker("urllogin", [](TypeName name)->ACL* { return new ACLStrategised<char const *>(new ACLRegexData, new ACLUrlLoginStrategy, name); });
+    RegisterMaker("urlpath_regex", [](TypeName name)->ACL* { return new ACLStrategised<char const *>(new ACLRegexData, new ACLUrlPathStrategy, name); });
+    RegisterMaker("port", [](TypeName name)->ACL* { return new ACLStrategised<int>(new ACLIntRange, new ACLUrlPortStrategy, name); });
+    RegisterMaker("external", [](TypeName name)->ACL* { return new ACLExternal(name); });
+    RegisterMaker("squid_error", [](TypeName name)->ACL* { return new ACLStrategised<err_type>(new ACLSquidErrorData, new ACLSquidErrorStrategy, name); });
+    RegisterMaker("connections_encrypted", [](TypeName name)->ACL* { return new Acl::ConnectionsEncrypted(name); });
+    RegisterMaker("tag", [](TypeName name)->ACL* { return new ACLStrategised<const char *>(new ACLStringData, new ACLTagStrategy, name); });
+    RegisterMaker("note", [](TypeName name)->ACL* { return new ACLStrategised<NotePairs::Entry*>(new ACLNoteData, new ACLNoteStrategy, name); });
+    RegisterMaker("annotate_client", [](TypeName name)->ACL* { return new ACLStrategised<NotePairs::Entry*>(new ACLAnnotationData, new ACLAnnotateClientStrategy, name); });
+    RegisterMaker("annotate_transaction", [](TypeName name)->ACL* { return new ACLStrategised<NotePairs::Entry*>(new ACLAnnotationData, new ACLAnnotateTransactionStrategy, name); });
+    RegisterMaker("has", [](TypeName name)->ACL* {return new ACLStrategised<ACLChecklist *>(new ACLHasComponentData, new ACLHasComponentStrategy, name); });
 
-ACL::Prototype ACLServerName::LiteralRegistryProtoype(&ACLServerName::LiteralRegistryEntry_, "ssl::server_name");
-ACLStrategised<char const *> ACLServerName::LiteralRegistryEntry_(new ACLServerNameData, ACLServerNameStrategy::Instance(), "ssl::server_name");
-ACL::Prototype ACLServerName::RegexRegistryProtoype(&ACLServerName::RegexRegistryEntry_, "ssl::server_name_regex");
-ACLFlag  ServerNameRegexFlags[] = {ACL_F_REGEX_CASE, ACL_F_END};
-ACLStrategised<char const *> ACLServerName::RegexRegistryEntry_(new ACLRegexData, ACLServerNameStrategy::Instance(), "ssl::server_name_regex", ServerNameRegexFlags);
+#if USE_OPENSSL
+    RegisterMaker("ssl_error", [](TypeName name)->ACL* { return new ACLStrategised<const Security::CertErrors *>(new ACLSslErrorData, new ACLSslErrorStrategy, name); });
+    RegisterMaker("user_cert", [](TypeName name)->ACL* { return new ACLStrategised<X509*>(new ACLCertificateData(Ssl::GetX509UserAttribute, "*"), new ACLCertificateStrategy, name); });
+    RegisterMaker("ca_cert", [](TypeName name)->ACL* { return new ACLStrategised<X509*>(new ACLCertificateData(Ssl::GetX509CAAttribute, "*"), new ACLCertificateStrategy, name); });
+    RegisterMaker("server_cert_fingerprint", [](TypeName name)->ACL* { return new ACLStrategised<X509*>(new ACLCertificateData(Ssl::GetX509Fingerprint, "-sha1", true), new ACLServerCertificateStrategy, name); });
+    RegisterMaker("at_step", [](TypeName name)->ACL* { return new ACLStrategised<Ssl::BumpStep>(new ACLAtStepData, new ACLAtStepStrategy, name); });
+    RegisterMaker("ssl::server_name", [](TypeName name)->ACL* { return new ACLStrategised<char const *>(new ACLServerNameData, new ACLServerNameStrategy, name); });
+    RegisterMaker("ssl::server_name_regex", [](TypeName name)->ACL* { return new ACLStrategised<char const *>(new ACLRegexData, new ACLServerNameStrategy, name); });
 #endif
 
 #if USE_SQUID_EUI
-ACL::Prototype ACLARP::RegistryProtoype(&ACLARP::RegistryEntry_, "arp");
-ACLARP ACLARP::RegistryEntry_("arp");
-ACL::Prototype ACLEui64::RegistryProtoype(&ACLEui64::RegistryEntry_, "eui64");
-ACLEui64 ACLEui64::RegistryEntry_("eui64");
+    RegisterMaker("arp", [](TypeName name)->ACL* { return new ACLARP(name); });
+    RegisterMaker("eui64", [](TypeName name)->ACL* { return new ACLEui64(name); });
 #endif
 
 #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");
+    RegisterMaker("ident", [](TypeName name)->ACL* { return new ACLIdent(new ACLUserData, name); });
+    RegisterMaker("ident_regex", [](TypeName name)->ACL* { return new ACLIdent(new ACLRegexData, name); });
 #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");
+    RegisterMaker("ext_user", [](TypeName name)->ACL* { return new ACLExtUser(new ACLUserData, name); });
+    RegisterMaker("ext_user_regex", [](TypeName name)->ACL* { return new ACLExtUser(new ACLRegexData, name); });
+    RegisterMaker("proxy_auth", [](TypeName name)->ACL* { return new ACLProxyAuth(new ACLUserData, name); });
+    RegisterMaker("proxy_auth_regex", [](TypeName name)->ACL* { return new ACLProxyAuth(new ACLRegexData, name); });
+    RegisterMaker("max_user_ip", [](TypeName name)->ACL* { return new ACLMaxUserIP(name); });
 #endif
 
-ACL::Prototype ACLTag::RegistryProtoype(&ACLTag::RegistryEntry_, "tag");
-ACLStrategised<const char *> ACLTag::RegistryEntry_(new ACLStringData, ACLTagStrategy::Instance(), "tag");
-
-ACL::Prototype Acl::AnyOf::RegistryProtoype(&Acl::AnyOf::RegistryEntry_, "any-of");
-Acl::AnyOf Acl::AnyOf::RegistryEntry_;
-
-ACL::Prototype Acl::AllOf::RegistryProtoype(&Acl::AllOf::RegistryEntry_, "all-of");
-Acl::AllOf Acl::AllOf::RegistryEntry_;
-
-ACL::Prototype ACLNote::RegistryProtoype(&ACLNote::RegistryEntry_, "note");
-ACLStrategised<NotePairs::Entry *> ACLNote::RegistryEntry_(new ACLNoteData, ACLNoteStrategy::Instance(), "note");
-
-ACL::Prototype ACLAnnotateClient::RegistryProtoype(&ACLAnnotateClient::RegistryEntry_, "annotate_client");
-ACLStrategised<NotePairs::Entry *> ACLAnnotateClient::RegistryEntry_(new ACLAnnotationData, ACLAnnotateClientStrategy::Instance(), "annotate_client");
-
-ACL::Prototype ACLAnnotateTransaction::RegistryProtoype(&ACLAnnotateTransaction::RegistryEntry_, "annotate_transaction");
-ACLStrategised<NotePairs::Entry *> ACLAnnotateTransaction::RegistryEntry_(new ACLAnnotationData, ACLAnnotateTransactionStrategy::Instance(), "annotate_transaction");
-
 #if USE_ADAPTATION
-ACL::Prototype ACLAdaptationService::RegistryProtoype(&ACLAdaptationService::RegistryEntry_, "adaptation_service");
-ACLStrategised<const char *> ACLAdaptationService::RegistryEntry_(new ACLAdaptationServiceData, ACLAdaptationServiceStrategy::Instance(), "adaptation_service");
+    RegisterMaker("adaptation_service", [](TypeName name)->ACL* { return new ACLStrategised<const char *>(new ACLAdaptationServiceData, new ACLAdaptationServiceStrategy, name); });
 #endif
 
-ACL::Prototype ACLSquidError::RegistryProtoype(&ACLSquidError::RegistryEntry_, "squid_error");
-ACLStrategised<err_type> ACLSquidError::RegistryEntry_(new ACLSquidErrorData, ACLSquidErrorStrategy::Instance(), "squid_error");
-
-ACL::Prototype Acl::ConnectionsEncrypted::RegistryProtoype(&Acl::ConnectionsEncrypted::RegistryEntry_, "connections_encrypted");
-Acl::ConnectionsEncrypted Acl::ConnectionsEncrypted::RegistryEntry_("connections_encrypted");
-
-ACL::Prototype ACLHasComponent::RegistryProtoype(&ACLHasComponent::RegistryEntry_, "has");
-ACLStrategised<ACLChecklist *> ACLHasComponent::RegistryEntry_(new ACLHasComponentData, ACLHasComponentStrategy::Instance(), "has");
+#if SQUID_SNMP
+    RegisterMaker("snmp_community", [](TypeName name)->ACL* { return new ACLStrategised<const char *>(new ACLStringData, new ACLSNMPCommunityStrategy, name); });
+#endif
+}
 
index a22d8ac993635e94557b28878bd9cf041afed5fb..9e7e2f606adfc5424fae4b0a27c1736acdfa7b5c 100644 (file)
@@ -62,8 +62,6 @@ public:
     virtual bool empty () const;
 
 protected:
-    static Prototype RegistryProtoype;
-    static ACLExternal RegistryEntry_;
     external_acl_data *data;
     char const *class_;
 };
index 73b499d02388ffde45a6b6b0c75e8e8e893ba00f..bddd15e665d979ddff95bd94730dc94c835b6bb0 100644 (file)
@@ -15,6 +15,7 @@
 #include "base/RefCount.h"
 #include "DelayBucket.h"
 #include "DelayPools.h"
+#include "sbuf/SBuf.h"
 
 class MessageBucket;
 typedef RefCount<MessageBucket> MessageBucketPointer;
index 78111e352b27ecca0f190d38ac64fc312f018c0f..8db5020353a383773892470b7b3946f2758fc545 100644 (file)
 #include "acl/Acl.h"
 #include "acl/Checklist.h"
 #include "acl/Gadgets.h"
+#include "acl/Options.h"
 #include "anyp/PortCfg.h"
 #include "cache_cf.h"
 #include "ConfigParser.h"
 #include "Debug.h"
-#include "dlink.h"
 #include "fatal.h"
 #include "globals.h"
 #include "profiler/Profiler.h"
+#include "sbuf/List.h"
+#include "sbuf/Stream.h"
 #include "SquidConfig.h"
 
-#include <vector>
-
-#define abortFlags(CONTENT) \
-   do { \
-    debugs(28, 0, CONTENT); \
-    self_destruct(); \
-   } while (0)
-
-const ACLFlag ACLFlags::NoFlags[1] = {ACL_F_END};
+#include <algorithm>
+#include <map>
 
 const char *AclMatchedName = NULL;
 
-ACLFlags::FlagsTokenizer::FlagsTokenizer()
-    : tokPos(nullptr), Parameter(nullptr) {}
+namespace Acl {
 
-ACLFlag
-ACLFlags::FlagsTokenizer::nextFlag()
-{
-    if (needNextToken()) {
-        if (!nextToken())
-            return 0;
-    } else
-        ++tokPos;
-    return *tokPos;
-}
-
-bool
-ACLFlags::FlagsTokenizer::hasParameter() const
-{
-    return tokPos && tokPos[0] && !tokPos[1] && Parameter;
-}
+/// ACL type name comparison functor
+class TypeNameCmp {
+public:
+    bool operator()(TypeName a, TypeName b) const { return strcmp(a, b) < 0; }
+};
 
-SBuf
-ACLFlags::FlagsTokenizer::getParameter() const
-{
-    return hasParameter() ? SBuf(Parameter) : SBuf();
-}
+/// ACL makers indexed by ACL type name
+typedef std::map<TypeName, Maker, TypeNameCmp> Makers;
 
-bool
-ACLFlags::FlagsTokenizer::needNextToken() const
+/// registered ACL Makers
+static Makers &
+TheMakers()
 {
-    return !tokPos || !tokPos[0] || !tokPos[1];
+    static Makers Registry;
+    return Registry;
 }
 
-bool
-ACLFlags::FlagsTokenizer::nextToken()
+/// creates an ACL object of the named (and already registered) ACL child type
+static
+ACL *
+Make(TypeName typeName)
 {
-    char *t = ConfigParser::PeekAtToken();
-    if (t == NULL || t[0] != '-' || !t[1])
-        return false;
-    if (strchr(t, '=')) {
-        if(!ConfigParser::NextKvPair(tokPos, Parameter))
-            abortFlags("Invalid formatting for flag '" << t << "'");
-        assert(tokPos[0] == '-');
-        tokPos++;
-    } else {
-        (void)ConfigParser::NextToken();
-        if (!strcmp(t, "--"))
-            return false;
-        tokPos = t + 1;
+    const auto pos = TheMakers().find(typeName);
+    if (pos == TheMakers().end()) {
+        debugs(28, DBG_CRITICAL, "FATAL: Invalid ACL type '" << typeName << "'");
+        self_destruct();
+        assert(false); // not reached
     }
-    return true;
-}
-
-ACLFlags::~ACLFlags()
-{
-    delete delimiters_;
-}
-
-ACLFlags::Status
-ACLFlags::flagStatus(const ACLFlag f) const
-{
-    if (f == ACL_F_REGEX_CASE)
-        return noParameter;
-    if (f == ACL_F_SUBSTRING)
-        return parameterOptional;
-    if (supported_.find(f) != std::string::npos)
-        return noParameter;
-    return notSupported;
-}
-
-bool
-ACLFlags::parameterSupported(const ACLFlag f, const SBuf &val) const
-{
-    if (f == ACL_F_SUBSTRING)
-        return val.findFirstOf(CharacterSet::ALPHA + CharacterSet::DIGIT) == SBuf::npos;
-    return true;
-}
 
-void
-ACLFlags::makeSet(const ACLFlag f, const SBuf &param)
-{
-    flags_ |= flagToInt(f);
-    if (!param.isEmpty())
-        flagParameters_[f].append(param);
+    ACL *result = (pos->second)(pos->first);
+    debugs(28, 4, typeName << '=' << result);
+    assert(result);
+    return result;
 }
 
-void
-ACLFlags::makeUnSet(const ACLFlag f)
-{
-    flags_ &= ~flagToInt(f);
-    flagParameters_[f].clear();
-}
+} // namespace Acl
 
 void
-ACLFlags::parseFlags()
-{
-    FlagsTokenizer tokenizer;
-    ACLFlag flag('\0');
-    while ((flag = tokenizer.nextFlag())) {
-        switch (flagStatus(flag))
-        {
-        case notSupported:
-            abortFlags("Flag '" << flag << "' not supported");
-            break;
-        case noParameter:
-            makeSet(flag);
-            break;
-        case parameterRequired:
-            if (!tokenizer.hasParameter()) {
-                abortFlags("Flag '" << flag << "' must have a parameter");
-                break;
-            }
-        case parameterOptional:
-            SBuf param;
-            if (tokenizer.hasParameter()) {
-                param = tokenizer.getParameter();
-                if (!parameterSupported(flag, param))
-                    abortFlags("Parameter '" << param << "' for flag '" << flag << "' not supported");
-            }
-            makeSet(flag, param);
-            break;
-        }
-    }
-
-    /*Regex code needs to parse -i file*/
-    if ( isSet(ACL_F_REGEX_CASE)) {
-        ConfigParser::TokenPutBack("-i");
-        makeUnSet('i');
-    }
-}
-
-SBuf
-ACLFlags::parameter(const ACLFlag f) const
+Acl::RegisterMaker(TypeName typeName, Maker maker)
 {
-    assert(static_cast<uint32_t>(f - 'A') < FlagIndexMax);
-    auto p = flagParameters_.find(f);
-    return p == flagParameters_.end() ? SBuf() : p->second;
-}
-
-const CharacterSet *
-ACLFlags::delimiters()
-{
-    if (isSet(ACL_F_SUBSTRING) && !delimiters_) {
-        static const SBuf defaultParameter(",");
-        SBuf rawParameter = parameter(ACL_F_SUBSTRING);
-        if (rawParameter.isEmpty())
-            rawParameter = defaultParameter;
-        delimiters_ = new CharacterSet("ACLFlags::delimiters", rawParameter.c_str());
-    }
-    return delimiters_;
-}
-
-const char *
-ACLFlags::flagsStr() const
-{
-    static char buf[64];
-    if (flags_ == 0)
-        return "";
-
-    char *s = buf;
-    *s++ = '-';
-    for (ACLFlag f = 'A'; f <= 'z'; f++) {
-        // ACL_F_REGEX_CASE (-i) flag handled by ACLRegexData class, ignore
-        if (isSet(f) && f != ACL_F_REGEX_CASE)
-            *s++ = f;
-    }
-    *s = '\0';
-    return buf;
+    assert(typeName);
+    assert(*typeName);
+    TheMakers().emplace(typeName, maker);
 }
 
 void *
@@ -231,17 +104,6 @@ ACL::FindByName(const char *name)
     return NULL;
 }
 
-ACL *
-ACL::Factory (char const *type)
-{
-    ACL *result = Prototype::Factory (type);
-
-    if (!result)
-        fatal ("Unknown acl type in ACL::Factory");
-
-    return result;
-}
-
 ACL::ACL() :
     cfgline(nullptr),
     next(nullptr),
@@ -250,15 +112,6 @@ ACL::ACL() :
     *name = 0;
 }
 
-ACL::ACL(const ACLFlag flgs[]) :
-    cfgline(NULL),
-    next(NULL),
-    flags(flgs),
-    registered(false)
-{
-    *name = 0;
-}
-
 bool ACL::valid () const
 {
     return true;
@@ -373,16 +226,9 @@ ACL::ParseAclLine(ConfigParser &parser, ACL ** head)
         return; // ignore the line
     }
 
-    if (!Prototype::Registered(theType)) {
-        debugs(28, DBG_CRITICAL, "FATAL: Invalid ACL type '" << theType << "'");
-        // XXX: make this an ERROR and skip the ACL creation. We *may* die later when its use is attempted. Or may not.
-        parser.destruct();
-        return;
-    }
-
     if ((A = FindByName(aclname)) == NULL) {
         debugs(28, 3, "aclParseAclLine: Creating ACL '" << aclname << "'");
-        A = ACL::Factory(theType);
+        A = Acl::Make(theType);
         A->context(aclname, config_input_line);
         new_acl = 1;
     } else {
@@ -402,7 +248,7 @@ ACL::ParseAclLine(ConfigParser &parser, ACL ** head)
      */
     AclMatchedName = A->name;   /* ugly */
 
-    A->flags.parseFlags();
+    A->parseFlags();
 
     /*split the function here */
     A->parse();
@@ -439,6 +285,30 @@ ACL::isProxyAuth() const
     return false;
 }
 
+void
+ACL::parseFlags()
+{
+    // ACL kids that carry ACLData which supports parameter flags override this
+    Acl::ParseFlags(options(), Acl::NoFlags());
+}
+
+SBufList
+ACL::dumpOptions()
+{
+    SBufList result;
+    const auto &myOptions = options();
+    // optimization: most ACLs do not have myOptions
+    // this check also works around dump_SBufList() adding ' ' after empty items
+    if (!myOptions.empty()) {
+        SBufStream stream;
+        stream << myOptions;
+        const SBuf optionsImage = stream.buf();
+        if (!optionsImage.isEmpty())
+            result.push_back(optionsImage);
+    }
+    return result;
+}
+
 /* ACL result caching routines */
 
 int
@@ -530,69 +400,6 @@ ACL::~ACL()
     AclMatchedName = NULL; // in case it was pointing to our name
 }
 
-ACL::Prototype::Prototype() : prototype (NULL), typeString (NULL) {}
-
-ACL::Prototype::Prototype (ACL const *aPrototype, char const *aType) : prototype (aPrototype), typeString (aType)
-{
-    registerMe ();
-}
-
-std::vector<ACL::Prototype const *> * ACL::Prototype::Registry;
-void *ACL::Prototype::Initialized;
-
-bool
-ACL::Prototype::Registered(char const *aType)
-{
-    debugs(28, 7, "ACL::Prototype::Registered: invoked for type " << aType);
-
-    for (iterator i = Registry->begin(); i != Registry->end(); ++i)
-        if (!strcmp (aType, (*i)->typeString)) {
-            debugs(28, 7, "ACL::Prototype::Registered:    yes");
-            return true;
-        }
-
-    debugs(28, 7, "ACL::Prototype::Registered:    no");
-    return false;
-}
-
-void
-ACL::Prototype::registerMe ()
-{
-    if (!Registry || (Initialized != ((char *)Registry - 5))  ) {
-        /* TODO: extract this */
-        /* Not initialised */
-        Registry = new std::vector<ACL::Prototype const *>;
-        Initialized = (char *)Registry - 5;
-    }
-
-    if (Registered (typeString))
-        fatalf ("Attempt to register %s twice", typeString);
-
-    Registry->push_back (this);
-}
-
-ACL::Prototype::~Prototype()
-{
-    // TODO: unregister me
-}
-
-ACL *
-ACL::Prototype::Factory (char const *typeToClone)
-{
-    debugs(28, 4, "ACL::Prototype::Factory: cloning an object for type '" << typeToClone << "'");
-
-    for (iterator i = Registry->begin(); i != Registry->end(); ++i)
-        if (!strcmp (typeToClone, (*i)->typeString)) {
-            ACL *A = (*i)->prototype->clone();
-            A->flags = (*i)->prototype->flags;
-            return A;
-        }
-
-    debugs(28, 4, "ACL::Prototype::Factory: cloning failed, no type '" << typeToClone << "' available");
-
-    return NULL;
-}
-
 void
 ACL::Initialize()
 {
index c837089ca4568d9b8a7b74afc5431884d1eb0fe0..9ed1b19c30c90b01f44314b5af8e8e117007b042 100644 (file)
 #define SQUID_ACL_H
 
 #include "acl/forward.h"
-#include "base/CharacterSet.h"
+#include "acl/Options.h"
 #include "cbdata.h"
 #include "defines.h"
 #include "dlink.h"
-#include "sbuf/List.h"
+#include "sbuf/forward.h"
 
-#include <map>
 #include <ostream>
-#include <string>
-#include <vector>
 
 class ConfigParser;
 
-typedef char ACLFlag;
-// ACLData Flags
-#define ACL_F_REGEX_CASE 'i'
-#define ACL_F_NO_LOOKUP 'n'
-#define ACL_F_STRICT 's'
-#define ACL_F_SUBSTRING 'm'
-#define ACL_F_END '\0'
-
-/**
- * \ingroup ACLAPI
- * Used to hold a list of one-letter flags which can be passed as parameters
- * to acls  (eg '-i', '-n' etc)
- */
-class ACLFlags
-{
-public:
-    enum Status
-    {
-        notSupported,
-        noParameter,
-        parameterOptional,
-        parameterRequired
-    };
-
-    explicit ACLFlags(const ACLFlag flags[]) : supported_(flags), flags_(0), delimiters_(nullptr) {}
-    ACLFlags() : flags_(0), delimiters_(nullptr) {}
-    ~ACLFlags();
-    /// \return a Status for the given ACLFlag.
-    Status flagStatus(const ACLFlag f) const;
-    /// \return true if the parameter for the given flag is acceptable.
-    bool parameterSupported(const ACLFlag f, const SBuf &val) const;
-    /// Set the given flag
-    void makeSet(const ACLFlag f, const SBuf &param = SBuf(""));
-    void makeUnSet(const ACLFlag f); ///< Unset the given flag
-    /// \return true if the given flag is set.
-    bool isSet(const ACLFlag f) const { return flags_ & flagToInt(f);}
-    /// \return the parameter value of the given flag if set.
-    SBuf parameter(const ACLFlag f) const;
-    /// \return ACL_F_SUBSTRING parameter value(if set) converted to CharacterSet.
-    const CharacterSet *delimiters();
-    /// Parse optional flags given in the form -[A..Z|a..z]
-    void parseFlags();
-    const char *flagsStr() const; ///< Convert the flags to a string representation
-    /**
-     * Lexical analyzer for ACL flags
-     *
-     * Support tokens in the form:
-     *   flag := '-' [A-Z|a-z]+ ['=' parameter ]
-     * Each token consist by one or more single-letter flags, which may
-     * followed by a parameter string.
-     * The parameter can belongs only to the last flag in token.
-     */
-    class FlagsTokenizer
-    {
-    public:
-        FlagsTokenizer();
-        ACLFlag nextFlag(); ///< The next flag or '\0' if finished
-        /// \return true if a parameter follows the last parsed flag.
-        bool hasParameter() const;
-        /// \return the parameter of last parsed flag, if exist.
-        SBuf getParameter() const;
-
-    private:
-        /// \return true if the current token parsing is finished.
-        bool needNextToken() const;
-        /// Peeks at the next token and return false if the next token
-        /// is not flag, or a '--' is read.
-        bool nextToken();
-
-        char *tokPos;
-        char *Parameter;
-    };
+namespace Acl {
 
-private:
-    /// Convert a flag to a 64bit unsigned integer.
-    /// The characters from 'A' to 'z' represented by the values from 65 to 122.
-    /// They are 57 different characters which can be fit to the bits of an 64bit
-    /// integer.
-    uint64_t flagToInt(const ACLFlag f) const {
-        assert('A' <= f && f <= 'z');
-        return ((uint64_t)1 << (f - 'A'));
-    }
+/// the ACL type name known to admins
+typedef const char *TypeName;
+/// a "factory" function for making ACL objects (of some ACL child type)
+typedef ACL *(*Maker)(TypeName typeName);
+/// use the given ACL Maker for all ACLs of the named type
+void RegisterMaker(TypeName typeName, Maker maker);
 
-    std::string supported_; ///< The supported character flags
-    uint64_t flags_; ///< The flags which are set
-    static const uint32_t FlagIndexMax = 'z' - 'A';
-    std::map<ACLFlag, SBuf> flagParameters_;
-    CharacterSet *delimiters_;
-public:
-    static const ACLFlag NoFlags[1]; ///< An empty flags list
-};
+} // namespace Acl
 
 /// A configurable condition. A node in the ACL expression tree.
 /// Can evaluate itself in FilledChecklist context.
@@ -126,13 +42,11 @@ public:
     void *operator new(size_t);
     void operator delete(void *);
 
-    static ACL *Factory(char const *);
     static void ParseAclLine(ConfigParser &parser, ACL ** head);
     static void Initialize();
     static ACL *FindByName(const char *name);
 
     ACL();
-    explicit ACL(const ACLFlag flgs[]);
     virtual ~ACL();
 
     /// sets user-specified ACL name and squid.conf context
@@ -144,7 +58,11 @@ public:
     /// Updates the checklist state on match, async, and failure.
     bool matches(ACLChecklist *checklist) const;
 
-    virtual ACL *clone() const = 0;
+    /// \returns (linked) Options supported by this ACL
+    virtual const Acl::Options &options() { return Acl::NoOptions(); }
+
+    /// configures ACL options, throwing on configuration errors
+    virtual void parseFlags();
 
     /// parses node represenation in squid.conf; dies on failures
     virtual void parse() = 0;
@@ -159,36 +77,13 @@ public:
 
     virtual void prepareForUse() {}
 
+    SBufList dumpOptions(); ///< \returns approximate options configuration
+
     char name[ACL_NAME_SZ];
     char *cfgline;
     ACL *next; // XXX: remove or at least use refcounting
-    ACLFlags flags; ///< The list of given ACL flags
     bool registered; ///< added to the global list of ACLs via aclRegister()
 
-public:
-
-    class Prototype
-    {
-
-    public:
-        Prototype();
-        Prototype(ACL const *, char const *);
-        ~Prototype();
-        static bool Registered(char const *);
-        static ACL *Factory(char const *);
-
-    private:
-        ACL const *prototype;
-        char const *typeString;
-
-    private:
-        static std::vector<Prototype const *> * Registry;
-        static void *Initialized;
-        typedef std::vector<Prototype const*>::iterator iterator;
-        typedef std::vector<Prototype const*>::const_iterator const_iterator;
-        void registerMe();
-    };
-
 private:
     /// Matches the actual data in checklist against this ACL.
     virtual int match(ACLChecklist *checklist) = 0; // XXX: missing const
index 2957266201b289c82b0fb3a678b7a7440c80ce69..37c4b31f49674dcb4050c57c5b04a27bc6ada70f 100644 (file)
@@ -8,14 +8,14 @@
 
 #include "squid.h"
 #include "acl/AdaptationService.h"
-#include "acl/Checklist.h"
+#include "acl/FilledChecklist.h"
 #include "acl/IntRange.h"
 #include "adaptation/Config.h"
 #include "adaptation/History.h"
 #include "HttpRequest.h"
 
 int
-ACLAdaptationServiceStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLAdaptationServiceStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     HttpRequest::Pointer request = checklist->request;
     if (request == NULL)
@@ -33,11 +33,3 @@ ACLAdaptationServiceStrategy::match (ACLData<MatchType> * &data, ACLFilledCheckl
     return 0;
 }
 
-ACLAdaptationServiceStrategy *
-ACLAdaptationServiceStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLAdaptationServiceStrategy ACLAdaptationServiceStrategy::Instance_;
-
index 1b2ca5cf06e80241d21786439aa34acf9ea6fa4d..160e403204d4c970510d5cdc013d6eb82011b6ca 100644 (file)
@@ -9,7 +9,6 @@
 #ifndef SQUID_ACLADAPTATIONSERVICE_H
 #define SQUID_ACLADAPTATIONSERVICE_H
 
-#include "acl/Strategised.h"
 #include "acl/Strategy.h"
 
 /// \ingroup ACLAPI
@@ -17,27 +16,7 @@ class ACLAdaptationServiceStrategy : public ACLStrategy<const char *>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
-    static ACLAdaptationServiceStrategy *Instance();
-    /**
-     * Not implemented to prevent copies of the instance.
-     */
-    ACLAdaptationServiceStrategy(ACLAdaptationServiceStrategy const &);
-
-private:
-    static ACLAdaptationServiceStrategy Instance_;
-    ACLAdaptationServiceStrategy() {}
-
-    ACLAdaptationServiceStrategy &operator = (ACLAdaptationServiceStrategy const &);
-};
-
-/// \ingroup ACLAPI
-class ACLAdaptationService
-{
-
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<const char *> RegistryEntry_;
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *) override;
 };
 
 #endif /* SQUID_ACLADAPTATIONSERVICE_H */
index 211b41e1799d277ac859cbcd6f6c06e273d827bc..e038af22d1571c54f139bcda6fd68935b6f5f304 100644 (file)
@@ -31,9 +31,6 @@ public:
 private:
     /* Acl::InnerNode API */
     virtual int doMatch(ACLChecklist *checklist, Nodes::const_iterator start) const;
-
-    static Prototype RegistryProtoype;
-    static AllOf RegistryEntry_;
 };
 
 } // namespace Acl
index 3aa16ad0337c7a5ef57f60eb178fe7fea1c306f1..235d671577eee90bee79b3aaabeadd5c6201e37c 100644 (file)
@@ -9,29 +9,22 @@
 #include "squid.h"
 #include "acl/AnnotateClient.h"
 #include "acl/AnnotationData.h"
+#include "acl/FilledChecklist.h"
 #include "client_side.h"
 #include "http/Stream.h"
 #include "Notes.h"
 
 int
-ACLAnnotateClientStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &flags)
+ACLAnnotateClientStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     if (const auto conn = checklist->conn()) {
         ACLAnnotationData *tdata = dynamic_cast<ACLAnnotationData*>(data);
         assert(tdata);
-        tdata->annotate(conn->notes(), flags.delimiters(), checklist->al);
+        tdata->annotate(conn->notes(), &delimiters.value, checklist->al);
         if (const auto request = checklist->request)
-            tdata->annotate(request->notes(), flags.delimiters(), checklist->al);
+            tdata->annotate(request->notes(), &delimiters.value, checklist->al);
         return 1;
     }
     return 0;
 }
 
-ACLAnnotateClientStrategy *
-ACLAnnotateClientStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLAnnotateClientStrategy ACLAnnotateClientStrategy::Instance_;
-
index bb63ca3cb115c3906b9ced5cedb9b0a9d9761356..84c2487b1a1631cd6de4efdee7135e1848bdb9cb 100644 (file)
@@ -9,31 +9,15 @@
 #ifndef SQUID_ACLANNOTATECLIENT
 #define SQUID_ACLANNOTATECLIENT
 
-#include "acl/Strategised.h"
-#include "acl/Strategy.h"
+#include "acl/Note.h"
+#include "Notes.h"
 
 /// \ingroup ACLAPI
-class ACLAnnotateClientStrategy : public ACLStrategy<NotePairs::Entry *>
+class ACLAnnotateClientStrategy : public Acl::AnnotationStrategy
 {
 public:
-    static ACLAnnotateClientStrategy *Instance();
-    ACLAnnotateClientStrategy(ACLAnnotateClientStrategy const &) = delete;
-    ACLAnnotateClientStrategy& operator=(ACLAnnotateClientStrategy const &) = delete;
-
     virtual bool requiresRequest() const { return true; }
-    virtual int match(ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
-
-private:
-    static ACLAnnotateClientStrategy Instance_;
-    ACLAnnotateClientStrategy() { }
-};
-
-/// \ingroup ACLAPI
-class ACLAnnotateClient
-{
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<NotePairs::Entry *> RegistryEntry_;
+    virtual int match(ACLData<MatchType> * &, ACLFilledChecklist *);
 };
 
 #endif /* SQUID_ACLANNOTATECLIENT */
index ff758c99187d19e609a397e7728c5187cc248b25..a1d37488bc5361d80550973ef77a22f334abfa6d 100644 (file)
@@ -9,27 +9,19 @@
 #include "squid.h"
 #include "acl/AnnotateTransaction.h"
 #include "acl/AnnotationData.h"
-#include "acl/Checklist.h"
+#include "acl/FilledChecklist.h"
 #include "HttpRequest.h"
 #include "Notes.h"
 
 int
-ACLAnnotateTransactionStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &flags)
+ACLAnnotateTransactionStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     if (const auto request = checklist->request) {
         ACLAnnotationData *tdata = dynamic_cast<ACLAnnotationData*>(data);
         assert(tdata);
-        tdata->annotate(request->notes(), flags.delimiters(), checklist->al);
+        tdata->annotate(request->notes(), &delimiters.value, checklist->al);
         return 1;
     }
     return 0;
 }
 
-ACLAnnotateTransactionStrategy *
-ACLAnnotateTransactionStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLAnnotateTransactionStrategy ACLAnnotateTransactionStrategy::Instance_;
-
index 441db54b4201fbb01c435fceb4f0629571b89976..c1da5fb556567d3e5c6c48238cdfad6b9f3d05e8 100644 (file)
@@ -9,31 +9,15 @@
 #ifndef SQUID_ACLANNOTATETRANSACTION
 #define SQUID_ACLANNOTATETRANSACTION
 
-#include "acl/Strategised.h"
-#include "acl/Strategy.h"
+#include "acl/Note.h"
+#include "Notes.h"
 
 /// \ingroup ACLAPI
-class ACLAnnotateTransactionStrategy : public ACLStrategy<NotePairs::Entry *>
+class ACLAnnotateTransactionStrategy: public Acl::AnnotationStrategy
 {
 public:
-    virtual int match(ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
+    virtual int match(ACLData<MatchType> * &, ACLFilledChecklist *);
     virtual bool requiresRequest() const { return true; }
-
-    static ACLAnnotateTransactionStrategy *Instance();
-    ACLAnnotateTransactionStrategy(ACLAnnotateTransactionStrategy const &) = delete;
-    ACLAnnotateTransactionStrategy& operator=(ACLAnnotateTransactionStrategy const &) = delete;
-
-private:
-    static ACLAnnotateTransactionStrategy Instance_;
-    ACLAnnotateTransactionStrategy() {}
-};
-
-/// \ingroup ACLAPI
-class ACLAnnotateTransaction
-{
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<NotePairs::Entry *> RegistryEntry_;
 };
 
 #endif /* SQUID_ACLANNOTATETRANSACTION */
index f5fc86e7bde5eb3e176b41db2d66d30d39ea52c7..e90b95da7218ba7c80f1fbc886f366b7547af827 100644 (file)
@@ -24,10 +24,6 @@ public:
     virtual char const *typeString() const;
     virtual ACL *clone() const;
     virtual void parse();
-
-private:
-    static Prototype RegistryProtoype;
-    static AnyOf RegistryEntry_;
 };
 
 } // namespace Acl
index a7d7ace3a219cdbbd84597df862349c51b46b577..dd345d4276550655b9afebfdf2c2f8225bcb6872 100644 (file)
@@ -10,7 +10,6 @@
 #define SQUID_ACLARP_H
 
 #include "acl/Acl.h"
-#include "acl/Checklist.h"
 
 #include <set>
 
@@ -38,8 +37,6 @@ public:
     virtual bool empty () const;
 
 protected:
-    static Prototype RegistryProtoype;
-    static ACLARP RegistryEntry_;
     char const *class_;
     typedef std::set<Eui::Eui48> AclArpData_t;
     AclArpData_t aclArpData;
index 300107ff8934a1120d59a0bd106c65c2709f58e1..5707ea1ac8f0a548b6c51ae6e258caed29b34d86 100644 (file)
@@ -15,6 +15,7 @@
 #include "acl/DestinationAsn.h"
 #include "acl/DestinationIp.h"
 #include "acl/SourceAsn.h"
+#include "acl/Strategised.h"
 #include "FwdState.h"
 #include "HttpReply.h"
 #include "HttpRequest.h"
@@ -577,30 +578,14 @@ ACLASN::clone() const
 
 template class ACLStrategised<Ip::Address>;
 
-ACL::Prototype ACLASN::SourceRegistryProtoype(&ACLASN::SourceRegistryEntry_, "src_as");
-
-ACLStrategised<Ip::Address> ACLASN::SourceRegistryEntry_(new ACLASN, ACLSourceASNStrategy::Instance(), "src_as");
-
-ACL::Prototype ACLASN::DestinationRegistryProtoype(&ACLASN::DestinationRegistryEntry_, "dst_as");
-
-ACLStrategised<Ip::Address> ACLASN::DestinationRegistryEntry_(new ACLASN, ACLDestinationASNStrategy::Instance(), "dst_as");
-
 int
-ACLSourceASNStrategy::match (ACLData<Ip::Address> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLSourceASNStrategy::match (ACLData<Ip::Address> * &data, ACLFilledChecklist *checklist)
 {
     return data->match(checklist->src_addr);
 }
 
-ACLSourceASNStrategy *
-ACLSourceASNStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLSourceASNStrategy ACLSourceASNStrategy::Instance_;
-
 int
-ACLDestinationASNStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLDestinationASNStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     const ipcache_addrs *ia = ipcache_gethostbyname(checklist->request->url.host(), IP_LOOKUP_IF_MISS);
 
@@ -624,11 +609,3 @@ ACLDestinationASNStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist
     return data->match(noaddr);
 }
 
-ACLDestinationASNStrategy *
-ACLDestinationASNStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLDestinationASNStrategy ACLDestinationASNStrategy::Instance_;
-
index c2674c98464e4f570e5b67b3976014dc8972f886..1093de58c97475abac4e336b05f162a579d5b2c4 100644 (file)
@@ -9,9 +9,7 @@
 #ifndef SQUID_ACLASN_H
 #define SQUID_ACLASN_H
 
-#include "acl/Checklist.h"
 #include "acl/Data.h"
-#include "acl/Strategised.h"
 #include "base/CbDataList.h"
 #include "ip/Address.h"
 
@@ -40,10 +38,6 @@ public:
     virtual void prepareForUse();
 
 private:
-    static ACL::Prototype SourceRegistryProtoype;
-    static ACLStrategised<Ip::Address> SourceRegistryEntry_;
-    static ACL::Prototype DestinationRegistryProtoype;
-    static ACLStrategised<Ip::Address> DestinationRegistryEntry_;
     CbDataList<int> *data;
 };
 
index 89ec6633ca5070d89040b704d4f564483c606860..dad464e2d9803f34ade3c597e942e97c3d12cdd1 100644 (file)
 
 #include "acl/AtStep.h"
 #include "acl/AtStepData.h"
-#include "acl/Checklist.h"
+#include "acl/FilledChecklist.h"
 #include "client_side.h"
 #include "http/Stream.h"
 #include "ssl/ServerBump.h"
 
 int
-ACLAtStepStrategy::match (ACLData<Ssl::BumpStep> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLAtStepStrategy::match (ACLData<Ssl::BumpStep> * &data, ACLFilledChecklist *checklist)
 {
     Ssl::ServerBump *bump = NULL;
     if (checklist->conn() != NULL && (bump = checklist->conn()->serverBump()))
@@ -28,13 +28,5 @@ ACLAtStepStrategy::match (ACLData<Ssl::BumpStep> * &data, ACLFilledChecklist *ch
     return 0;
 }
 
-ACLAtStepStrategy *
-ACLAtStepStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLAtStepStrategy ACLAtStepStrategy::Instance_;
-
 #endif /* USE_OPENSSL */
 
index 6b077ba17db994bc13c98992c4cce62cc502d228..25f5440f2e9d2538f73644794fdda4d633ef32f1 100644 (file)
@@ -11,7 +11,6 @@
 
 #if USE_OPENSSL
 
-#include "acl/Strategised.h"
 #include "acl/Strategy.h"
 #include "ssl/support.h"
 
@@ -20,25 +19,7 @@ class ACLAtStepStrategy : public ACLStrategy<Ssl::BumpStep>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
-    static ACLAtStepStrategy *Instance();
-
-    // Not implemented to prevent copies of the instance.
-    ACLAtStepStrategy(ACLAtStepStrategy const &);
-
-private:
-    static ACLAtStepStrategy Instance_;
-    ACLAtStepStrategy() {}
-
-    ACLAtStepStrategy&operator=(ACLAtStepStrategy const &);
-};
-
-class ACLAtStep
-{
-
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<Ssl::BumpStep> RegistryEntry_;
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *) override;
 };
 
 #endif /* USE_OPENSSL */
index ff1dfb227cbe86eeb885de4396a9f5314bda8ed6..661f9318b179e7d5a6bb8a50febc74578e30a863 100644 (file)
@@ -10,6 +10,7 @@
 #include "acl/BoolOps.h"
 #include "acl/Checklist.h"
 #include "Debug.h"
+#include "sbuf/SBuf.h"
 
 /* Acl::NotNode */
 
diff --git a/src/acl/Browser.cc b/src/acl/Browser.cc
deleted file mode 100644 (file)
index e777acf..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
- *
- * Squid software is distributed under GPLv2+ license and includes
- * contributions from numerous individuals and organizations.
- * Please see the COPYING and CONTRIBUTORS files for details.
- */
-
-/* DEBUG: section 28    Access Control */
-
-#include "squid.h"
-#include "acl/Browser.h"
-#include "acl/Checklist.h"
-#include "acl/RegexData.h"
-
-/* explicit template instantiation required for some systems */
-
-template class ACLRequestHeaderStrategy<Http::HdrType::USER_AGENT>;
-
diff --git a/src/acl/Browser.h b/src/acl/Browser.h
deleted file mode 100644 (file)
index ac3c337..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
- *
- * Squid software is distributed under GPLv2+ license and includes
- * contributions from numerous individuals and organizations.
- * Please see the COPYING and CONTRIBUTORS files for details.
- */
-
-#ifndef SQUID_ACLBROWSER_H
-#define SQUID_ACLBROWSER_H
-
-#include "acl/Acl.h"
-#include "acl/Data.h"
-#include "acl/RequestHeaderStrategy.h"
-#include "acl/Strategised.h"
-
-/// \ingroup ACLAPI
-class ACLBrowser
-{
-
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<char const *> RegistryEntry_;
-};
-
-#endif /* SQUID_ACLBROWSER_H */
-
index 26ed5c3688a5cd6ec15c2a8fe4fb1dd371152a47..fd693e2c062a410e3328ba942a2e51bd58dc1937 100644 (file)
@@ -25,7 +25,7 @@
 #include "HttpRequest.h"
 
 int
-ACLCertificateStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLCertificateStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     const int fd = checklist->fd();
     const bool goodDescriptor = 0 <= fd && fd <= Biggest_FD;
@@ -36,13 +36,5 @@ ACLCertificateStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *c
     return res;
 }
 
-ACLCertificateStrategy *
-ACLCertificateStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLCertificateStrategy ACLCertificateStrategy::Instance_;
-
 #endif /* USE_OPENSSL */
 
index 9d29f0b710528da2df1abecd8c52e2e77833c921..322d80f96f4b5d735bbfb0bfc66516b606abed07 100644 (file)
@@ -20,29 +20,7 @@ class ACLCertificateStrategy : public ACLStrategy<X509 *>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
-    static ACLCertificateStrategy *Instance();
-    /* Not implemented to prevent copies of the instance. */
-    /* Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends */
-    ACLCertificateStrategy(ACLCertificateStrategy const &);
-
-private:
-    static ACLCertificateStrategy Instance_;
-    ACLCertificateStrategy() {}
-
-    ACLCertificateStrategy&operator=(ACLCertificateStrategy const &);
-};
-
-/// \ingroup ACLAPI
-class ACLCertificate
-{
-
-private:
-    static ACL::Prototype UserRegistryProtoype;
-    static ACLStrategised<X509*> UserRegistryEntry_;
-    static ACL::Prototype CARegistryProtoype;
-    static ACLStrategised<X509 *> CARegistryEntry_;
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *);
 };
 
 #endif /* SQUID_ACLCERTIFICATE_H */
diff --git a/src/acl/CharacterSetOption.h b/src/acl/CharacterSetOption.h
new file mode 100644 (file)
index 0000000..cfeafa0
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#ifndef SQUID_ACL_CHARACTER_SET_OPTION_H
+#define SQUID_ACL_CHARACTER_SET_OPTION_H
+
+#include "acl/Options.h"
+#include "base/CharacterSet.h"
+#include "sbuf/SBuf.h"
+
+namespace Acl {
+
+typedef OptionValue<CharacterSet> CharacterSetOptionValue;
+
+/* TypedOption<CharacterSetOptionValue> specializations */
+
+template <>
+inline
+void
+TypedOption<CharacterSetOptionValue>::import(const SBuf &rawValue) const
+{
+    SBuf chars = rawValue; // because c_str() is not constant
+    recipient_->value = CharacterSet(__FILE__, chars.c_str());
+}
+
+template <>
+inline
+void
+TypedOption<CharacterSetOptionValue>::print(std::ostream &os) const
+{
+    recipient_->value.printChars(os); // TODO: Quote if needed.
+}
+
+/// option value to configure one or more characters (e.g., -m=",;")
+class CharacterSetOption: public TypedOption<CharacterSetOptionValue>
+{
+public:
+    typedef TypedOption<CharacterSetOptionValue> Parent;
+    CharacterSetOption(): Parent(valueOptional) {}
+};
+
+} // namespace Acl
+
+#endif /* SQUID_ACL_CHARACTER_SET_OPTION_H */
+
index 0df050839e1c3334afe3391e5350d7b6f24e0e53..7684de471b5f14fcebac7d42b141216d84d30b7a 100644 (file)
@@ -33,8 +33,6 @@ public:
     virtual bool empty () const;
 
 protected:
-    static Prototype RegistryProtoype;
-    static ConnectionsEncrypted RegistryEntry_;
     char const *class_;
 };
 
index 1276173355580552ef02d3ce2aec6130b8327fc2..88a8afa77f6cfa7771e25d37c8551f86cacbfeb8 100644 (file)
@@ -9,9 +9,10 @@
 #ifndef SQUID_ACLDATA_H
 #define SQUID_ACLDATA_H
 
+#include "acl/Options.h"
 #include "sbuf/List.h"
 
-/// \ingroup ACLAPI
+/// Configured ACL parameter(s) (e.g., domain names in dstdomain ACL).
 template <class M>
 class ACLData
 {
@@ -20,6 +21,9 @@ public:
 
     virtual ~ACLData() {}
 
+    /// \returns the flags supported by these ACL parameters (e.g., "-i")
+    virtual const Acl::ParameterFlags &supportedFlags() const { return Acl::NoFlags(); }
+
     virtual bool match(M) =0;
     virtual SBufList dump() const =0;
     virtual void parse() =0;
index e5a620706663d4fe2a2f009edf43ad09c10e568c..350ff8e959869478421cc85f4430dee23fc40a4d 100644 (file)
@@ -18,24 +18,8 @@ class ACLDestinationASNStrategy : public ACLStrategy<Ip::Address>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *);
     virtual bool requiresRequest() const {return true;}
-
-    static ACLDestinationASNStrategy *Instance();
-
-    /**
-     * Not implemented to prevent copies of the instance.
-     \par
-     * Not private to prevent brain dead g++ warnings about
-     * private constructors with no friends
-     */
-    ACLDestinationASNStrategy(ACLDestinationASNStrategy const &);
-
-private:
-    static ACLDestinationASNStrategy Instance_;
-    ACLDestinationASNStrategy() {}
-
-    ACLDestinationASNStrategy&operator=(ACLDestinationASNStrategy const &);
 };
 
 #endif /* SQUID_ACLDESTINATIONASN_H */
index 2b6a06842c0f6f8ba96bf5a8eda0e03978179a9c..cf95988fc8caadc49cf0301c102b48d3e3a942e9 100644 (file)
@@ -41,8 +41,19 @@ DestinationDomainLookup::LookupDone(const char *, const Dns::LookupDetails &deta
     checklist->resumeNonBlockingCheck(DestinationDomainLookup::Instance());
 }
 
+/* ACLDestinationDomainStrategy */
+
+const Acl::Options &
+ACLDestinationDomainStrategy::options()
+{
+    static const Acl::BooleanOption LookupBanFlag;
+    static const Acl::Options MyOptions = { { "-n", &LookupBanFlag } };
+    LookupBanFlag.linkWith(&lookupBanned);
+    return MyOptions;
+}
+
 int
-ACLDestinationDomainStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &flags)
+ACLDestinationDomainStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     assert(checklist != NULL && checklist->request != NULL);
 
@@ -50,7 +61,7 @@ ACLDestinationDomainStrategy::match (ACLData<MatchType> * &data, ACLFilledCheckl
         return 1;
     }
 
-    if (flags.isSet(ACL_F_NO_LOOKUP)) {
+    if (lookupBanned) {
         debugs(28, 3, "No-lookup DNS ACL '" << AclMatchedName << "' for " << checklist->request->url.host());
         return 0;
     }
@@ -91,11 +102,3 @@ ACLDestinationDomainStrategy::match (ACLData<MatchType> * &data, ACLFilledCheckl
     return data->match("none");
 }
 
-ACLDestinationDomainStrategy *
-ACLDestinationDomainStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLDestinationDomainStrategy ACLDestinationDomainStrategy::Instance_;
-
index 5e2485cb5dbaeff17d728d16e425c051926e108e..2c12abdb2a7a4f38dce4e77f6504b914b5472075 100644 (file)
@@ -20,23 +20,13 @@ class ACLDestinationDomainStrategy : public ACLStrategy<char const *>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
-    static ACLDestinationDomainStrategy *Instance();
+    /* ACLStrategy API */
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *);
     virtual bool requiresRequest() const {return true;}
-
-    /**
-     * Not implemented to prevent copies of the instance.
-     \par
-     * Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends
-     */
-    ACLDestinationDomainStrategy(ACLDestinationDomainStrategy const &);
+    virtual const Acl::Options &options();
 
 private:
-    static ACLDestinationDomainStrategy Instance_;
-    ACLDestinationDomainStrategy() {}
-
-    ACLDestinationDomainStrategy&operator=(ACLDestinationDomainStrategy const &);
+    Acl::BooleanOptionValue lookupBanned; ///< Are DNS lookups allowed?
 };
 
 /// \ingroup ACLAPI
@@ -52,16 +42,5 @@ private:
     static void LookupDone(const char *, const Dns::LookupDetails &, void *);
 };
 
-/// \ingroup ACLAPI
-class ACLDestinationDomain
-{
-
-private:
-    static ACL::Prototype LiteralRegistryProtoype;
-    static ACLStrategised<char const *> LiteralRegistryEntry_;
-    static ACL::Prototype RegexRegistryProtoype;
-    static ACLStrategised<char const *> RegexRegistryEntry_;
-};
-
 #endif /* SQUID_ACLDESTINATIONDOMAIN_H */
 
index 9cfbc14f03c8495c9deb8aad8dabc25d3ef31792..13262eb6e3287128dec4bb731730e3d44195c2e6 100644 (file)
 #include "HttpRequest.h"
 #include "SquidConfig.h"
 
-ACLFlag ACLDestinationIP::SupportedFlags[] = {ACL_F_NO_LOOKUP, ACL_F_END};
-
 char const *
 ACLDestinationIP::typeString() const
 {
     return "dst";
 }
 
+const Acl::Options &
+ACLDestinationIP::options()
+{
+    static const Acl::BooleanOption LookupBan;
+    static const Acl::Options MyOptions = { { "-n", &LookupBan } };
+    LookupBan.linkWith(&lookupBanned);
+    return MyOptions;
+}
+
 int
 ACLDestinationIP::match(ACLChecklist *cl)
 {
@@ -44,7 +51,7 @@ ACLDestinationIP::match(ACLChecklist *cl)
                ACLIP::match(conn->clientConnection->local) : -1;
     }
 
-    if (flags.isSet(ACL_F_NO_LOOKUP)) {
+    if (lookupBanned) {
         if (!checklist->request->url.hostIsNumeric()) {
             debugs(28, 3, "No-lookup DNS ACL '" << AclMatchedName << "' for " << checklist->request->url.host());
             return 0;
index 9d0eaeaefb1db217a7a10c4cf32d988efcaea9c9..a6747a6d704c33bbfd091ebcaf4b4a849b060a19 100644 (file)
@@ -30,16 +30,14 @@ class ACLDestinationIP : public ACLIP
     MEMPROXY_CLASS(ACLDestinationIP);
 
 public:
-    ACLDestinationIP(): ACLIP(ACLDestinationIP::SupportedFlags) {}
     virtual char const *typeString() const;
+    virtual const Acl::Options &options();
     virtual int match(ACLChecklist *checklist);
 
     virtual ACL *clone()const;
 
-    static ACLFlag SupportedFlags[];
 private:
-    static Prototype RegistryProtoype;
-    static ACLDestinationIP RegistryEntry_;
+    Acl::BooleanOptionValue lookupBanned; ///< are DNS lookups allowed?
 };
 
 #endif /* SQUID_ACLDESTINATIONIP_H */
index 01dc10a17db4bce0568ec62ef72342134610d354..fd3e0bf73692343b0fcdf4205d282b83ee2e25c6 100644 (file)
@@ -10,7 +10,6 @@
 #define SQUID_ACLEUI64_H
 
 #include "acl/Acl.h"
-#include "acl/Checklist.h"
 
 #include <set>
 
@@ -37,8 +36,6 @@ public:
     virtual bool empty () const;
 
 protected:
-    static Prototype RegistryProtoype;
-    static ACLEui64 RegistryEntry_;
     typedef std::set<Eui::Eui64> Eui64Data_t;
     Eui64Data_t eui64Data;
     char const *class_;
index 973d7f12333d562cf184663c5cdbc404e1965f81..f2a15f68bcb2afac39b5de816a10c90082b9f104 100644 (file)
@@ -43,6 +43,12 @@ ACLExtUser::typeString() const
     return type_;
 }
 
+void
+ACLExtUser::parseFlags()
+{
+    ParseFlags(Acl::NoOptions(), data->supportedFlags());
+}
+
 void
 ACLExtUser::parse()
 {
index f6cdb84469dbd806e1d129724a406b3064694347..6d1e228292fd4310b40ef43e860c48624a928de4 100644 (file)
@@ -25,19 +25,16 @@ public:
     ACLExtUser & operator= (ACLExtUser const &rhs);
     ~ACLExtUser();
 
+    /* ACL API */
     virtual char const *typeString() const;
     virtual void parse();
-
+    virtual void parseFlags();
     virtual int match(ACLChecklist *checklist);
     virtual SBufList dump() const;
     virtual bool empty () const;
     virtual ACL *clone()const;
 
 private:
-    static Prototype UserRegistryProtoype;
-    static ACLExtUser UserRegistryEntry_;
-    static Prototype RegexRegistryProtoype;
-    static ACLExtUser RegexRegistryEntry_;
     ACLData<char const *> *data;
     char const *type_;
 };
index 1b0d4dd1b4004215dd78e2830c83c06271530f96..221a093480ae3ac06f8b78d69a08be793ab1105f 100644 (file)
 #include "acl/HasComponentData.h"
 
 int
-ACLHasComponentStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &flags)
+ACLHasComponentStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     ACLHasComponentData *cdata = dynamic_cast<ACLHasComponentData*>(data);
     assert(cdata);
     return cdata->match(checklist);
 }
-
-ACLHasComponentStrategy *
-ACLHasComponentStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLHasComponentStrategy ACLHasComponentStrategy::Instance_;
-
index 3aba6cdda8b5d7753663edefff040664c2a16007..8fddc47c95fbc38eefd8a955b6888c6315b09782 100644 (file)
 class ACLHasComponentStrategy : public ACLStrategy<ACLChecklist *>
 {
 public:
-    static ACLHasComponentStrategy *Instance();
-    ACLHasComponentStrategy(ACLHasComponentStrategy const &) = delete;
-    ACLHasComponentStrategy& operator=(ACLHasComponentStrategy const &) = delete;
-    virtual int match(ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
-
-private:
-    static ACLHasComponentStrategy Instance_;
-    ACLHasComponentStrategy() { }
-};
-
-/// \ingroup ACLAPI
-class ACLHasComponent
-{
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<ACLChecklist *> RegistryEntry_;
+    virtual int match(ACLData<MatchType> * &, ACLFilledChecklist *);
 };
 
 #endif
index b56465362bab311217c0b2210690abd126de4726..326a7b36f2fef07a812eb5b6f4f0b787526af165 100644 (file)
@@ -10,6 +10,7 @@
 #include "acl/Checklist.h"
 #include "acl/HierCode.h"
 #include "acl/HierCodeData.h"
+#include "acl/Strategised.h"
 #include "HttpRequest.h"
 
 /* explicit template instantiation required for some systems */
 template class ACLStrategised<hier_code>;
 
 int
-ACLHierCodeStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLHierCodeStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     return data->match (checklist->request->hier.code);
 }
 
-ACLHierCodeStrategy *
-ACLHierCodeStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLHierCodeStrategy ACLHierCodeStrategy::Instance_;
-
index 0d513d07be5ec01445d985a1617e6a627ba06e8e..d501a76a364fe46be3fc4201124bceb767be0753 100644 (file)
@@ -9,7 +9,6 @@
 #ifndef SQUID_ACLHIERCODE_H
 #define SQUID_ACLHIERCODE_H
 
-#include "acl/Strategised.h"
 #include "acl/Strategy.h"
 #include "hier_code.h"
 
@@ -18,33 +17,8 @@ class ACLHierCodeStrategy : public ACLStrategy<hier_code>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *);
     virtual bool requiresRequest() const {return true;}
-
-    static ACLHierCodeStrategy *Instance();
-
-    /**
-     * Not implemented to prevent copies of the instance.
-     \par
-     * Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends
-     */
-    ACLHierCodeStrategy(ACLHierCodeStrategy const &);
-
-private:
-    static ACLHierCodeStrategy Instance_;
-    ACLHierCodeStrategy() {}
-
-    ACLHierCodeStrategy &operator=(ACLHierCodeStrategy const &);
-};
-
-/// \ingroup ACLAPI
-class ACLHierCode
-{
-
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<hier_code> RegistryEntry_;
 };
 
 #endif /* SQUID_ACLHIERCODE_H */
index bfad171e680416f15a8348701ca8a69b95ba92df..4d492c7c2e69d9d7f62a1539038f917b1ebd54a5 100644 (file)
@@ -7,22 +7,14 @@
  */
 
 #include "squid.h"
-#include "acl/Checklist.h"
+#include "acl/FilledChecklist.h"
 #include "acl/HttpHeaderData.h"
 #include "acl/HttpRepHeader.h"
 #include "HttpReply.h"
 
 int
-ACLHTTPRepHeaderStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLHTTPRepHeaderStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     return data->match (&checklist->reply->header);
 }
 
-ACLHTTPRepHeaderStrategy *
-ACLHTTPRepHeaderStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLHTTPRepHeaderStrategy ACLHTTPRepHeaderStrategy::Instance_;
-
index 71e2a7dafc26d7690c8fb9322bf158c8ddc7f1a0..dc417c15b4b071d5f04a974169e90576c4a63da2 100644 (file)
@@ -18,32 +18,8 @@ class ACLHTTPRepHeaderStrategy : public ACLStrategy<HttpHeader*>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *);
     virtual bool requiresReply() const { return true; }
-
-    static ACLHTTPRepHeaderStrategy *Instance();
-    /**
-     * Not implemented to prevent copies of the instance.
-     \par
-     * Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends
-     */
-    ACLHTTPRepHeaderStrategy(ACLHTTPRepHeaderStrategy const &);
-
-private:
-    static ACLHTTPRepHeaderStrategy Instance_;
-    ACLHTTPRepHeaderStrategy() { }
-
-    ACLHTTPRepHeaderStrategy&operator = (ACLHTTPRepHeaderStrategy const &);
-};
-
-/// \ingroup ACLAPI
-class ACLHTTPRepHeader
-{
-
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<HttpHeader*> RegistryEntry_;
 };
 
 #endif /* SQUID_ACLHTTPREPHEADER_H */
index e481f8fcc5f46b4d055c48194c6996ec4473af7f..7a808e952e0becf6ec82d49b9adabcb12a3f6a45 100644 (file)
@@ -7,22 +7,14 @@
  */
 
 #include "squid.h"
-#include "acl/Checklist.h"
+#include "acl/FilledChecklist.h"
 #include "acl/HttpHeaderData.h"
 #include "acl/HttpReqHeader.h"
 #include "HttpRequest.h"
 
 int
-ACLHTTPReqHeaderStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLHTTPReqHeaderStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     return data->match (&checklist->request->header);
 }
 
-ACLHTTPReqHeaderStrategy *
-ACLHTTPReqHeaderStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLHTTPReqHeaderStrategy ACLHTTPReqHeaderStrategy::Instance_;
-
index 5be681db6870f0df3be95318a3485b2e420ca286..def941227f09e022c47996857ed3d4718ec00041 100644 (file)
@@ -9,7 +9,6 @@
 #ifndef SQUID_ACLHTTPREQHEADER_H
 #define SQUID_ACLHTTPREQHEADER_H
 
-#include "acl/Strategised.h"
 #include "acl/Strategy.h"
 #include "HttpHeader.h"
 
@@ -18,29 +17,8 @@ class ACLHTTPReqHeaderStrategy : public ACLStrategy<HttpHeader*>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *);
     virtual bool requiresRequest() const { return true; }
-
-    static ACLHTTPReqHeaderStrategy *Instance();
-    /* Not implemented to prevent copies of the instance. */
-    /* Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends */
-    ACLHTTPReqHeaderStrategy(ACLHTTPReqHeaderStrategy const &);
-
-private:
-    static ACLHTTPReqHeaderStrategy Instance_;
-    ACLHTTPReqHeaderStrategy() { }
-
-    ACLHTTPReqHeaderStrategy&operator = (ACLHTTPReqHeaderStrategy const &);
-};
-
-/// \ingroup ACLAPI
-class ACLHTTPReqHeader
-{
-
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<HttpHeader*> RegistryEntry_;
 };
 
 #endif /* SQUID_ACLHTTPREQHEADER_H */
index b5d6b07b5240f3a74503336f6be3962e181a4c8a..836bedec03c8f9a3c33aa5df998d05729dfacd53 100644 (file)
@@ -43,8 +43,6 @@ public:
     virtual bool requiresReply() const { return true; }
 
 protected:
-    static Prototype RegistryProtoype;
-    static ACLHTTPStatus RegistryEntry_;
     Splay<acl_httpstatus_data*> *data;
     char const *class_;
 };
index 2f23d53a5286c47582b0b5bf48367a143b9cc3bf..53194f9a31b4dafbf5dd6b61c9d96e8679d99520 100644 (file)
@@ -477,8 +477,6 @@ ACLIP::parse()
     if (data == NULL)
         data = new IPSplay();
 
-    flags.parseFlags();
-
     while (char *t = ConfigParser::strtokFile()) {
         acl_ip_data *q = acl_ip_data::FactoryParse(t);
 
index 7a93bf1e816139639aaacdb2dd2013115742fa46..6f48915f9bbc00d6947b983a222bd9f3132681e8 100644 (file)
@@ -48,8 +48,6 @@ public:
     void operator delete(void *);
 
     ACLIP() : data(NULL) {}
-    explicit ACLIP(const ACLFlag flgs[]) : ACL(flgs), data(NULL) {}
-
     ~ACLIP();
 
     typedef Splay<acl_ip_data *> IPSplay;
index af71364dc7dfeec685197ed195e08a37dd143e2c..bfccbd3cf582b88c3d20ca8b0df9fd0de89d7dad 100644 (file)
@@ -17,15 +17,9 @@ class ACLLocalIP : public ACLIP
     MEMPROXY_CLASS(ACLLocalIP);
 
 public:
-    static ACLLocalIP const &RegistryEntry();
-
     virtual char const *typeString() const;
     virtual int match(ACLChecklist *checklist);
     virtual ACL *clone()const;
-
-private:
-    static Prototype RegistryProtoype;
-    static ACLLocalIP RegistryEntry_;
 };
 
 #endif /* SQUID_ACLLOCALIP_H */
index 5c947619a86e7102f08b3bea60c97276e70b1a65..dc0aa23a672398d0a641ea12dcc20b6a6d213b05 100644 (file)
@@ -7,21 +7,12 @@
  */
 
 #include "squid.h"
-#include "acl/Checklist.h"
-#include "acl/IntRange.h"
+#include "acl/FilledChecklist.h"
 #include "acl/LocalPort.h"
 
 int
-ACLLocalPortStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLLocalPortStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     return data->match (checklist->my_addr.port());
 }
 
-ACLLocalPortStrategy *
-ACLLocalPortStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLLocalPortStrategy ACLLocalPortStrategy::Instance_;
-
index 2d9242de8f7832cafd3773b05fd052e8ece05e7a..cf07dafc65d3c7beeb44574660808b41aa935cca 100644 (file)
@@ -9,7 +9,6 @@
 #ifndef SQUID_ACLLOCALPORT_H
 #define SQUID_ACLLOCALPORT_H
 
-#include "acl/Strategised.h"
 #include "acl/Strategy.h"
 
 /// \ingroup ACLAPI
@@ -17,30 +16,7 @@ class ACLLocalPortStrategy : public ACLStrategy<int>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
-    static ACLLocalPortStrategy *Instance();
-    /**
-     * Not implemented to prevent copies of the instance.
-     \par
-     * Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends
-     */
-    ACLLocalPortStrategy(ACLLocalPortStrategy const &);
-
-private:
-    static ACLLocalPortStrategy Instance_;
-    ACLLocalPortStrategy() {}
-
-    ACLLocalPortStrategy&operator=(ACLLocalPortStrategy const &);
-};
-
-/// \ingroup ACLAPI
-class ACLLocalPort
-{
-
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<int> RegistryEntry_;
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *) override;
 };
 
 #endif /* SQUID_ACLLOCALPORT_H */
index 133ba56cba65fd1a864f840d6daf1868053342a5..98804b9e449054c2033e07734931a081dccf97d5 100644 (file)
@@ -23,12 +23,15 @@ libapi_la_SOURCES = \
        forward.h \
        InnerNode.cc \
        InnerNode.h \
+       Options.h \
+       Options.cc \
        Tree.cc \
        Tree.h
 
 ## Data-dependent Squid/transaction state used by specific ACLs.
 ## Does not refer to specific ACLs to avoid circular dependencies.
 libstate_la_SOURCES = \
+       CharacterSetOption.h \
        Data.h \
        Strategy.h \
        Strategised.cc \
@@ -62,8 +65,6 @@ libacls_la_SOURCES = \
        AnyOf.h \
        Asn.cc \
        Asn.h \
-       Browser.cc \
-       Browser.h \
        ConnectionsEncrypted.cc \
        ConnectionsEncrypted.h \
        DestinationAsn.h \
@@ -117,13 +118,9 @@ libacls_la_SOURCES = \
        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 \
index 78d267362e562a7f2923a76c69a4393220b1d03a..8dbcdf072043127a6509fcb83f864c79975837b2 100644 (file)
@@ -10,7 +10,6 @@
 #define SQUID_ACLMAXCONNECTION_H
 
 #include "acl/Acl.h"
-#include "acl/Checklist.h"
 
 /// \ingroup ACLAPI
 class ACLMaxConnection : public ACL
@@ -33,8 +32,6 @@ public:
     virtual void prepareForUse();
 
 protected:
-    static Prototype RegistryProtoype;
-    static ACLMaxConnection RegistryEntry_;
     char const *class_;
     int limit;
 };
index b8040e3796a4df639ee2766c6c82fe9c04734877..dfb619f6587024c6947e5b86842448130f4fdb23 100644 (file)
@@ -7,9 +7,10 @@
  */
 
 #include "squid.h"
-#include "acl/Checklist.h"
+#include "acl/FilledChecklist.h"
 #include "acl/Method.h"
 #include "acl/MethodData.h"
+#include "acl/Strategised.h"
 #include "HttpRequest.h"
 
 /* explicit template instantiation required for some systems */
 template class ACLStrategised<HttpRequestMethod>;
 
 int
-ACLMethodStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLMethodStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     return data->match (checklist->request->method);
 }
 
-ACLMethodStrategy *
-ACLMethodStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLMethodStrategy ACLMethodStrategy::Instance_;
-
index 710019d221cf8d0b3dd5fc9a06d262cac25d0c38..37d13512ca0807fc574136c22dc745b63d477c10 100644 (file)
@@ -9,7 +9,6 @@
 #ifndef SQUID_ACLMETHOD_H
 #define SQUID_ACLMETHOD_H
 
-#include "acl/Strategised.h"
 #include "acl/Strategy.h"
 #include "http/RequestMethod.h"
 
@@ -18,33 +17,8 @@ class ACLMethodStrategy : public ACLStrategy<HttpRequestMethod>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *);
     virtual bool requiresRequest() const {return true;}
-
-    static ACLMethodStrategy *Instance();
-
-    /**
-     * Not implemented to prevent copies of the instance.
-     \par
-     * Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends
-     */
-    ACLMethodStrategy(ACLMethodStrategy const &);
-
-private:
-    static ACLMethodStrategy Instance_;
-    ACLMethodStrategy() {}
-
-    ACLMethodStrategy&operator=(ACLMethodStrategy const &);
-};
-
-/// \ingroup ACLAPI
-class ACLMethod
-{
-
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<HttpRequestMethod> RegistryEntry_;
 };
 
 #endif /* SQUID_ACLMETHOD_H */
index 9566d76bf534925f272537ee4918d3c93c1a75bd..2de70ca53c07e03b159803052b3dc6aa63d81c14 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include "squid.h"
-#include "acl/Checklist.h"
+#include "acl/FilledChecklist.h"
 #include "acl/MyPortName.h"
 #include "acl/StringData.h"
 #include "anyp/PortCfg.h"
@@ -16,7 +16,7 @@
 #include "HttpRequest.h"
 
 int
-ACLMyPortNameStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLMyPortNameStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     if (checklist->conn() != NULL && checklist->conn()->port != NULL)
         return data->match(checklist->conn()->port->name);
@@ -25,11 +25,3 @@ ACLMyPortNameStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *che
     return 0;
 }
 
-ACLMyPortNameStrategy *
-ACLMyPortNameStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLMyPortNameStrategy ACLMyPortNameStrategy::Instance_;
-
index 3c2429528fb312b1fdb2503e69facdda539044ce..e385055195999ce9f90adc81a7b19b67e8cd8092 100644 (file)
@@ -8,33 +8,13 @@
 
 #ifndef SQUID_ACLMYPORTNAME_H
 #define SQUID_ACLMYPORTNAME_H
-#include "acl/Strategised.h"
 #include "acl/Strategy.h"
 
 class ACLMyPortNameStrategy : public ACLStrategy<const char *>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
-    static ACLMyPortNameStrategy *Instance();
-    /* Not implemented to prevent copies of the instance. */
-    /* Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends */
-    ACLMyPortNameStrategy(ACLMyPortNameStrategy const &);
-
-private:
-    static ACLMyPortNameStrategy Instance_;
-    ACLMyPortNameStrategy() {}
-
-    ACLMyPortNameStrategy&operator=(ACLMyPortNameStrategy const &);
-};
-
-class ACLMyPortName
-{
-
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<const char *> RegistryEntry_;
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *) override;
 };
 
 #endif /* SQUID_ACLMYPORTNAME_H */
index a58ed9504aa79f3fcb551df267e300d8af94bbcc..c27489e1cb34a68f4cc3c18df07523d8fc5bd820 100644 (file)
@@ -7,24 +7,36 @@
  */
 
 #include "squid.h"
-#include "acl/Checklist.h"
+#include "acl/FilledChecklist.h"
 #include "acl/HttpHeaderData.h"
 #include "acl/Note.h"
 #include "acl/NoteData.h"
 #include "HttpRequest.h"
-#include "Notes.h"
-#include "parser/Tokenizer.h"
-#include "sbuf/StringConvert.h"
+
+/* Acl::AnnotationStrategy */
+
+const Acl::Options &
+Acl::AnnotationStrategy::options()
+{
+    static const Acl::CharacterSetOption Delimiters;
+    static const Acl::Options MyOptions = {
+        { "-m", &Delimiters }
+    };
+    Delimiters.linkWith(&delimiters);
+    return MyOptions;
+}
+
+/* ACLNoteStrategy */
 
 int
-ACLNoteStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &flags)
+ACLNoteStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     if (const auto request = checklist->request) {
-        if (request->hasNotes() && matchNotes(data, request->notes().getRaw(), flags.delimiters()))
+        if (request->hasNotes() && matchNotes(data, request->notes().getRaw()))
             return 1;
 #if USE_ADAPTATION
         const Adaptation::History::Pointer ah = request->adaptLogHistory();
-        if (ah != NULL && ah->metaHeaders != NULL && matchNotes(data, ah->metaHeaders.getRaw(), flags.delimiters()))
+        if (ah != NULL && ah->metaHeaders != NULL && matchNotes(data, ah->metaHeaders.getRaw()))
             return 1;
 #endif
     }
@@ -32,20 +44,12 @@ ACLNoteStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *checklist
 }
 
 bool
-ACLNoteStrategy::matchNotes(ACLData<MatchType> *noteData, const NotePairs *note, const CharacterSet *delimiters) const
+ACLNoteStrategy::matchNotes(ACLData<MatchType> *noteData, const NotePairs *note) const
 {
-    const NotePairs::Entries &entries = note->expandListEntries(delimiters);
+    const NotePairs::Entries &entries = note->expandListEntries(&delimiters.value);
     for (auto e: entries)
         if (noteData->match(e.getRaw()))
             return true;
     return false;
 }
 
-ACLNoteStrategy *
-ACLNoteStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLNoteStrategy ACLNoteStrategy::Instance_;
-
index aa93ffe472bb28897ec0434984327c7ffa93bfdf..86fd1204cd2865f009be478efb24df16978a394b 100644 (file)
@@ -9,42 +9,36 @@
 #ifndef SQUID_ACLNOTE_H
 #define SQUID_ACLNOTE_H
 
-#include "acl/Strategised.h"
+#include "acl/CharacterSetOption.h"
+#include "acl/Data.h"
 #include "acl/Strategy.h"
+#include "Notes.h"
 
-class ACLNoteData;
-class CharacterSet;
-class HttpRequest;
+namespace Acl {
 
-/// \ingroup ACLAPI
-class ACLNoteStrategy : public ACLStrategy<NotePairs::Entry *>
+/// common parent of several ACLs dealing with transaction annotations
+class AnnotationStrategy: public ACLStrategy<NotePairs::Entry *>
 {
-
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
-    virtual bool requiresRequest() const { return true; }
+    AnnotationStrategy(): delimiters(CharacterSet(__FILE__, ",")) {}
 
-    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() { }
+    virtual const Acl::Options &options() override;
 
-    ACLNoteStrategy& operator = (ACLNoteStrategy const &);
-    bool matchNotes(ACLData<MatchType> *, const NotePairs *, const CharacterSet *) const;
+    Acl::CharacterSetOptionValue delimiters; ///< annotation separators
 };
 
+} // namespace Acl
+
 /// \ingroup ACLAPI
-class ACLNote
+class ACLNoteStrategy: public Acl::AnnotationStrategy
 {
 
+public:
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *);
+    virtual bool requiresRequest() const { return true; }
+
 private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<NotePairs::Entry *> RegistryEntry_;
+    bool matchNotes(ACLData<MatchType> *, const NotePairs *) const;
 };
 
 #endif /* SQUID_ACLNOTE_H */
diff --git a/src/acl/Options.cc b/src/acl/Options.cc
new file mode 100644 (file)
index 0000000..44d9e48
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#include "squid.h"
+#include "acl/Options.h"
+#include "ConfigParser.h"
+#include "Debug.h"
+#include "sbuf/Stream.h"
+
+#include <iostream>
+#include <vector>
+
+namespace Acl {
+
+/// low-level parser that extracts but does not interpret ACL options
+class OptionExtractor
+{
+public:
+    /// parses the next option and fills public members with its details
+    /// \returns whether option extraction was successful
+    bool extractOne();
+
+    /* extracted option details (after successful extraction */
+    SBuf name; ///< extracted option name, including dash(es)
+    bool hasValue = false; ///< whether the option has a value (-x=value)
+    const SBuf &value() const; ///< extracted option value (requires hasValue)
+
+protected:
+    bool advance();
+    void extractWhole();
+    void extractShort();
+
+private:
+    SBuf prefix_; ///< option name(s), including leading dash(es)
+    SBuf value_; ///< the last seen value of some option
+    SBuf::size_type letterPos_ = 0; ///< letter position inside an -xyz sequence
+    bool sawValue_ = false; ///< the current option sequence had a value
+};
+
+/// parses/validates/stores ACL options; skips/preserves parameter flags
+class OptionsParser
+{
+public:
+    OptionsParser(const Options &options, const ParameterFlags &flags);
+
+    // fill previously supplied options container, throwing on errors
+    void parse();
+
+private:
+    const Option *findOption(/* const */ SBuf &rawName);
+
+    /// ACL parameter flags in parsing order
+    typedef std::vector<OptionName> Names;
+    /// parsed ACL parameter flags that must be preserved for ACLData::parse()
+    static Names flagsToSkip;
+
+    const Options &options_; ///< caller-supported, linked options
+    const ParameterFlags &parameterFlags_; ///< caller-supported parameter flags
+};
+
+} // namespace Acl
+
+/* Acl::OptionNameCmp */
+
+bool
+Acl::OptionNameCmp::operator()(const OptionName a, const OptionName b) const
+{
+    return strcmp(a, b) < 0;
+}
+
+/* Acl::OptionExtractor */
+
+const SBuf &
+Acl::OptionExtractor::value() const
+{
+    Must(hasValue);
+    return value_;
+}
+
+bool
+Acl::OptionExtractor::extractOne()
+{
+    if (!prefix_.isEmpty()) {
+        extractShort(); // continue with the previously extracted flags
+        return true;
+    }
+
+    if (!advance())
+        return false; // end of options (and, possibly, the whole "acl" directive)
+
+    if (prefix_.length() < 2)
+        throw TexcHere(ToSBuf("truncated(?) ACL flag: ", prefix_)); // single - or +
+
+    if (prefix_[0] == '-' && prefix_[1] == '-') {
+        if (prefix_.length() == 2)
+            return false; // skipped "--", an explicit end-of-options marker
+        extractWhole();
+        return true;
+    }
+
+    if (prefix_.length() == 2) { // common trivial case: -x or +y
+        extractWhole();
+        return true;
+    }
+
+    // -xyz or +xyz
+    letterPos_ = 1;
+    extractShort();
+    return true;
+}
+
+/// extracts a token with the next option/flag(s) or returns false
+bool
+Acl::OptionExtractor::advance()
+{
+    const char *next = ConfigParser::PeekAtToken();
+    if (!next)
+        return false; // end of the "acl" line
+
+    const char nextChar = *next;
+    if (!(nextChar == '-' || nextChar == '+'))
+        return false; // start of ACL parameters
+
+    sawValue_ = strchr(next, '='); // TODO: Make ConfigParser reject '^=.*' tokens
+    if (sawValue_) {
+        char *rawPrefix = nullptr;
+        char *rawValue = nullptr;
+        if (!ConfigParser::NextKvPair(rawPrefix, rawValue))
+            throw TexcHere(ToSBuf("Malformed acl option=value: ", next));
+        prefix_.assign(rawPrefix);
+        value_.assign(rawValue);
+    } else {
+        prefix_.assign(next);
+        ConfigParser::NextToken(); // consume what we have peeked at
+    }
+    return true;
+}
+
+/// handles -x[=option] or --foo[=option]
+void
+Acl::OptionExtractor::extractWhole()
+{
+    debugs(28, 8, "from " << prefix_ << " value: " << sawValue_);
+    hasValue = sawValue_;
+    name = prefix_;
+    prefix_.clear();
+}
+
+/// handles one flag letter inside an -xyx[=option] or +xyz[=option] sequence
+void
+Acl::OptionExtractor::extractShort()
+{
+    debugs(28, 8, "from " << prefix_ << " at " << letterPos_ << " value: " << sawValue_);
+    name.assign(prefix_.rawContent(), 1); // leading - or +
+    name.append(prefix_.at(letterPos_++));
+    if (letterPos_ >= prefix_.length()) { // got last flag in the sequence
+        hasValue = sawValue_;
+        prefix_.clear();
+    } else {
+        hasValue = false;
+    }
+}
+
+/* Acl::OptionsParser */
+
+// being "static" is an optimization to avoid paying for vector creation/growth
+Acl::OptionsParser::Names Acl::OptionsParser::flagsToSkip;
+
+Acl::OptionsParser::OptionsParser(const Options &options, const ParameterFlags &flags):
+    options_(options),
+    parameterFlags_(flags)
+{
+}
+
+const Acl::Option *
+Acl::OptionsParser::findOption(/* const */ SBuf &rawNameBuf)
+{
+    // TODO: new std::map::find() in C++14 does not require this conversion
+    const auto rawName = rawNameBuf.c_str();
+
+    const auto optionPos = options_.find(rawName);
+    if (optionPos != options_.end())
+        return optionPos->second;
+
+    const auto flagPos = parameterFlags_.find(rawName);
+    if (flagPos != parameterFlags_.end()) {
+        flagsToSkip.push_back(*flagPos); // *flagPos is permanent unlike rawName
+        return nullptr;
+    }
+
+    throw TexcHere(ToSBuf("unsupported ACL option: ", rawNameBuf));
+}
+
+void
+Acl::OptionsParser::parse()
+{
+    flagsToSkip.clear();
+
+    OptionExtractor oex;
+    while (oex.extractOne()) {
+        /* const */ auto rawName = oex.name;
+        if (const Option *optionPtr = findOption(rawName)) {
+            const Option &option = *optionPtr;
+            if (option.configured())
+                debugs(28, 7, "acl uses multiple " << rawName << " options");
+            switch (option.valueExpectation)
+            {
+            case Option::valueNone:
+                if (oex.hasValue)
+                    throw TexcHere(ToSBuf("unexpected value for an ACL option: ", rawName, '=', oex.value()));
+                option.configureDefault();
+                break;
+            case Option::valueRequired:
+                if (!oex.hasValue)
+                    throw TexcHere(ToSBuf("missing required value for ACL option ", rawName));
+                option.configureWith(oex.value());
+                break;
+            case Option::valueOptional:
+                if (oex.hasValue)
+                    option.configureWith(oex.value());
+                else
+                    option.configureDefault();
+                break;
+            }
+        }
+        // else skip supported parameter flag
+    }
+
+    /* hack: regex code wants to parse all -i and +i flags itself */
+    for (const auto name: flagsToSkip)
+        ConfigParser::TokenPutBack(name);
+}
+
+void
+Acl::ParseFlags(const Options &options, const ParameterFlags &flags)
+{
+    OptionsParser parser(options, flags);
+    parser.parse();
+}
+
+const Acl::Options &
+Acl::NoOptions()
+{
+    static const Options none;
+    return none;
+}
+
+const Acl::ParameterFlags &
+Acl::NoFlags()
+{
+    static const ParameterFlags none;
+    return none;
+}
+
+std::ostream &
+operator <<(std::ostream &os, const Acl::Option &option)
+{
+    if (option.valued()) {
+        os << '=';
+        option.print(os);
+    }
+    return os;
+}
+
+std::ostream &
+operator <<(std::ostream &os, const Acl::Options &options)
+{
+    for (const auto pos: options) {
+        assert(pos.second);
+        const auto &option = *pos.second;
+        if (option.configured())
+            os << pos.first << option;
+    }
+    // TODO: Remember "--" presence and print that delimiter when present.
+    // Detecting its need is difficult because parameter flags start with "-".
+    return os;
+}
+
diff --git a/src/acl/Options.h b/src/acl/Options.h
new file mode 100644 (file)
index 0000000..f36c451
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#ifndef SQUID_ACL_OPTIONS_H
+#define SQUID_ACL_OPTIONS_H
+
+#include "acl/forward.h"
+#include "sbuf/forward.h"
+
+#include <iosfwd>
+#include <map>
+#include <set>
+
+// After all same-name acl configuration lines are merged into one ACL:
+//   configuration = acl name type [option...] [[flag...] parameter...]
+//   option = -x[=value] | --name[=value]
+//   flag = option
+//
+// Options and flags use the same syntax, but differ in scope and handling code:
+// * ACL options appear before all parameters and apply to all parameters.
+//   They are handled by ACL kids (or equivalent).
+// * Parameter flags may appear after some other parameters and apply only to
+//   the subsequent parameters (until they are overwritten by later flags).
+//   They are handled by ACLData kids.
+// ACL options parsing code skips and leaves leading parameter flags (if any)
+// for ACLData code to process.
+
+namespace Acl {
+
+typedef const char *OptionName;
+
+/// A single option supported by an ACL: -x[=value] or --name[=value]
+/// Unlike a parameter flag, this option applies to all ACL parameters.
+class Option
+{
+public:
+    typedef enum { valueNone, valueOptional, valueRequired } ValueExpectation;
+    explicit Option(ValueExpectation vex = valueNone): valueExpectation(vex) {}
+    virtual ~Option() {}
+
+    /// whether the admin explicitly specified this option
+    /// (i.e., whether configureWith() or configureDefault() has been called)
+    virtual bool configured() const = 0;
+
+    /// called after parsing -x or --name
+    virtual void configureDefault() const = 0;
+
+    /// called after parsing -x=value or --name=value
+    virtual void configureWith(const SBuf &rawValue) const = 0;
+
+    virtual bool valued() const = 0;
+
+    /// prints a configuration snippet (as an admin could have typed)
+    virtual void print(std::ostream &os) const = 0;
+
+    ValueExpectation valueExpectation = valueNone; ///< expect "=value" part?
+};
+
+/// Stores configuration of a typical boolean flag or a single-value Option.
+template <class Value>
+class OptionValue
+{
+public:
+    typedef Value value_type;
+
+    OptionValue(): value {} {}
+    explicit OptionValue(const Value &aValue): value(aValue) {}
+
+    explicit operator bool() const { return configured; }
+
+    Value value; ///< final value storage, possibly after conversions
+    bool configured = false; ///< whether the option was present in squid.conf
+    bool valued = false; ///< whether a configured option had a value
+};
+
+/// a type-specific Option (e.g., a boolean --toggle or -m=SBuf)
+template <class Recipient>
+class TypedOption: public Option
+{
+public:
+    //typedef typename Recipient::value_type value_type;
+    explicit TypedOption(ValueExpectation vex = valueNone): Option(vex) {}
+
+    /// who to tell when this option is enabled
+    void linkWith(Recipient *recipient) const
+    {
+        assert(recipient);
+        recipient_ = recipient;
+    }
+
+    /* Option API */
+
+    virtual bool configured() const override { return recipient_ && recipient_->configured; }
+    virtual bool valued() const override { return recipient_ && recipient_->valued; }
+
+    /// sets the default value when option is used without a value
+    virtual void configureDefault() const override
+    {
+        assert(recipient_);
+        recipient_->configured = true;
+        recipient_->valued = false;
+        // sets recipient_->value to default
+        setDefault();
+    }
+
+    /// sets the option value from rawValue
+    virtual void configureWith(const SBuf &rawValue) const override
+    {
+        assert(recipient_);
+        recipient_->configured = true;
+        recipient_->valued = true;
+        import(rawValue);
+    }
+
+    virtual void print(std::ostream &os) const override { if (valued()) os << recipient_->value; }
+
+private:
+    void import(const SBuf &rawValue) const { recipient_->value = rawValue; }
+    void setDefault() const { /*leave recipient_->value as is*/}
+
+    // The "mutable" specifier demarcates set-once Option kind/behavior from the
+    // ever-changing recipient of the actual admin-configured option value.
+    mutable Recipient *recipient_ = nullptr; ///< parsing results storage
+};
+
+/* two typical option kinds: --foo and --bar=text  */
+typedef OptionValue<bool> BooleanOptionValue;
+typedef OptionValue<SBuf> TextOptionValue;
+typedef TypedOption<BooleanOptionValue> BooleanOption;
+typedef TypedOption<TextOptionValue> TextOption;
+
+// this specialization should never be called until we start supporting
+// boolean option values like --name=enable or --name=false
+template <>
+inline void
+BooleanOption::import(const SBuf &) const
+{
+    assert(!"boolean options do not have ...=values (for now)");
+}
+
+template <>
+inline void
+BooleanOption::setDefault() const
+{
+    recipient_->value = true;
+}
+
+/// option name comparison functor
+class OptionNameCmp {
+public:
+    bool operator()(const OptionName a, const OptionName b) const;
+};
+/// name:option map
+typedef std::map<OptionName, const Option*, OptionNameCmp> Options;
+
+/// a set of parameter flag names
+typedef std::set<OptionName, OptionNameCmp> ParameterFlags;
+
+/// parses the flags part of the being-parsed ACL, filling Option values
+/// \param options options supported by the ACL as a whole (e.g., -n)
+/// \param flags options supported by ACL parameter(s) (e.g., -i)
+void ParseFlags(const Options &options, const ParameterFlags &flags);
+
+/* handy for Class::options() and Class::supportedFlags() defaults */
+const Options &NoOptions(); ///< \returns an empty Options container
+const ParameterFlags &NoFlags(); ///< \returns an empty ParameterFlags container
+
+} // namespace Acl
+
+std::ostream &operator <<(std::ostream &os, const Acl::Option &option);
+std::ostream &operator <<(std::ostream &os, const Acl::Options &options);
+
+#endif /* SQUID_ACL_OPTIONS_H */
+
index 702a90c31b2cca7b22d02bdfadc4537380b2c9c3..aa5aaf16cb974d15fc4bfade64ac88a6f8588bd9 100644 (file)
@@ -7,25 +7,16 @@
  */
 
 #include "squid.h"
-#include "acl/Checklist.h"
+#include "acl/FilledChecklist.h"
 #include "acl/PeerName.h"
 #include "acl/RegexData.h"
 #include "acl/StringData.h"
-#include "CachePeer.h"
 
 int
-ACLPeerNameStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLPeerNameStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     if (!checklist->dst_peer_name.isEmpty())
         return data->match(checklist->dst_peer_name.c_str());
     return 0;
 }
 
-ACLPeerNameStrategy *
-ACLPeerNameStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLPeerNameStrategy ACLPeerNameStrategy::Instance_;
-
index 84145ed4402715728518413d7376cc71e3b6806e..38e56f66f3ae2f84dcc5c6fedf869a2cc2dbd97b 100644 (file)
@@ -9,35 +9,13 @@
 #ifndef SQUID_ACLPEERNAME_H
 #define SQUID_ACLPEERNAME_H
 
-#include "acl/Strategised.h"
 #include "acl/Strategy.h"
 
 class ACLPeerNameStrategy : public ACLStrategy<const char *>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
-    static ACLPeerNameStrategy *Instance();
-    /* Not implemented to prevent copies of the instance. */
-    /* Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends */
-    ACLPeerNameStrategy(ACLPeerNameStrategy const &);
-
-private:
-    static ACLPeerNameStrategy Instance_;
-    ACLPeerNameStrategy() {}
-
-    ACLPeerNameStrategy&operator=(ACLPeerNameStrategy const &);
-};
-
-class ACLPeerName
-{
-
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<const char *> RegistryEntry_;
-    static ACL::Prototype RegexRegistryProtoype;
-    static ACLStrategised<char const *> RegexRegistryEntry_;
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *) override;
 };
 
 #endif /* SQUID_ACLPEERNAME_H */
index 551ac65b691f361b3740a2c0ecad99fc29ac8348..bf142bf6c80c676e6aaad904dc05723696387307 100644 (file)
@@ -7,9 +7,10 @@
  */
 
 #include "squid.h"
-#include "acl/Checklist.h"
+#include "acl/FilledChecklist.h"
 #include "acl/Protocol.h"
 #include "acl/ProtocolData.h"
+#include "acl/Strategised.h"
 #include "HttpRequest.h"
 
 /* explicit template instantiation required for some systems */
 template class ACLStrategised<AnyP::ProtocolType>;
 
 int
-ACLProtocolStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLProtocolStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     return data->match(checklist->request->url.getScheme());
 }
 
-ACLProtocolStrategy *
-ACLProtocolStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLProtocolStrategy ACLProtocolStrategy::Instance_;
-
index 9e541d8d8c9c62e70338d599b49f37480c786626..d157324cb57c83e10c11ad9e11c21d239c4d44e5 100644 (file)
@@ -9,7 +9,6 @@
 #ifndef SQUID_ACLPROTOCOL_H
 #define SQUID_ACLPROTOCOL_H
 
-#include "acl/Strategised.h"
 #include "acl/Strategy.h"
 #include "anyp/ProtocolType.h"
 
@@ -17,28 +16,8 @@ class ACLProtocolStrategy : public ACLStrategy<AnyP::ProtocolType>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *);
     virtual bool requiresRequest() const {return true;}
-
-    static ACLProtocolStrategy *Instance();
-    /* Not implemented to prevent copies of the instance. */
-    /* Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends */
-    ACLProtocolStrategy(ACLProtocolStrategy const &);
-
-private:
-    static ACLProtocolStrategy Instance_;
-    ACLProtocolStrategy() {}
-
-    ACLProtocolStrategy&operator=(ACLProtocolStrategy const &);
-};
-
-class ACLProtocol
-{
-
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<AnyP::ProtocolType> RegistryEntry_;
 };
 
 #endif /* SQUID_ACLPROTOCOL_H */
index f373facc1486885f4532cf3943d67af0f2912277..002e7d46d7ccb4207c480d259ac29fdba5e9c0c6 100644 (file)
@@ -10,7 +10,6 @@
 #define SQUID_ACL_RANDOM_H
 
 #include "acl/Acl.h"
-#include "acl/Checklist.h"
 
 class ACLRandom : public ACL
 {
@@ -31,8 +30,6 @@ public:
     virtual bool valid() const;
 
 protected:
-    static Prototype RegistryProtoype;
-    static ACLRandom RegistryEntry_;
     double data;        // value to be exceeded before this ACL will match
     char pattern[256];  // pattern from config file. Used to generate 'data'
     char const *class_;
diff --git a/src/acl/Referer.cc b/src/acl/Referer.cc
deleted file mode 100644 (file)
index 6f99c09..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
- *
- * Squid software is distributed under GPLv2+ license and includes
- * contributions from numerous individuals and organizations.
- * Please see the COPYING and CONTRIBUTORS files for details.
- */
-
-/* DEBUG: section 28    Access Control */
-
-#include "squid.h"
-#include "acl/Checklist.h"
-#include "acl/Referer.h"
-#include "acl/RegexData.h"
-
-/* explicit template instantiation required for some systems */
-
-template class ACLRequestHeaderStrategy<Http::HdrType::REFERER>;
-
diff --git a/src/acl/Referer.h b/src/acl/Referer.h
deleted file mode 100644 (file)
index 31c584a..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
- *
- * Squid software is distributed under GPLv2+ license and includes
- * contributions from numerous individuals and organizations.
- * Please see the COPYING and CONTRIBUTORS files for details.
- */
-
-#ifndef SQUID_ACLREFERER_H
-#define SQUID_ACLREFERER_H
-#include "acl/Acl.h"
-#include "acl/Data.h"
-#include "acl/RequestHeaderStrategy.h"
-#include "acl/Strategised.h"
-
-class ACLReferer
-{
-
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<char const *> RegistryEntry_;
-};
-
-#endif /* SQUID_ACLREFERER_H */
-
index a5ad88e09d5b6cefd0b6c9f579a5aa4457ec6e94..f6c33b5b3861b344d4b90a510ed25edf5162683a 100644 (file)
@@ -28,6 +28,13 @@ ACLRegexData::~ACLRegexData()
 {
 }
 
+const Acl::ParameterFlags &
+ACLRegexData::supportedFlags() const
+{
+    static const Acl::ParameterFlags flags = { "-i", "+i" };
+    return flags;
+}
+
 bool
 ACLRegexData::match(char const *word)
 {
index 862170ce567c1db449e5a52b25e0c890a341dd74..42c00cca6d28336f67ac79253afaa4a80be6711b 100644 (file)
@@ -24,6 +24,7 @@ public:
     virtual bool match(char const *user);
     virtual SBufList dump() const;
     virtual void parse();
+    virtual const Acl::ParameterFlags &supportedFlags() const;
     virtual bool empty() const;
     virtual ACLData<char const *> *clone() const;
 
index 69427772facae4d811ec01fff1ba55b237a2964e..a611f41cbaa99eab18cf7138757567bf2080d15c 100644 (file)
@@ -9,8 +9,6 @@
 #ifndef SQUID_ACLREPLYHEADERSTRATEGY_H
 #define SQUID_ACLREPLYHEADERSTRATEGY_H
 
-class ACLChecklist;
-
 #include "acl/Acl.h"
 #include "acl/Data.h"
 #include "acl/FilledChecklist.h"
@@ -22,25 +20,13 @@ class ACLReplyHeaderStrategy : public ACLStrategy<char const *>
 {
 
 public:
-    virtual int match (ACLData<char const *> * &, ACLFilledChecklist *, ACLFlags &);
+    virtual int match (ACLData<char const *> * &, ACLFilledChecklist *);
     virtual bool requiresReply() const {return true;}
-
-    static ACLReplyHeaderStrategy *Instance();
-    /* Not implemented to prevent copies of the instance. */
-    /* Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends */
-    ACLReplyHeaderStrategy(ACLReplyHeaderStrategy const &);
-
-private:
-    static ACLReplyHeaderStrategy *Instance_;
-    ACLReplyHeaderStrategy() {}
-
-    ACLReplyHeaderStrategy&operator=(ACLReplyHeaderStrategy const &);
 };
 
 template <Http::HdrType header>
 int
-ACLReplyHeaderStrategy<header>::match (ACLData<char const *> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLReplyHeaderStrategy<header>::match (ACLData<char const *> * &data, ACLFilledChecklist *checklist)
 {
     char const *theHeader = checklist->reply->header.getStr(header);
 
@@ -50,18 +36,5 @@ ACLReplyHeaderStrategy<header>::match (ACLData<char const *> * &data, ACLFilledC
     return data->match(theHeader);
 }
 
-template <Http::HdrType header>
-ACLReplyHeaderStrategy<header> *
-ACLReplyHeaderStrategy<header>::Instance()
-{
-    if (!Instance_)
-        Instance_ = new ACLReplyHeaderStrategy<header>;
-
-    return Instance_;
-}
-
-template <Http::HdrType header>
-ACLReplyHeaderStrategy<header> * ACLReplyHeaderStrategy<header>::Instance_ = NULL;
-
 #endif /* SQUID_REPLYHEADERSTRATEGY_H */
 
diff --git a/src/acl/ReplyMimeType.cc b/src/acl/ReplyMimeType.cc
deleted file mode 100644 (file)
index fbf9764..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
- *
- * Squid software is distributed under GPLv2+ license and includes
- * contributions from numerous individuals and organizations.
- * Please see the COPYING and CONTRIBUTORS files for details.
- */
-
-/* DEBUG: section 28    Access Control */
-
-#include "squid.h"
-#include "acl/Checklist.h"
-#include "acl/RegexData.h"
-#include "acl/ReplyMimeType.h"
-
-/* explicit template instantiation required for some systems */
-
-template class ACLReplyHeaderStrategy<Http::HdrType::CONTENT_TYPE>;
-
index 93d77c44bad225d85c42d7dc2c9516a31fbcec16..9ba376597483de8c60f0a756e9d8d4bc24316cff 100644 (file)
@@ -9,26 +9,15 @@
 #ifndef SQUID_ACLREPLYMIMETYPE_H
 #define SQUID_ACLREPLYMIMETYPE_H
 
-#include "acl/Acl.h"
-#include "acl/Strategised.h"
-
-class ACLReplyMIMEType
-{
-
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<char const *> RegistryEntry_;
-};
-
-/* partial specialisation */
-
-#include "acl/Checklist.h"
+#include "acl/FilledChecklist.h"
 #include "acl/Data.h"
 #include "acl/ReplyHeaderStrategy.h"
 
+/* partial specialisation */
+
 template <>
 inline int
-ACLReplyHeaderStrategy<Http::HdrType::CONTENT_TYPE>::match(ACLData<char const *> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLReplyHeaderStrategy<Http::HdrType::CONTENT_TYPE>::match(ACLData<char const *> * &data, ACLFilledChecklist *checklist)
 {
     char const *theHeader = checklist->reply->header.getStr(Http::HdrType::CONTENT_TYPE);
 
index f4c783aa7f36a5129a9bb2b16feae8c6f6b5b320..135587c4c14cbf5719d7efb8240bbde4c5ee1bae 100644 (file)
@@ -19,25 +19,13 @@ class ACLRequestHeaderStrategy : public ACLStrategy<char const *>
 {
 
 public:
-    virtual int match (ACLData<char const *> * &, ACLFilledChecklist *, ACLFlags &);
+    virtual int match (ACLData<char const *> * &, ACLFilledChecklist *);
     virtual bool requiresRequest() const {return true;}
-
-    static ACLRequestHeaderStrategy *Instance();
-    /* Not implemented to prevent copies of the instance. */
-    /* Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends */
-    ACLRequestHeaderStrategy(ACLRequestHeaderStrategy const &);
-
-private:
-    static ACLRequestHeaderStrategy *Instance_;
-    ACLRequestHeaderStrategy() {}
-
-    ACLRequestHeaderStrategy&operator=(ACLRequestHeaderStrategy const &);
 };
 
 template <Http::HdrType header>
 int
-ACLRequestHeaderStrategy<header>::match (ACLData<char const *> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLRequestHeaderStrategy<header>::match (ACLData<char const *> * &data, ACLFilledChecklist *checklist)
 {
     char const *theHeader = checklist->request->header.getStr(header);
 
@@ -47,18 +35,5 @@ ACLRequestHeaderStrategy<header>::match (ACLData<char const *> * &data, ACLFille
     return data->match(theHeader);
 }
 
-template <Http::HdrType header>
-ACLRequestHeaderStrategy<header> *
-ACLRequestHeaderStrategy<header>::Instance()
-{
-    if (!Instance_)
-        Instance_ = new ACLRequestHeaderStrategy<header>;
-
-    return Instance_;
-}
-
-template <Http::HdrType header>
-ACLRequestHeaderStrategy<header> * ACLRequestHeaderStrategy<header>::Instance_ = NULL;
-
 #endif /* SQUID_REQUESTHEADERSTRATEGY_H */
 
diff --git a/src/acl/RequestMimeType.cc b/src/acl/RequestMimeType.cc
deleted file mode 100644 (file)
index 508fdac..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
- *
- * Squid software is distributed under GPLv2+ license and includes
- * contributions from numerous individuals and organizations.
- * Please see the COPYING and CONTRIBUTORS files for details.
- */
-
-/* DEBUG: section 28    Access Control */
-
-#include "squid.h"
-#include "acl/Checklist.h"
-#include "acl/RegexData.h"
-#include "acl/RequestMimeType.h"
-
-/* explicit template instantiation required for some systems */
-
-template class ACLRequestHeaderStrategy<Http::HdrType::CONTENT_TYPE>;
-
index 4240d4acbde0c46454f91568d2bfa9c7f0b06fa7..6d269a4946b7483212d20527ebeb3d4b2e824bb1 100644 (file)
@@ -9,26 +9,15 @@
 #ifndef SQUID_ACLREQUESTMIMETYPE_H
 #define SQUID_ACLREQUESTMIMETYPE_H
 
-#include "acl/Acl.h"
-#include "acl/Strategised.h"
-
-class ACLRequestMIMEType
-{
-
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<char const *> RegistryEntry_;
-};
-
-/* partial specialisation */
-
-#include "acl/Checklist.h"
+#include "acl/FilledChecklist.h"
 #include "acl/Data.h"
 #include "acl/RequestHeaderStrategy.h"
 
+/* partial specialisation */
+
 template <>
 inline int
-ACLRequestHeaderStrategy<Http::HdrType::CONTENT_TYPE>::match (ACLData<char const *> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLRequestHeaderStrategy<Http::HdrType::CONTENT_TYPE>::match (ACLData<char const *> * &data, ACLFilledChecklist *checklist)
 {
     char const *theHeader = checklist->request->header.getStr(Http::HdrType::CONTENT_TYPE);
 
index 4c3a1a720c784a464342dcdc7b2bc5330cd708d0..e01d4d976fd952609c9a79ee02193905640e93f8 100644 (file)
@@ -19,7 +19,7 @@
 #include "ssl/ServerBump.h"
 
 int
-ACLServerCertificateStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLServerCertificateStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     Security::CertPointer cert;
     if (checklist->serverCert)
@@ -33,13 +33,5 @@ ACLServerCertificateStrategy::match(ACLData<MatchType> * &data, ACLFilledCheckli
     return data->match(cert.get());
 }
 
-ACLServerCertificateStrategy *
-ACLServerCertificateStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLServerCertificateStrategy ACLServerCertificateStrategy::Instance_;
-
 #endif /* USE_OPENSSL */
 
index 3631ab5127671a4a22117e46b8a81ca26af7bfc8..f26273aa29e425bd3bc37469ec03da480d558ecb 100644 (file)
 class ACLServerCertificateStrategy : public ACLStrategy<X509 *>
 {
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
-    static ACLServerCertificateStrategy *Instance();
-    /* Not implemented to prevent copies of the instance. */
-    /* Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends */
-    ACLServerCertificateStrategy(ACLServerCertificateStrategy const &);
-
-private:
-    static ACLServerCertificateStrategy Instance_;
-    ACLServerCertificateStrategy() {}
-
-    ACLServerCertificateStrategy&operator=(ACLServerCertificateStrategy const &);
-};
-
-/// \ingroup ACLAPI
-class ACLServerCertificate
-{
-private:
-    static ACL::Prototype X509FingerprintRegistryProtoype;
-    static ACLStrategised<X509*> X509FingerprintRegistryEntry_;
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *) override;
 };
 
 #endif /* SQUID_ACLSERVERCERTIFICATE_H */
index 3738943faafdb7377cacd6b2f2ef76a8eda68fed..15d02e9c3667835baf7a7a57edb86169960ec74f 100644 (file)
@@ -9,8 +9,8 @@
 /* DEBUG: section 28    Access Control */
 
 #include "squid.h"
-#include "acl/Checklist.h"
 #include "acl/DomainData.h"
+#include "acl/FilledChecklist.h"
 #include "acl/RegexData.h"
 #include "acl/ServerName.h"
 #include "client_side.h"
@@ -87,7 +87,7 @@ check_cert_domain( void *check_data, ASN1_STRING *cn_data)
 }
 
 int
-ACLServerNameStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &flags)
+ACLServerNameStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     assert(checklist != NULL && checklist->request != NULL);
 
@@ -116,11 +116,3 @@ ACLServerNameStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *ch
     return data->match(serverName);
 }
 
-ACLServerNameStrategy *
-ACLServerNameStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLServerNameStrategy ACLServerNameStrategy::Instance_;
-
index e31befa4494998abfbc4ece1f853a3167503963c..32af2dbd8a121c0b05d0be58d4f9f5778c88f8fc 100644 (file)
 #define SQUID_ACLSERVERNAME_H
 
 #include "acl/Acl.h"
-#include "acl/Checklist.h"
-#include "acl/Data.h"
 #include "acl/DomainData.h"
-#include "acl/Strategised.h"
+#include "acl/Strategy.h"
 
 class ACLServerNameData : public ACLDomainData {
     MEMPROXY_CLASS(ACLServerNameData);
@@ -27,33 +25,10 @@ class ACLServerNameStrategy : public ACLStrategy<char const *>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
-    static ACLServerNameStrategy *Instance();
+    /* ACLStrategy API */
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *);
     virtual bool requiresRequest() const {return true;}
 
-    /**
-     * Not implemented to prevent copies of the instance.
-     \par
-     * Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends
-     */
-    ACLServerNameStrategy(ACLServerNameStrategy const &);
-
-private:
-    static ACLServerNameStrategy Instance_;
-    ACLServerNameStrategy() {}
-
-    ACLServerNameStrategy&operator=(ACLServerNameStrategy const &);
-};
-
-class ACLServerName
-{
-
-private:
-    static ACL::Prototype LiteralRegistryProtoype;
-    static ACLStrategised<char const *> LiteralRegistryEntry_;
-    static ACL::Prototype RegexRegistryProtoype;
-    static ACLStrategised<char const *> RegexRegistryEntry_;
 };
 
 #endif /* SQUID_ACLSERVERNAME_H */
index 643f0feef9b3b9e405f177c236a21c57ca8aa20d..3b19bd6b938179861218ff301426413c8367d132 100644 (file)
@@ -18,18 +18,7 @@ class ACLSourceASNStrategy : public ACLStrategy<Ip::Address>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
-    static ACLSourceASNStrategy *Instance();
-    /* Not implemented to prevent copies of the instance. */
-    /* Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends */
-    ACLSourceASNStrategy(ACLSourceASNStrategy const &);
-
-private:
-    static ACLSourceASNStrategy Instance_;
-    ACLSourceASNStrategy() {}
-
-    ACLSourceASNStrategy&operator=(ACLSourceASNStrategy const &);
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *) override;
 };
 
 #endif /* SQUID_ACL_SOURCEASN_H */
index 4a5c5f7a78902f4c3494cf215f93c47f2cdab669..a76cd5bb8c34dfe75442292ad54556ff07bb67f3 100644 (file)
@@ -11,6 +11,7 @@
 #include "squid.h"
 #include "acl/Checklist.h"
 #include "acl/DomainData.h"
+#include "acl/FilledChecklist.h"
 #include "acl/RegexData.h"
 #include "acl/SourceDomain.h"
 #include "fqdncache.h"
@@ -40,7 +41,7 @@ SourceDomainLookup::LookupDone(const char *, const Dns::LookupDetails &details,
 }
 
 int
-ACLSourceDomainStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLSourceDomainStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     const char *fqdn = NULL;
     fqdn = fqdncache_gethostbyaddr(checklist->src_addr, FQDN_LOOKUP_IF_MISS);
@@ -58,11 +59,3 @@ ACLSourceDomainStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *
     return data->match("none");
 }
 
-ACLSourceDomainStrategy *
-ACLSourceDomainStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLSourceDomainStrategy ACLSourceDomainStrategy::Instance_;
-
index cd189e473335e6bb2f3edfaf4c94468c6b5c0ef0..d6ac22ae4d6b58f57057703c5df0cd6d012fa51b 100644 (file)
 #include "acl/Acl.h"
 #include "acl/Checklist.h"
 #include "acl/Data.h"
-#include "acl/Strategised.h"
+#include "acl/Strategy.h"
 #include "dns/forward.h"
 
 class ACLSourceDomainStrategy : public ACLStrategy<char const *>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
-    static ACLSourceDomainStrategy *Instance();
-    /* Not implemented to prevent copies of the instance. */
-    /* Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends */
-    ACLSourceDomainStrategy(ACLSourceDomainStrategy const &);
-
-private:
-    static ACLSourceDomainStrategy Instance_;
-    ACLSourceDomainStrategy() {}
-
-    ACLSourceDomainStrategy&operator=(ACLSourceDomainStrategy const &);
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *) override;
 };
 
 class SourceDomainLookup : public ACLChecklist::AsyncState
@@ -44,15 +33,5 @@ private:
     static void LookupDone(const char *, const Dns::LookupDetails &, void *);
 };
 
-class ACLSourceDomain
-{
-
-private:
-    static ACL::Prototype LiteralRegistryProtoype;
-    static ACLStrategised<char const *> LiteralRegistryEntry_;
-    static ACL::Prototype RegexRegistryProtoype;
-    static ACLStrategised<char const *> RegexRegistryEntry_;
-};
-
 #endif /* SQUID_ACLSOURCEDOMAIN_H */
 
index 4cf0968e60bc3fadd80725e2565a033e29db7d79..43633f5f7d368d37e3d093809c5ef70e81163924 100644 (file)
@@ -19,10 +19,6 @@ public:
     virtual char const *typeString() const;
     virtual int match(ACLChecklist *checklist);
     virtual ACL *clone()const;
-
-private:
-    static Prototype RegistryProtoype;
-    static ACLSourceIP RegistryEntry_;
 };
 
 #endif /* SQUID_ACLSOURCEIP_H */
index b31c758fffb2f6c4a252a43f50d926c2f03b4f91..5e760b46e352292231a86b6ee09fd1c05f5a9f42 100644 (file)
@@ -7,12 +7,12 @@
  */
 
 #include "squid.h"
-#include "acl/Checklist.h"
+#include "acl/FilledChecklist.h"
 #include "acl/SquidError.h"
 #include "HttpRequest.h"
 
 int
-ACLSquidErrorStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLSquidErrorStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     if (checklist->requestErrorType != ERR_MAX)
         return data->match(checklist->requestErrorType);
@@ -21,11 +21,3 @@ ACLSquidErrorStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *ch
     return 0;
 }
 
-ACLSquidErrorStrategy *
-ACLSquidErrorStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLSquidErrorStrategy ACLSquidErrorStrategy::Instance_;
-
index 7b119c2d3db872f2487e2a8f26df39d2cdc4252b..3bc2ff304b42827c4cb3a10d4e0f21689274d983 100644 (file)
@@ -9,7 +9,6 @@
 #ifndef SQUID_ACLSQUIDERROR_H
 #define SQUID_ACLSQUIDERROR_H
 
-#include "acl/Strategised.h"
 #include "acl/Strategy.h"
 #include "err_type.h"
 
@@ -17,27 +16,7 @@ class ACLSquidErrorStrategy : public ACLStrategy<err_type>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
-
-    static ACLSquidErrorStrategy *Instance();
-    /* Not implemented to prevent copies of the instance. */
-    /* Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends */
-    ACLSquidErrorStrategy(ACLSquidErrorStrategy const &);
-
-private:
-    static ACLSquidErrorStrategy Instance_;
-    ACLSquidErrorStrategy() {}
-
-    ACLSquidErrorStrategy&operator=(ACLSquidErrorStrategy const &);
-};
-
-class ACLSquidError
-{
-
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<err_type> RegistryEntry_;
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *) override;
 };
 
 #endif /* SQUID_ACLSQUIDERROR_H */
index bf82936a0ca99e51e3bc3920e150029649b92602..f21d808586f4e1b8765f914588ec08f41212130d 100644 (file)
@@ -7,21 +7,13 @@
  */
 
 #include "squid.h"
-#include "acl/Checklist.h"
+#include "acl/FilledChecklist.h"
 #include "acl/SslError.h"
 #include "acl/SslErrorData.h"
 
 int
-ACLSslErrorStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLSslErrorStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     return data->match (checklist->sslErrors);
 }
 
-ACLSslErrorStrategy *
-ACLSslErrorStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLSslErrorStrategy ACLSslErrorStrategy::Instance_;
-
index 036a3994cbe0386a0b93ddd035ba98e7154b5838..c4225c063409b6656dc9a57d3ff5a396dd842d41 100644 (file)
@@ -9,33 +9,14 @@
 #ifndef SQUID_ACLSSL_ERROR_H
 #define SQUID_ACLSSL_ERROR_H
 
-#include "acl/Strategised.h"
 #include "acl/Strategy.h"
+#include "security/forward.h"
 
 class ACLSslErrorStrategy : public ACLStrategy<const Security::CertErrors *>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
-    static ACLSslErrorStrategy *Instance();
-    /* Not implemented to prevent copies of the instance. */
-    /* Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends */
-    ACLSslErrorStrategy(ACLSslErrorStrategy const &);
-
-private:
-    static ACLSslErrorStrategy Instance_;
-    ACLSslErrorStrategy() {}
-
-    ACLSslErrorStrategy&operator=(ACLSslErrorStrategy const &);
-};
-
-class ACLSslError
-{
-
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<const Security::CertErrors *> RegistryEntry_;
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *) override;
 };
 
 #endif /* SQUID_ACLSSL_ERROR_H */
index 9a092e2f9f49bb6a8c65bfd42135dc2aa6240a0c..9043188c651fabf144e266ff4a8ffbca7562d375 100644 (file)
 #include "acl/FilledChecklist.h"
 #include "acl/Strategy.h"
 
+// XXX: Replace with a much simpler abstract ACL child class without the
+// ACLStrategy parameter (and associated call forwarding). Duplicating key
+// portions of the ACL class API in ACLStrategy is not needed because
+// ACLStrategy is unused outside the ACLStrategised context. Existing classes
+// like ACLExtUser, ACLProxyAuth, and ACLIdent seem to confirm this assertion.
+// It also requires forwarding ACL info to ACLStrategy as method parameters.
+
+/// Splits the ACL API into two individually configurable components:
+/// * ACLStrategy that usually extracts information from the current transaction
+/// * ACLData that usually matches information against admin-configured values
 template <class M>
 class ACLStrategised : public ACL
 {
@@ -23,24 +33,24 @@ public:
     typedef M MatchType;
 
     ~ACLStrategised();
-    ACLStrategised(ACLData<MatchType> *, ACLStrategy<MatchType> *, char const *, const ACLFlag flags[] = ACLFlags::NoFlags);
-    ACLStrategised (ACLStrategised const &);
-    ACLStrategised &operator= (ACLStrategised const &);
+    ACLStrategised(ACLData<MatchType> *, ACLStrategy<MatchType> *, char const *);
+    ACLStrategised(ACLStrategised const &&) = delete;
 
     virtual char const *typeString() const;
+    virtual void parseFlags();
+
     virtual bool requiresRequest() const {return matcher->requiresRequest();}
 
     virtual bool requiresReply() const {return matcher->requiresReply();}
 
     virtual void prepareForUse() { data->prepareForUse();}
-
+    virtual const Acl::Options &options() { return matcher->options(); }
     virtual void parse();
     virtual int match(ACLChecklist *checklist);
     virtual int match (M const &);
     virtual SBufList dump() const;
     virtual bool empty () const;
     virtual bool valid () const;
-    virtual ACL *clone()const;
 
 private:
     ACLData<MatchType> *data;
@@ -57,27 +67,21 @@ ACLStrategised<MatchType>::~ACLStrategised()
 }
 
 template <class MatchType>
-ACLStrategised<MatchType>::ACLStrategised(ACLData<MatchType> *newData, ACLStrategy<MatchType> *theStrategy, char const *theType, const ACLFlag flgs[]) : ACL(flgs), data (newData), type_(theType), matcher(theStrategy) {}
-
-template <class MatchType>
-ACLStrategised<MatchType>::ACLStrategised (ACLStrategised const &old) : data (old.data->clone()), type_(old.type_), matcher (old.matcher)
+ACLStrategised<MatchType>::ACLStrategised(ACLData<MatchType> *newData, ACLStrategy<MatchType> *theStrategy, char const *theType): data(newData), type_(theType), matcher(theStrategy)
 {}
 
 template <class MatchType>
-ACLStrategised<MatchType> &
-ACLStrategised<MatchType>::operator= (ACLStrategised const &rhs)
+char const *
+ACLStrategised<MatchType>::typeString() const
 {
-    data = rhs.data->clone();
-    type_ = rhs.type_;
-    matcher = rhs.matcher;
-    return *this;
+    return type_;
 }
 
 template <class MatchType>
-char const *
-ACLStrategised<MatchType>::typeString() const
+void
+ACLStrategised<MatchType>::parseFlags()
 {
-    return type_;
+    ParseFlags(options(), data->supportedFlags());
 }
 
 template <class MatchType>
@@ -100,7 +104,7 @@ ACLStrategised<MatchType>::match(ACLChecklist *cl)
 {
     ACLFilledChecklist *checklist = dynamic_cast<ACLFilledChecklist*>(cl);
     assert(checklist);
-    return matcher->match(data, checklist, flags);
+    return matcher->match(data, checklist);
 }
 
 template <class MatchType>
@@ -124,12 +128,5 @@ ACLStrategised<MatchType>::valid () const
     return matcher->valid();
 }
 
-template <class MatchType>
-ACL *
-ACLStrategised<MatchType>::clone() const
-{
-    return new ACLStrategised(*this);
-}
-
 #endif /* SQUID_ACLSTRATEGISED_H */
 
index 613d33f969b5e15ee6aa457efd67e31a986aac03..feaf5f8ce91cee2197a07db277a9e25edd08a361 100644 (file)
 
 #include "acl/Acl.h"
 #include "acl/Data.h"
+#include "acl/Options.h"
 
 class ACLFilledChecklist;
 
 template<class M>
 
+/// A matching algorithm.
 class ACLStrategy
 {
 
 public:
     typedef M MatchType;
-    virtual int match (ACLData<M> * &, ACLFilledChecklist *, ACLFlags &) = 0;
+
+    /* Replicate ACL API parts relevant to the matching algorithm. */
+    virtual const Acl::Options &options() { return Acl::NoOptions(); }
+    virtual int match (ACLData<M> * &, ACLFilledChecklist *) = 0;
     virtual bool requiresRequest() const {return false;}
 
     virtual bool requiresReply() const {return false;}
index e2143513d4452cab83f63d23914dec8feff235c0..e884b53e7095ca37f6d1b20f584cb44165cddfda 100644 (file)
@@ -7,24 +7,16 @@
  */
 
 #include "squid.h"
-#include "acl/Checklist.h"
+#include "acl/FilledChecklist.h"
 #include "acl/StringData.h"
 #include "acl/Tag.h"
 #include "HttpRequest.h"
 
 int
-ACLTagStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLTagStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     if (checklist->request != NULL)
         return data->match (checklist->request->tag.termedBuf());
     return 0;
 }
 
-ACLTagStrategy *
-ACLTagStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLTagStrategy ACLTagStrategy::Instance_;
-
index 2c3d9b2fea57a3bc587cb86c88b7435404fd22d7..4e093bf5139cc5b5a17bcc524b5a570b579a959d 100644 (file)
@@ -9,33 +9,13 @@
 #ifndef SQUID_ACLTAG_H
 #define SQUID_ACLTAG_H
 
-#include "acl/Strategised.h"
 #include "acl/Strategy.h"
 
 class ACLTagStrategy : public ACLStrategy<const char *>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
-    static ACLTagStrategy *Instance();
-    /* Not implemented to prevent copies of the instance. */
-    /* Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends */
-    ACLTagStrategy(ACLTagStrategy const &);
-
-private:
-    static ACLTagStrategy Instance_;
-    ACLTagStrategy() {}
-
-    ACLTagStrategy&operator=(ACLTagStrategy const &);
-};
-
-class ACLTag
-{
-
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<const char *> RegistryEntry_;
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *) override;
 };
 
 #endif /* SQUID_ACLMYPORTNAME_H */
index 03646df212d2ff4953c7bd823fc9c393bf7f6d21..0267ba7089ad8e1d4ac1ee156096d2c2f7abcfd8 100644 (file)
 #include "SquidTime.h"
 
 int
-ACLTimeStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *, ACLFlags &)
+ACLTimeStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *)
 {
     return data->match(squid_curtime);
 }
 
-ACLTimeStrategy *
-ACLTimeStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLTimeStrategy ACLTimeStrategy::Instance_;
-
index db749ffe1d90f86419d866acb2a52792761d9c77..41cd06a82fe568236f40b487697219056cdb0e05 100644 (file)
@@ -8,36 +8,14 @@
 
 #ifndef SQUID_ACLTIME_H
 #define SQUID_ACLTIME_H
-#include "acl/Acl.h"
 #include "acl/Data.h"
 #include "acl/Strategised.h"
 
-class ACLChecklist; // XXX: we do not need it
-
 class ACLTimeStrategy : public ACLStrategy<time_t>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
-    static ACLTimeStrategy *Instance();
-    /* Not implemented to prevent copies of the instance. */
-    /* Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends */
-    ACLTimeStrategy(ACLTimeStrategy const &);
-
-private:
-    static ACLTimeStrategy Instance_;
-    ACLTimeStrategy() {}
-
-    ACLTimeStrategy&operator=(ACLTimeStrategy const &);
-};
-
-class ACLTime
-{
-
-public:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<time_t> RegistryEntry_;
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *) override;
 };
 
 #endif /* SQUID_ACLTIME_H */
index b6b76d85a72992cb94731d8380cb4091ed52bb43..c744219c211fa3ed97ed185a4ee8bb8e1401e9af 100644 (file)
@@ -9,7 +9,7 @@
 /* DEBUG: section 28    Access Control */
 
 #include "squid.h"
-#include "acl/Checklist.h"
+#include "acl/FilledChecklist.h"
 #include "acl/RegexData.h"
 #include "acl/Url.h"
 #include "HttpRequest.h"
@@ -17,7 +17,7 @@
 #include "src/URL.h"
 
 int
-ACLUrlStrategy::match (ACLData<char const *> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLUrlStrategy::match (ACLData<char const *> * &data, ACLFilledChecklist *checklist)
 {
     char *esc_buf = SBufToCstring(checklist->request->effectiveRequestUri());
     rfc1738_unescape(esc_buf);
@@ -26,11 +26,3 @@ ACLUrlStrategy::match (ACLData<char const *> * &data, ACLFilledChecklist *checkl
     return result;
 }
 
-ACLUrlStrategy *
-ACLUrlStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLUrlStrategy ACLUrlStrategy::Instance_;
-
index 95dc02aaa1a4acbd48407adfd48d83439e29044d..950ef4341ac7591d8aee0545c205c40f72a65b23 100644 (file)
@@ -8,7 +8,7 @@
 
 #ifndef SQUID_ACLURL_H
 #define SQUID_ACLURL_H
-#include "acl/Acl.h"
+
 #include "acl/Data.h"
 #include "acl/Strategised.h"
 
@@ -16,29 +16,8 @@ class ACLUrlStrategy : public ACLStrategy<char const *>
 {
 
 public:
-    virtual int match (ACLData<char const *> * &, ACLFilledChecklist *, ACLFlags &);
+    virtual int match (ACLData<char const *> * &, ACLFilledChecklist *);
     virtual bool requiresRequest() const {return true;}
-
-    static ACLUrlStrategy *Instance();
-    /* Not implemented to prevent copies of the instance. */
-    /* Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends */
-    ACLUrlStrategy(ACLUrlStrategy const &);
-
-private:
-    static ACLUrlStrategy Instance_;
-    ACLUrlStrategy() {}
-
-    ACLUrlStrategy&operator=(ACLUrlStrategy const &);
-};
-
-class ACLUrl
-{
-
-public:
-    static ACL::Prototype RegistryProtoype;
-    static ACL::Prototype LegacyRegistryProtoype;
-    static ACLStrategised<char const *> RegistryEntry_;
 };
 
 #endif /* SQUID_ACLURL_H */
index 734c597db41a1ac10a6b3a2db5bfb58c4de62d69..52fae965d5e3da143f7ee92f7202a337d555fed4 100644 (file)
@@ -9,14 +9,14 @@
 /* DEBUG: section 28    Access Control */
 
 #include "squid.h"
-#include "acl/Checklist.h"
+#include "acl/FilledChecklist.h"
 #include "acl/RegexData.h"
 #include "acl/UrlLogin.h"
 #include "HttpRequest.h"
 #include "rfc1738.h"
 
 int
-ACLUrlLoginStrategy::match(ACLData<char const *> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLUrlLoginStrategy::match(ACLData<char const *> * &data, ACLFilledChecklist *checklist)
 {
     if (checklist->request->url.userInfo().isEmpty()) {
         debugs(28, 5, "URL has no user-info details. cannot match");
@@ -31,11 +31,3 @@ ACLUrlLoginStrategy::match(ACLData<char const *> * &data, ACLFilledChecklist *ch
     return data->match(str);
 }
 
-ACLUrlLoginStrategy *
-ACLUrlLoginStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLUrlLoginStrategy ACLUrlLoginStrategy::Instance_;
-
index 22fe41f5af21db590f8654c832daa03f3320ab83..bc635836cfb68ee39defd45fbace2e04dc157c0a 100644 (file)
 
 #include "acl/Acl.h"
 #include "acl/Data.h"
-#include "acl/Strategised.h"
 #include "acl/Strategy.h"
 
 class ACLUrlLoginStrategy : public ACLStrategy<char const *>
 {
 
 public:
-    virtual int match (ACLData<char const *> * &, ACLFilledChecklist *, ACLFlags &);
+    virtual int match (ACLData<char const *> * &, ACLFilledChecklist *);
     virtual bool requiresRequest() const {return true;}
-
-    static ACLUrlLoginStrategy *Instance();
-    /* Not implemented to prevent copies of the instance. */
-    /* Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends */
-    ACLUrlLoginStrategy(ACLUrlLoginStrategy const &);
-
-private:
-    static ACLUrlLoginStrategy Instance_;
-    ACLUrlLoginStrategy() {}
-
-    ACLUrlLoginStrategy&operator=(ACLUrlLoginStrategy const &);
-};
-
-class ACLUrlLogin
-{
-
-public:
-    static ACL::Prototype RegistryProtoype;
-    static ACL::Prototype LegacyRegistryProtoype;
-    static ACLStrategised<char const *> RegistryEntry_;
 };
 
 #endif /* SQUID_ACLURLLOGIN_H */
index 2ac2be006ed87f165ee7160a738e16bafc9a9052..c9a4f0aed4bacaf40b5a9adfb6a8a2fc458e4fac 100644 (file)
@@ -9,14 +9,14 @@
 /* DEBUG: section 28    Access Control */
 
 #include "squid.h"
-#include "acl/Checklist.h"
+#include "acl/FilledChecklist.h"
 #include "acl/RegexData.h"
 #include "acl/UrlPath.h"
 #include "HttpRequest.h"
 #include "rfc1738.h"
 
 int
-ACLUrlPathStrategy::match (ACLData<char const *> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLUrlPathStrategy::match (ACLData<char const *> * &data, ACLFilledChecklist *checklist)
 {
     if (checklist->request->url.path().isEmpty())
         return -1;
@@ -28,11 +28,3 @@ ACLUrlPathStrategy::match (ACLData<char const *> * &data, ACLFilledChecklist *ch
     return result;
 }
 
-ACLUrlPathStrategy *
-ACLUrlPathStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLUrlPathStrategy ACLUrlPathStrategy::Instance_;
-
index f249394a68f6ceb16343060205f6219394ee72de..571fafd35355b24b76d2466e2b2ffbfb499013cb 100644 (file)
@@ -8,38 +8,15 @@
 
 #ifndef SQUID_ACLURLPATH_H
 #define SQUID_ACLURLPATH_H
-#include "acl/Acl.h"
-#include "acl/Data.h"
-#include "acl/Strategised.h"
+
 #include "acl/Strategy.h"
 
 class ACLUrlPathStrategy : public ACLStrategy<char const *>
 {
 
 public:
-    virtual int match (ACLData<char const *> * &, ACLFilledChecklist *, ACLFlags &);
+    virtual int match (ACLData<char const *> * &, ACLFilledChecklist *);
     virtual bool requiresRequest() const {return true;}
-
-    static ACLUrlPathStrategy *Instance();
-    /* Not implemented to prevent copies of the instance. */
-    /* Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends */
-    ACLUrlPathStrategy(ACLUrlPathStrategy const &);
-
-private:
-    static ACLUrlPathStrategy Instance_;
-    ACLUrlPathStrategy() {}
-
-    ACLUrlPathStrategy&operator=(ACLUrlPathStrategy const &);
-};
-
-class ACLUrlPath
-{
-
-public:
-    static ACL::Prototype RegistryProtoype;
-    static ACL::Prototype LegacyRegistryProtoype;
-    static ACLStrategised<char const *> RegistryEntry_;
 };
 
 #endif /* SQUID_ACLURLPATH_H */
index c2f0ad11d138ca2e5e3dc59f652f38788fdcc03f..ae3797bbd67999554cbe2ca6aabdd6d55579afce 100644 (file)
@@ -7,22 +7,13 @@
  */
 
 #include "squid.h"
-#include "acl/Checklist.h"
-#include "acl/IntRange.h"
+#include "acl/FilledChecklist.h"
 #include "acl/UrlPort.h"
 #include "HttpRequest.h"
 
 int
-ACLUrlPortStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLUrlPortStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     return data->match(checklist->request->url.port());
 }
 
-ACLUrlPortStrategy *
-ACLUrlPortStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLUrlPortStrategy ACLUrlPortStrategy::Instance_;
-
index 19cd8caba4567ac96c06056ec22f890570eb8e47..d0bb64c57f3ad419a1e6340e78614f0e51c11ea6 100644 (file)
@@ -8,35 +8,15 @@
 
 #ifndef SQUID_ACLURLPORT_H
 #define SQUID_ACLURLPORT_H
-#include "acl/Strategised.h"
+
 #include "acl/Strategy.h"
 
 class ACLUrlPortStrategy : public ACLStrategy<int>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *);
     virtual bool requiresRequest() const {return true;}
-
-    static ACLUrlPortStrategy *Instance();
-    /* Not implemented to prevent copies of the instance. */
-    /* Not private to prevent brain dead g+++ warnings about
-     * private constructors with no friends */
-    ACLUrlPortStrategy(ACLUrlPortStrategy const &);
-
-private:
-    static ACLUrlPortStrategy Instance_;
-    ACLUrlPortStrategy() {}
-
-    ACLUrlPortStrategy&operator=(ACLUrlPortStrategy const &);
-};
-
-class ACLUrlPort
-{
-
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<int> RegistryEntry_;
 };
 
 #endif /* SQUID_ACLURLPORT_H */
index 755f340d8ee2829766dda3429aa746f329fbd507..5d425b9725f2ea25f50785f9b5e1b6fb1d179ef5 100644 (file)
@@ -29,6 +29,9 @@ class AndNode;
 class OrNode;
 class Tree;
 
+/// prepares to parse ACLs configuration
+void Init(void);
+
 } // namespace Acl
 
 class allow_t;
index 5ee8110e5c41abe985476c4b2ae90b5aaf494d49..71ff3e3ce5ddbf1aa364f6cf23747a5efcea8260 100644 (file)
 #include "Parsing.h"
 #include "wordlist.h"
 
-ACLFlag ACLMaxUserIP::SupportedFlags[] = {ACL_F_STRICT, ACL_F_END};
-
 ACLMaxUserIP::ACLMaxUserIP(char const *theClass) :
-    ACL(SupportedFlags),
     class_(theClass),
     maximum(0)
 {}
 
-ACLMaxUserIP::ACLMaxUserIP(ACLMaxUserIP const &old) :
-    class_(old.class_),
-    maximum(old.maximum)
-{
-    flags = old.flags;
-}
-
-ACLMaxUserIP::~ACLMaxUserIP()
-{}
-
 ACL *
 ACLMaxUserIP::clone() const
 {
@@ -60,6 +47,15 @@ ACLMaxUserIP::valid() const
     return maximum > 0;
 }
 
+const Acl::Options &
+ACLMaxUserIP::options()
+{
+    static const Acl::BooleanOption BeStrict;
+    static const Acl::Options MyOptions = { { "-s", &BeStrict } };
+    BeStrict.linkWith(&beStrict);
+    return MyOptions;
+}
+
 void
 ACLMaxUserIP::parse()
 {
@@ -102,7 +98,7 @@ ACLMaxUserIP::match(Auth::UserRequest::Pointer auth_user_request, Ip::Address co
     debugs(28, DBG_IMPORTANT, "aclMatchUserMaxIP: user '" << auth_user_request->username() << "' tries to use too many IP addresses (max " << maximum << " allowed)!");
 
     /* this is a match */
-    if (flags.isSet(ACL_F_STRICT)) {
+    if (beStrict) {
         /*
          * simply deny access - the user name is already associated with
          * the request
index 3487e23859b2d287c868993781e397e397c4fef7..c485324743c1f21addb90d9b7f9622bc6f32beb1 100644 (file)
@@ -12,7 +12,6 @@
 #if USE_AUTH
 
 #include "acl/Acl.h"
-#include "acl/Checklist.h"
 #include "auth/UserRequest.h"
 
 class ACLMaxUserIP : public ACL
@@ -20,13 +19,11 @@ class ACLMaxUserIP : public ACL
     MEMPROXY_CLASS(ACLMaxUserIP);
 
 public:
-    ACLMaxUserIP(char const *theClass);
-    ACLMaxUserIP(ACLMaxUserIP const &old);
-    ~ACLMaxUserIP();
-    ACLMaxUserIP &operator =(ACLMaxUserIP const &);
+    explicit ACLMaxUserIP(char const *theClass);
 
     virtual ACL *clone() const;
     virtual char const *typeString() const;
+    virtual const Acl::Options &options();
     virtual void parse();
     virtual int match(ACLChecklist *cl);
     virtual SBufList dump() const;
@@ -36,14 +33,13 @@ public:
 
     int getMaximum() const {return maximum;}
 
-    bool getStrict() const {return flags.isSet(ACL_F_STRICT);}
-
 private:
-    static Prototype RegistryProtoype;
-    static ACLMaxUserIP RegistryEntry_;
-    static ACLFlag SupportedFlags[];
-
     int match(Auth::UserRequest::Pointer auth_user_request, Ip::Address const &src_addr);
+
+public:
+    Acl::BooleanOptionValue beStrict; ///< Enforce "one user, one device" policy?
+
+private:
     char const *class_;
     int maximum;
 };
index 5763643da4244e0d1094f21761e35e6da5af3d2d..e81af5ae90a647774968fc164d868f010d0cfc07 100644 (file)
@@ -50,6 +50,12 @@ ACLProxyAuth::typeString() const
     return type_;
 }
 
+void
+ACLProxyAuth::parseFlags()
+{
+    ParseFlags(Acl::NoOptions(), data->supportedFlags());
+}
+
 void
 ACLProxyAuth::parse()
 {
index 59db9370b05b60892d5b34b3915c182d52cb1fc6..0901f1da3d6b15458e41aab741e8772b00e93b57 100644 (file)
@@ -37,24 +37,20 @@ public:
     ACLProxyAuth(ACLProxyAuth const &);
     ACLProxyAuth &operator =(ACLProxyAuth const &);
 
+    /* ACL API */
     virtual char const *typeString() const;
     virtual void parse();
     virtual bool isProxyAuth() const {return true;}
-
+    virtual void parseFlags();
     virtual int match(ACLChecklist *checklist);
     virtual SBufList dump() const;
     virtual bool valid() const;
     virtual bool empty() const;
     virtual bool requiresRequest() const {return true;}
-
     virtual ACL *clone() const;
     virtual int matchForCache(ACLChecklist *checklist);
 
 private:
-    static Prototype UserRegistryProtoype;
-    static ACLProxyAuth UserRegistryEntry_;
-    static Prototype RegexRegistryProtoype;
-    static ACLProxyAuth RegexRegistryEntry_;
     int matchProxyAuth(ACLChecklist *);
     ACLData<char const *> *data;
     char const *type_;
index 8bf088425c383793e2af5b22a1c3ccd57004902b..14173b010cd359b5a7e1f487af47de7fd1cb7b2c 100644 (file)
@@ -97,6 +97,15 @@ CharacterSet::CharacterSet(const char *label, std::initializer_list<std::pair<ui
         addRange(range.first, range.second);
 }
 
+void
+CharacterSet::printChars(std::ostream &os) const
+{
+    for (size_t idx = 0; idx < 256; ++idx) {
+        if (chars_[idx])
+            os << static_cast<char>(idx);
+    }
+}
+
 CharacterSet
 operator+ (CharacterSet lhs, const CharacterSet &rhs)
 {
index 1c1cfc6ed8238c07084e4e74c7694eb487a40425..2f9490de834118a68e38dfdc18367d699fa70f18 100644 (file)
@@ -19,9 +19,8 @@ class CharacterSet
 public:
     typedef std::vector<uint8_t> Storage;
 
-    /// define a character set with the given label ("anonymous" if nullptr)
-    ///  with specified initial contents
-    CharacterSet(const char *label, const char * const initial);
+    /// a character set with a given label and contents
+    explicit CharacterSet(const char *label = "anonymous", const char * const chars = "");
 
     /// define a character set with the given label ("anonymous" if nullptr)
     ///  containing characters defined in the supplied ranges
@@ -33,6 +32,9 @@ public:
     /// \see addRange
     CharacterSet(const char *label, std::initializer_list<std::pair<uint8_t,uint8_t>> ranges);
 
+    /// whether the set lacks any members
+    bool isEmpty() const { return chars_.empty(); }
+
     /// whether a given character exists in the set
     bool operator[](unsigned char c) const {return chars_[static_cast<uint8_t>(c)] != 0;}
 
@@ -60,6 +62,9 @@ public:
     /// \note Ignores label
     bool operator != (const CharacterSet &cs) const { return !operator==(cs); }
 
+    /// prints all chars in arbitrary order, without any quoting/escaping
+    void printChars(std::ostream &os) const;
+
     /// optional set label for debugging (default: "anonymous")
     const char * name;
 
index 815199a4c723587464a5f175b35f04e5958770de..1ff67e067a92a6ebcd5a2018f00cb60b02885dcd 100644 (file)
@@ -567,8 +567,9 @@ parseOneConfigFile(const char *file_name, unsigned int depth)
     return err_count;
 }
 
+static
 int
-parseConfigFile(const char *file_name)
+parseConfigFileOrThrow(const char *file_name)
 {
     int err_count = 0;
 
@@ -609,6 +610,20 @@ parseConfigFile(const char *file_name)
     return err_count;
 }
 
+// TODO: Refactor main.cc to centrally handle (and report) all exceptions.
+int
+parseConfigFile(const char *file_name)
+{
+    try {
+        return parseConfigFileOrThrow(file_name);
+    }
+    catch (const std::exception &ex) {
+        debugs(3, DBG_CRITICAL, "FATAL: bad configuration: " << ex.what());
+        self_destruct();
+        return 1; // not reached
+    }
+}
+
 static void
 configDoConfigure(void)
 {
@@ -1342,12 +1357,14 @@ dump_acl(StoreEntry * entry, const char *name, ACL * ae)
 {
     while (ae != NULL) {
         debugs(3, 3, "dump_acl: " << name << " " << ae->name);
-        storeAppendPrintf(entry, "%s %s %s %s ",
+        storeAppendPrintf(entry, "%s %s %s ",
                           name,
                           ae->name,
-                          ae->typeString(),
-                          ae->flags.flagsStr());
-        dump_SBufList(entry, ae->dump());
+                          ae->typeString());
+        SBufList tail;
+        tail.splice(tail.end(), ae->dumpOptions());
+        tail.splice(tail.end(), ae->dump()); // ACL parameters
+        dump_SBufList(entry, tail);
         ae = ae->next;
     }
 }
index c8c08fee81f705d914b22ae744b9f4fa71dfac83..f560af5c7496641eb03b7b9801bc3f69ec914f7e 100644 (file)
@@ -1149,17 +1149,6 @@ ExternalACLLookup::LookupDone(void *data, const ExternalACLEntryPointer &result)
     checklist->resumeNonBlockingCheck(ExternalACLLookup::Instance());
 }
 
-/* This registers "external" in the registry. To do dynamic definitions
- * of external ACL's, rather than a static prototype, have a Prototype instance
- * prototype in the class that defines each external acl 'class'.
- * Then, then the external acl instance is created, it self registers under
- * it's name.
- * Be sure that clone is fully functional for that acl class though!
- */
-ACL::Prototype ACLExternal::RegistryProtoype(&ACLExternal::RegistryEntry_, "external");
-
-ACLExternal ACLExternal::RegistryEntry_("external");
-
 ACL *
 ACLExternal::clone() const
 {
index d838a4dc19f4183eb0d5dadddca7f70fa515e798..d4dedbac4b46f76b4f682d305b3d0f5aa0c0556b 100644 (file)
@@ -46,6 +46,12 @@ ACLIdent::typeString() const
     return type_;
 }
 
+void
+ACLIdent::parseFlags()
+{
+    ParseFlags(Acl::NoOptions(), data->supportedFlags());
+}
+
 void
 ACLIdent::parse()
 {
index 37310b3d8ddef44ece4707a1579bd02d7a4c13ff..287430aed2c29d00582aa997c46fff45b9eda3d3 100644 (file)
@@ -40,20 +40,17 @@ public:
     ACLIdent & operator= (ACLIdent const &rhs);
     ~ACLIdent();
 
+    /* ACL API */
     virtual char const *typeString() const;
     virtual void parse();
     virtual bool isProxyAuth() const {return true;}
-
+    virtual void parseFlags();
     virtual int match(ACLChecklist *checklist);
     virtual SBufList dump() const;
     virtual bool empty () const;
     virtual ACL *clone()const;
 
 private:
-    static Prototype UserRegistryProtoype;
-    static ACLIdent UserRegistryEntry_;
-    static Prototype RegexRegistryProtoype;
-    static ACLIdent RegexRegistryEntry_;
     ACLData<char const *> *data;
     char const *type_;
 };
index 12f326caeb950e192c0ae01ac87b57984f33d74e..31bc25754270053abc5a5c707123f077200cbb04 100644 (file)
@@ -10,8 +10,9 @@
 
 #include "squid.h"
 #include "AccessLogEntry.h"
-#include "acl/Acl.h"
+//#include "acl/Acl.h"
 #include "acl/Asn.h"
+#include "acl/forward.h"
 #include "anyp/UriScheme.h"
 #include "auth/Config.h"
 #include "auth/Gadgets.h"
@@ -1556,6 +1557,7 @@ SquidMain(int argc, char **argv)
 
         /* we may want the parsing process to set this up in the future */
         Store::Init();
+        Acl::Init();
         Auth::Init();      /* required for config parsing. NOP if !USE_AUTH */
         Ip::ProbeTransport(); // determine IPv4 or IPv6 capabilities before parsing.
 
index 69b3686353aa23cb1b2812e7f705e92b5601651c..4965278c724767ab76744ebf2b3c71297ac4ebeb 100644 (file)
@@ -1130,51 +1130,9 @@ oid2addr(oid * id, Ip::Address &addr, u_int size)
         addr = i6addr;
 }
 
-/* SNMP checklists */
-#include "acl/Strategised.h"
-#include "acl/Strategy.h"
-#include "acl/StringData.h"
-
-class ACLSNMPCommunityStrategy : public ACLStrategy<char const *>
-{
-
-public:
-    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
-    static ACLSNMPCommunityStrategy *Instance();
-    /* Not implemented to prevent copies of the instance. */
-    /* Not private to prevent brain dead g++ warnings about
-     * private constructors with no friends */
-    ACLSNMPCommunityStrategy(ACLSNMPCommunityStrategy const &);
-
-private:
-    static ACLSNMPCommunityStrategy Instance_;
-    ACLSNMPCommunityStrategy() {}
-
-    ACLSNMPCommunityStrategy&operator=(ACLSNMPCommunityStrategy const &);
-};
-
-class ACLSNMPCommunity
-{
-
-private:
-    static ACL::Prototype RegistryProtoype;
-    static ACLStrategised<char const *> RegistryEntry_;
-};
-
-ACL::Prototype ACLSNMPCommunity::RegistryProtoype(&ACLSNMPCommunity::RegistryEntry_, "snmp_community");
-ACLStrategised<char const *> ACLSNMPCommunity::RegistryEntry_(new ACLStringData, ACLSNMPCommunityStrategy::Instance(), "snmp_community");
-
 int
-ACLSNMPCommunityStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+ACLSNMPCommunityStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     return data->match (checklist->snmp_community);
 }
 
-ACLSNMPCommunityStrategy *
-ACLSNMPCommunityStrategy::Instance()
-{
-    return &Instance_;
-}
-
-ACLSNMPCommunityStrategy ACLSNMPCommunityStrategy::Instance_;
-
index 541aa281abc0c8cb914a360917cc506e457dd1c3..ed89ef8a9d7eab96fb7e39ff0c285cbe8aec02ad 100644 (file)
@@ -11,6 +11,7 @@
 #ifndef SQUID_SNMP_CORE_H
 #define SQUID_SNMP_CORE_H
 
+#include "acl/Strategy.h"
 #include "cache_snmp.h"
 #include "comm/forward.h"
 #include "ip/forward.h"
@@ -51,5 +52,11 @@ const char * snmpDebugOid(oid * Name, snint Len, MemBuf &outbuf);
 void addr2oid(Ip::Address &addr, oid *Dest);
 void oid2addr(oid *Dest, Ip::Address &addr, u_int code);
 
+class ACLSNMPCommunityStrategy: public ACLStrategy<char const *>
+{
+public:
+    virtual int match (ACLData<MatchType> *&data, ACLFilledChecklist *checklist) override;
+};
+
 #endif /* SQUID_SNMP_CORE_H */
 
index d978d51b7dcae9b9919072d3f89e37f70c837432..487ef979cf419325b0393ffb2f1af404a63bb3d8 100644 (file)
@@ -20,8 +20,6 @@ allow_t AuthenticateAcl(ACLChecklist *) STUB_RETVAL(ACCESS_DENIED)
 #include "auth/AclMaxUserIp.h"
 ACL * ACLMaxUserIP::clone() const STUB_RETVAL(NULL)
 ACLMaxUserIP::ACLMaxUserIP (char const *) STUB
-ACLMaxUserIP::ACLMaxUserIP (ACLMaxUserIP const &) STUB
-ACLMaxUserIP::~ACLMaxUserIP() STUB
 char const * ACLMaxUserIP::typeString() const STUB_RETVAL(NULL)
 bool ACLMaxUserIP::empty () const STUB_RETVAL(false)
 bool ACLMaxUserIP::valid () const STUB_RETVAL(false)
@@ -29,6 +27,7 @@ void ACLMaxUserIP::parse() STUB
 int ACLMaxUserIP::match(Auth::UserRequest::Pointer, Ip::Address const &) STUB_RETVAL(0)
 int ACLMaxUserIP::match(ACLChecklist *) STUB_RETVAL(0)
 SBufList ACLMaxUserIP::dump() const STUB_RETVAL(SBufList())
+const Acl::Options &ACLMaxUserIP::options() STUB_RETVAL(Acl::NoOptions())
 
 #include "auth/AclProxyAuth.h"
 ACLProxyAuth::~ACLProxyAuth() STUB
@@ -47,6 +46,7 @@ void ProxyAuthLookup::LookupDone(void *) STUB
 ACL * ACLProxyAuth::clone() const STUB_RETVAL(NULL)
 int ACLProxyAuth::matchForCache(ACLChecklist *) STUB_RETVAL(0)
 int ACLProxyAuth::matchProxyAuth(ACLChecklist *) STUB_RETVAL(0)
+void ACLProxyAuth::parseFlags() STUB
 
 #endif /* USE_AUTH */
 
index 9185a4b8c2cb09c2be79776415988a03b52bf189..e1245f770959d2b4fb2f000f9e3419c24098dc53 100644 (file)
@@ -10,7 +10,9 @@
 
 #if USE_AUTH
 
+#include "acl/Acl.h"
 #include "auth/AclMaxUserIp.h"
+#include "auth/UserRequest.h"
 #include "ConfigParser.h"
 #include "testACLMaxUserIP.h"
 #include "unitTestMain.h"
@@ -26,13 +28,17 @@ testACLMaxUserIP::testDefaults()
     /* 0 is not a valid maximum, so we start at 0 */
     CPPUNIT_ASSERT_EQUAL(0,anACL.getMaximum());
     /* and we have no option to turn strict OFF, so start ON. */
-    CPPUNIT_ASSERT_EQUAL(false,anACL.getStrict());
+    CPPUNIT_ASSERT_EQUAL(false, static_cast<bool>(anACL.beStrict));
     /* an unparsed acl must not be valid - there is no sane default */
     CPPUNIT_ASSERT_EQUAL(false,anACL.valid());
 }
 
-ACL::Prototype ACLMaxUserIP::RegistryProtoype(&ACLMaxUserIP::RegistryEntry_, "max_user_ip");
-ACLMaxUserIP ACLMaxUserIP::RegistryEntry_("max_user_ip");
+void
+testACLMaxUserIP::setUp()
+{
+    CPPUNIT_NS::TestFixture::setUp();
+    Acl::RegisterMaker("max_user_ip", [](Acl::TypeName name)->ACL* { return new ACLMaxUserIP(name); });
+}
 
 void
 testACLMaxUserIP::testParseLine()
@@ -49,7 +55,7 @@ testACLMaxUserIP::testParseLine()
     if (maxUserIpACL) {
         /* we want a maximum of one, and strict to be true */
         CPPUNIT_ASSERT_EQUAL(1, maxUserIpACL->getMaximum());
-        CPPUNIT_ASSERT_EQUAL(true, maxUserIpACL->getStrict());
+        CPPUNIT_ASSERT_EQUAL(true, static_cast<bool>(maxUserIpACL->beStrict));
         /* the acl must be vaid */
         CPPUNIT_ASSERT_EQUAL(true, maxUserIpACL->valid());
     }
index d57d3d1bb3d37dd2b1dacd01d455954dca21a228..936f81dd8f0eebc7416ceec9cff7b0d9410289c5 100644 (file)
@@ -27,6 +27,7 @@ class testACLMaxUserIP : public CPPUNIT_NS::TestFixture
     CPPUNIT_TEST_SUITE_END();
 
 public:
+    virtual void setUp() override;
 
 protected:
     void testDefaults();