* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
*
*/
-#include "config.h"
+#include "squid.h"
#include "comm/Connection.h"
#include "comm/Write.h"
+#include "err_detail_type.h"
#include "errorpage.h"
#if USE_AUTH
#include "auth/UserRequest.h"
#include "MemObject.h"
#include "fde.h"
#include "MemBuf.h"
+#include "protos.h"
#include "rfc1738.h"
#include "URLScheme.h"
#include "wordlist.h"
-#include "err_detail_type.h"
/**
\defgroup ErrorPageInternal Error Page Internals
class ErrorPageFile: public TemplateFile
{
public:
- ErrorPageFile(const char *name): TemplateFile(name) { textBuf.init();}
+ ErrorPageFile(const char *name, const err_type code): TemplateFile(name,code) { textBuf.init();}
/// The template text data read from disk
const char *text() { return textBuf.content(); }
* (a) default language translation directory (error_default_language)
* (b) admin specified custom directory (error_directory)
*/
- ErrorPageFile errTmpl(err_type_str[i]);
+ ErrorPageFile errTmpl(err_type_str[i], i);
error_text[i] = errTmpl.loadDefault() ? xstrdup(errTmpl.text()) : NULL;
} else {
/** \par
if (strchr(pg, ':') == NULL) {
/** But only if they are not redirection URL. */
- ErrorPageFile errTmpl(pg);
+ ErrorPageFile errTmpl(pg, ERR_MAX);
error_text[i] = errTmpl.loadDefault() ? xstrdup(errTmpl.text()) : NULL;
}
}
// look for and load stylesheet into global MemBuf for it.
if (Config.errorStylesheet) {
- ErrorPageFile tmpl("StylesSheet");
+ ErrorPageFile tmpl("StylesSheet", ERR_MAX);
tmpl.loadFromFile(Config.errorStylesheet);
error_stylesheet.Printf("%s",tmpl.text());
}
if (error_text) {
int i;
- for (i = ERR_NONE + 1; i < error_page_count; i++)
+ for (i = ERR_NONE + 1; i < error_page_count; ++i)
safe_free(error_text[i]);
safe_free(error_text);
{
int i;
- for (i = 0; i < error_hard_text_count; i++)
+ for (i = 0; i < error_hard_text_count; ++i)
if (error_hard_text[i].type == type)
return error_hard_text[i].text;
return NULL;
}
-TemplateFile::TemplateFile(const char *name): silent(false), wasLoaded(false), templateName(name)
+TemplateFile::TemplateFile(const char *name, const err_type code): silent(false), wasLoaded(false), templateName(name), templateCode(code)
{
assert(name);
}
/** test error_default_language location */
if (!loaded() && Config.errorDefaultLanguage) {
if (!tryLoadTemplate(Config.errorDefaultLanguage)) {
- debugs(1, DBG_CRITICAL, "Unable to load default error language files. Reset to backups.");
+ debugs(1, (templateCode < TCP_RESET ? DBG_CRITICAL : 3), "Unable to load default error language files. Reset to backups.");
}
}
#endif
}
/* giving up if failed */
- if (!loaded())
- fatal("failed to find or read error text file.");
+ if (!loaded()) {
+ debugs(1, (templateCode < TCP_RESET ? DBG_CRITICAL : 3), "WARNING: failed to find or read error text file " << templateName);
+ parse("Internal Error: Missing Template ", 33, '\0');
+ parse(templateName.termedBuf(), templateName.size(), '\0');
+ }
return true;
}
if (fd < 0) {
/* with dynamic locale negotiation we may see some failures before a success. */
- if (!silent)
+ if (!silent && templateCode < TCP_RESET)
debugs(4, DBG_CRITICAL, HERE << "'" << path << "': " << xstrerror());
wasLoaded = false;
return wasLoaded;
if (!pos) {
/* skip any initial whitespace. */
- while (pos < hdr.size() && xisspace(hdr[pos])) pos++;
+ while (pos < hdr.size() && xisspace(hdr[pos]))
+ ++pos;
} else {
// IFF we terminated the tag on whitespace or ';' we need to skip to the next ',' or end of header.
- while (pos < hdr.size() && hdr[pos] != ',') pos++;
- if (hdr[pos] == ',') pos++;
+ while (pos < hdr.size() && hdr[pos] != ',')
+ ++pos;
+ if (hdr[pos] == ',')
+ ++pos;
}
/*
if (*dt != '-' && *dt != '*' && (*dt < 'a' || *dt > 'z') )
invalid_byte = true;
else
- dt++; // move to next destination byte.
+ ++dt; // move to next destination byte.
}
- pos++;
+ ++pos;
}
- *dt++ = '\0'; // nul-terminated the filename content string before system use.
+ *dt = '\0'; // nul-terminated the filename content string before system use.
+ ++dt;
debugs(4, 9, HERE << "STATE: dt='" << dt << "', lang='" << lang << "', pos=" << pos << ", buf='" << ((pos < hdr.size()) ? hdr.substr(pos,hdr.size()) : "") << "'");
static int
errorPageId(const char *page_name)
{
- for (int i = 0; i < ERR_MAX; i++) {
+ for (int i = 0; i < ERR_MAX; ++i) {
if (strcmp(err_type_str[i], page_name) == 0)
return i;
}
- for (size_t j = 0; j < ErrorDynamicPages.size(); j++) {
+ for (size_t j = 0; j < ErrorDynamicPages.size(); ++j) {
if (strcmp(ErrorDynamicPages.items[j]->page_name, page_name) == 0)
return j + ERR_MAX;
}
callback(NULL),
callback_data(NULL),
request_hdrs(NULL),
- err_msg(NULL)
+ err_msg(NULL),
#if USE_SSL
- , detail(NULL)
+ detail(NULL),
#endif
+ detailCode(ERR_DETAIL_NONE)
{
memset(&flags, 0, sizeof(flags));
memset(&ftp, 0, sizeof(ftp));
if (req != NULL) {
request = HTTPMSGLOCK(req);
src_addr = req->client_addr;
- request->detailError(type, ERR_DETAIL_NONE);
}
}
HttpReply *rep;
debugs(4, 3, HERE << conn << ", err=" << err);
assert(Comm::IsConnOpen(conn));
- /*
- * ugh, this is how we make sure error codes get back to
- * the client side for logging and error tracking.
- */
-
- if (err->request)
- err->request->detailError(err->type, err->xerrno);
/* moved in front of errorBuildBuf @?@ */
err->flags.flag_cbdata = 1;
if (ftp.request) {
str.Printf("FTP Request: %s\r\n", ftp.request);
- str.Printf("FTP Reply: %s\r\n", ftp.reply);
+ str.Printf("FTP Reply: %s\r\n", (ftp.reply? ftp.reply:"[none]"));
str.Printf("FTP Msg: ");
wordlistCat(ftp.server_msg, &str);
str.Printf("\r\n");
case 'R':
if (building_deny_info_url) {
p = (request->urlpath.size() != 0 ? request->urlpath.termedBuf() : "/");
+ no_urlescape = 1;
break;
}
if (NULL != request) {
AnyP::ProtocolType_str[request->http_ver.protocol],
request->http_ver.major, request->http_ver.minor);
packerToMemInit(&pck, &mb);
- request->header.packInto(&pck);
+ request->header.packInto(&pck, true); //hide authorization data
packerClean(&pck);
} else if (request_hdrs) {
p = request_hdrs;
/* for backward compat we make %s show the full URL. Drop this in some future release. */
if (building_deny_info_url) {
p = request ? urlCanonical(request) : url;
- debugs(0,0, "WARNING: deny_info now accepts coded tags. Use %u to get the full URL instead of %s");
+ debugs(0, DBG_CRITICAL, "WARNING: deny_info now accepts coded tags. Use %u to get the full URL instead of %s");
} else
p = visible_appname_string;
break;
rep->header.putStr(HDR_CONTENT_LANGUAGE, "en");
}
- httpBodySet(&rep->body, content);
+ rep->body.setMb(content);
/* do not memBufClean() or delete the content, it was absorbed by httpBody */
}
+ // Make sure error codes get back to the client side for logging and
+ // error tracking.
+ if (request) {
+ int edc = ERR_DETAIL_NONE; // error detail code
+#if USE_SSL
+ if (detail)
+ edc = detail->errorNo();
+ else
+#endif
+ if (detailCode)
+ edc = detailCode;
+ else
+ edc = xerrno;
+ request->detailError(type, edc);
+ }
+
return rep;
}
assert(page_id > ERR_NONE && page_id < error_page_count);
#if USE_ERR_LOCALES
- ErrorPageFile *localeTmpl = NULL;
+ ErrorPageFile *localeTmpl = NULL;
/** error_directory option in squid.conf overrides translations.
* Custom errors are always found either in error_directory or the templates directory.
if (err_language && err_language != Config.errorDefaultLanguage)
safe_free(err_language);
- localeTmpl = new ErrorPageFile(err_type_str[page_id]);
+ localeTmpl = new ErrorPageFile(err_type_str[page_id], static_cast<err_type>(page_id));
if (localeTmpl->loadFor(request)) {
m = localeTmpl->text();
assert(localeTmpl->language());