Subject: | HTTP::Negotiate bug: order of variants matters |
It appears that the ordering of the variants affects the outcome of the choose() command.
If I simply reverse the position of the variant in the array-reference passed into choose, I can
get very different results. To demonstrate this, I created a matrix of 3 variants, and submitted
them to choose. This should've resulted in the same outcome each time, but it was different for
several of them.
I've attached a test file to show the problem better.
Please note that you'll probably want to apply the patch I submitted yesterday for
HTTP::Negotiate, since it fixed half of the problems this test case exposes.
#!perl
use strict;
use warnings FATAL => 'all';
use Test::More tests => 54;
use HTTP::Negotiate qw(choose);
use HTTP::Headers;
use constant CANADIAN => [ 'Canadian English' => 1.0, 'text/html', undef, undef, 'en-CA', undef ];
use constant GENERIC => [ 'Generic English' => 1.0, 'text/html', undef, undef, 'en', undef ];
use constant DEFAULT => [ 'Default' => 1.0, 'text/html', undef, undef, undef, undef ];
# the ordering of the variants seems to affect the
# outcome of content-negotiation
tests([ CANADIAN, GENERIC, DEFAULT ], 1);
tests([ CANADIAN, DEFAULT, GENERIC ], 2);
tests([ GENERIC, CANADIAN, DEFAULT ], 3);
tests([ GENERIC, DEFAULT, CANADIAN ], 4);
tests([ DEFAULT, CANADIAN, DEFAULT ], 5);
tests([ DEFAULT, DEFAULT, CANADIAN ], 6);
sub tests {
my($v, $set) = @_;
test_language($v, 'en', GENERIC->[0], $set);
test_language($v, 'en-US', GENERIC->[0], $set);
test_language($v, 'en-CA', CANADIAN->[0], $set);
test_language($v, 'fr', DEFAULT->[0], $set);
test_language($v, 'fr, en', GENERIC->[0], $set);
test_language($v, 'en-CA, en', CANADIAN->[0], $set);
test_language($v, 'en, en-CA', GENERIC->[0], $set);
test_language($v, 'en-CA;q=0.9, en;q=1.0', GENERIC->[0], $set);
test_language($v, 'en;q=1.0, en-CA;q=0.9', GENERIC->[0], $set);
return;
}
sub test_language {
my($v, $accept_lang, $expect, $set) = @_;
my $preference = choose($v, HTTP::Headers->new('Accept-Language' => $accept_lang));
is($preference, $expect, "(Set $set) Accept-Language: $accept_lang");
return;
}