]> git.ipfire.org Git - thirdparty/squid.git/blame - src/Notes.h
Maintenance: automate header guards 2/3 (#1655)
[thirdparty/squid.git] / src / Notes.h
CommitLineData
bbc27441 1/*
b8ae064d 2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
bbc27441
AJ
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
ff9d9458
FC
9#ifndef SQUID_SRC_NOTES_H
10#define SQUID_SRC_NOTES_H
b3404bc5 11
6f58d7d7 12#include "acl/forward.h"
cf9f0261 13#include "base/RefCount.h"
af0ded40 14#include "format/Format.h"
ed6e9fb9 15#include "mem/forward.h"
ab2acef6 16#include "sbuf/forward.h"
cf9f0261 17#include "SquidString.h"
b3404bc5 18
e67eab3a 19#include <iosfwd>
b3404bc5 20#include <string>
81481ec0 21#include <vector>
b3404bc5 22
b3404bc5
CT
23class HttpRequest;
24class HttpReply;
75d47340
CT
25class AccessLogEntry;
26class NotePairs;
27
af0ded40 28typedef RefCount<AccessLogEntry> AccessLogEntryPointer;
75d47340 29typedef RefCount<NotePairs> NotePairsPointer;
b3404bc5
CT
30
31/**
cf9f0261
CT
32 * Used to store a note configuration. The notes are custom key:value
33 * pairs ICAP request headers or ECAP options used to pass
b3404bc5 34 * custom transaction-state related meta information to squid
cf9f0261 35 * internal subsystems or to adaptation services.
b3404bc5
CT
36 */
37class Note: public RefCountable
38{
39public:
40 typedef RefCount<Note> Pointer;
75d47340 41
b3404bc5
CT
42 /// Stores a value for the note.
43 class Value: public RefCountable
44 {
45 public:
46 typedef RefCount<Value> Pointer;
75d47340
CT
47 friend class Note;
48
49 enum Method { mhReplace, mhAppend };
50
51 Value(const char *aVal, const bool quoted, const char *descr, const Method method = mhReplace);
337b9aa4 52 ~Value() override;
75d47340
CT
53 Value(const Value&) = delete;
54 Value &operator=(const Value&) = delete;
55
56 Method method() const { return theMethod; }
57 const SBuf &value() const { return theValue; }
b3404bc5 58
75d47340 59 ACLList *aclList; ///< The access list used to determine if this value is valid for a request
b3404bc5 60
75d47340
CT
61 private:
62 /// \return the formatted value with expanded logformat %macros (quoted values).
63 /// \return the original value (non-quoted values).
64 const SBuf &format(const AccessLogEntryPointer &al);
65
66 Format::Format *valueFormat; ///< Compiled annotation value format.
67 SBuf theValue; ///< Configured annotation value, possibly with %macros.
68 /// The expanded value produced by format(), empty for non-quoted values.
69 SBuf theFormattedValue;
70 /// Specifies how theValue will be applied to the existing annotation
71 /// with the same key: it either replaces the existing value or is appended
72 /// to the list of existing values.
73 Method theMethod;
74 };
75 typedef std::vector<Value::Pointer> Values;
b3404bc5 76
75d47340
CT
77 Note(const char *aKey, const size_t keyLen): theKey(aKey, keyLen) {}
78 explicit Note(const SBuf aKey): theKey(aKey) {}
79 Note(const Note&) = delete;
80 Note &operator=(const Note&) = delete;
81
82 /// Adds a value to the note and returns a pointer to the
83 /// related Value object.
84 Value::Pointer addValue(const char *value, const bool quoted, const char *descr,
b8f75894 85 const Value::Method m = Value::mhAppend);
75d47340
CT
86
87 /// Walks through the possible values list of the note, selects
88 /// the first value, matching the given HttpRequest and HttpReply
2f8abb64 89 /// and assigns the given 'matched' to it.
75d47340
CT
90 /// \return true if matched, false otherwise
91 bool match(HttpRequest *request, HttpReply *reply, const AccessLogEntryPointer &al, SBuf &matched);
92 const SBuf &key() const { return theKey; }
93 void updateNotePairs(NotePairsPointer pairs, const CharacterSet *delimiters, const AccessLogEntryPointer &al);
e67eab3a
FC
94
95 /// Prints key and value(s) using a "note" directive format (including directive name).
96 void printAsNoteDirective(StoreEntry *, const char *directiveName) const;
97
98 /// Prints using "annotate_transaction acl parameter" format, one key=value
99 /// or key+=value parameter per stored value.
100 void printAsAnnotationAclParameters(std::ostream &) const;
fd7f26ea 101
75d47340
CT
102private:
103 SBuf theKey; ///< The note key
b3404bc5
CT
104 Values values; ///< The possible values list for the note
105};
106
107class ConfigParser;
75d47340 108
b3404bc5 109/**
cf9f0261 110 * Used to store a notes configuration list.
b3404bc5 111 */
75d47340 112class Notes : public RefCountable
ffb82151 113{
b3404bc5 114public:
75d47340 115 typedef RefCount<Notes> Pointer;
4668df3d 116 typedef std::vector<SBuf> Keys; ///< unordered annotation names
81481ec0 117 typedef std::vector<Note::Pointer> NotesList;
b3404bc5 118 typedef NotesList::iterator iterator; ///< iterates over the notes list
bc600349 119 typedef NotesList::const_iterator const_iterator; ///< iterates over the notes list
b3404bc5 120
70d0ef18 121 explicit Notes(const char *aDescr, const Keys *extraReservedKeys = nullptr, bool allowFormatted = true);
4668df3d 122 Notes() = default;
337b9aa4 123 ~Notes() override { notes.clear(); }
75d47340
CT
124 Notes(const Notes&) = delete;
125 Notes &operator=(const Notes&) = delete;
126
127 /// Parses a notes line and returns a pointer to the parsed Note object.
b3404bc5 128 Note::Pointer parse(ConfigParser &parser);
75d47340
CT
129
130 /// Parses an annotate line with "key=value" or "key+=value" formats.
131 void parseKvPair();
132
e67eab3a
FC
133 /// Prints notes using "note" squid.conf directive format, one directive per stored note.
134 void printAsNoteDirectives(StoreEntry *, const char *directiveName) const;
135
75d47340
CT
136 /// clean the notes list
137 void clean() { notes.clear(); }
b3404bc5
CT
138
139 /// points to the first argument
140 iterator begin() { return notes.begin(); }
141 /// points to the end of list
142 iterator end() { return notes.end(); }
75d47340
CT
143 /// \returns true if the notes list is empty
144 bool empty() const { return notes.empty(); }
e67eab3a
FC
145
146 /// print notes using "annotate_transaction acl parameters" format, one
147 /// key=value parameter per note
148 void printAsAnnotationAclParameters(std::ostream &) const;
149
75d47340 150 void updateNotePairs(NotePairsPointer pairs, const CharacterSet *delimiters,
b8f75894 151 const AccessLogEntryPointer &al);
75d47340 152private:
4668df3d
CT
153 /// Makes sure the given key is not on the given list of banned names.
154 void banReservedKey(const SBuf &key, const Keys &banned) const;
75d47340 155
70d0ef18 156 /// Verifies that the key is not reserved (fatal error) and
75d47340 157 /// does not contain special characters (non-fatal error).
75d47340
CT
158 void validateKey(const SBuf &key) const;
159
160 /// Adds a note to the notes list and returns a pointer to the
161 /// related Note object. If the note key already exists in list,
162 /// returns a pointer to the existing object.
163 /// If keyLen is not provided, the noteKey is assumed null-terminated.
164 Note::Pointer add(const SBuf &noteKey);
165 Note::Pointer find(const SBuf &noteKey);
b3404bc5
CT
166
167 NotesList notes; ///< The Note::Pointer objects array list
4668df3d
CT
168 const char *descr = nullptr; ///< identifies note source in error messages
169
70d0ef18 170 Keys reservedKeys; ///< a list of additional prohibited key names
4668df3d
CT
171 bool formattedValues = false; ///< whether to expand quoted logformat %codes
172
70d0ef18 173 static const Notes::Keys &ReservedKeys(); ///< always prohibited key names
b3404bc5
CT
174};
175
cf9f0261
CT
176/**
177 * Used to store list of notes
178 */
179class NotePairs: public RefCountable
ffb82151 180{
b3404bc5 181public:
cf9f0261
CT
182 typedef RefCount<NotePairs> Pointer;
183
75d47340
CT
184 /// Used to store a note key/value pair.
185 class Entry : public RefCountable
7e6ef752 186 {
741c2986 187 MEMPROXY_CLASS(Entry);
cf9f0261 188 public:
75d47340
CT
189 typedef RefCount<Entry> Pointer;
190
191 Entry(const SBuf &aKey, const SBuf &aValue)
192 : theName(aKey), theValue(aValue) {}
193 Entry(const char *aKey, const char *aValue)
194 : theName(aKey), theValue(aValue) {}
195 Entry(const Entry &) = delete;
196 Entry &operator=(const Entry &) = delete;
197
198 const SBuf &name() const { return theName; }
199 const SBuf &value() const { return theValue; }
200
201 private:
202 SBuf theName;
203 SBuf theValue;
cf9f0261 204 };
75d47340 205 typedef std::vector<Entry::Pointer> Entries; ///< The key/value pair entries
d665de37 206 typedef std::vector<SBuf> Names;
cf9f0261 207
d74740bd 208 NotePairs() {}
75d47340
CT
209 NotePairs &operator=(NotePairs const &) = delete;
210 NotePairs(NotePairs const &) = delete;
cf9f0261 211
75d47340 212 /// Append the entries of the src NotePairs list to our list.
cf9f0261
CT
213 void append(const NotePairs *src);
214
d665de37
A
215 /// Replace existing list entries with the src NotePairs entries.
216 /// Do not replace but append entries named in the appendables
217 /// Entries which do not exist in the destination set are added.
218 void replaceOrAddOrAppend(const NotePairs *src, const Names &appendables);
219
75d47340
CT
220 /// Replace existing list entries with the src NotePairs entries.
221 /// Entries which do not exist in the destination set are added.
457857fe
CT
222 void replaceOrAdd(const NotePairs *src);
223
75d47340
CT
224 /// Append any new entries of the src NotePairs list to our list.
225 /// Entries which already exist in the destination set are ignored.
71e7400c
AJ
226 void appendNewOnly(const NotePairs *src);
227
75d47340
CT
228 /// \param resultNote a comma separated list of notes with key 'noteKey'.
229 /// \returns true if there are entries with the given 'noteKey'.
230 /// Use findFirst() instead when a unique kv-pair is needed.
231 bool find(SBuf &resultNote, const char *noteKey, const char *sep = ",") const;
cf9f0261 232
75d47340 233 /// \returns the first note value for this key or an empty string.
cf9f0261
CT
234 const char *findFirst(const char *noteKey) const;
235
75d47340
CT
236 /// Adds a note key and value to the notes list.
237 /// If the key name already exists in the list, add the given value to its set
238 /// of values.
239 void add(const SBuf &key, const SBuf &value);
cf9f0261
CT
240 void add(const char *key, const char *value);
241
75d47340
CT
242 /// Remove all notes with a given key. If keyLen is not
243 /// provided, the key is assumed null-terminated.
457857fe 244 void remove(const char *key);
75d47340
CT
245 void remove(const SBuf &key);
246
247 /// Adds a note key and values strList to the notes list.
248 /// If the key name already exists in the list, add the new values to its set
249 /// of values.
250 void addStrList(const SBuf &key, const SBuf &values, const CharacterSet &delimiters);
457857fe 251
75d47340
CT
252 /// \returns true if the key/value pair is already stored
253 bool hasPair(const SBuf &key, const SBuf &value) const;
254
e67eab3a
FC
255 /// Reports all entries (if any), printing exactly four items for each:
256 /// entry name, nameValueSeparator, entry value, and entry terminator.
257 void print(std::ostream &os, const char *nameValueSeparator, const char *entryTerminator) const;
cf9f0261 258
75d47340 259 /// \returns true if there are not entries in the list
cf9f0261
CT
260 bool empty() const {return entries.empty();}
261
75d47340
CT
262 void clear() { entries.clear(); }
263
264 /// If delimiters are provided, returns another Entries, converting each single multi-token
265 /// pair to multiple single-token pairs; returns existing entries otherwise.
266 const Entries &expandListEntries(const CharacterSet *delimiters) const;
95c0dbfc
CT
267
268private:
75d47340 269 Entries entries; ///< The key/value pair entries
b3404bc5
CT
270};
271
ff9d9458 272#endif /* SQUID_SRC_NOTES_H */
f53969cc 273