]> git.ipfire.org Git - thirdparty/squid.git/blob - src/Notes.h
Docs: Copyright updates for 2018 (#114)
[thirdparty/squid.git] / src / Notes.h
1 /*
2 * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 #ifndef SQUID_NOTES_H
10 #define SQUID_NOTES_H
11
12 #include "acl/forward.h"
13 #include "base/RefCount.h"
14 #include "format/Format.h"
15 #include "mem/forward.h"
16 #include "SquidString.h"
17
18 #include <string>
19 #include <vector>
20
21 class HttpRequest;
22 class HttpReply;
23 class AccessLogEntry;
24 class NotePairs;
25
26 typedef RefCount<AccessLogEntry> AccessLogEntryPointer;
27 typedef RefCount<NotePairs> NotePairsPointer;
28
29 /**
30 * Used to store a note configuration. The notes are custom key:value
31 * pairs ICAP request headers or ECAP options used to pass
32 * custom transaction-state related meta information to squid
33 * internal subsystems or to adaptation services.
34 */
35 class Note: public RefCountable
36 {
37 public:
38 typedef RefCount<Note> Pointer;
39
40 /// Stores a value for the note.
41 class Value: public RefCountable
42 {
43 public:
44 typedef RefCount<Value> Pointer;
45 friend class Note;
46
47 enum Method { mhReplace, mhAppend };
48
49 Value(const char *aVal, const bool quoted, const char *descr, const Method method = mhReplace);
50 ~Value();
51 Value(const Value&) = delete;
52 Value &operator=(const Value&) = delete;
53
54 Method method() const { return theMethod; }
55 const SBuf &value() const { return theValue; }
56
57 ACLList *aclList; ///< The access list used to determine if this value is valid for a request
58
59 private:
60 /// \return the formatted value with expanded logformat %macros (quoted values).
61 /// \return the original value (non-quoted values).
62 const SBuf &format(const AccessLogEntryPointer &al);
63
64 Format::Format *valueFormat; ///< Compiled annotation value format.
65 SBuf theValue; ///< Configured annotation value, possibly with %macros.
66 /// The expanded value produced by format(), empty for non-quoted values.
67 SBuf theFormattedValue;
68 /// Specifies how theValue will be applied to the existing annotation
69 /// with the same key: it either replaces the existing value or is appended
70 /// to the list of existing values.
71 Method theMethod;
72 };
73 typedef std::vector<Value::Pointer> Values;
74
75 Note(const char *aKey, const size_t keyLen): theKey(aKey, keyLen) {}
76 explicit Note(const SBuf aKey): theKey(aKey) {}
77 Note(const Note&) = delete;
78 Note &operator=(const Note&) = delete;
79
80 /// Adds a value to the note and returns a pointer to the
81 /// related Value object.
82 Value::Pointer addValue(const char *value, const bool quoted, const char *descr,
83 const Value::Method m = Value::mhAppend);
84
85 /// Walks through the possible values list of the note, selects
86 /// the first value, matching the given HttpRequest and HttpReply
87 /// and assignes the given 'matched' to it.
88 /// \return true if matched, false otherwise
89 bool match(HttpRequest *request, HttpReply *reply, const AccessLogEntryPointer &al, SBuf &matched);
90 const SBuf &key() const { return theKey; }
91 void updateNotePairs(NotePairsPointer pairs, const CharacterSet *delimiters, const AccessLogEntryPointer &al);
92 /// Dump the single Note to the given StoreEntry object.
93 void dump(StoreEntry *entry, const char *key);
94 /// For the key and all its Values compile a string of
95 /// "Key: Value" pairs separated by sep string.
96 SBuf toString(const char *sep) const;
97
98 private:
99 SBuf theKey; ///< The note key
100 Values values; ///< The possible values list for the note
101 };
102
103 class ConfigParser;
104
105 /**
106 * Used to store a notes configuration list.
107 */
108 class Notes : public RefCountable
109 {
110 public:
111 typedef RefCount<Notes> Pointer;
112 typedef std::vector<Note::Pointer> NotesList;
113 typedef NotesList::iterator iterator; ///< iterates over the notes list
114 typedef NotesList::const_iterator const_iterator; ///< iterates over the notes list
115
116 Notes(const char *aDescr, const char **metasBlacklist, bool allowFormatted = true): descr(aDescr), blacklisted(metasBlacklist), formattedValues(allowFormatted) {}
117 Notes(): descr(nullptr), blacklisted(nullptr), formattedValues(false) {}
118 ~Notes() { notes.clear(); }
119 Notes(const Notes&) = delete;
120 Notes &operator=(const Notes&) = delete;
121
122 /// Parses a notes line and returns a pointer to the parsed Note object.
123 Note::Pointer parse(ConfigParser &parser);
124
125 /// Parses an annotate line with "key=value" or "key+=value" formats.
126 void parseKvPair();
127
128 /// Dump the notes list to the given StoreEntry object.
129 void dump(StoreEntry *entry, const char *name);
130 /// clean the notes list
131 void clean() { notes.clear(); }
132
133 /// points to the first argument
134 iterator begin() { return notes.begin(); }
135 /// points to the end of list
136 iterator end() { return notes.end(); }
137 /// \returns true if the notes list is empty
138 bool empty() const { return notes.empty(); }
139 /// Convert Notes list to a string consist of "Key: Value"
140 /// entries separated by sep string.
141 const char *toString(const char *sep = "\r\n") const;
142 void updateNotePairs(NotePairsPointer pairs, const CharacterSet *delimiters,
143 const AccessLogEntryPointer &al);
144 private:
145
146 /// Verifies that the key is not blacklisted (fatal error) and
147 /// does not contain special characters (non-fatal error).
148 /// If keyLen is not provided, the key is assumed null-terminated.
149 void validateKey(const SBuf &key) const;
150
151 /// Adds a note to the notes list and returns a pointer to the
152 /// related Note object. If the note key already exists in list,
153 /// returns a pointer to the existing object.
154 /// If keyLen is not provided, the noteKey is assumed null-terminated.
155 Note::Pointer add(const SBuf &noteKey);
156 Note::Pointer find(const SBuf &noteKey);
157
158 NotesList notes; ///< The Note::Pointer objects array list
159 const char *descr; ///< A short description for notes list
160 const char **blacklisted; ///< Null terminated list of blacklisted note keys
161 bool formattedValues; ///< Whether the formatted values are supported
162 };
163
164 /**
165 * Used to store list of notes
166 */
167 class NotePairs: public RefCountable
168 {
169 public:
170 typedef RefCount<NotePairs> Pointer;
171
172 /// Used to store a note key/value pair.
173 class Entry : public RefCountable
174 {
175 MEMPROXY_CLASS(Entry);
176 public:
177 typedef RefCount<Entry> Pointer;
178
179 Entry(const SBuf &aKey, const SBuf &aValue)
180 : theName(aKey), theValue(aValue) {}
181 Entry(const char *aKey, const char *aValue)
182 : theName(aKey), theValue(aValue) {}
183 Entry(const Entry &) = delete;
184 Entry &operator=(const Entry &) = delete;
185
186 const SBuf &name() const { return theName; }
187 const SBuf &value() const { return theValue; }
188
189 private:
190 SBuf theName;
191 SBuf theValue;
192 };
193 typedef std::vector<Entry::Pointer> Entries; ///< The key/value pair entries
194
195 NotePairs() {}
196 NotePairs &operator=(NotePairs const &) = delete;
197 NotePairs(NotePairs const &) = delete;
198
199 /// Append the entries of the src NotePairs list to our list.
200 void append(const NotePairs *src);
201
202 /// Replace existing list entries with the src NotePairs entries.
203 /// Entries which do not exist in the destination set are added.
204 void replaceOrAdd(const NotePairs *src);
205
206 /// Append any new entries of the src NotePairs list to our list.
207 /// Entries which already exist in the destination set are ignored.
208 void appendNewOnly(const NotePairs *src);
209
210 /// \param resultNote a comma separated list of notes with key 'noteKey'.
211 /// \returns true if there are entries with the given 'noteKey'.
212 /// Use findFirst() instead when a unique kv-pair is needed.
213 bool find(SBuf &resultNote, const char *noteKey, const char *sep = ",") const;
214
215 /// \returns the first note value for this key or an empty string.
216 const char *findFirst(const char *noteKey) const;
217
218 /// Adds a note key and value to the notes list.
219 /// If the key name already exists in the list, add the given value to its set
220 /// of values.
221 void add(const SBuf &key, const SBuf &value);
222 void add(const char *key, const char *value);
223
224 /// Remove all notes with a given key. If keyLen is not
225 /// provided, the key is assumed null-terminated.
226 void remove(const char *key);
227 void remove(const SBuf &key);
228
229 /// Adds a note key and values strList to the notes list.
230 /// If the key name already exists in the list, add the new values to its set
231 /// of values.
232 void addStrList(const SBuf &key, const SBuf &values, const CharacterSet &delimiters);
233
234 /// \returns true if the key/value pair is already stored
235 bool hasPair(const SBuf &key, const SBuf &value) const;
236
237 /// Convert NotePairs list to a string consist of "Key: Value"
238 /// entries separated by sep string.
239 const char *toString(const char *sep = "\r\n") const;
240
241 /// \returns true if there are not entries in the list
242 bool empty() const {return entries.empty();}
243
244 void clear() { entries.clear(); }
245
246 /// If delimiters are provided, returns another Entries, converting each single multi-token
247 /// pair to multiple single-token pairs; returns existing entries otherwise.
248 const Entries &expandListEntries(const CharacterSet *delimiters) const;
249
250 private:
251 Entries entries; ///< The key/value pair entries
252 };
253
254 #endif
255