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

Hi Monks,

I have a cgi script that is supposed to redirect the user on success. I was running it on a somewhat antiquated version of Ubuntu, and when I upgraded it to Lucid (running Perl 5.10.1 under apache 2.2.14), it stopped working. The error message is,

Invalid header value contains a newline not followed by whitespace: status: 302 found location: http://localhost/

The relevant code seems to be this:

my $set_username = $q->cookie( -name => "user_name", -value => $user_name, -expires => "+1d", ); my $set_session = $q->cookie( -name => "session", -value => $secret, -expires => "+1d", ); print $q->header( -cookie => [ $set_session, $set_username ], $q->redirect("http://localhost/"));

I've tried chomping the relevant variables, adding whitespace, etc., but it doesn't seem to help. As you may have guessed, it is a login script. Does anybody have any pointers on how to fix this?

Thanks!

Replies are listed 'Best First'.
Re: CGI error: "Invalid header value contains a newline not followed by whitespace"
by InfiniteSilence (Curate) on Feb 04, 2012 at 03:53 UTC

    Works for me once you define the variables being passed into the cookie method.

    #!/usr/bin/perl -w use strict; use CGI; use CGI::Cookie; my $q = CGI->new(); my ($username, $secret) = ('wowza','special'); my $set_username = $q->cookie( -name => "user_name", -value => $username, -expires => "+1d", ); my $set_session = $q->cookie( -name => "session", -value => $secret, -expires => "+1d", ); print $q->header( -cookie=>[$set_session, $set_username], $q->redirect +(q|http://www.google.com/|)); #print $q->header(); print $q->html($q->body($q->h1('hi there'))); 1;

    Celebrate Intellectual Diversity

      I may not have been clear enough in my earlier reply. What I mean to say is: your code throws the same error on my configuration, and so it sounds like the new version of CGI.pm disallows whatever I was used to doing. I hope to understand the issue (sounds like a security precaution) and fix it rather than blindly backing out of the newer version of the CGI library.

      Thanks!
        You call header() and redirect(), but redirect() itself calls header(), and in HTTP you only print headers once

      What version of Perl and apache have you?

      Thanks!
Re: CGI error: "Invalid header value contains a newline not followed by whitespace"
by Khen1950fx (Canon) on Feb 04, 2012 at 08:17 UTC
    I think that your problem is:
    print $q->header( -cookie => [ $set_session, $set_username ] , $q->re +direct("http://localhost/"));
    This works for me:
    #!/usr/bin/perl use strict; use warnings; use CGI; my $user_name = 'user'; my $secret = 'password'; my $q = CGI->new; my $set_username = $q->cookie( -name => "user_name", -value => $user_name, -expires => "+1d", ); my $set_session = $q->cookie( -name => "session", -value => $secret, -expires => "+1d", ); print $q->header( -cookie => [ $set_session, $set_username ]); print $q->redirect('http://localhost/');

      On my box, that code also fails, differently. It sends the cookies, but then prints the HTTP 302 code to the browser, rather than redirecting, like so:

      Status: 302 Found Location: http://localhost

      However, monkeying around with your code, I made this slight adjustment (look closely to see the difference!):

      print $q->header( -cookie => [ $set_session, $set_username ], print $q->redirect('http://localhost/'));

      ... and lo! my script works again! :D

      That's right, on my box, I will now have to insert a superfluous print in all of my cgi scripts that happen to send a redirect in the html header. How bizarre. But thanks to the both of you for the help!

      FYI, I experienced this behaviour with both whatever version of CGI.pm came with Lucid (didn't check), and then with the latest from git, 3.59 I guess.

        The correct code is:

        print $q->redirect( -uri => 'http://localhost/', -cookie => [ $set_session, $set_username ], );

        You only print headers once, either use redirect, or use header, not both

        print $q->header( -status => '302 Found', -uri => 'http://localhost/', -cookie => [ $set_session $set_username ], ); __END__