Why would Perl's CGI::cookie be able to set a cookie in IE, but not Firefox?
cgi, cookies, mason, perl
Solution
Argh! It turns out the issue is that there is only one cookie in play when running on "localhost", but there are multiple cookies in play when hosted on SourceForge's servers.
If you look at the Firefox request headers cut-n-pasted in the question above, you'll notice that there are several cookie name-value pairs... with each pair separated by semicolons. My code was failing to account for this, so all it saw was one giant mal-formed cookie.
I'm still not 100% sure why it was partially working in IE, and I may revisit this in the future to see if more can be learned. But it's basically a moot point for now. I altered the code to split on semicolons AND then split on equals signs, I'm processing cookies just fine now.
Thanks to everyone for your insight and suggestions! Pierre-Luc, I did give your answer an upvote out of gratitude for all the comments beneath it.
sub getCookie {
my $cookieName = shift;
my %headers = $r->headers_in;
my @keys = keys( %headers );
foreach my $name ( @keys ) {
if( $name eq 'Cookie') {
my @semicolontokens = split( ';', $headers{$name} );
foreach my $splitname ( @semicolontokens ) {
$splitname =~ s/^\s+//;
$splitname =~ s/\s+$//;
my @pair = split( '=', $splitname );
if( $pair[0] eq $cookieName ) {
return $pair[1];
}
}
}
}
Problem
I have a bit of Perl CGI code which I'm trying to run in the project web space of a SourceForge account. The code is able to set a browser cookie just fine when talking to IE, but the cookie is not set when talking to Firefox. When I test with Apache on "localhost", both browsers work fine. It's only on the remote SourceForge URL that Firefox craps out. A search has turned up dozens of near-duplicate questions, but usually people have the exact opposite problem! (Firefox being fine and IE having the problem) Here is the utility sub I'm calling to set cookies: ``` sub setCookie { my $name = shift; my $value = shift; my $expires = shift; my $path = shift; my $domain = shift; if( !defined( $expires ) ) { $expires = '+4h'; } if( !defined( $path ) ) { $path = '/'; } if( !defined( $domain ) ) { $domain = 'steveperkins.sourceforge.net'; } my $cookie = CGI::cookie( -name => $name, -value => $value, -domain => $domain, -expies => $expires, -path => $path ); $r->header_out('Set-cookie' => $cookie); } ``` Any ideas? My first thought was some kind of subdomain issue, because my SourceForge project URL has a subdomain in it while "localhost" does not. I've experimented with setting the cookie domain to my specific subdomain, or to just the base "sourceforge.net". It doesn't seem to make a difference either way. UPDATE: Someone in the comments below asked about the HTTP response headers. I've used the network traffic analyzer tool Wireshark to monitor the request and response headers for both IE and Firefox, and here's what they look like: IE (works) Request ``` GET http://myproject.sourceforge.net/cgi-bin/myscript.cgi?page=user&userID=1 HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-ms-application, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */* Referer: http://myproject.sourceforge.net/cgi-bin/myscript.cgi Accept-Language: en-us UA-CPU: x86 Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.5.30729; InfoPath.1; .NET CLR 3.0.30618) Proxy-Connection: Keep-Alive Host: myproject.sourceforge.net Authorization: Basic [password omitted] ``` Response ``` HTTP/1.1 200 OK Server: nginx/0.7.63 Date: Tue, 26 Oct 2010 18:23:49 GMT Content-Type: text/html; charset=ISO-8859-1 Expires: Thu, 28 Oct 2010 18:23:49 GMT Cache-Control: max-age=172800, proxy-revalidate Transfer-Encoding: chunked Proxy-Connection: Keep-Alive Connection: Keep-Alive Content-Encoding: gzip Set-Cookie: USER=1; domain=myproject.sourceforge.net; path=/ ``` Firefox (doesn't work) Request ``` GET http://myproject.sourceforge.net/cgi-bin/myscript.cgi HTTP/1.1 Host: myproject.sourceforge.net User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.11) Gecko/20101012 Firefox/3.6.11 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 115 Proxy-Connection: keep-alive Cookie: __utma=191645736.1501259260.1287701281.1288028150.1288100562.10; __utmz=191645736.1288101011.10.10.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=sourceforge%20project%20web%20space%20basic%20auth; _jsuid=4215309712123065236 Authorization: Basic [password omitted] ``` Response ``` HTTP/1.1 200 OK Server: nginx/0.7.63 Date: Tue, 26 Oct 2010 18:17:58 GMT Content-Type: text/html; charset=ISO-8859-1 Expires: Thu, 28 Oct 2010 18:17:58 GMT Cache-Control: max-age=172800, proxy-revalidate Transfer-Encoding: chunked Proxy-Connection: Keep-Alive Connection: Keep-Alive Content-Encoding: gzip Age: 0 ```