RemoveRedirectCGIQueryHandler

There's a handler that purports to replace CGI redirectio. I guess it was intended to provide some sort of REST functionality at some point in the far distant past. As far as I can tell it's unused, and I just discovered it's really dangerous; it relies on the plugin implementing everything that the core does on a redirect. In the old days, when you could rely on CGI, that wasn't so bad; but with FSA, it's bad news IMHO.

I strongly believe it should be deprecated in 1.1.

It is unused by any plugin checked in to subversion.

-- CrawfordCurrie - 11 Aug 2009

for those of us that have too many unpublished plugins - the code and docco that Crawford is refering to iss


=begin TML

---+++ redirectCgiQuery( $query, $url, $passthru )

Redirect to URL
   * =$query= - CGI query object. Ignored, only there for compatibility. The session CGI query object is used instead.
   * =$url=   - URL to redirect to
   * =$passthru= - enable passthrough.

Return:             none

Print output to STDOUT that will cause a 302 redirect to a new URL.
Nothing more should be printed to STDOUT after this method has been called.

The =$passthru= parameter allows you to pass the parameters that were passed
to the current query on to the target URL, as long as it is another URL on the
same installation. If =$passthru= is set to a true value, then Foswiki
will save the current URL parameters, and then try to restore them on the
other side of the redirect. Parameters are stored on the server in a cache
file.

Note that if =$passthru= is set, then any parameters in =$url= will be lost
when the old parameters are restored. if you want to change any parameter
values, you will need to do that in the current CGI query before redirecting
e.g.
<verbatim>
my $query = Foswiki::Func::getRequestObject();
$query->param(-name => 'text', -value => 'Different text');
Foswiki::Func::redirectCgiQuery(
  undef, Foswiki::Func::getScriptUrl($web, $topic, 'edit'), 1);
</verbatim>
=$passthru= does nothing if =$url= does not point to a script in the current
Foswiki installation.

=cut

sub redirectCgiQuery {
    my ( $query, $url, $passthru ) = @_;
    ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
    return $Foswiki::Plugins::SESSION->redirect( $url, $passthru );
}

and so far, i agree - i'm looking through my more exploitative hack plugins to see if i've used it for anything smile

-- SvenDowideit - 12 Aug 2009

Or asked the other way around: can anybody imagine how to make any use of this handler without breaking things terribly?

-- MichaelDaum - 12 Aug 2009

Kenneth: I wrote myself in as committed developer, but never added a commitment date. This proposal has been around for quite a while now, with very little feedback (and none of it negative) so I propose that we should accept this change, on the basis that consensus has been reached.

Note that this is a deprecation so will have no functional impact in 1.1. However the release note need to highlight what was done.

Aside from this comment I have made the following changes:
  1. Set ReasonForDecision to ConsensusReached (was: None)
  2. Set DateOfCommitment to today

-- CrawfordCurrie - 01 Apr 2010

You break all the rules again now.

NO!

Concensus is not reached when we have not had the proposal committed.

I will not accept any exceptions to this rule

-- KennethLavrsen - 01 Apr 2010

I am using the redirectCgiQueryHandler in the HijaxPlugin (not developed in SVN) but I'm not actually doing any redirecting, just making sure some parameters are in the url for the redirect that is handled by the core, i.e. I'm returning 0.

sub redirectCgiQueryHandler {
    # do not uncomment, use $_[0], $_[1] instead
    ### my ( $query, $url ) = @_;
    if ($debug) {
        my $query_string = $_[0]->query_string();
        Foswiki::Func::writeDebug( "- ${pluginName}::redirectCgiQueryHandler( $query_string, $_[1] )" );
    }
    return 0 unless $_[0]->param('cover') && $_[0]->param('cover') =~ /ajax/;
    my $append = ($_[1] =~ m/(\?.*)$/) ? '&' : '?';
    $_[1] .= $append.'cover='.$_[0]->param('cover');
    return 0 if $_[1] =~ /foswiki_redirect_cache/; # this is an intermediate step, patience
    $_[1] .= '&hijax='.join('&hijax=',$_[0]->param('hijax')) if $_[0]->param('hijax');
    $_[1] .= '&tmplp='.join('&tmplp=',$_[0]->param('tmplp')) if $_[0]->param('tmplp');
    if ($_[0]->param('returntemplate') && $_[1] !~ /oops(accessdenied|alerts)/) { 
        $_[1] .= '&template='.$_[0]->param('returntemplate');
    }
    if ($debug) {
        my $query_string = $_[0]->query_string();
        Foswiki::Func::writeDebug( "- ${pluginName}::redirectCgiQueryHandler( $query_string, $_[1] )" );
    }
    return 0;
}

