=== modified file 'src/errorpage.cc' --- src/errorpage.cc 2009-08-23 09:30:49 +0000 +++ src/errorpage.cc 2009-09-22 12:45:24 +0000 @@ -595,11 +595,12 @@ #define CVT_BUF_SZ 512 const char * -ErrorState::Convert(char token) +ErrorState::Convert(char token, bool url_presentable) { static MemBuf mb; const char *p = NULL; /* takes priority over mb if set */ int do_quote = 1; + int no_urlescape = 1; /* item is NOT to be further URL-encoded */ char ntoabuf[MAX_IPSTRLEN]; mb.reset(); @@ -607,37 +608,30 @@ switch (token) { case 'a': - if (request && request->auth_user_request) p = request->auth_user_request->username(); - if (!p) p = "-"; - break; case 'B': p = request ? ftpUrlWith2f(request) : "[no URL]"; - + no_urlescape = 1; break; case 'c': p = errorPageName(type); - break; case 'e': mb.Printf("%d", xerrno); - break; case 'E': - if (xerrno) mb.Printf("(%d) %s", xerrno, strerror(xerrno)); else mb.Printf("[No Error]"); - break; case 'f': @@ -646,7 +640,6 @@ p = ftp.request; else p = "nothing"; - break; case 'F': @@ -655,13 +648,12 @@ p = ftp.reply; else p = "nothing"; - break; case 'g': + if (url_presentable) break; /* FTP SERVER MESSAGE */ wordlistCat(ftp.server_msg, &mb); - break; case 'h': @@ -676,12 +668,10 @@ p = request->GetHost(); } else p = "[unknown host]"; - break; case 'i': mb.Printf("%s", src_addr.NtoA(ntoabuf,MAX_IPSTRLEN)); - break; case 'I': @@ -689,36 +679,34 @@ mb.Printf("%s", request->hier.host); else p = "[unknown]"; - break; case 'l': + if (!url_presentable) break; mb.append(error_stylesheet.content(), error_stylesheet.contentSize()); do_quote = 0; break; case 'L': + if (!url_presentable) break; if (Config.errHtmlText) { mb.Printf("%s", Config.errHtmlText); do_quote = 0; } else p = "[not available]"; - break; case 'm': + if (!url_presentable) break; p = auth_user_request->denyMessage("[not available]"); - break; case 'M': p = request ? RequestMethodStr(request->method) : "[unknown method]"; - break; case 'o': p = external_acl_message ? external_acl_message : "[not available]"; - break; case 'p': @@ -727,7 +715,6 @@ } else { p = "[unknown port]"; } - break; case 'P': @@ -735,7 +722,10 @@ break; case 'R': - + if (url_presentable) { + p = (request->urlpath.size() != 0 ? request->urlpath.termedBuf() : "/"); + break; + } if (NULL != request) { Packer p; String urlpath_or_slash; @@ -757,16 +747,21 @@ } else { p = "[no request]"; } - break; case 's': - p = visible_appname_string; + /* for backward compatibility we need to maek %s show the full URL. */ + if (url_presentable) { + p = request ? urlCanonical(request) : url ? url : "[no URL]"; + debugs(0,0, "WARNING: deny_info now accepts coded tags. Use %u to get the full URL instead of %s"); + } + else + p = visible_appname_string; break; case 'S': + if (!url_presentable) break; /* signature may contain %-escapes, recursion */ - if (page_id != ERR_SQUID_SIGNATURE) { const int saved_id = page_id; page_id = ERR_SQUID_SIGNATURE; @@ -780,7 +775,6 @@ /* wow, somebody put %S into ERR_SIGNATURE, stop recursion */ p = "[%S]"; } - break; case 't': @@ -802,46 +796,41 @@ break; case 'w': - if (Config.adminEmail) mb.Printf("%s", Config.adminEmail); else p = "[unknown]"; - break; case 'W': + if (!url_presentable) break; if (Config.adminEmail && Config.onoff.emailErrData) Dump(&mb); - break; case 'z': + if (!url_presentable) break; if (dnsError.size() > 0) p = dnsError.termedBuf(); else p = "[unknown]"; - break; case 'Z': + if (!url_presentable) break; if (err_msg) p = err_msg; else p = "[unknown]"; - break; case '%': p = "%"; - break; default: mb.Printf("%%%c", token); - do_quote = 0; - break; } @@ -855,9 +844,32 @@ if (do_quote) p = html_quote(p); + if (url_presentable && !no_urlescape) + p = rfc1738_escape_part(p); + return p; } +void +ErrorState::DenyInfoLocation(const char *name, HttpRequest *request, MemBuf &result) +{ + char const *m = name; + char const *p = m; + char const *t; + + while ((p = strchr(m, '%'))) { + result.append(m, p - m); /* copy */ + t = Convert(*++p, true); /* convert */ + result.Printf("%s", t); /* copy */ + m = p + 1; /* advance */ + } + + if (*m) + result.Printf("%s", m); /* copy tail */ + + assert((size_t)result.contentSize() == strlen(result.content())); +} + HttpReply * ErrorState::BuildHttpReply() { @@ -871,8 +883,10 @@ 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_LOCATION, name, quoted_url); + MemBuf redirect_location; + redirect_location.init(); + DenyInfoLocation(name, request, redirect_location); + httpHeaderPutStrf(&rep->header, HDR_LOCATION, "%s", redirect_location.content() ); } httpHeaderPutStrf(&rep->header, HDR_X_SQUID_ERROR, "%d %s", httpStatus, "Access Denied"); @@ -1048,7 +1062,7 @@ while ((p = strchr(m, '%'))) { content->append(m, p - m); /* copy */ - t = Convert(*++p); /* convert */ + t = Convert(*++p, false); /* convert */ content->Printf("%s", t); /* copy */ m = p + 1; /* advance */ } === modified file 'src/errorpage.h' --- src/errorpage.h 2009-07-12 22:56:47 +0000 +++ src/errorpage.h 2009-09-22 11:55:39 +0000 @@ -99,9 +99,21 @@ MemBuf *BuildContent(void); /** - * Convert an error template into an error page. - */ - const char *Convert(char token); + * Generates the Location: header value for a deny_info error page + * to be used for this error. + */ + void DenyInfoLocation(const char *name, HttpRequest *request, MemBuf &result); + + /** + * Map the Error page and deny_info template % codes into textual output. + * + * Several of the codes produce blocks of non-URL compatible results. + * When processing the deny_info location URL they will be skipped. + * + * \param token The token following % which need to be converted + * \param url_presentable URL-encode the the output for deny_info redirect + */ + const char *Convert(char token, bool url_presentable); /** * CacheManager / Debug dump of the ErrorState object.