Skip to content

Instantly share code, notes, and snippets.

@kentfredric
Created October 29, 2009 05:10
Show Gist options
  • Save kentfredric/221171 to your computer and use it in GitHub Desktop.
Save kentfredric/221171 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl
use strict;
use warnings;
use HTTP::Engine;
my $engine = HTTP::Engine->new(
interface => {
module => 'ServerSimple',
args => {
host => 'localhost',
port => '8080',
},
request_handler => \&handle_request,
},
);
use HTTP::Engine::Response;
sub fisher_yates_shuffle {
my $deck = shift; # $deck is a reference to an array
return unless @$deck; # must not be empty!
my $i = @$deck;
while ( --$i ) {
my $j = int rand( $i + 1 );
@$deck[ $i, $j ] = @$deck[ $j, $i ];
}
}
sub randcookie {
my (@chars) = map { chr($_) } map { ord('A') .. ord('z') } 1 .. 10;
fisher_yates_shuffle( \@chars );
return join '', @chars[ 0 .. 10 ];
}
sub handle_request {
my $req = shift;
my $resp = HTTP::Engine::Response->new();
use YAML::XS qw( Dump );
my $ctext = Dump({
cookies => $req->cookies ,
headers => $req->headers,
request_uri => $req->request_uri,
} );
$resp->status(200);
$resp->headers->header( 'Content-Type' => 'text/plain' );
$resp->body( $ctext );
if( $req->request_uri =~ qr{/normal$} ){
normal_cookies( $resp );
return $resp;
}
if( $req->request_uri =~ qr{/normal2$} ){
normal_cookies2( $resp );
return $resp;
}
if( $req->request_uri =~ qr{/weird$} ){
weird_cookies( $resp );
return $resp;
}
if( $req->request_uri =~ qr{/weird2$} ){
weird_cookies2( $resp );
return $resp;
}
if( $req->request_uri =~ qr{/weird3$} ){
weird_cookies3( $resp );
return $resp;
}
if( $req->request_uri =~ qr{/weird4$} ){
weird_cookies4( $resp );
return $resp;
}
$resp->headers->header( 'Content-Type' => "text/html" );
$resp->body(<<'EOF');
<ul>
<li><a href="/weird">Weird Cookies ( 2 cookies, 1 path, 1 string ) </a>
<li><a href="/weird2">Weird Cookies2 ( 2 cookies, 1 path, array ) </a>
<li><a href="/weird3">Weird Cookies3 ( 2 cookies, 2 paths, 1 string ) </a>
<li><a href="/weird4">Weird Cookies4 ( 2 cookies, 2 paths, array ) </a>
<li><a href="/normal">Normal Cookies ( 1 value, 1 path ) </a>
<li><a href="/normal2">Normal Cookies2 ( 1 path, valuearray )( WARNING: Kills Server )</a>
</ul>
EOF
return $resp;
}
# Firefox only returns the most recently set value of foo.
sub normal_cookies {
my $resp = shift;
$resp->cookies->{foo} = { value => randcookie() };
}
# Firefox only returns the most recently set value of foo.
sub normal_cookies2 {
my $resp = shift;
# this is illegal.
$resp->cookies->{foo} = [
{ value => 'A' . randcookie() },
{ value => 'B' . randcookie() },
];
}
#
#
# Note: We sent 2 cookies with identical keys,
# but firefox only sees the first, and returns only the first.
#
sub weird_cookies {
my $resp = shift;
$resp->headers->header('Set-Cookie' => 'foo=A' . randcookie(). '; path=/; foo=B' . randcookie() . '; path=/;' );
}
#
# This also sends 2 cookies, but puts a \n in the response, ie:
# >>
# Connection: close
# Content-Length: 586
# Content-Type: text/plain
# Set-Cookie: foo=AqZI_GmTOBlV; path=/;
# foo=BwMD^frWvQoW; path=/;
# Status: 200
# >>
# Firefox in this case only sees the last cookie.
#
sub weird_cookies2 {
my $resp = shift;
$resp->headers->header('Set-Cookie' => [
'foo=A' . randcookie(). '; path=/;',
'foo=B' . randcookie() . '; path=/;'
]);
}
sub weird_cookies3 {
my $resp = shift;
$resp->headers->header('Set-Cookie' => 'foo=A' . randcookie(). '; path=/; foo=B' . randcookie() . '; path=/wierd3;' );
}
sub weird_cookies4 {
my $resp = shift;
$resp->headers->header('Set-Cookie' => [
'foo=A' . randcookie(). '; path=/;',
'foo=B' . randcookie() . '; path=/weird4;'
]);
}
$engine->run();
I wrote a simple test server to demonstrate plainly how browsers react to various cookies, just to make sure we're not making things up, and it confers with our logic, that adding more cookie headers with the same value result in replacing the key.
http://gist.github.com/221171
as such, the test
ok($req->header("Cookie"), "x=bcd; foo=1; foo=1");
is something that should never happen, at least on firefox.
I can't imagine a sane case where you'd actually want to store the same cookie with the same key name twice, with either differing or the same value ... I think I shall report this as a bug.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment