]> git.ipfire.org Git - thirdparty/squid.git/blob - src/Notes.h
2043a9d0be1499324a161b622c4753c93c069a51
[thirdparty/squid.git] / src / Notes.h
1 /*
2 * Copyright (C) 1996-2020 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 assigns 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<SBuf> Keys; ///< unordered annotation names
113 typedef std::vector<Note::Pointer> NotesList;
114 typedef NotesList::iterator iterator; ///< iterates over the notes list
115 typedef NotesList::const_iterator const_iterator; ///< iterates over the notes list
116
117 explicit Notes(const char *aDescr, const Keys *extraReservedKeys = nullptr, bool allowFormatted = true);
118 Notes() = default;
119 ~Notes() { notes.clear(); }
120 Notes(const Notes&) = delete;
121 Notes &operator=(const Notes&) = delete;
122
123 /// Parses a notes line and returns a pointer to the parsed Note object.
124 Note::Pointer parse(ConfigParser &parser);
125
126 /// Parses an annotate line with "key=value" or "key+=value" formats.
127 void parseKvPair();
128
129 /// Dump the notes list to the given StoreEntry object.
130 void dump(StoreEntry *entry, const char *name);
131 /// clean the notes list
132 void clean() { notes.clear(); }
133
134 /// points to the first argument
135 iterator begin() { return notes.begin(); }
136 /// points to the end of list
137 iterator end() { return notes.end(); }
138 /// \returns true if the notes list is empty
139 bool empty() const { return notes.empty(); }
140 /// Convert Notes list to a string consist of "Key: Value"
141 /// entries separated by sep string.
142 const char *toString(const char *sep = "\r\n") const;
143 void updateNotePairs(NotePairsPointer pairs, const CharacterSet *delimiters,
144 const AccessLogEntryPointer &al);
145 private:
146 /// Makes sure the given key is not on the given list of banned names.
147 void banReservedKey(const SBuf &key, const Keys &banned) const;
148
149 /// Verifies that the key is not reserved (fatal error) and
150 /// does not contain special characters (non-fatal error).
151 void validateKey(const SBuf &key) const;
152
153 /// Adds a note to the notes list and returns a pointer to the
154 /// related Note object. If the note key already exists in list,
155 /// returns a pointer to the existing object.
156 /// If keyLen is not provided, the noteKey is assumed null-terminated.
157 Note::Pointer add(const SBuf &noteKey);
158 Note::Pointer find(const SBuf &noteKey);
159
160 NotesList notes; ///< The Note::Pointer objects array list
161 const char *descr = nullptr; ///< identifies note source in error messages
162
163 Keys reservedKeys; ///< a list of additional prohibited key names
164 bool formattedValues = false; ///< whether to expand quoted logformat %codes
165
166 static const Notes::Keys &ReservedKeys(); ///< always prohibited key names
167 };
168
169 /**
170 * Used to store list of notes
171 */
172 class NotePairs: public RefCountable
173 {
174 public:
175 typedef RefCount<NotePairs> Pointer;
176
177 /// Used to store a note key/value pair.
178 class Entry : public RefCountable
179 {
180 MEMPROXY_CLASS(Entry);
181 public:
182 typedef RefCount<Entry> Pointer;
183
184 Entry(const SBuf &aKey, const SBuf &aValue)
185 : theName(aKey), theValue(aValue) {}
186 Entry(const char *aKey, const char *aValue)
187 : theName(aKey), theValue(aValue) {}
188 Entry(const Entry &) = delete;
189 Entry &operator=(const Entry &) = delete;
190
191 const SBuf &name() const { return theName; }
192 const SBuf &value() const { return theValue; }
193
194 private:
195 SBuf theName;
196 SBuf theValue;
197 };
198 typedef std::vector<Entry::Pointer> Entries; ///< The key/value pair entries
199 typedef std::vector<SBuf> Names;
200
201 NotePairs() {}
202 NotePairs &operator=(NotePairs const &) = delete;
203 NotePairs(NotePairs const &) = delete;
204
205 /// Append the entries of the src NotePairs list to our list.
206 void append(const NotePairs *src);
207
208 /// Replace existing list entries with the src NotePairs entries.
209 /// Do not replace but append entries named in the appendables
210 /// Entries which do not exist in the destination set are added.
211 void replaceOrAddOrAppend(const NotePairs *src, const Names &appendables);
212
213 /// Replace existing list entries with the src NotePairs entries.
214 /// Entries which do not exist in the destination set are added.
215 void replaceOrAdd(const NotePairs *src);
216
217 /// Append any new entries of the src NotePairs list to our list.
218 /// Entries which already exist in the destination set are ignored.
219 void appendNewOnly(const NotePairs *src);
220
221 /// \param resultNote a comma separated list of notes with key 'noteKey'.
222 /// \returns true if there are entries with the given 'noteKey'.
223 /// Use findFirst() instead when a unique kv-pair is needed.
224 bool find(SBuf &resultNote, const char *noteKey, const char *sep = ",") const;
225
226 /// \returns the first note value for this key or an empty string.
227 const char *findFirst(const char *noteKey) const;
228
229 /// Adds a note key and value to the notes list.
230 /// If the key name already exists in the list, add the given value to its set
231 /// of values.
232 void add(const SBuf &key, const SBuf &value);
233 void add(const char *key, const char *value);
234
235 /// Remove all notes with a given key. If keyLen is not
236 /// provided, the key is assumed null-terminated.
237 void remove(const char *key);
238 void remove(const SBuf &key);
239
240 /// Adds a note key and values strList to the notes list.
241 /// If the key name already exists in the list, add the new values to its set
242 /// of values.
243 void addStrList(const SBuf &key, const SBuf &values, const CharacterSet &delimiters);
244
245 /// \returns true if the key/value pair is already stored
246 bool hasPair(const SBuf &key, const SBuf &value) const;
247
248 /// Convert NotePairs list to a string consist of "Key: Value"
249 /// entries separated by sep string.
250 const char *toString(const char *sep = "\r\n") const;
251
252 /// \returns true if there are not entries in the list
253 bool empty() const {return entries.empty();}
254
255 void clear() { entries.clear(); }
256
257 /// If delimiters are provided, returns another Entries, converting each single multi-token
258 /// pair to multiple single-token pairs; returns existing entries otherwise.
259 const Entries &expandListEntries(const CharacterSet *delimiters) const;
260
261 private:
262 Entries entries; ///< The key/value pair entries
263 };
264
265 #endif
266