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

Fellow monasterians,
I was just about ready to post this yesterday and then thought I had a solution after reading this answer. NOT.

I'm using HTML:Template to render my pages. So, I have the obligatory:
print "Content-type: text/html\n\n"; print $template->output();
However, sometimes, not always, before the pages are output, I use CGI to write a cookie:
my $newcookie = $query->cookie( -name=>'gardensessionID', -value=> $sessionnum, -expires=>'+24h'); print $query->header(-cookie=>$newcookie);
Those times when a cookie is written, the 'unsightly' Content-type... line is printed to the top of my output page. Here's a summary of how my script flows:

1. at top of script, a new template file name A is defined
2a. script is routed to subroutines which do not write a cookie, OR...
2b. is routed to a subroutines which do write a cookie, and defines a new file name B
3. either subroutine returns to output the defined page

Question: how do I arrange the use of the print "Content-type..." line to avoid printing it to screen in instances of 2b? Thanks in advance!

P.S. You can see the entire script on my scratchpad (experienced monks could have a field day with the rest of the code--but I'm still learning).

—Brad
"A little yeast leavens the whole dough."

Replies are listed 'Best First'.
Re: Unwanted appearance of "Content-type..."
by matija (Priest) on May 03, 2004 at 14:49 UTC
    What you're seeing is what happens when you call print header twice in one CGI session. You're not doing that only because you're rolling your own with the print "Content-type:..." statement.

    The solutions, as I see it are:

    • Keep a variable with the cookie, and replace the printing of the template with
      print header(-cookie=>$cookie,-type=>'text/html'); print $template->output();
    • Have a "smart" print_header subroutine that knows if a header has been printed in that session yet, and what the type was set to. That routine can warn you if you're attempting to set a new type.It can also warn you if you try to set a cookie after the header has been printed, and it's too late for cookies.
    I use the later approach when I have to deal with long, complicated code, where I can't tell which paths contain a print header and which don't - and the cookies are set and printed all over the place. (I once had to maintain a piece of code that set several cookies, at various points in the code. Sometimes I came this >< close to shooting the original author).
      matija, awesome, thanks. Went with your first bullet point:
      if ( $newcookie ) { print $query->header(-cookie=>$newcookie,-type=>'text/html'); } else { print "Content-type: text/html\n\n"; } print $template->output();
      and it worked perfectly. And thanks for the explanation as well. Looks like I need to do some more reading about HTTP protocols.

      —Brad
      "A little yeast leavens the whole dough."
        That issue has nothing to do with the HTTP, it is just that you didn't read the documentation for CGI::header() closely enough. CGI::header() prints *all* the headers for a typical page, including content type.
Re: Unwanted appearance of "Content-type..."
by Arunbear (Prior) on May 04, 2004 at 09:01 UTC
Re: Unwanted appearance of "Content-type..."
by Anonymous Monk on May 04, 2004 at 06:42 UTC
    Just as an additional note, in a production environment, you might what to read up on DBI placeholders. Otherwise, when these sort of statements
    my $session = $query->param('session'); $stmt = "DELETE FROM shopcart WHERE session = '$session'";
    get executed, and for example some little bastard has entered the following as the value for 'session'
    $session = "' OR '' = '";
    the contents of your shopcart table will get thoroughly trashed... :)