From 303208e0fba2760a1863d71d7d2c9730f5480db4 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 30 Oct 2011 16:15:29 +0000 Subject: [PATCH] Let +fast-redirects{check-decoded-url} check URL segments separately If there are other parameters behind the redirect URL, this makes it unnecessary to cut them of by additionally using a +redirect{} pcrs command. Patch submitted by Jamie Zawinski in #3429848. --- filters.c | 51 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/filters.c b/filters.c index 1949b21c..963adac9 100644 --- a/filters.c +++ b/filters.c @@ -1,4 +1,4 @@ -const char filters_rcs[] = "$Id: filters.c,v 1.144 2011/07/30 15:15:25 fabiankeil Exp $"; +const char filters_rcs[] = "$Id: filters.c,v 1.145 2011/09/04 11:10:56 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/filters.c,v $ @@ -1106,21 +1106,52 @@ char *get_last_url(char *subject, const char *redirect_mode) } if (0 == strcmpic(redirect_mode, "check-decoded-url")) - { - log_error(LOG_LEVEL_REDIRECTS, "Decoding \"%s\" if necessary.", subject); - new_url = url_decode(subject); - if (new_url != NULL) + { + log_error(LOG_LEVEL_REDIRECTS, "Checking \"%s\" for encoded redirects.", + subject); + + /* jwz: Check each parameter in the URL separately. + Sectionize the URL at "?" and "&", + then URL-decode each component, + and look for a URL in the decoded result. + Keep the last one we spot. + */ + char *found = 0; + char *s = strdup (subject); + char *token = strtok (s, "?&"); + while (token) { - freez(subject); - subject = new_url; + char *dtoken = url_decode (token); + if (!dtoken) continue; + char *h1 = strstr (dtoken, "http://"); + char *h2 = strstr (dtoken, "https://"); + char *h = (h1 && h2 + ? (h1 < h2 ? h1 : h2) + : (h1 ? h1 : h2)); + if (h) + { + freez(found); + found = strdup (h); + } + token = strtok (0, "?&"); } - else + freez(s); + + if (found) { - log_error(LOG_LEVEL_ERROR, "Unable to decode \"%s\".", subject); + freez(subject); + return found; } + + freez (subject); + return NULL; } - log_error(LOG_LEVEL_REDIRECTS, "Checking \"%s\" for redirects.", subject); + + /* Else, just look for a URL inside this one, without decoding anything. */ + + log_error(LOG_LEVEL_REDIRECTS, "Checking \"%s\" for unencoded redirects.", + subject); /* * Find the last URL encoded in the request -- 2.39.2