const char *ConfigParser::CfgLine = NULL;
const char *ConfigParser::CfgPos = NULL;
std::queue<char *> ConfigParser::CfgLineTokens_;
-std::queue<std::string> ConfigParser::Undo_;
bool ConfigParser::AllowMacros_ = false;
bool ConfigParser::ParseQuotedOrToEol_ = false;
bool ConfigParser::ParseKvPair_ = false;
cfg_filename, config_lineno, config_input_line);
}
-void
-ConfigParser::TokenPutBack(const char *tok)
-{
- assert(tok);
- Undo_.push(tok);
-}
-
-char *
-ConfigParser::Undo()
-{
- static char undoToken[CONFIG_LINE_LIMIT];
- if (!Undo_.empty()) {
- xstrncpy(undoToken, Undo_.front().c_str(), sizeof(undoToken));
- undoToken[sizeof(undoToken) - 1] = '\0';
- if (!PreviewMode_)
- Undo_.pop();
- return undoToken;
- }
- return NULL;
-}
-
char *
ConfigParser::strtokFile()
{
char *t;
static char buf[CONFIG_LINE_LIMIT];
- if ((t = ConfigParser::Undo()))
- return t;
-
do {
if (!fromFile) {
ConfigParser::NextToken()
{
char *token = NULL;
- if ((token = ConfigParser::Undo())) {
- debugs(3, 6, "TOKEN (undone): " << token);
- return token;
- }
do {
while (token == NULL && !CfgFiles.empty()) {
*/
static char *PeekAtToken();
- /**
- * The next NextToken call will return the token as next element
- * It can be used repeatedly to add more than one tokens in a FIFO list.
- */
- static void TokenPutBack(const char *token);
-
/// Set the configuration file line to parse.
static void SetCfgLine(char *line);
int lineNo; ///< Current line number
};
- /// Return the last TokenPutBack() queued element or NULL if none exist
- static char *Undo();
-
/**
* Unquotes the token, which must be quoted.
* \param next if it is not NULL, it is set after the end of token.
static const char *CfgLine; ///< The current line to parse
static const char *CfgPos; ///< Pointer to the next element in cfgLine string
static std::queue<char *> CfgLineTokens_; ///< Store the list of tokens for current configuration line
- static std::queue<std::string> Undo_; ///< The list with TokenPutBack() queued elements
static bool AllowMacros_;
static bool ParseQuotedOrToEol_; ///< The next tokens will be handled as quoted or to_eol token
static bool RecognizeQuotedPair_; ///< The next tokens may contain quoted-pair (\-escaped) characters
void
ACL::parseFlags()
{
- // ACL kids that carry ACLData which supports parameter flags override this
- Acl::ParseFlags(options(), Acl::NoFlags());
+ Acl::Options allOptions = options();
+ for (const auto lineOption: lineOptions()) {
+ lineOption->unconfigure(); // forget any previous "acl ..." line effects
+ allOptions.push_back(lineOption);
+ }
+ Acl::ParseFlags(allOptions);
}
SBufList
ACL::dumpOptions()
{
SBufList result;
+
const auto &myOptions = options();
+ // XXX: No lineOptions() call here because we do not remember ACL "line"
+ // boundaries and associated "line" options; we cannot report them.
+
// optimization: most ACLs do not have myOptions
// this check also works around dump_SBufList() adding ' ' after empty items
if (!myOptions.empty()) {
/// Updates the checklist state on match, async, and failure.
bool matches(ACLChecklist *checklist) const;
- /// \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();
+ void parseFlags();
/// parses node representation in squid.conf; dies on failures
virtual void parse() = 0;
virtual bool requiresRequest() const;
/// whether our (i.e. shallow) match() requires checklist to have a reply
virtual bool requiresReply() const;
+
+ // TODO: Rename to globalOptions(); these are not the only supported options
+ /// \returns (linked) 'global' Options supported by this ACL
+ virtual const Acl::Options &options() { return Acl::NoOptions(); }
+
+ /// \returns (linked) "line" Options supported by this ACL
+ /// \see ACL::options()
+ virtual const Acl::Options &lineOptions() { return Acl::NoOptions(); }
};
/// \ingroup ACLAPI
{
public:
typedef TypedOption<CharacterSetOptionValue> Parent;
- CharacterSetOption(): Parent(valueOptional) {}
+ explicit CharacterSetOption(const char *name): Parent(name, nullptr, valueOptional) {}
};
} // namespace Acl
ACLData(ACLData<M> &&) = delete; // no copying of any kind
virtual ~ACLData() {}
- /// \returns the flags supported by these ACL parameters (e.g., "-i")
- virtual const Acl::ParameterFlags &supportedFlags() const { return Acl::NoFlags(); }
+ /// supported ACL "line" options (e.g., "-i")
+ virtual const Acl::Options &lineOptions() { return Acl::NoOptions(); }
virtual bool match(M) =0;
virtual SBufList dump() const =0;
const Acl::Options &
ACLDestinationDomainStrategy::options()
{
- static const Acl::BooleanOption LookupBanFlag;
- static const Acl::Options MyOptions = { { "-n", &LookupBanFlag } };
+ static const Acl::BooleanOption LookupBanFlag("-n");
+ static const Acl::Options MyOptions = { &LookupBanFlag };
LookupBanFlag.linkWith(&lookupBanned);
return MyOptions;
}
const Acl::Options &
ACLDestinationIP::options()
{
- static const Acl::BooleanOption LookupBan;
- static const Acl::Options MyOptions = { { "-n", &LookupBan } };
+ static const Acl::BooleanOption LookupBan("-n");
+ static const Acl::Options MyOptions = { &LookupBan };
LookupBan.linkWith(&lookupBanned);
return MyOptions;
}
return type_;
}
-void
-ACLExtUser::parseFlags()
+const Acl::Options &
+ACLExtUser::lineOptions()
{
- ParseFlags(Acl::NoOptions(), data->supportedFlags());
+ return data->lineOptions();
}
void
/* 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;
private:
+ /* ACL API */
+ virtual const Acl::Options &lineOptions();
+
ACLData<char const *> *data;
char const *type_;
};
return sl;
}
+const Acl::Options &
+ACLHTTPHeaderData::lineOptions()
+{
+ return regex_rule->lineOptions();
+}
+
void
ACLHTTPHeaderData::parse()
{
virtual bool empty() const;
private:
+ /* ACLData API */
+ virtual const Acl::Options &lineOptions();
+
Http::HdrType hdrId; /**< set if header is known */
SBuf hdrName; /**< always set */
ACLData<char const *> * regex_rule;
const Acl::Options &
Acl::AnnotationStrategy::options()
{
- static const Acl::CharacterSetOption Delimiters;
- static const Acl::Options MyOptions = {
- { "-m", &Delimiters }
- };
+ static const Acl::CharacterSetOption Delimiters("-m");
+ static const Acl::Options MyOptions = { &Delimiters };
Delimiters.linkWith(&delimiters);
return MyOptions;
}
#include "sbuf/Stream.h"
#include <iostream>
+#include <utility>
#include <vector>
namespace Acl {
class OptionsParser
{
public:
- OptionsParser(const Options &options, const ParameterFlags &flags);
+ explicit OptionsParser(const Options &options);
// 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;
+ using SupportedOption = std::pair<const Option *, bool /* enable */ >;
+ SupportedOption supportedOption(const SBuf &name) const;
const Options &options_; ///< caller-supported, linked options
- const ParameterFlags ¶meterFlags_; ///< caller-supported parameter flags
};
} // namespace Acl
-/* Acl::OptionNameCmp */
+/* Acl::Option */
-bool
-Acl::OptionNameCmp::operator()(const OptionName a, const OptionName b) const
+Acl::Option::Option(const char * const nameThatEnables, const char * const nameThatDisables, const ValueExpectation vex):
+ onName(nameThatEnables),
+ offName(nameThatDisables),
+ valueExpectation(vex)
{
- return strcmp(a, b) < 0;
+ assert(onName);
}
/* Acl::OptionExtractor */
/* 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)
+Acl::OptionsParser::OptionsParser(const Options &options):
+ options_(options)
{
}
-const Acl::Option *
-Acl::OptionsParser::findOption(/* const */ SBuf &rawNameBuf)
+/// \returns named supported option paired with a name-based enable/disable flag
+Acl::OptionsParser::SupportedOption
+Acl::OptionsParser::supportedOption(const SBuf &name) const
{
- // 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;
+ for (const auto option: options_) {
+ if (name.cmp(option->onName) == 0)
+ return SupportedOption(option, true);
+ if (option->offName && name.cmp(option->offName) == 0)
+ return SupportedOption(option, false);
}
- throw TexcHere(ToSBuf("unsupported ACL option: ", rawNameBuf));
+ throw TexcHere(ToSBuf("unsupported ACL option: ", name));
}
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;
+ const auto explicitOption = supportedOption(oex.name);
+ const auto &option = *explicitOption.first;
+ if (explicitOption.second) {
+ /* configuration enables this option */
if (option.configured())
- debugs(28, 7, "acl uses multiple " << rawName << " options");
+ debugs(28, 7, "acl uses multiple " << oex.name << " options");
switch (option.valueExpectation)
{
case Option::valueNone:
if (oex.hasValue)
- throw TexcHere(ToSBuf("unexpected value for an ACL option: ", rawName, '=', oex.value()));
- option.configureDefault();
+ throw TexcHere(ToSBuf("unexpected value for an ACL option: ", oex.name, '=', oex.value()));
+ option.enable();
break;
case Option::valueRequired:
if (!oex.hasValue)
- throw TexcHere(ToSBuf("missing required value for ACL option ", rawName));
+ throw TexcHere(ToSBuf("missing required value for ACL option ", oex.name));
option.configureWith(oex.value());
break;
case Option::valueOptional:
if (oex.hasValue)
option.configureWith(oex.value());
else
- option.configureDefault();
+ option.enable();
break;
}
+ } else {
+ if (oex.hasValue)
+ throw TexcHere(ToSBuf("unexpected value when disabling an ACL option: ", oex.name, '=', oex.value()));
+ option.disable();
}
- // 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)
+Acl::ParseFlags(const Options &options)
{
- OptionsParser parser(options, flags);
+ OptionsParser parser(options);
parser.parse();
}
return none;
}
-const Acl::ParameterFlags &
-Acl::NoFlags()
+const Acl::BooleanOption &
+Acl::CaseSensitivityOption()
{
- static const ParameterFlags none;
- return none;
+ static const BooleanOption MyOption("-i", "+i");
+ return MyOption;
}
std::ostream &
operator <<(std::ostream &os, const Acl::Option &option)
{
- if (option.valued()) {
- os << '=';
- option.print(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;
- }
+ for (const auto option: options)
+ os << *option;
+
// TODO: Remember "--" presence and print that delimiter when present.
// Detecting its need is difficult because parameter flags start with "-".
return os;
#include "sbuf/forward.h"
#include <iosfwd>
-#include <map>
-#include <set>
+#include <vector>
-// 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
+// After line continuation is handled by the preprocessor, an ACL object
+// configuration can be visualized as a sequence of same-name "acl ..." lines:
//
-// 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.
+// L1: acl exampleA typeT parameter1 -i parameter2 parameter3
+// L2: acl exampleA typeT parameter4
+// L3: acl exampleA typeT -i -n parameter5 +i parameter6
+// L4: acl exampleA typeT -n parameter7
+//
+// There are two kinds of ACL options (a.k.a. flags):
+//
+// * Global (e.g., "-n"): Applies to all parameters regardless of where the
+// option was discovered/parsed (e.g., "-n" on L3 affects parameter2 on L1).
+// Declared by ACL class kids (or equivalent) via ACL::options().
+//
+// * Line (e.g., "-i"): Applies to the yet unparsed ACL parameters of the
+// current "acl ..." line (e.g., "-i" on L1 has no effect on parameter4 on L2)
+// Declared by ACLData class kids (or equivalent) via lineOptions().
+//
+// Here is the option:explicitly-affected-parameters map for the above exampleA:
+// "-n": parameter1-7 (i.e. all parameters)
+// "-i": parameter2, parameter3; parameter5
+// "+i": parameter6
+//
+// The option name spelling determines the option kind and effect.
+// Both option kinds use the same general option configuration syntax:
+// option = name [ '=' value ]
+// where "name" is option-specific spelling that looks like -x, +x, or --long
+//
+// On each "acl ..." line, global options can only appear before the first
+// parameter, while line options can go before any parameter.
+//
+// XXX: The fact that global options affect previous (and subsequent) same-name
+// "acl name ..." lines surprises and confuses those who comprehend ACLs in
+// terms of configuration lines (which Squid effectively merges together).
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) {}
+ explicit Option(const char *nameThatEnables, const char *nameThatDisables = nullptr, ValueExpectation vex = valueNone);
virtual ~Option() {}
- /// whether the admin explicitly specified this option
- /// (i.e., whether configureWith() or configureDefault() has been called)
+ /// whether the admin explicitly specified this option (i.e., whether
+ /// enable(), configureWith(), or disable() has been called)
virtual bool configured() const = 0;
- /// called after parsing -x or --name
- virtual void configureDefault() const = 0;
+ /// called after parsing onName without a value (e.g., -x or --enable-x)
+ virtual void enable() const = 0;
- /// called after parsing -x=value or --name=value
+ /// called after parsing onName and a value (e.g., -x=v or --enable-x=v)
virtual void configureWith(const SBuf &rawValue) const = 0;
+ /// called after parsing offName (e.g., +i or --disable-x)
+ virtual void disable() const = 0;
+
+ /// clear enable(), configureWith(), or disable() effects
+ virtual void unconfigure() const = 0;
+
+ /// whether disable() has been called
+ virtual bool disabled() 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;
+ /// A name that must be used to explicitly enable this Option (required).
+ const char * const onName = nullptr;
+
+ /// A name that must be used to explicitly disable this Option (optional).
+ /// Nil for (and only for) options that cannot be disabled().
+ const char * const offName = nullptr;
+
ValueExpectation valueExpectation = valueNone; ///< expect "=value" part?
};
public:
typedef Value value_type;
+ // TODO: Some callers use .value without checking whether the option is
+ // enabled(), accessing the (default-initialized or customized) default
+ // value that way. This trick will stop working if we add valued options
+ // that can be disabled (e.g., --with-foo=x --without-foo). To support such
+ // options, store the default value separately and provide value accessor.
+
OptionValue(): value {} {}
explicit OptionValue(const Value &aValue): value(aValue) {}
- explicit operator bool() const { return configured; }
+ /// whether the option is explicitly turned "on" (with or without a value)
+ bool enabled() const { return configured && !disabled; }
+ explicit operator bool() const { return enabled(); }
+
+ /// go back to the default-initialized state
+ void reset() { *this = OptionValue<Value>(); }
Value value; ///< final value storage, possibly after conversions
bool configured = false; ///< whether the option was present in squid.conf
+ /* flags for configured options */
+ bool disabled = false; ///< whether the option was turned off
bool valued = false; ///< whether a configured option had a value
};
{
public:
//typedef typename Recipient::value_type value_type;
- explicit TypedOption(ValueExpectation vex = valueNone): Option(vex) {}
+ explicit TypedOption(const char *nameThatEnables, const char *nameThatDisables = nullptr, ValueExpectation vex = valueNone):
+ Option(nameThatEnables, nameThatDisables, vex) {}
/// who to tell when this option is enabled
void linkWith(Recipient *recipient) const
/* Option API */
virtual bool configured() const override { return recipient_ && recipient_->configured; }
+ virtual bool disabled() const override { return recipient_ && recipient_->disabled && /* paranoid: */ offName; }
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
+ virtual void unconfigure() const override {
+ assert(recipient_);
+ recipient_->reset();
+ }
+
+ virtual void enable() const override
{
assert(recipient_);
recipient_->configured = true;
+ recipient_->disabled = false;
recipient_->valued = false;
- // sets recipient_->value to default
- setDefault();
+ // leave recipient_->value unchanged
}
- /// sets the option value from rawValue
virtual void configureWith(const SBuf &rawValue) const override
{
assert(recipient_);
recipient_->configured = true;
+ recipient_->disabled = false;
recipient_->valued = true;
import(rawValue);
}
- virtual void print(std::ostream &os) const override { if (valued()) os << recipient_->value; }
+ virtual void disable() const override
+ {
+ assert(recipient_);
+ recipient_->configured = true;
+ recipient_->disabled = true;
+ recipient_->valued = false;
+ // leave recipient_->value unchanged
+ }
+
+ virtual void print(std::ostream &os) const override
+ {
+ if (configured()) {
+ os << ' ' << (disabled() ? offName : onName);
+ if (valued())
+ os << '=' << recipient_->value;
+ }
+ // else do not report the implicit default
+ }
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.
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;
+using Options = std::vector<const Option *>;
/// 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);
+void ParseFlags(const Options &options);
-/* handy for Class::options() and Class::supportedFlags() defaults */
+/* handy for Class::options() and lineOptions() defaults */
const Options &NoOptions(); ///< \returns an empty Options container
-const ParameterFlags &NoFlags(); ///< \returns an empty ParameterFlags container
+
+/// A boolean option that controls case-sensitivity (-i/+i).
+/// An enabled (-i) state is "case insensitive".
+/// A disabled (+i) and default states are "case sensitive".
+const BooleanOption &CaseSensitivityOption();
} // namespace Acl
#include "sbuf/Algorithms.h"
#include "sbuf/List.h"
+Acl::BooleanOptionValue ACLRegexData::CaseInsensitive_;
+
ACLRegexData::~ACLRegexData()
{
}
-const Acl::ParameterFlags &
-ACLRegexData::supportedFlags() const
+const Acl::Options &
+ACLRegexData::lineOptions()
{
- static const Acl::ParameterFlags flags = { "-i", "+i" };
- return flags;
+ static auto MyCaseSensitivityOption = Acl::CaseSensitivityOption();
+ static const Acl::Options MyOptions = { &MyCaseSensitivityOption };
+ MyCaseSensitivityOption.linkWith(&CaseInsensitive_);
+ return MyOptions;
}
bool
* called only once per ACL.
*/
static int
-compileOptimisedREs(std::list<RegexPattern> &curlist, const SBufList &sl)
+compileOptimisedREs(std::list<RegexPattern> &curlist, const SBufList &sl, const int flagsAtLineStart)
{
std::list<RegexPattern> newlist;
SBufList accumulatedRE;
int numREs = 0, reSize = 0;
- int flags = REG_EXTENDED | REG_NOSUB;
+ auto flags = flagsAtLineStart;
for (const SBuf & configurationLineWord : sl) {
static const SBuf minus_i("-i");
}
static void
-compileUnoptimisedREs(std::list<RegexPattern> &curlist, const SBufList &sl)
+compileUnoptimisedREs(std::list<RegexPattern> &curlist, const SBufList &sl, const int flagsAtLineStart)
{
- int flags = REG_EXTENDED | REG_NOSUB;
+ auto flags = flagsAtLineStart;
static const SBuf minus_i("-i"), plus_i("+i");
for (auto configurationLineWord : sl) {
{
debugs(28, 2, "new Regex line or file");
+ int flagsAtLineStart = REG_EXTENDED | REG_NOSUB;
+ if (CaseInsensitive_)
+ flagsAtLineStart |= REG_ICASE;
+
SBufList sl;
while (char *t = ConfigParser::RegexStrtokFile()) {
const char *clean = removeUnnecessaryWildcards(t);
}
}
- if (!compileOptimisedREs(data, sl)) {
+ if (!compileOptimisedREs(data, sl, flagsAtLineStart)) {
debugs(28, DBG_IMPORTANT, "WARNING: optimisation of regular expressions failed; using fallback method without optimisation");
- compileUnoptimisedREs(data, sl);
+ compileUnoptimisedREs(data, sl, flagsAtLineStart);
}
}
virtual bool match(char const *user);
virtual SBufList dump() const;
virtual void parse();
- virtual const Acl::ParameterFlags &supportedFlags() const;
virtual bool empty() const;
private:
+ /// whether parse() is called in a case insensitive context
+ static Acl::BooleanOptionValue CaseInsensitive_;
+
+ /* ACLData API */
+ virtual const Acl::Options &lineOptions();
+
std::list<RegexPattern> data;
};
const Acl::Options &
ACLServerNameStrategy::options()
{
- static const Acl::BooleanOption ClientRequested;
- static const Acl::BooleanOption ServerProvided;
- static const Acl::BooleanOption Consensus;
- static const Acl::Options MyOptions = {
- {"--client-requested", &ClientRequested},
- {"--server-provided", &ServerProvided},
- {"--consensus", &Consensus}
- };
-
+ static const Acl::BooleanOption ClientRequested("--client-requested");
+ static const Acl::BooleanOption ServerProvided("--server-provided");
+ static const Acl::BooleanOption Consensus("--consensus");
+ static const Acl::Options MyOptions = { &ClientRequested, &ServerProvided, &Consensus };
ClientRequested.linkWith(&useClientRequested);
ServerProvided.linkWith(&useServerProvided);
Consensus.linkWith(&useConsensus);
ACLStrategised(ACLData<MatchType> *, ACLStrategy<MatchType> *, char const *);
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 bool valid () const;
private:
+ /* ACL API */
+ virtual const Acl::Options &options() { return matcher->options(); }
+ virtual const Acl::Options &lineOptions() { return data->lineOptions(); }
+
ACLData<MatchType> *data;
char const *type_;
ACLStrategy<MatchType> *matcher;
return type_;
}
-template <class MatchType>
-void
-ACLStrategised<MatchType>::parseFlags()
-{
- ParseFlags(options(), data->supportedFlags());
-}
-
template <class MatchType>
void
ACLStrategised<MatchType>::parse()
#include "squid.h"
#include "acl/Checklist.h"
+#include "acl/Options.h"
#include "acl/UserData.h"
#include "ConfigParser.h"
#include "Debug.h"
#include "sbuf/Algorithms.h"
#include "util.h"
-const Acl::ParameterFlags &
-ACLUserData::supportedFlags() const
-{
- static const Acl::ParameterFlags flagNames = { "-i", "+i" };
- return flagNames;
-}
+Acl::BooleanOptionValue ACLUserData::CaseInsensitive_;
bool
ACLUserData::match(char const *user)
flags.required = false;
}
+const Acl::Options &
+ACLUserData::lineOptions()
+{
+ static auto MyCaseSensitivityOption = Acl::CaseSensitivityOption();
+ static const Acl::Options MyOptions = { &MyCaseSensitivityOption };
+ MyCaseSensitivityOption.linkWith(&CaseInsensitive_);
+ return MyOptions;
+}
+
void
ACLUserData::parse()
{
debugs(28, 2, "parsing user list");
+ flags.case_insensitive = bool(CaseInsensitive_);
char *t = NULL;
if ((t = ConfigParser::strtokFile())) {
ACLUserData();
bool match(char const *user);
virtual SBufList dump() const;
- void parse();
- virtual const Acl::ParameterFlags &supportedFlags() const;
+ virtual void parse();
bool empty() const;
private:
+ /// whether parse() is called in a case insensitive context
+ static Acl::BooleanOptionValue CaseInsensitive_;
+
+ /* ACLData API */
+ virtual const Acl::Options &lineOptions();
typedef std::set<SBuf,bool(*)(const SBuf&, const SBuf&)> UserDataNames_t;
UserDataNames_t userDataNames;
const Acl::Options &
ACLMaxUserIP::options()
{
- static const Acl::BooleanOption BeStrict;
- static const Acl::Options MyOptions = { { "-s", &BeStrict } };
+ static const Acl::BooleanOption BeStrict("-s");
+ static const Acl::Options MyOptions = { &BeStrict };
BeStrict.linkWith(&beStrict);
return MyOptions;
}
return type_;
}
-void
-ACLProxyAuth::parseFlags()
+const Acl::Options &
+ACLProxyAuth::lineOptions()
{
- ParseFlags(Acl::NoOptions(), data->supportedFlags());
+ return data->lineOptions();
}
void
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 int matchForCache(ACLChecklist *checklist);
private:
+ /* ACL API */
+ virtual const Acl::Options &lineOptions();
+
int matchProxyAuth(ACLChecklist *);
ACLData<char const *> *data;
char const *type_;
return type_;
}
-void
-ACLIdent::parseFlags()
+const Acl::Options &
+ACLIdent::lineOptions()
{
- ParseFlags(Acl::NoOptions(), data->supportedFlags());
+ return data->lineOptions();
}
void
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;
private:
+ /* ACL API */
+ virtual const Acl::Options &lineOptions();
+
ACLData<char const *> *data;
char const *type_;
};
void ProxyAuthLookup::LookupDone(void *) STUB
int ACLProxyAuth::matchForCache(ACLChecklist *) STUB_RETVAL(0)
int ACLProxyAuth::matchProxyAuth(ACLChecklist *) STUB_RETVAL(0)
-void ACLProxyAuth::parseFlags() STUB
+const Acl::Options &ACLProxyAuth::lineOptions() STUB_RETVAL(Acl::NoOptions())
#endif /* USE_AUTH */