#include "config.h"
#include "errorpage.h"
-#include "AuthUserRequest.h"
+#include "auth/UserRequest.h"
#include "SquidTime.h"
#include "Store.h"
#include "HttpReply.h"
* to the client socket.
*
\note If there is a callback, the callback is responsible for
- * closeing the FD, otherwise we do it ourseves.
+ * closing the FD, otherwise we do it ourselves.
*/
static void
errorSendComplete(int fd, char *bufnotused, size_t size, comm_err_t errflag, int xerrno, void *data)
HTTPMSGUNLOCK(err->request);
safe_free(err->redirect_url);
safe_free(err->url);
- safe_free(err->dnsserver_msg);
safe_free(err->request_hdrs);
wordlistDestroy(&err->ftp.server_msg);
safe_free(err->ftp.request);
if (auth_user_request->denyMessage())
str.Printf("Auth ErrMsg: %s\r\n", auth_user_request->denyMessage());
- if (dnsserver_msg) {
- str.Printf("DNS Server ErrMsg: %s\r\n", dnsserver_msg);
- }
+ if (dnsError.size() > 0)
+ str.Printf("DNS ErrMsg: %s\r\n", dnsError.termedBuf());
/* - TimeStamp */
str.Printf("TimeStamp: %s\r\n\r\n", mkrfc1123(squid_curtime));
/* - IP stuff */
str.Printf("ClientIP: %s\r\n", src_addr.NtoA(ntoabuf,MAX_IPSTRLEN));
- if (request && request->hier.host) {
+ if (request && request->hier.host[0] != '\0') {
str.Printf("ServerIP: %s\r\n", request->hier.host);
}
case 'h':
mb.Printf("%s", getMyHostname());
-
break;
case 'H':
if (request) {
- if (request->hier.host)
+ if (request->hier.host[0] != '\0') // if non-empty string.
p = request->hier.host;
else
p = request->GetHost();
break;
case 'I':
- if (request && request->hier.host) {
+ if (request && request->hier.host[0] != '\0') // if non-empty string
mb.Printf("%s", request->hier.host);
- } else
+ else
p = "[unknown]";
break;
break;
case 'U':
- p = request ? urlCanonicalClean(request) : url ? url : "[no URL]";
+ /* Using the fake-https version of canonical so error pages see https:// */
+ /* even when the url-path cannot be shown as more than '*' */
+ p = request ? urlCanonicalFakeHttps(request) : url ? url : "[no URL]";
break;
case 'u':
break;
case 'z':
- if (dnsserver_msg)
- p = dnsserver_msg;
+ if (dnsError.size() > 0)
+ p = dnsError.termedBuf();
else
p = "[unknown]";
if (strchr(name, ':')) {
/* Redirection */
- rep->setHeaders(version, HTTP_MOVED_TEMPORARILY, NULL, "text/html", 0, 0, squid_curtime);
+ rep->setHeaders(version, HTTP_MOVED_TEMPORARILY, NULL, "text/html", 0, 0, -1);
if (request) {
char *quoted_url = rfc1738_escape_part(urlCanonical(request));
httpHeaderPutStrf(&rep->header, HDR_X_SQUID_ERROR, "%d %s", httpStatus, "Access Denied");
} else {
MemBuf *content = BuildContent();
- rep->setHeaders(version, httpStatus, NULL, "text/html", content->contentSize(), 0, squid_curtime);
+ rep->setHeaders(version, httpStatus, NULL, "text/html", content->contentSize(), 0, -1);
/*
* include some information for downstream caches. Implicit
* replaceable content. This isn't quite sufficient. xerrno is not
while ( pos < hdr.size() ) {
+ /* skip any initial whitespace. */
+ while (pos < hdr.size() && xisspace(hdr[pos])) pos++;
+
/*
* Header value format:
* - sequence of whitespace delimited tags
* - IFF a tag contains only two characters we can wildcard ANY translations matching: <it> '-'? .*
* with preference given to an exact match.
*/
+ bool invalid_byte = false;
while (pos < hdr.size() && hdr[pos] != ';' && hdr[pos] != ',' && !xisspace(hdr[pos]) && dt < (dir+256) ) {
- *dt++ = xtolower(hdr[pos++]);
+ if (!invalid_byte) {
+#if HTTP_VIOLATIONS
+ // if accepting violations we may as well accept some broken browsers
+ // which may send us the right code, wrong ISO formatting.
+ if (hdr[pos] == '_')
+ *dt = '-';
+ else
+#endif
+ *dt = xtolower(hdr[pos]);
+ // valid codes only contain A-Z, hyphen (-) and *
+ if (*dt != '-' && *dt != '*' && (*dt < 'a' || *dt > 'z') )
+ invalid_byte = true;
+ else
+ dt++; // move to next destination byte.
+ }
+ pos++;
}
*dt++ = '\0'; // nul-terminated the filename content string before system use.
- debugs(4, 9, HERE << "STATE: dt='" << dt << "', reset='" << reset << "', reset[1]='" << reset[1] << "', pos=" << pos << ", buf='" << hdr.substr(pos,hdr.size()) << "'");
+ debugs(4, 9, HERE << "STATE: dt='" << dt << "', reset='" << reset << "', pos=" << pos << ", buf='" << ((pos < hdr.size()) ? hdr.substr(pos,hdr.size()) : "") << "'");
/* if we found anything we might use, try it. */
- if (*reset != '\0') {
+ if (*reset != '\0' && !invalid_byte) {
+
+ /* wildcard uses the configured default language */
+ if (reset[0] == '*' && reset[1] == '\0') {
+ debugs(4, 6, HERE << "Found language '" << reset << "'. Using configured default.");
+ m = error_text[page_id];
+ if (!Config.errorDirectory)
+ err_language = Config.errorDefaultLanguage;
+ break;
+ }
debugs(4, 6, HERE << "Found language '" << reset << "', testing for available template in: '" << dir << "'");
+
m = errorTryLoadText( err_type_str[page_id], dir, false);
if (m) {
dt = reset; // reset for next tag testing. we replace the failed name instead of cloning.
- // IFF we terminated the tag on ';' we need to skip the 'q=' bit to the next ',' or end.
+ // 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++;
}