/* * Copyright (C) 1996-2018 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_NOTES_H #define SQUID_NOTES_H #include "acl/forward.h" #include "base/RefCount.h" #include "CbDataList.h" #include "format/Format.h" #include "MemPool.h" #include "SquidString.h" #include "typedefs.h" #include #include class HttpRequest; class HttpReply; typedef RefCount AccessLogEntryPointer; /** * Used to store a note configuration. The notes are custom key:value * pairs ICAP request headers or ECAP options used to pass * custom transaction-state related meta information to squid * internal subsystems or to adaptation services. */ class Note: public RefCountable { public: typedef RefCount Pointer; /// Stores a value for the note. class Value: public RefCountable { public: typedef RefCount Pointer; String value; ///< Configured annotation value, possibly with %macros ACLList *aclList; ///< The access list used to determine if this value is valid for a request /// Compiled annotation value format Format::Format *valueFormat; explicit Value(const String &aVal) : value(aVal), aclList(NULL), valueFormat(NULL) {} ~Value(); }; typedef std::vector Values; explicit Note(const String &aKey): key(aKey) {} /** * Adds a value to the note and returns a pointer to the * related Value object. */ Value::Pointer addValue(const String &value); /** * Walks through the possible values list of the note and selects * the first value which matches the given HttpRequest and HttpReply * or NULL if none matches. * If an AccessLogEntry given and Value::valueFormat is not null, the * formatted value returned. */ const char *match(HttpRequest *request, HttpReply *reply, const AccessLogEntryPointer &al); String key; ///< The note key Values values; ///< The possible values list for the note }; class ConfigParser; /** * Used to store a notes configuration list. */ class Notes { public: typedef std::vector NotesList; typedef NotesList::iterator iterator; ///< iterates over the notes list typedef NotesList::const_iterator const_iterator; ///< iterates over the notes list Notes(const char *aDescr, const char **metasBlacklist, bool allowFormatted = false): descr(aDescr), blacklisted(metasBlacklist), formattedValues(allowFormatted) {} Notes(): descr(NULL), blacklisted(NULL), formattedValues(false) {} ~Notes() { notes.clear(); } /** * Parse a notes line and returns a pointer to the * parsed Note object. */ Note::Pointer parse(ConfigParser &parser); /** * Dump the notes list to the given StoreEntry object. */ void dump(StoreEntry *entry, const char *name); void clean(); /// clean the notes list /// points to the first argument iterator begin() { return notes.begin(); } /// points to the end of list iterator end() { return notes.end(); } /// return true if the notes list is empty bool empty() { return notes.empty(); } NotesList notes; ///< The Note::Pointer objects array list const char *descr; ///< A short description for notes list const char **blacklisted; ///< Null terminated list of blacklisted note keys bool formattedValues; ///< Whether the formatted values are supported private: /** * Adds a note to the notes list and returns a pointer to the * related Note object. If the note key already exists in list, * returns a pointer to the existing object. */ Note::Pointer add(const String ¬eKey); }; /** * Used to store list of notes */ class NotePairs: public RefCountable { public: typedef RefCount Pointer; /** * Used to store a note key/value pair. */ class Entry { public: Entry(const char *aKey, const char *aValue): name(aKey), value(aValue) {} String name; String value; MEMPROXY_CLASS(Entry); }; NotePairs() {} ~NotePairs(); /** * Append the entries of the src NotePairs list to our list. */ void append(const NotePairs *src); /** * Replace existing list entries with the src NotePairs entries. * Entries which do not exist in the destination set are added. */ void replaceOrAdd(const NotePairs *src); /** * Append any new entries of the src NotePairs list to our list. * Entries which already exist in the destination set are ignored. */ void appendNewOnly(const NotePairs *src); /** * Returns a comma separated list of notes with key 'noteKey'. * Use findFirst instead when a unique kv-pair is needed. */ const char *find(const char *noteKey, const char *sep = ",") const; /** * Returns the first note value for this key or an empty string. */ const char *findFirst(const char *noteKey) const; /** * Adds a note key and value to the notes list. * If the key name already exists in list, add the given value to its set * of values. */ void add(const char *key, const char *value); /** * Remove all notes with a given key. */ void remove(const char *key); /** * Adds a note key and values strList to the notes list. * If the key name already exists in list, add the new values to its set * of values. */ void addStrList(const char *key, const char *values); /** * Return true if the key/value pair is already stored */ bool hasPair(const char *key, const char *value) const; /** * Convert NotePairs list to a string consist of "Key: Value" * entries separated by sep string. */ const char *toString(const char *sep = "\r\n") const; /** * True if there are not entries in the list */ bool empty() const {return entries.empty();} std::vector entries; ///< The key/value pair entries private: NotePairs &operator = (NotePairs const &); // Not implemented NotePairs(NotePairs const &); // Not implemented }; MEMPROXY_CLASS_INLINE(NotePairs::Entry); class AccessLogEntry; /** * Keep in sync HttpRequest and the corresponding AccessLogEntry objects */ NotePairs &SyncNotes(AccessLogEntry &ale, HttpRequest &request); class ConnStateData; /** * Updates ConnStateData ids and HttpRequest notes from helpers received notes. */ void UpdateRequestNotes(ConnStateData *csd, HttpRequest &request, NotePairs const ¬es); #endif