+/*
+ * Copyright (C) 1996-2015 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 "HttpHeader.h"
-#include "HttpHeaderTools.h"
-#include "typedefs.h"
+#include "acl/forward.h"
+#include "base/RefCount.h"
+#include "format/Format.h"
+#include "mem/forward.h"
+#include "SquidString.h"
-#if HAVE_STRING
#include <string>
-#endif
+#include <vector>
class HttpRequest;
class HttpReply;
+typedef RefCount<AccessLogEntry> AccessLogEntryPointer;
/**
- * Used to store notes. The notes are custom key:value pairs
- * ICAP request headers or ECAP options used to pass
+ * 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 addaptation services.
+ * internal subsystems or to adaptation services.
*/
class Note: public RefCountable
{
{
public:
typedef RefCount<Value> Pointer;
- String value; ///< a note value
+ String value; ///< Configured annotation value, possibly with %macros
ACLList *aclList; ///< The access list used to determine if this value is valid for a request
- explicit Value(const String &aVal) : value(aVal), aclList(NULL) {}
+ /// Compiled annotation value format
+ Format::Format *valueFormat;
+ explicit Value(const String &aVal) : value(aVal), aclList(NULL), valueFormat(NULL) {}
~Value();
};
- typedef Vector<Value::Pointer> Values;
+ typedef std::vector<Value::Pointer> Values;
explicit Note(const String &aKey): key(aKey) {}
* 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);
-
- /**
- * Returns the first value for this key or an empty string.
- */
- const char *firstValue() const { return (values.size()>0&&values[0]->value.defined()?values[0]->value.termedBuf():""); }
+ 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 list.
+ * Used to store a notes configuration list.
*/
class Notes
{
public:
- typedef Vector<Note::Pointer> NotesList;
+ typedef std::vector<Note::Pointer> 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): descr(aDescr), blacklisted(metasBlacklist) {}
- Notes(): descr(NULL), blacklisted(NULL) {}
- ~Notes() { notes.clean(); }
+ 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.
/// return true if the notes list is empty
bool empty() { return notes.empty(); }
- /**
- * 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 String ¬eKey, const String ¬eValue);
-
- /**
- * Returns a pointer to an existing Note with given key name or nil.
- */
- Note::Pointer find(const String ¬eKey) const;
-
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:
/**
* returns a pointer to the existing object.
*/
Note::Pointer add(const String ¬eKey);
-
};
-class NotePairs : public HttpHeader
+/**
+ * Used to store list of notes
+ */
+class NotePairs: public RefCountable
{
public:
- NotePairs() : HttpHeader(hoNote) {}
+ typedef RefCount<NotePairs> Pointer;
+
+ /**
+ * Used to store a note key/value pair.
+ */
+ class Entry
+ {
+ MEMPROXY_CLASS(Entry);
+ public:
+ Entry(const char *aKey, const char *aValue): name(aKey), value(aValue) {}
+ String name;
+ String value;
+ };
+
+ 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<NotePairs::Entry *> entries; ///< The key/value pair entries
+
+private:
+ NotePairs &operator = (NotePairs const &); // Not implemented
+ NotePairs(NotePairs const &); // Not implemented
};
+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
+