Search squid archive

Re: Re: can squid redirect the browser?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Brian J. Murrell wrote:
On Thu, 2009-10-29 at 23:58 +0100, Henrik Nordstrom wrote:
Either using url_rewrite_program and an url rewriter/redirector helper,
or by using http_access deny + deny_info.

Ahhh.  deny_info is interesting.  I guess there is no manipulating the
url that caused the deny, i.e. to customize the 302.

So, writing a deny such that if the URL denied was
http://foo.bar.com/some/path/index.hml, I can take the path portion and
do a 302 redirect to http://internal.my.domain.com/<same path as denied
url>.

Perhaps that's going to be left to the domain of redirector helpers.


I got that going a few weeks ago. It's scheduled for 3.2. The patch should still apply easily to 3.1.


Amos
--
Please be using
  Current Stable Squid 2.7.STABLE7 or 3.0.STABLE20
  Current Beta Squid 3.1.0.14
=== 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.


[Index of Archives]     [Linux Audio Users]     [Samba]     [Big List of Linux Books]     [Linux USB]     [Yosemite News]

  Powered by Linux