#endif
#include "acl/FilledChecklist.h"
#include "acl/Gadgets.h"
+#include "acl/HasComponent.h"
+#include "acl/HasComponentData.h"
#include "acl/HierCode.h"
#include "acl/HierCodeData.h"
#include "acl/HttpHeaderData.h"
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");
+
--- /dev/null
+/*
+ * 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/HasComponent.h"
+#include "acl/HasComponentData.h"
+
+int
+ACLHasComponentStrategy::match(ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &flags)
+{
+ ACLHasComponentData *cdata = dynamic_cast<ACLHasComponentData*>(data);
+ assert(cdata);
+ return cdata->match(checklist);
+}
+
+ACLHasComponentStrategy *
+ACLHasComponentStrategy::Instance()
+{
+ return &Instance_;
+}
+
+ACLHasComponentStrategy ACLHasComponentStrategy::Instance_;
+
--- /dev/null
+/*
+ * 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_ACLHASCOMPONENT_H
+#define SQUID_ACLHASCOMPONENT_H
+
+#include "acl/Strategised.h"
+#include "acl/Strategy.h"
+
+/// \ingroup ACLAPI
+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_;
+};
+
+#endif
+
--- /dev/null
+/*
+ * 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/HasComponentData.h"
+#include "cache_cf.h"
+#include "ConfigParser.h"
+#include "sbuf/Algorithms.h"
+
+
+const SBuf ACLHasComponentData::RequestStr("request");
+const SBuf ACLHasComponentData::ResponseStr("response");
+const SBuf ACLHasComponentData::AleStr("ALE");
+
+ACLHasComponentData::ACLHasComponentData()
+ : componentMethods(coEnd, nullptr)
+{ }
+
+void
+ACLHasComponentData::parse()
+{
+ const char *tok = ConfigParser::NextToken();
+ if (!tok) {
+ debugs(28, DBG_CRITICAL, "FATAL: \"has\" acl argument missing");
+ self_destruct();
+ return;
+ }
+ if (ConfigParser::PeekAtToken()) {
+ debugs(28, DBG_CRITICAL, "FATAL: multiple components not supported for \"has\" acl");
+ self_destruct();
+ return;
+ }
+ parseComponent(tok);
+}
+
+bool
+ACLHasComponentData::match(ACLChecklist *checklist)
+{
+ for (const auto method: componentMethods)
+ if (method && (checklist->*method)())
+ return true;
+ return false;
+}
+
+SBufList
+ACLHasComponentData::dump() const
+{
+ SBufList sl;
+ if (componentMethods.at(coRequest))
+ sl.push_back(RequestStr);
+ if (componentMethods.at(coResponse))
+ sl.push_back(ResponseStr);
+ if (componentMethods.at(coAle))
+ sl.push_back(AleStr);
+ return sl;
+}
+
+void
+ACLHasComponentData::parseComponent(const char *token)
+{
+ if (RequestStr.cmp(token) == 0)
+ componentMethods[coRequest] = &ACLChecklist::hasRequest;
+ else if (ResponseStr.cmp(token) == 0)
+ componentMethods[coResponse] = &ACLChecklist::hasReply;
+ else if (AleStr.cmp(token) == 0)
+ componentMethods[coAle] = &ACLChecklist::hasAle;
+ else {
+ debugs(28, DBG_CRITICAL, "FATAL: unsupported component '" << token << "' for 'has' acl");
+ self_destruct();
+ }
+}
+
+ACLData<ACLChecklist *> *
+ACLHasComponentData::clone() const
+{
+ return new ACLHasComponentData(*this);
+}
+
--- /dev/null
+/*
+ * 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_ACLHASCOMPONENTDATA_H
+#define SQUID_ACLHASCOMPONENTDATA_H
+
+#include "acl/Checklist.h"
+#include "acl/Data.h"
+
+/// \ingroup ACLAPI
+class ACLHasComponentData : public ACLData<ACLChecklist *>
+{
+ MEMPROXY_CLASS(ACLHasComponentData);
+
+public:
+ ACLHasComponentData();
+
+ /* ACLData<M> API */
+ virtual bool match(ACLChecklist *) override;
+ virtual SBufList dump() const override;
+ virtual void parse() override;
+ virtual bool empty() const override { return false; }
+ virtual ACLData<ACLChecklist *> *clone() const override;
+
+private:
+ enum ComponentKind { coRequest = 0, coResponse, coAle, coEnd };
+ void parseComponent(const char *token);
+
+ static const SBuf RequestStr;
+ static const SBuf ResponseStr;
+ static const SBuf AleStr;
+
+ typedef bool (ACLChecklist::*ComponentCheck)() const;
+ /// component check callbacks, ordered by component kind ID
+ std::vector<ComponentCheck> componentMethods;
+};
+
+#endif
+
DomainData.h \
ExtUser.cc \
ExtUser.h \
+ HasComponent.cc \
+ HasComponent.h \
+ HasComponentData.cc \
+ HasComponentData.h \
HierCodeData.cc \
HierCodeData.h \
HierCode.cc \
# adaptation_meta because it starts matching immediately after
# the service has been selected for adaptation.
+ acl aclname has component
+ # matches a transaction "component" [fast]
+ #
+ # Supported transaction components are:
+ # request: transaction has a request header (at least)
+ # response: transaction has a response header (at least)
+ # ALE: transaction has an internally-generated Access Log Entry
+ # structure; bugs notwithstanding, all transaction have it
+ #
+ # For example, the following configuration helps when dealing with HTTP
+ # clients that close connections without sending a request header:
+ #
+ # acl hasRequest has request
+ # acl logMe note important_transaction
+ # # avoid "logMe ACL is used in context without an HTTP request" warnings
+ # access_log ... logformat=detailed hasRequest logMe
+ # # log request-less transactions, instead of ignoring them
+ # access_log ... logformat=brief !hasRequest
+ #
+ # Multiple components are not supported for one "acl" rule, but
+ # can be specified (and are ORed) using multiple same-name rules:
+ #
+ # # OK, this strange logging daemon needs request or response,
+ # # but can work without either a request or a response:
+ # acl hasWhatMyLoggingDaemonNeeds has request
+ # acl hasWhatMyLoggingDaemonNeeds has response
+
IF USE_OPENSSL
acl aclname ssl_error errorname
# match against SSL certificate validation error [fast]