in reply to Calling a cgi with another cgi

Here's a one line solution to redirect a cgi to another cgi.
#Your Perl Program here print "Location:http://www.perlmonks.org\n\n";
Don't output a content-type header in your cgi.
The Location tag is a redirect ala http & apache.
Just output the Location call above and you
will be redirected on the server.

jtrue

Replies are listed 'Best First'.
Re: Re: Calling a cgi with another cgi
by davis (Vicar) on Oct 16, 2002 at 08:46 UTC

    Actually, no.

    Sorry, but that doesn't work. I've just tried the following script:

    #!/usr/bin/perl use warnings; use strict; print "Location:http://www.perlmonks.org/\n\n";

    And it failed - no redirection, just the string "Location:http://www.perlmonks.org/\n\n" in my browser.

    The reason it failed on my machine is because (IIRC) Apache looked at the first few lines of output of the script, didn't see a header, and so added the header itself (specifying plain text) before sending the output of the script.

    You can make yours work by adding the line

    print "HTTP/1.1 302 Moved\n";

    above the existing print() line.

    I've also just tried the following:

    #!/usr/bin/perl use warnings; use strict; use CGI; my $q = new CGI; print $q->redirect( -uri => 'http://www.perlmonks.org/' );
    Which outputs:
    Status: 302 Moved location: http://www.perlmonks.org/
    When called on the command line.

    When called by the webserver, it outputs a valid, correct, and working header that redirects the client.

    I'm not completely against printing the headers yourself for such a simple task, but I am against printing headers wrongly. Using the CGI module saves you from having to read the RFCs to find out why your script didn't work, and will save time: it took about 5 seconds to produce the CGI.pm method, and closer to 5 minutes for me to make your version work1

    When there's a monastery full of monks suggesting 'use CGI;', perhaps they're onto something

    Please Note:
    This isn't intended to be a telling-off: I did honestly want to see if your version worked.
    Cheers.


    1: - I'm not good at creating HTTP headers, so I don't claim that to be a good comparison.
    davis
    Is this going out live?
    No, Homer, very few cartoons are broadcast live - it's a terrible strain on the animator's wrist

    Update: After an interesting ChatterBox discussion with true, and some playing around with webserver configs, I've come to the following conclusion (for apache):

    true's solution works, if:

    1. You're not using modperl, or
    2. You are using modperl, but you've got "PerlSendHeader On" in your httpd.conf, or
    3. You play around with it to add the correct HTTP headers yourself

    The CGI.pm solution works whatever because it checks to see if modperl's running, and whether the header's been sent.

    References: the modperl guide, and Writing Apache Modules with Perl and C.

      Thanks for the info and input.
      I know CGI.pm is cool.
      This does redirect on my apache 1.3.6 webserver.
      I tried it again to be sure.
      #!/usr/bin/perl -w use strict; #Your Perl Program here print "Location:http://www.perlmonks.org\n\n"; exit;

      FYI
      I also tried to add your 302 tag but it failed.
      #!/usr/bin/perl -w use strict; ##Your Perl Program here print "HTTP/1.1 302 Moved\n"; print "Location:http://www.perlmonks.org\n\n"; exit;
      The httpd log reports:"...malformed header from script. Bad header=HTTP/1.1 302 Moved:..."

      cheers,
      jtrue
      First off, thanks to davis, your time has been very valuable.
      I should have clarified my current non-modperl status
      in my earlier post.
      Sadly i can't test under mod_perl right now.
      But, if anybodies is curious, I tested
      the code below successfully on
      Win2k apache and linux apache.
      Running perl 5.005 sans mod_perl
      #!/usr/bin/perl -w use strict; print "Location:http://www.google.com\n\n"; exit;
      Also, note on both platforms,
      adding the line
      print "HTTP/1.1 302 Moved\n";
      causes a mal-formed header error.

      The Motto of the story...
      use da CGI module!

      jtrue

      <edit:made grammar edit
        Allright Good People!

        What a lot of information this little question generated. I will work with your suggestions a little later - when time permits and I feels sure that I will get this working. Thanks a lot for all your time and input! You are the best!

        Donnie

Re: Re: Calling a cgi with another cgi
by Donnie (Acolyte) on Oct 16, 2002 at 19:41 UTC
    jtrue: It looks like your scheme would work - however, there is a problem. If I DO NOT use the header "print "Content-type: text/html\n\n";" this script will not run. Just gives the dreaded "Internal Server Error" message. Maybe I cannot redirect from a script that uses this header - because it just won't run without it?? Should I just abandon the idea?

      Donnie, Don't give up just yet. Make sure you don't print anything to STDOUT before you output the Location redirect. Try this code on your server as is, then add your code, avoid printing to STDOUT.

      #!/usr/bin/perl -w use strict; #!/usr/bin/perl #Your Perl Program here #DO NOT output anything to STDOUT print "Location:http://www.google.com/search?q=perl\n\n"; #OUTPUT ANYTHING OR NOTHING ##Your Perl Program here exit;

      Things you probably know anyway.

    • Apache is the guy doing the work here.
    • Perl doesn't know you are 'redirecting' it anywhere.
    • HTTP HTTP/1.x is a protocal in and of itself.
    • Read about the HTTP Location Header here
    • The above code works on Apache 1.3.6 with perl5.005
    • Here's a working link to prove it.
    • http://perl.to/d.cgi?pm=Donnie

      jtrue