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

Hi all.

I am trying to write a simple login form. The first page is simply HTML with two text fields ( name and password ) with one submit button. This part is finished. The form action is a perl based CGI script that looks like this:
#!C:\perl\perl.exe -wT use strict; use CGI qw( :standard ); use CGI::Carp qw( fatalsToBrowser ); print "Content-type: text/html\n\n"; my $Name = param("Name"); my $Password = param("Password"); redirect("/login.html") unless param("Name");
The login.html form is in the apache htdocs folder and the perl script is in cgi-bin.Since I am still learning the nuances of writing CGI scripts, I am slightly puzzled as to why the browser does not display the login.html page if I don't insert into the Name field. I can only assume I need to to modify my httpd.conf file ( Apache 1.3.20 ) to handle both HTML and CGI based applications? If so, any help in doing so would be most appreciated. The text I am using to learn CGI isn't particularly good. ( i.e. many demos, few explanations ).

Thanks,
-Katie

Replies are listed 'Best First'.
Re: Perl/CGI redirect.
by Zaxo (Archbishop) on May 20, 2002 at 06:23 UTC

    You shouldn't print the Content-Type header if you are going to redirect. It should be one or the other, so:

    use CGI qw( :standard ); use CGI::Carp qw( fatalsToBrowser ); print redirect("/login.html") and exit 0 unless defined param("Name"); my $Name = param("Name"); my $Password = param("Password"); print header; # CGI.pm method # print "Content-type: text/html\n\n";
    The logic could as easily be done in an if(){}else{} type construct, but I like the directness of this way. I omitted definedness checking on param('Password'), but you might want to add it in.

    Update: You also need to print the redirect, corrected in code.

    After Compline,
    Zaxo

Re: Perl/CGI redirect.
by Dog and Pony (Priest) on May 20, 2002 at 10:15 UTC
    Others have already given you the answer for this particular problem, so I thought I'd offer some more generic tips.
    The text I am using to learn CGI isn't particularly good. ( i.e. many demos, few explanations ).
    It was quite some time since I looked at it, but I think that this tutorial by Ovid looked excellent if you want to learn CGI with perl - and moreover, in a clean and secure way too.

    Also, if you want to see a little more what happens behind the scenes of a normal header and a redirect, just try this silly little program on the command line (not on the web server):

    #!/usr/bin/perl -w use strict; use CGI; my $q = CGI->new; print "This is the redirect header:\n"; print $q->redirect('/login.html'); print "And this is the normal header:\n"; print $q->header; print "And this is an alternative header:\n"; print $q->header('text/plain');
    Those are the texts that your script sends to the web browser to tell it what is happening, and what it should do. Either one of these should come first in your script (unless you are doing some by hand manipulation of the headers) and they are not possible to combine. Since you use CGI.pm anyways, might as well use the header function too, instead of printing "Content-type..." by yourself. That way you will not have any spelling errors, and CGI.pm will see to it that it works even on half-broken servers. :)


    You have moved into a dark place.
    It is pitch black. You are likely to be eaten by a grue.
Re: Perl/CGI redirect.
by DigitalKitty (Parson) on May 20, 2002 at 13:27 UTC
    Hi all.

    Thanks for all the helpful suggestions. They were/are most appreciated. For those that are interested, I fixed the problem ( a minor side-effect of the learning process ). Here is the finished code snippet:

    #!c:\perl\perl.exe -wT use strict; use CGI::Carp qw( fatalsToBrowser ); use CGI qw( :standard ); print redirect( "/login.htm" ) unless param( "Name" ); my $Name = param( "Name" ); my $Password = param( "Password" ); print header(); # CGI.pm method

    Simple yes, but I intend to build on this foundation. A very dedicated former college instructor of mine emailed and asked if I could help him set up a perl based user authentication script. With all he did for me, I wasn't about to let me him down.
    Thanks again for all the help,

    -DK
Re: Perl/CGI redirect.
by kodo (Hermit) on May 20, 2002 at 09:34 UTC
    As far as I know it's usually not a problem to have the header printed and then redirect basically but it could be depending on server/configuration. I would try to replace the /login.html with a full url like http://myserver/login.html, which solves the problem in most cases. If that also don't works I would try to just do a print q(<META HTTP-EQUIV="refresh" CONTENT="n; URL=http://foo.bar/">); -> helped me in one case but I still don't know why tbh...

    greets,
    giant


    -----BEGIN PERL GEEK CODE BLOCK-----
    Version: 0.01
    P++>+++$c-> P6 >+R+>+M+>++O
    >+MA+>+++E+>++PU+>+++BD C+>++D!S X!WP
    >+++MO?PP++n CO?PO-o+G
    A--OL!Ee---Ev++Eon!Eot!Eob!Eoa!uL++uB
    uS!uH+uo+w---m!osA-osBE-
    ------END PERL GEEK CODE BLOCK------
      As far as I know...
      Hopefully, the people reading your node will know from the way you start your answer that the remaining text is not to be trusted. {grin}

      I suggest you read the rest of the messages in this thread, and others, before answering on this subject again. Your statement contained many vaguenesses and a few misleading (and incorrect) claims.

      In brief:

      • No, you can't have both a normal header and a redirect.
      • A body HTML redirect is not the same as a header redirect, and is generally frowned upon except in the rare case that you don't have control of the headers. Of course, in CGI, you have complete control of the headers, so this is never needed in a CGI world. And a body HTML redirect messes up your back button.
      • A header redirect is an instruction to the webserver. If this contains a full URL, then it's an external redirect passed to the browser. If it's just an absolute path, it's an internal redirect. These have different distinct and useful purposes, and it's good to know how to use both.
      So you were kinda 0 for 3 there.

      Your willingness to help is appreciated and noted, however.

      -- Randal L. Schwartz, Perl hacker

        Uhm okay I feel sorry then for posting wrong stuff on this one. But the one with the full-URL is even in perldoc CGI:

        One hint I can offer is that relative links may not work correctly when you generate a redirection to another docu�
        ment on your site. This is due to a well-intentioned optimization that some servers use. The solution to this is to use the full URL (including the http: part) of the document you are redirecting to.

        But anyway I'll go back to the books and think more carefully before I post something next time, because it's really bad to post wrong stuff :(

        /me asks the gods for mercy and goes back to meditation...