<html>
<body>
<font size=3>At 12:03 PM 1/17/2008, Christopher H. Laco wrote:<br>
<blockquote type=cite class=cite cite="">Jonas Alves wrote:<br>
<blockquote type=cite class=cite cite="">On Jan 17, 2008 2:32 PM,
Christopher H. Laco <claco@chrislaco.com> wrote:<br>
<blockquote type=cite class=cite cite="">I've touched on this before, and
posted about it on UP:<br>
<a href="http://use.perl.org/~jk2addict/journal/35411" eudora="autourl">
http://use.perl.org/~jk2addict/journal/35411</a><br><br>
In a nutshell, Firefox 2.x Accept header totaly screws with the REST<br>
controller when you use it as a base for View negotiations. If you
have<br>
a default type of text/html pointed to a View::TT, REST will see<br>
text/xml from Firefox and try and send that instead, based on this
header:<br><br>
text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5<br>
<br>
What does everyone think about a config option/toggle to tell REST
to<br>
ignore the Accept header, allowing it to fall back to the default<br>
content-type in config when no Cntent-Type header or content-type
params<br>
are specified?<br><br>
-=Chris<br>
</blockquote>I have a subclass of Action::Serialize that does this:<br>
my $default =
$controller->config->{serialize}{default};<br>
my $pcontent_type = $c->req->preferred_content_type;<br>
my $content_types = $c->req->accepted_content_types_qvalue;<br>
my $ordered_content_types = $c->req->accepted_content_types;<br>
my $max_qvalue = $content_types->{$pcontent_type};<br>
my %max_qvalue_content_types = map {<br>
$content_types->{$_} eq
$max_qvalue ? ($_ => $default) : ()<br>
} keys %$content_types;<br>
my $content_type = $max_qvalue_content_types{$default}<br>
|| $pcontent_type<br>
|| $c->req->content_type;<br>
And in a subclass of Request::REST mixed with Plugin::Flavour:<br>
sub preferred_content_type {<br>
my $self = shift;<br>
if ($self->flavour) {<br>
my $type =
$self->{ext_map}{$self->flavour}<br>
|| $self->_ext_to_type($self->flavour);<br>
return $type;<br>
}<br>
$self->accepted_content_types->[0];<br>
}<br>
sub accepted_content_types_qvalue {<br>
my $self = shift;<br>
return $self->{content_types_qvalue} if
$self->{content_types_qvalue};<br>
my %types;<br>
if ($self->method eq "GET" &&
$self->param('content-type')) {<br>
$types{
$self->param('content-type') } = 2;<br>
}<br>
# This is taken from chansen's
Apache2::UploadProgress.<br>
if ( $self->header('Accept') ) {<br>
$self->accept_only(1)
unless keys %types;<br>
my $accept_header =
$self->header('Accept');<br>
my
$counter = 0;<br>
foreach my $pair (
split_header_words($accept_header) ) {<br>
my (
$type, $qvalue ) = @{$pair}[ 0, 3 ];<br>
next
if $types{$type};<br>
$qvalue = 1 unless defined $qvalue;<br>
$types{$type} = sprintf '%.3f', $qvalue;<br>
}<br>
}<br>
return $self->{content_types_qvalue} =
\%types;<br>
}<br><br>
That way all works fine. If you add an extension to the uri (like<br>
.json or .xml), it serves that content-type. Else it tries to find
the<br>
greater qvalue on the Accept Header and tries to serve that. If it
has<br>
more than one content-type with the same max qvalue it tries to find<br>
the default content-type in that list and serve it. If it isn't in
the<br>
max qvalue list than it serves the first content-type on that list.<br>
I think that is a sane approach.<br>
</blockquote><br>
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. :-)<br><br>
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.<br><br>
-=Chris</font></blockquote><br>
Just wanted to note that using extensions on URIs to select content_type
is a technique mentioned in the "RESTful Web Services"
book. I think it was touted as a "way to be sure the right
type was returned". I hadn't gotten to seeing if it'd work
with REST stuff here. Color me interested ....</body>
</html>