Subject: | url() rewrite/path_info handling not compatible with CGI::Application::Dispatch rewriting |
The current logic for url() forces the path_info to be undefined if
rewriting is in use.
However, there is somewhat common use-case where combining rewriting and
the path_info is desired, and this is currently not possible with URL.
The rewriting recipe is simple conceptually: If a file or directory
physically exists, serve it directly. If the path does not physically
exist, give the path to a dispatcher as path_info, which will take it
from there.
This is how Drupal implements their "Clean URIs" solution, and
CGI::Application::Dispatch uses the same recipe. Here's how it looks in
mod_rewrite:
# If an actual file or directory is requested, serve directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Otherwise, pass everything through to the dispatcher
RewriteRule ^(.*)$ /cgi-bin/dispatch.cgi/$1 [L,QSA]
Below is one proposed fix. It says to only clear out the path_info if
you specifically asked for it to be thrown away ( path_info => 0 ). This
allows "rewrite" to be used with or without path_info().
Although it seems technically correct, it's not backwards compatible,
since the 3.12 release around 2005. The situation is complicated by
self_url() always "passes path_info => 1"
To stay backwards compatible, we have to keep the notion that rewrite=>1
always implies throwing out path_info. I think a compatible solution
would have to involve adding yet-another flag, like
"keep_rewrite_path_info"... or something.
Mark
--- old-alphasite/perllib/CGI.pm 2009-04-13 21:29:16.000000000 -0400
+++ new-alphasite/perllib/CGI.pm 2009-04-13 21:29:16.000000000 -0400
@@ -2717,7 +2717,11 @@
my $query_str = $self->query_string;
my $rewrite_in_use = $request_uri && $request_uri !~ /^\Q$script_name/;
- undef $path if $rewrite_in_use && $rewrite; # path not valid when
rewriting active
+
+ # path not valid when rewriting active, unless you specifically ask
for it.
+ if ($rewrite_in_use && $rewrite && not $path_info) {
+ undef $path;
+ }
my $uri = $rewrite && $request_uri ? $request_uri :
$script_name;
$uri =~ s/\?.*$//s; #
remove query string