It seems that when a Redirect directive with an absolute path as target, like in the configuration below, is specified in server config context, no scheme or hostname will get prefixed to the absolute path for matching requests, which is not according to the documentation of the Redirect directive: "The new URL should be an absolute URL beginning with a scheme and hostname, but a URL-path beginning with a slash may also be used, in which case the scheme and hostname of the current server will be added." And, this also differs from how Redirect directives with absolute path targets are handled, for example, in directory context, which is in line with the documentation, it seems. To demonstrate the problem, consider the following configuration: Redirect /test/source1 /test/dest <Directory /var/www/test> Redirect /test/source2 /test/dest </Directory> With the above configuration, the command curl --include http://localhost/test/source1/ gives the following output: HTTP/1.1 302 Found Date: Mon, 03 Dec 2007 22:04:32 GMT Server: Apache/2.2.6 (Debian) PHP/5.2.4-2 with Suhosin-Patch Location: /test/dest/ Content-Length: 300 Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>302 Found</title> </head><body> <h1>Found</h1> <p>The document has moved <a href="/test/dest/">here</a>.</p> <hr> <address>Apache/2.2.6 (Debian) PHP/5.2.4-2 with Suhosin-Patch Server at localhost Port 80</address> </body></html> While the command curl --include http://localhost/test/source2/ gives this output: HTTP/1.1 302 Found Date: Mon, 03 Dec 2007 22:04:44 GMT Server: Apache/2.2.6 (Debian) PHP/5.2.4-2 with Suhosin-Patch Location: http://localhost/test/dest/ Content-Length: 316 Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>302 Found</title> </head><body> <h1>Found</h1> <p>The document has moved <a href="http://localhost/test/dest/">here</a>.</p> <hr> <address>Apache/2.2.6 (Debian) PHP/5.2.4-2 with Suhosin-Patch Server at localhost Port 80</address> </body></html> Note how the Location header in the HTTP response differ in the output of the two commands. I believe the cause for this discrepancy is in the function translate_alias_redir in file mod_alias.c, which seems to process redirections (as well as aliases) specified in server config context, while the function fixup_redir seems to process redirections specified in directory context. Note how the blocks of the if statements which test for redirection (with condition ap_is_HTTP_REDIRECT(status)) differ. I think these should be almost, if not completely, the same, and I'll also attach a patch suggesting this. Since the patch simply makes the two if statements identical, a change not directly related, is also introduced, meaning that a query string following a '?' in the URL is also handled the same way in both contexts. While this also seems reasonable, I think, I have not much experience with Apache internals, so the patch is merely a suggestion, of course. Note, I use the version of Apache packaged by Debian, but the source file mod_alias.c, which I think contains the cause of the problem, has not been modified by Debian, as far as I can see.
Created attachment 21229 [details] Attempt to improve handling of absolute paths in Redirect directives
Reviewing your patch, it's basically good (thanks!), but it's too strict for 2.2 (we'll get complaints about returning internal server error on configs that previously "worked" - as far as the user was concerned). Any objection to my changing that to just log a warning and fall back to old-behaviour if it doesn't construct a valid URL?
No, I think that seems reasonable. Thanks.
I've committed your patch to /trunk/ in r785575. I'll propose a modified patch for backport to 2.2: http://people.apache.org/~niq/patches/44020.patch
Backported to 2.2 in r791541
Because write "Redirect permanent /xxx /yyy" is correct usage according to the documentation, I consider logging leven "warn" too high and propose to change ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "incomplete redirection target of '%s' for " "URI '%s' modified to '%s'", orig_target, r->uri, ret); to ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "incomplete redirection target of '%s' for " "URI '%s' modified to '%s'", orig_target, r->uri, ret); in mod_alias.c. (In our environment where different webservers serve the same content, writing the short URL for server-local redirects avoids the need for different .htaccess files for each server. But using the short URLs pollutes our error logs with these warnings.) Thank you.
Currently the 'incomplete redirection target' message occurres twice in mod_alias.c, once with APLOG_DEBUG, once with APLON_WARNING. Both should be APLOG_DEBUG. Thank you.
as per #c7, these messages still go to the warning log & pollute the logfile quite a bit. if the syntax is correct, it should all go to the debug loglevel
Fixed in r1165101 / 2.2.21