2 * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
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.
9 /* DEBUG: section 04 Error Generation */
11 #ifndef SQUID_ERRORPAGE_H
12 #define SQUID_ERRORPAGE_H
15 #include "comm/forward.h"
16 #include "err_detail_type.h"
18 #include "http/forward.h"
19 #include "http/StatusCode.h"
20 #include "ip/Address.h"
21 #include "SquidString.h"
22 /* auth/UserRequest.h is empty unless USE_AUTH is defined */
23 #include "auth/UserRequest.h"
25 #include "ssl/ErrorDetail.h"
28 /// error page callback
29 typedef void ERCB(int fd
, void *, size_t);
32 \defgroup ErrorPageAPI Error Pages API
34 \section ErrorPageStringCodes Error Page % codes for text insertion.
38 B - URL with FTP %2f hack x
39 c - Squid error code x
40 d - seconds elapsed since request received x
44 f - FTP request line x
46 g - FTP server message x
48 H - server host name x
49 i - client IP address x
50 I - server IP address x
51 l - HREF link for CSS stylesheet inclusion x
52 L - HREF link for more info/contact x
54 m - Error message returned by auth helper x
55 o - Message returned external acl helper x
58 R - Full HTTP Request x
59 S - squid signature from ERR_SIGNATURE x
60 s - caching proxy software with version x
63 U - URL without password x
64 u - URL with password x
65 w - cachemgr email address x
66 W - error data (to be included in the mailto links)
68 z - dns server error message x
69 Z - Preformatted error message x
77 /// \ingroup ErrorPageAPI
80 CBDATA_CLASS(ErrorState
);
83 ErrorState(err_type type
, Http::StatusCode
, HttpRequest
* request
);
84 ErrorState() = delete; // not implemented.
87 /// Creates a general request forwarding error with the right http_status.
88 static ErrorState
*NewForwarding(err_type
, HttpRequestPointer
&);
91 * Allocates and initializes an error response
93 HttpReply
*BuildHttpReply(void);
95 /// set error type-specific detail code
96 void detailError(int dCode
) {detailCode
= dCode
;}
100 * Locates error page template to be used for this error
101 * and constructs the HTML page content from it.
103 MemBuf
*BuildContent(void);
106 * Convert the given template string into textual output
108 * \param text The string to be converted
109 * \param allowRecursion Whether to convert codes which output may contain codes
111 MemBuf
*ConvertText(const char *text
, bool allowRecursion
);
114 * Generates the Location: header value for a deny_info error page
115 * to be used for this error.
117 void DenyInfoLocation(const char *name
, HttpRequest
*request
, MemBuf
&result
);
120 * Map the Error page and deny_info template % codes into textual output.
122 * Several of the codes produce blocks of non-URL compatible results.
123 * When processing the deny_info location URL they will be skipped.
125 * \param token The token following % which need to be converted
126 * \param building_deny_info_url Perform special deny_info actions, such as URL-encoding and token skipping.
127 * \ allowRecursion True if the codes which do recursions should converted
129 const char *Convert(char token
, bool building_deny_info_url
, bool allowRecursion
);
132 * CacheManager / Debug dump of the ErrorState object.
133 * Writes output into the given MemBuf.
134 \retval 0 successful completion.
136 int Dump(MemBuf
* mb
);
139 err_type type
= ERR_NONE
;
140 int page_id
= ERR_NONE
;
141 char *err_language
= nullptr;
142 Http::StatusCode httpStatus
;
144 Auth::UserRequest::Pointer auth_user_request
;
146 HttpRequestPointer request
;
149 unsigned short port
= 0;
150 String dnsError
; ///< DNS lookup error message
153 Ip::Address src_addr
;
154 char *redirect_url
= nullptr;
156 void *callback_data
= nullptr;
159 wordlist
*server_msg
= nullptr;
160 char *request
= nullptr;
161 char *reply
= nullptr;
162 char *cwd_msg
= nullptr;
163 MemBuf
*listing
= nullptr;
166 char *request_hdrs
= nullptr;
167 char *err_msg
= nullptr; /* Preformatted error message from the cache */
170 Ssl::ErrorDetail
*detail
= nullptr;
172 /// type-specific detail about the transaction error;
173 /// overwrites xerrno; overwritten by detail, if any.
174 int detailCode
= ERR_DETAIL_NONE
;
178 \ingroup ErrorPageAPI
180 * This function finds the error messages formats, and stores
181 * them in error_text[]
184 * error_text[] - is modified
186 void errorInitialize(void);
188 /// \ingroup ErrorPageAPI
189 void errorClean(void);
192 * \ingroup ErrorPageAPI
194 * This function generates a error page from the info contained
195 * by err and then sends it to the client.
196 * The callback function errorSendComplete() is called after
197 * the page has been written to the client (clientConn).
198 * errorSendComplete() deallocates err. We need to add
199 * err to the cbdata because comm_write() requires it
200 * for all callback data pointers.
202 \note normally errorSend() should only be called from
203 * routines in ssl.c and pass.c, where we don't have any
204 * StoreEntry's. In client_side.c we must allocate a StoreEntry
205 * for errors and use errorAppendEntry() to account for
206 * persistent/pipeline connections.
208 \param clientConn socket where page object is to be written
209 \param err This object is destroyed after use in this function.
211 void errorSend(const Comm::ConnectionPointer
&conn
, ErrorState
*err
);
214 \ingroup ErrorPageAPI
216 * This function generates a error page from the info contained
217 * by err and then stores the text in the specified store
219 * This function should only be called by "server
220 * side routines" which need to communicate errors to the
221 * client side. It should also be called from client_side.c
222 * because we now support persistent connections, and
223 * cannot assume that we can immediately write to the socket
227 \param err This object is destroyed after use in this function.
229 void errorAppendEntry(StoreEntry
*entry
, ErrorState
*err
);
231 /// \ingroup ErrorPageAPI
232 err_type
errorReservePageId(const char *page_name
);
234 const char *errorPageName(int pageId
); ///< error ID to string
237 \ingroup ErrorPageAPI
239 * loads text templates used for error pages and details;
240 * supports translation of templates
245 TemplateFile(const char *name
, const err_type code
);
246 virtual ~TemplateFile() {}
248 /// return true if the data loaded from disk without any problem
249 bool loaded() const {return wasLoaded
;}
252 * Load the page_name template from a file which probably exist at:
253 * (a) admin specified custom directory (error_directory)
254 * (b) default language translation directory (error_default_language)
255 * (c) English sub-directory where errors should ALWAYS exist
260 * Load an error template for a given HTTP request. This function examines the
261 * Accept-Language header and select the first available template. If the default
262 * template selected (eg because of a "Accept-Language: *"), or not available
263 * template found this function return false.
265 bool loadFor(const HttpRequest
*request
);
268 * Load the file given by "path". It uses the "parse()" method.
269 * On success return true and sets the "defined" member
271 bool loadFromFile(const char *path
);
273 /// The language used for the template
274 const char *language() {return errLanguage
.termedBuf();}
276 bool silent
; ///< Whether to print error messages on cache.log file or not. It is user defined.
279 /// Used to parse (if parsing required) the template data .
280 virtual bool parse(const char *buf
, int len
, bool eof
) = 0;
283 * Try to load the "page_name" template for a given language "lang"
284 * from squid errors directory
285 \return true on success false otherwise
287 bool tryLoadTemplate(const char *lang
);
289 bool wasLoaded
; ///< True if the template data read from disk without any problem
290 String errLanguage
; ///< The error language of the template.
291 String templateName
; ///< The name of the template
292 err_type templateCode
; ///< The internal code for this template.
296 * Parses the Accept-Language header value and return one language item on
298 * Will ignore any whitespace, q-values, and detectably invalid language
299 * codes in the header.
301 * \param hdr is the Accept-Language header value
302 * \param lang a buffer to store parsed language code in
303 * \param langlen the length of the lang buffer
304 * \param pos is used to store the offset state of parsing. Must be "0" on first call.
305 * Will be altered to point at the start of next field-value.
306 * \return true if something looking like a language token has been placed in lang, false otherwise
308 bool strHdrAcptLangGetItem(const String
&hdr
, char *lang
, int langLen
, size_t &pos
);
310 #endif /* SQUID_ERRORPAGE_H */