]> git.ipfire.org Git - thirdparty/squid.git/blob - src/errorpage.h
Merge from trunk
[thirdparty/squid.git] / src / errorpage.h
1 /*
2 * Copyright (C) 1996-2015 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 /* DEBUG: section 04 Error Generation */
10
11 #ifndef SQUID_ERRORPAGE_H
12 #define SQUID_ERRORPAGE_H
13
14 #include "cbdata.h"
15 #include "comm/forward.h"
16 #include "err_detail_type.h"
17 #include "err_type.h"
18 #include "http/StatusCode.h"
19 #include "ip/Address.h"
20 #include "SquidString.h"
21 /* auth/UserRequest.h is empty unless USE_AUTH is defined */
22 #include "auth/UserRequest.h"
23 #if USE_OPENSSL
24 #include "ssl/ErrorDetail.h"
25 #endif
26
27 /**
28 \defgroup ErrorPageAPI Error Pages API
29 \ingroup Components
30 \section ErrorPageStringCodes Error Page % codes for text insertion.
31 *
32 \verbatim
33 a - User identity x
34 B - URL with FTP %2f hack x
35 c - Squid error code x
36 d - seconds elapsed since request received x
37 D - Error details x
38 e - errno x
39 E - strerror() x
40 f - FTP request line x
41 F - FTP reply line x
42 g - FTP server message x
43 h - cache hostname x
44 H - server host name x
45 i - client IP address x
46 I - server IP address x
47 l - HREF link for CSS stylesheet inclusion x
48 L - HREF link for more info/contact x
49 M - Request Method x
50 m - Error message returned by auth helper x
51 o - Message returned external acl helper x
52 p - URL port # x
53 P - Protocol x
54 R - Full HTTP Request x
55 S - squid signature from ERR_SIGNATURE x
56 s - caching proxy software with version x
57 t - local time x
58 T - UTC x
59 U - URL without password x
60 u - URL with password x
61 w - cachemgr email address x
62 W - error data (to be included in the mailto links)
63 x - error name x
64 z - dns server error message x
65 Z - Preformatted error message x
66 \endverbatim
67 */
68
69 class HttpReply;
70 class HttpRequest;
71 class MemBuf;
72
73 /// \ingroup ErrorPageAPI
74 class ErrorState
75 {
76 CBDATA_CLASS(ErrorState);
77
78 public:
79 ErrorState(err_type type, Http::StatusCode, HttpRequest * request);
80 ErrorState(); // not implemented.
81 ~ErrorState();
82
83 /// Creates a general request forwarding error with the right http_status.
84 static ErrorState *NewForwarding(err_type type, HttpRequest *request);
85
86 /**
87 * Allocates and initializes an error response
88 */
89 HttpReply *BuildHttpReply(void);
90
91 /// set error type-specific detail code
92 void detailError(int dCode) {detailCode = dCode;}
93
94 private:
95 /**
96 * Locates error page template to be used for this error
97 * and constructs the HTML page content from it.
98 */
99 MemBuf *BuildContent(void);
100
101 /**
102 * Convert the given template string into textual output
103 *
104 * \param text The string to be converted
105 * \param allowRecursion Whether to convert codes which output may contain codes
106 */
107 MemBuf *ConvertText(const char *text, bool allowRecursion);
108
109 /**
110 * Generates the Location: header value for a deny_info error page
111 * to be used for this error.
112 */
113 void DenyInfoLocation(const char *name, HttpRequest *request, MemBuf &result);
114
115 /**
116 * Map the Error page and deny_info template % codes into textual output.
117 *
118 * Several of the codes produce blocks of non-URL compatible results.
119 * When processing the deny_info location URL they will be skipped.
120 *
121 * \param token The token following % which need to be converted
122 * \param building_deny_info_url Perform special deny_info actions, such as URL-encoding and token skipping.
123 * \ allowRecursion True if the codes which do recursions should converted
124 */
125 const char *Convert(char token, bool building_deny_info_url, bool allowRecursion);
126
127 /**
128 * CacheManager / Debug dump of the ErrorState object.
129 * Writes output into the given MemBuf.
130 \retval 0 successful completion.
131 */
132 int Dump(MemBuf * mb);
133
134 public:
135 err_type type;
136 int page_id;
137 char *err_language;
138 Http::StatusCode httpStatus;
139 #if USE_AUTH
140 Auth::UserRequest::Pointer auth_user_request;
141 #endif
142 HttpRequest *request;
143 char *url;
144 int xerrno;
145 unsigned short port;
146 String dnsError; ///< DNS lookup error message
147 time_t ttl;
148
149 Ip::Address src_addr;
150 char *redirect_url;
151 ERCB *callback;
152 void *callback_data;
153
154 struct {
155 wordlist *server_msg;
156 char *request;
157 char *reply;
158 char *cwd_msg;
159 MemBuf *listing;
160 } ftp;
161
162 char *request_hdrs;
163 char *err_msg; /* Preformatted error message from the cache */
164
165 #if USE_OPENSSL
166 Ssl::ErrorDetail *detail;
167 #endif
168 /// type-specific detail about the transaction error;
169 /// overwrites xerrno; overwritten by detail, if any.
170 int detailCode;
171 };
172
173 /**
174 \ingroup ErrorPageAPI
175 *
176 * This function finds the error messages formats, and stores
177 * them in error_text[]
178 *
179 \par Global effects:
180 * error_text[] - is modified
181 */
182 void errorInitialize(void);
183
184 /// \ingroup ErrorPageAPI
185 void errorClean(void);
186
187 /**
188 * \ingroup ErrorPageAPI
189 *
190 * This function generates a error page from the info contained
191 * by err and then sends it to the client.
192 * The callback function errorSendComplete() is called after
193 * the page has been written to the client (clientConn).
194 * errorSendComplete() deallocates err. We need to add
195 * err to the cbdata because comm_write() requires it
196 * for all callback data pointers.
197 *
198 \note normally errorSend() should only be called from
199 * routines in ssl.c and pass.c, where we don't have any
200 * StoreEntry's. In client_side.c we must allocate a StoreEntry
201 * for errors and use errorAppendEntry() to account for
202 * persistent/pipeline connections.
203 *
204 \param clientConn socket where page object is to be written
205 \param err This object is destroyed after use in this function.
206 */
207 void errorSend(const Comm::ConnectionPointer &conn, ErrorState *err);
208
209 /**
210 \ingroup ErrorPageAPI
211 *
212 * This function generates a error page from the info contained
213 * by err and then stores the text in the specified store
214 * entry.
215 * This function should only be called by "server
216 * side routines" which need to communicate errors to the
217 * client side. It should also be called from client_side.c
218 * because we now support persistent connections, and
219 * cannot assume that we can immediately write to the socket
220 * for an error.
221 *
222 \param entry ??
223 \param err This object is destroyed after use in this function.
224 */
225 void errorAppendEntry(StoreEntry *entry, ErrorState *err);
226
227 /// \ingroup ErrorPageAPI
228 err_type errorReservePageId(const char *page_name);
229
230 const char *errorPageName(int pageId); ///< error ID to string
231
232 /**
233 \ingroup ErrorPageAPI
234 *
235 * loads text templates used for error pages and details;
236 * supports translation of templates
237 */
238 class TemplateFile
239 {
240 public:
241 TemplateFile(const char *name, const err_type code);
242 virtual ~TemplateFile() {}
243
244 /// return true if the data loaded from disk without any problem
245 bool loaded() const {return wasLoaded;}
246
247 /**
248 * Load the page_name template from a file which probably exist at:
249 * (a) admin specified custom directory (error_directory)
250 * (b) default language translation directory (error_default_language)
251 * (c) English sub-directory where errors should ALWAYS exist
252 */
253 bool loadDefault();
254
255 /**
256 * Load an error template for a given HTTP request. This function examines the
257 * Accept-Language header and select the first available template. If the default
258 * template selected (eg because of a "Accept-Language: *"), or not available
259 * template found this function return false.
260 */
261 bool loadFor(const HttpRequest *request);
262
263 /**
264 * Load the file given by "path". It uses the "parse()" method.
265 * On success return true and sets the "defined" member
266 */
267 bool loadFromFile(const char *path);
268
269 /// The language used for the template
270 const char *language() {return errLanguage.termedBuf();}
271
272 bool silent; ///< Whether to print error messages on cache.log file or not. It is user defined.
273
274 protected:
275 /// Used to parse (if parsing required) the template data .
276 virtual bool parse(const char *buf, int len, bool eof) = 0;
277
278 /**
279 * Try to load the "page_name" template for a given language "lang"
280 * from squid errors directory
281 \return true on success false otherwise
282 */
283 bool tryLoadTemplate(const char *lang);
284
285 bool wasLoaded; ///< True if the template data read from disk without any problem
286 String errLanguage; ///< The error language of the template.
287 String templateName; ///< The name of the template
288 err_type templateCode; ///< The internal code for this template.
289 };
290
291 /**
292 * Parses the Accept-Language header value and return one language item on
293 * each call.
294 * Will ignore any whitespace, q-values, and detectably invalid language
295 * codes in the header.
296 *
297 * \param hdr is the Accept-Language header value
298 * \param lang a buffer to store parsed language code in
299 * \param langlen the length of the lang buffer
300 * \param pos is used to store the offset state of parsing. Must be "0" on first call.
301 * Will be altered to point at the start of next field-value.
302 * \return true if something looking like a language token has been placed in lang, false otherwise
303 */
304 bool strHdrAcptLangGetItem(const String &hdr, char *lang, int langLen, size_t &pos);
305
306 #endif /* SQUID_ERRORPAGE_H */
307