TWiki::Func::redirectCgiQuery does not handle URL fragments properly. (Fragment is the string after # in a URL that sends to a specific location on a page. TWiki sometimes calls them "Anchors".)
Specifically, redirectCgiQuery inserts its path (?twiki_redirect_cache=) string at the end of the URL instead of before the #. This si wrong. See
RFC2396 section 5.2 Oddly enough, the code goes out of it's way to do it the way it does, but it breaks every browser I've tried.
It's a 1-line fix in Client.pm line 507 in
TWiki-4.1.2, Sat, 03 Mar 2007, build 13046, Plugin API version
1.11
# Rewrite a URL inserting the session id
sub _rewriteURL {
...
# strip off the anchor
my $anchor = '';
if( $url =~ s/(#.*)// ) {
$anchor = $1;
}
# rebuild the URL
%RED%$url .= $anchor.$params;%ENDCOLOR%
%GREEN%$url .= $params.$anchor;%ENDCOLOR%
} # otherwise leave it untouched
} # otherwise leave it untouched
While in there, it would be nice if:
- One could get the URL without the print I use this for debugging to print what would have happened, diagnostic data, and provide a clickable link for manually redirecting.
- One could add a hash of additional parameters for CGI::redirect (e.g. -method=>'GET', -p3p=>[qw( xx, yy, zz)])
You can do this with a couple of lines of code.
Here's a scenario where it's useful (This follows the work-around given below):
if( $debug ) {
Dump application state
$redirect =~ s/^(Location: *)(.*)$/$1.$q->a({href=>$2}, $2)/mse;
print $q->p, $q->pre( "Redirect header:\n", $redirect );
} else {
print $redirect;
}
exit();
For anyone who has to live with this in the meantime, here's a work-around that I developed - obviously, the right fix is in redirectCgiQuery.
my $vurl = TWiki::Func::getViewUrl($wikiWeb, $wikiTopic); # Base URL of calendar
my $tag = "#Create_new_entry";
# Hack to add fragment tag to redirect, which TWiki doesn't handle right.
# (Right would be passing "$vurl.$tag" to redirect, which should put it's
# ?param string BEFORE the tag. Instead, it puts it after the tag, which
# doesn't work.)
# This gets the user back to the form's position on the page.
my ($tmp);
open( TMP, '+>', \$tmp ) or die "Can't open tempfile $tmp";
select TMP;
$| = 1;
TWiki::Func::redirectCgiQuery( $q, $vurl, 1 );
select STDOUT;
my $redirect = '';
seek TMP, 0, SEEK_SET;
while( <TMP> ) {
$_ =~ s/\r//g;
chomp $_;
$_ =~ s/^(Location:.*)$/$1$tag/;
$redirect .= "$_\r\n";
}
close TMP;
...
print $redirect;
--
TWiki:Main/TimotheLitt
- 20 Sep 2008
Possibly related
Item6461.
--
TWiki:Main.PeterThoeny
- 13 May 2010