The_Rev has asked for the wisdom of the Perl Monks concerning the following question:

Hello again, I know I've asked this question before, but I'm still unclear with the results.

I have the following code that redirects a person to another html page if a certain word is seen, using Apache as my webserver.

#!/perl/bin/perl.exe -wT use CGI; $q = new CGI; $name = $q->param('name'); $comment = $q->param('comment'); if ($name =~ /^Auto$/i){ print $q->redirect("http://somewhere.com/cgi-bin/Auto.cgi"); } else{ print $q->header("text/html"); }
My objective is to redirect them without having the URL in the browser change.

I know this is possible, but I'm uncertain as to how the code should look. I have tried using internal redirects (not providing an absolute path) but the URL still changes to reflect the new page.

Any ideas?

Replies are listed 'Best First'.
•Re: cgi redirect (again)
by merlyn (Sage) on Dec 03, 2002 at 15:29 UTC
    If you are using Apache (as you've said), and you change that middle line to:
    print $q->redirect("/cgi-bin/Auto.cgi");
    then you will not see "Auto.cgi" in your browser's URI line as a result of this script. Instead, you will see the output of "Auto.cgi", but the original URL of the script you posted. That's called an internal redirect, and it works (unless "Auto.cgi" itself is also doing a redirect).

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      I haven't been able to find any reference documenting this behaviour, but I've never been able to force an internal redirect on Apache unless I omitted the Status: header (which redirect() adds by default) using...

      print $q->redirect( -status => "", -uri => "/cgi-bin/Auto.cgi" );
      ...or even...
      print "Location: /cgi-bin/Auto.cgi\n\n";

      Maybe you'll have better luck with one of these?

          --k.


        Aha! I found the culprit! You were spot on, although slightly confused. Apache does notice the status header of an internal redirect. Here's the code:
        location = ap_table_get(r->headers_out, "Location"); if (location && location[0] == '/' && r->status == 200) {
        So if there's a status, it has to be "200". Any other status, and the code falls through to sending the header out to the client instead (an external redirect).

        And there appears to be no-way to force a 200 status using CGI.pm's "redirect". {sigh}

        -- Randal L. Schwartz, Perl hacker
        Be sure to read my standard disclaimer if this is a reply.


        update: Ahh. I was wrong about CGI.pm. You can use
        print redirect(-uri => "/foo", -status => 200);
      Correct me if I am wrong but internal redirects are only available when running under mod_perl in apache. Surely the code you posted will send out a redirect header to the browser if just running as a CGI. This would work but would change the URL displayed.

      One way to achieve a solution to the original question would be to have the CGI script request the page off the server and then pass it back to the browser verbatim, as if it were just a proxy.

      I may be wrong...

      Update: Typo (i before e except after c)

Re: cgi redirect (again)
by PodMaster (Abbot) on Dec 03, 2002 at 15:23 UTC
    use frames. for a web browser to allow what you're asking would be considered a security risk.

    update: ooooh, apache magic (the browser doesn't have a clue, apache takes care of it, works for me)


    MJD says you can't just make shit up and expect the computer to know what you mean, retardo!
    ** The Third rule of perl club is a statement of fact: pod is sexy.