Jonas Alves wrote:
On Jan 17, 2008 2:32 PM, Christopher H. Laco <[EMAIL PROTECTED]> wrote:I've touched on this before, and posted about it on UP: http://use.perl.org/~jk2addict/journal/35411In a nutshell, Firefox 2.x Accept header totaly screws with the REST controller when you use it as a base for View negotiations. If you have a default type of text/html pointed to a View::TT, REST will see text/xml from Firefox and try and send that instead, based on this header: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 What does everyone think about a config option/toggle to tell REST to ignore the Accept header, allowing it to fall back to the default content-type in config when no Cntent-Type header or content-type params are specified? -=ChrisI have a subclass of Action::Serialize that does this: my $default = $controller->config->{serialize}{default}; my $pcontent_type = $c->req->preferred_content_type; my $content_types = $c->req->accepted_content_types_qvalue; my $ordered_content_types = $c->req->accepted_content_types; my $max_qvalue = $content_types->{$pcontent_type}; my %max_qvalue_content_types = map { $content_types->{$_} eq $max_qvalue ? ($_ => $default) : () } keys %$content_types; my $content_type = $max_qvalue_content_types{$default} || $pcontent_type || $c->req->content_type; And in a subclass of Request::REST mixed with Plugin::Flavour: sub preferred_content_type { my $self = shift; if ($self->flavour) { my $type = $self->{ext_map}{$self->flavour} || $self->_ext_to_type($self->flavour); return $type; } $self->accepted_content_types->[0]; } sub accepted_content_types_qvalue { my $self = shift; return $self->{content_types_qvalue} if $self->{content_types_qvalue}; my %types; if ($self->method eq "GET" && $self->param('content-type')) { $types{ $self->param('content-type') } = 2; } # This is taken from chansen's Apache2::UploadProgress. if ( $self->header('Accept') ) { $self->accept_only(1) unless keys %types; my $accept_header = $self->header('Accept'); my $counter = 0; foreach my $pair ( split_header_words($accept_header) ) { my ( $type, $qvalue ) = @{$pair}[ 0, 3 ]; next if $types{$type}; $qvalue = 1 unless defined $qvalue; $types{$type} = sprintf '%.3f', $qvalue; } } return $self->{content_types_qvalue} = \%types; } That way all works fine. If you add an extension to the uri (like .json or .xml), it serves that content-type. Else it tries to find the greater qvalue on the Accept Header and tries to serve that. If it has more than one content-type with the same max qvalue it tries to find the default content-type in that list and serve it. If it isn't in the max qvalue list than it serves the first content-type on that list. I think that is a sane approach.
Well volunteered! I can't speak for the flavour stuff, but I'd think the q value logic would be well served in the REST package. :-)
I'd personally like the flavour stuff in there as well. In my case, I'm half way there. I have a type= that takes a friendly name (atom, rss, json) ... along wieh adding some of those content types to MIME::Types since it's missing a few of them for type->extension mapping.
-=Chris
signature.asc
Description: OpenPGP digital signature
_______________________________________________ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/