I don't think I'm in a position to be justified in blocking this, but I would like to keep some way of being able to manipulate the url string just before the redirect. I suppose I could try to work around it with a temporary cache file in the working directory for HijaxPlugin but it would never be 100% unless you can tell me how a plugin can pass a unique id across a redirect...

-- DavidPatterson - 06 Apr 2010

You appear to be trying to pass state from one script to another, by "patching" the URL. Is there a reason why you can't use the CGI session to store that state instead (Foswiki::Func::setSessionValue)?

-- CrawfordCurrie - 06 Apr 2010

Okay, thanks for the pointer. It means then that the initPlugin will always have to set a passthru-type cache just in case there is a redirect. The advantage of the redirectCgiQueryHandler was that it was on-demand, no unnecassary work being done.

How is the case for a preRedirectHandler so that plugins can know that a redirect is happening and why?

-- DavidPatterson - 07 Apr 2010

No, you should never need anything as heavy as a passthrough cache. Just stick your data directly into session values, and let someone else handle the files for you.

Why would you need to know if a redirect is happening?

-- CrawfordCurrie - 07 Apr 2010

Just stick your data directly into session values, and let someone else handle the files for you.
Yes, that's what I meant. Bad use of terminology, sorry.

HijaxPlugin makes sure that certain params persist regardless of what happens in the data flow, i.e. with cover=ajax the HijaxPlugin completePageHandler can parse the relevant content into a JSON string that the client-side js can make unambiguous sense of. So, if an OopsException is thrown, for example, that can also be returned as JSON which the js on the other side of the ajax call can present to the user as an error because the context variable is set as oops and the content variable contains the error message. Likewise, if a redirect to login is made, the login form can be presented and hijaxed for submission over ajax. Likewise for upload etc. So, setting the cover, hijax, tmplp variables in the session is only a small effort but not necessary if there's no redirect.

-- DavidPatterson - 07 Apr 2010

Thanks for that David, that makes it a lot clearer; I was struggling with the plugin description. Might I suggest you incorporate something similar to the above paragraph, as it makes it all make more sense? A worked example might also be of benefit.

From your description I would say the session is definitely where you should be passing this information. The amount of work required to maintain it is (AFAICT) tiny, and it's a lot less vulnerable than the URL.

-- CrawfordCurrie - 08 Apr 2010

Well past the 14 days limit with no concerns, so marking as accepted. I discussed a better approach with David (using the session), and he seems to be happy (or at least has gone quiet)

-- CrawfordCurrie - 19 Apr 2010

Wondering how Tasks.Item2602 should be addressed, in light of this proposal

(I assume close no action, but will leave that to Crawford & Arthur to sort out)

-- PaulHarvey - 21 Apr 2010

Item2602 addresses the Func call Foswiki::Func::redirectCgiQuery. This proposal deprecate a handler called redirectCgiQueryHandler.

I use the Func call in my plugins and I would not want that deprecated and would have barked like a dog if it was proposed.

-- KennethLavrsen - 21 Apr 2010

Yikes, my mistake :}

-- PaulHarvey - 21 Apr 2010

I've been coming back to this on and off for almost 18 months now without success and need some help. I wan't to remove the redirectCgiQueryHandler from HijaxPlugin but I can't see how without some other trigger that unambiguously says, "ok, server-side redirect happening." Note that HP isn't triggering the redirect, it just wants to make sure that cover=ajax persists so its completePageHandler can convert the response into JSON as expected by the AJAX call from the browser.

I understand that I can use setSessionValue to pass variables across scripts but I only want to do that in the case of a redirect. Am I missing something blindingly obvious? Can't we keep redirectCgiQueryHandler but remove its power to takeover the redirect mechanism, i.e. use it just as a heads-up for plugins?

For example:
script one initPlugin
    HijaxPlugin trigger is there (?cover=ajax)
    setSessionValue __in case__ of a redirect
    carry on

script two initPlugin
    no HijaxPlugin trigger but there is a sessionValue
    am I post re-direct as part of an AJAX call or just in a normal script execution?

Thanks for any help you can give.

-- DavidPatterson - 12 Sep 2011
Topic revision: r17 - 12 Sep 2011, DavidPatterson
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy