]> git.ipfire.org Git - thirdparty/squid.git/blame - src/errorpage.h
Maintenance: automate header guards 2/3 (#1655)
[thirdparty/squid.git] / src / errorpage.h
CommitLineData
aa839030 1/*
b8ae064d 2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
aa839030 3 *
bbc27441
AJ
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.
aa839030 7 */
8
bbc27441
AJ
9/* DEBUG: section 04 Error Generation */
10
ff9d9458
FC
11#ifndef SQUID_SRC_ERRORPAGE_H
12#define SQUID_SRC_ERRORPAGE_H
aa839030 13
aa839030 14#include "cbdata.h"
e0d28505 15#include "comm/forward.h"
83b053a0
CT
16#include "error/Detail.h"
17#include "error/forward.h"
fc94fd66 18#include "http/forward.h"
955394ce 19#include "http/StatusCode.h"
96d89ea0 20#include "ip/Address.h"
7e6eabbc
CT
21#include "log/forward.h"
22#include "sbuf/SBuf.h"
582c2af2 23#include "SquidString.h"
fafe8849 24/* auth/UserRequest.h is empty unless USE_AUTH is defined */
582c2af2 25#include "auth/UserRequest.h"
aa839030 26
8651e126
FC
27#include <optional>
28
822c0041
FC
29/// error page callback
30typedef void ERCB(int fd, void *, size_t);
31
63be0a78 32/**
33 \defgroup ErrorPageAPI Error Pages API
34 \ingroup Components
35 \section ErrorPageStringCodes Error Page % codes for text insertion.
36 *
37 \verbatim
38 a - User identity x
ea35939b 39 A - Local listening IP address x
63be0a78 40 B - URL with FTP %2f hack x
41 c - Squid error code x
42 d - seconds elapsed since request received x
4d16918e 43 D - Error details x
63be0a78 44 e - errno x
45 E - strerror() x
46 f - FTP request line x
47 F - FTP reply line x
48 g - FTP server message x
49 h - cache hostname x
50 H - server host name x
51 i - client IP address x
52 I - server IP address x
8e1a6bde 53 l - HREF link for CSS stylesheet inclusion x
63be0a78 54 L - HREF link for more info/contact x
55 M - Request Method x
56 m - Error message returned by auth helper x
57 o - Message returned external acl helper x
58 p - URL port # x
59 P - Protocol x
60 R - Full HTTP Request x
61 S - squid signature from ERR_SIGNATURE x
62 s - caching proxy software with version x
63 t - local time x
64 T - UTC x
65 U - URL without password x
66 u - URL with password x
67 w - cachemgr email address x
68 W - error data (to be included in the mailto links)
e4a8468d 69 x - error name x
63be0a78 70 z - dns server error message x
71 Z - Preformatted error message x
72 \endverbatim
7e6eabbc
CT
73 *
74 * Plus logformat %codes embedded using @Squid{%logformat_code} syntax.
63be0a78 75 */
76
c70281f8 77class MemBuf;
28d505bc 78class StoreEntry;
5fb9646e 79class wordlist;
9554bbf2 80
7e6eabbc
CT
81namespace ErrorPage {
82
83class Build;
84
85} // namespace ErrorPage
86
63be0a78 87/// \ingroup ErrorPageAPI
aa839030 88class ErrorState
89{
5c2f68b7
AJ
90 CBDATA_CLASS(ErrorState);
91
c70281f8 92public:
f5e17947 93 /// creates an error of type other than ERR_RELAY_REMOTE
7e6eabbc 94 ErrorState(err_type type, Http::StatusCode, HttpRequest * request, const AccessLogEntryPointer &al);
fc94fd66 95 ErrorState() = delete; // not implemented.
f5e17947
CT
96
97 /// creates an ERR_RELAY_REMOTE error
ef959d6e 98 ErrorState(HttpRequest * request, HttpReply *, const AccessLogEntryPointer &);
f5e17947 99
913524f0
AJ
100 ~ErrorState();
101
a23223bf 102 /// Creates a general request forwarding error with the right http_status.
7e6eabbc 103 static ErrorState *NewForwarding(err_type, HttpRequestPointer &, const AccessLogEntryPointer &);
a23223bf 104
c70281f8
AJ
105 /**
106 * Allocates and initializes an error response
107 */
108 HttpReply *BuildHttpReply(void);
109
7a957a93 110 /// set error type-specific detail code
83b053a0 111 void detailError(const ErrorDetail::Pointer &dCode) { detail = dCode; }
129fe2a1 112
7e6eabbc
CT
113 /// ensures that a future BuildHttpReply() is likely to succeed
114 void validate();
c70281f8 115
7e6eabbc
CT
116 /// the source of the error template (for reporting purposes)
117 SBuf inputLocation;
15b02e9a 118
7e6eabbc
CT
119private:
120 typedef ErrorPage::Build Build;
121
f5e17947 122 /// initializations shared by public constructors
ef959d6e 123 ErrorState(err_type, const AccessLogEntryPointer &);
f5e17947 124
7e6eabbc
CT
125 /// locates the right error page template for this error and compiles it
126 SBuf buildBody();
127
128 /// compiles error page or error detail template (i.e. anything but deny_url)
129 /// \param input the template text to be compiled
130 /// \param allowRecursion whether to compile %codes which produce %codes
131 SBuf compileBody(const char *text, bool allowRecursion);
132
133 /// compile a single-letter %code like %D
134 void compileLegacyCode(Build &build);
135
136 /// compile @Squid{%code} sequence containing a single logformat %code
137 void compileLogformatCode(Build &build);
138
139 /// replaces all legacy and logformat %codes in the given input
140 /// \param input the template text to be converted
141 /// \param building_deny_info_url whether input is a deny_info URL parameter
142 /// \param allowRecursion whether to compile %codes which produce %codes
143 /// \returns the given input with all %codes substituted
144 SBuf compile(const char *input, bool building_deny_info_url, bool allowRecursion);
145
146 /// React to a compile() error, throwing if buildContext allows.
147 /// \param msg description of what went wrong
405f850a
AJ
148 /// \param errorLocation approximate start of the problematic input
149 void noteBuildError(const char *const msg, const char * const errorLocation) {
150 noteBuildError_(msg, errorLocation, false);
7e6eabbc
CT
151 }
152
153 /// Note a compile() error but do not throw for backwards
154 /// compatibility with older configurations that may have such errors.
155 /// Should eventually be replaced with noteBuildError().
156 /// \param msg description of what went wrong
405f850a
AJ
157 /// \param errorLocation approximate start of the problematic input
158 void bypassBuildErrorXXX(const char *const msg, const char * const errorLocation) {
159 noteBuildError_(msg, errorLocation, true);
7e6eabbc 160 }
c70281f8
AJ
161
162 /**
163 * CacheManager / Debug dump of the ErrorState object.
164 * Writes output into the given MemBuf.
165 \retval 0 successful completion.
166 */
167 int Dump(MemBuf * mb);
2cc81f1f 168
169public:
fc94fd66
AJ
170 err_type type = ERR_NONE;
171 int page_id = ERR_NONE;
172 char *err_language = nullptr;
a75bf5d9 173 Http::StatusCode httpStatus = Http::scNone;
2f1431ea 174#if USE_AUTH
c7baff40 175 Auth::UserRequest::Pointer auth_user_request;
2f1431ea 176#endif
4c7c97f3 177 HttpRequestPointer request;
fc94fd66
AJ
178 char *url = nullptr;
179 int xerrno = 0;
8651e126 180 std::optional<SBuf> dnsError; ///< DNS lookup error message
fc94fd66 181 time_t ttl = 0;
aa839030 182
b7ac5457 183 Ip::Address src_addr;
fc94fd66 184 char *redirect_url = nullptr;
aa839030 185 ERCB *callback;
fc94fd66 186 void *callback_data = nullptr;
aa839030 187
26ac0430 188 struct {
fc94fd66
AJ
189 wordlist *server_msg = nullptr;
190 char *request = nullptr;
191 char *reply = nullptr;
192 char *cwd_msg = nullptr;
193 MemBuf *listing = nullptr;
3d0ac046 194 } ftp;
aa839030 195
fc94fd66
AJ
196 char *request_hdrs = nullptr;
197 char *err_msg = nullptr; /* Preformatted error message from the cache */
2cc81f1f 198
7e6eabbc
CT
199 AccessLogEntryPointer ale; ///< transaction details (or nil)
200
83b053a0
CT
201 // TODO: Replace type, xerrno and detail with Error while adding a virtual
202 // Error::Detail::sysError() method to extract errno in detailError().
129fe2a1 203 /// type-specific detail about the transaction error;
83b053a0
CT
204 /// overwrites xerrno;
205 ErrorDetail::Pointer detail;
7e6eabbc 206
f5e17947
CT
207 HttpReplyPointer response_;
208
7e6eabbc 209private:
405f850a 210 void noteBuildError_(const char *msg, const char *errorLocation, bool forceBypass);
7e6eabbc
CT
211
212 static const SBuf LogformatMagic; ///< marks each embedded logformat entry
aa839030 213};
214
63be0a78 215/**
216 \ingroup ErrorPageAPI
217 *
218 * This function finds the error messages formats, and stores
219 * them in error_text[]
220 *
221 \par Global effects:
222 * error_text[] - is modified
223 */
d9c252f2 224void errorInitialize(void);
63be0a78 225
226/// \ingroup ErrorPageAPI
d9c252f2 227void errorClean(void);
63be0a78 228
63be0a78 229/**
27774cee 230 * \ingroup ErrorPageAPI
63be0a78 231 *
232 * This function generates a error page from the info contained
233 * by err and then sends it to the client.
234 * The callback function errorSendComplete() is called after
e0d28505 235 * the page has been written to the client (clientConn).
63be0a78 236 * errorSendComplete() deallocates err. We need to add
237 * err to the cbdata because comm_write() requires it
238 * for all callback data pointers.
239 *
240 \note normally errorSend() should only be called from
241 * routines in ssl.c and pass.c, where we don't have any
242 * StoreEntry's. In client_side.c we must allocate a StoreEntry
243 * for errors and use errorAppendEntry() to account for
244 * persistent/pipeline connections.
245 *
1b76e6c1
AJ
246 \param clientConn socket where page object is to be written
247 \param err This object is destroyed after use in this function.
63be0a78 248 */
d9c252f2 249void errorSend(const Comm::ConnectionPointer &conn, ErrorState *err);
63be0a78 250
251/**
252 \ingroup ErrorPageAPI
253 *
254 * This function generates a error page from the info contained
255 * by err and then stores the text in the specified store
256 * entry.
257 * This function should only be called by "server
258 * side routines" which need to communicate errors to the
259 * client side. It should also be called from client_side.c
260 * because we now support persistent connections, and
261 * cannot assume that we can immediately write to the socket
262 * for an error.
263 *
264 \param entry ??
265 \param err This object is destroyed after use in this function.
266 */
d9c252f2 267void errorAppendEntry(StoreEntry *entry, ErrorState *err);
63be0a78 268
7e6eabbc
CT
269/// allocates a new slot for the error page
270err_type errorReservePageId(const char *page_name, const SBuf &cfgLocation);
aa839030 271
d9c252f2 272const char *errorPageName(int pageId); ///< error ID to string
aa839030 273
02259ff8
CT
274/**
275 \ingroup ErrorPageAPI
276 *
277 * loads text templates used for error pages and details;
278 * supports translation of templates
279 */
dc49061a
A
280class TemplateFile
281{
02259ff8 282public:
8ff2520a 283 TemplateFile(const char *name, const err_type code);
dc49061a 284 virtual ~TemplateFile() {}
02259ff8
CT
285
286 /// return true if the data loaded from disk without any problem
287 bool loaded() const {return wasLoaded;}
288
289 /**
290 * Load the page_name template from a file which probably exist at:
291 * (a) admin specified custom directory (error_directory)
292 * (b) default language translation directory (error_default_language)
293 * (c) English sub-directory where errors should ALWAYS exist
7e6eabbc 294 * If all of the above fail, setDefault() is called.
02259ff8 295 */
7e6eabbc 296 void loadDefault();
02259ff8
CT
297
298 /**
299 * Load an error template for a given HTTP request. This function examines the
300 * Accept-Language header and select the first available template. If the default
301 * template selected (eg because of a "Accept-Language: *"), or not available
302 * template found this function return false.
303 */
b248c2a3 304 bool loadFor(const HttpRequest *request);
02259ff8
CT
305
306 /**
307 * Load the file given by "path". It uses the "parse()" method.
308 * On success return true and sets the "defined" member
309 */
310 bool loadFromFile(const char *path);
311
312 /// The language used for the template
313 const char *language() {return errLanguage.termedBuf();}
314
7e6eabbc
CT
315 SBuf filename; ///< where the template was loaded from
316
02259ff8
CT
317 bool silent; ///< Whether to print error messages on cache.log file or not. It is user defined.
318
319protected:
7e6eabbc
CT
320 /// post-process the loaded template
321 virtual bool parse() { return true; }
322
323 /// recover from loadDefault() failure to load or parse() a template
324 virtual void setDefault() {}
02259ff8
CT
325
326 /**
327 * Try to load the "page_name" template for a given language "lang"
328 * from squid errors directory
329 \return true on success false otherwise
330 */
331 bool tryLoadTemplate(const char *lang);
332
7e6eabbc 333 SBuf template_; ///< raw template contents
02259ff8
CT
334 bool wasLoaded; ///< True if the template data read from disk without any problem
335 String errLanguage; ///< The error language of the template.
336 String templateName; ///< The name of the template
8ff2520a 337 err_type templateCode; ///< The internal code for this template.
02259ff8
CT
338};
339
340/**
341 * Parses the Accept-Language header value and return one language item on
342 * each call.
a32e7644
AJ
343 * Will ignore any whitespace, q-values, and detectably invalid language
344 * codes in the header.
345 *
02259ff8 346 * \param hdr is the Accept-Language header value
a32e7644 347 * \param lang a buffer to store parsed language code in
02259ff8 348 * \param langlen the length of the lang buffer
a32e7644
AJ
349 * \param pos is used to store the offset state of parsing. Must be "0" on first call.
350 * Will be altered to point at the start of next field-value.
351 * \return true if something looking like a language token has been placed in lang, false otherwise
02259ff8
CT
352 */
353bool strHdrAcptLangGetItem(const String &hdr, char *lang, int langLen, size_t &pos);
a32e7644 354
7ec92ef0
JR
355std::ostream &operator <<(std::ostream &, const ErrorState *);
356
ff9d9458 357#endif /* SQUID_SRC_ERRORPAGE_H */
f53969cc 358