<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 &lt;claco@chrislaco.com&gt; 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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
$controller-&gt;config-&gt;{serialize}{default};<br>
my $pcontent_type = $c-&gt;req-&gt;preferred_content_type;<br>
my $content_types = $c-&gt;req-&gt;accepted_content_types_qvalue;<br>
my $ordered_content_types = $c-&gt;req-&gt;accepted_content_types;<br>
my $max_qvalue = $content_types-&gt;{$pcontent_type};<br>
my %max_qvalue_content_types = map {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $content_types-&gt;{$_} eq
$max_qvalue ? ($_ =&gt; $default) : ()<br>
} keys %$content_types;<br>
my $content_type = $max_qvalue_content_types{$default}<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
|| $pcontent_type<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
|| $c-&gt;req-&gt;content_type;<br>
And in a subclass of Request::REST mixed with Plugin::Flavour:<br>
sub preferred_content_type {<br>
&nbsp;&nbsp;&nbsp; my $self = shift;<br>
&nbsp;&nbsp;&nbsp; if ($self-&gt;flavour) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my $type =
$self-&gt;{ext_map}{$self-&gt;flavour}<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
|| $self-&gt;_ext_to_type($self-&gt;flavour);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return $type;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; $self-&gt;accepted_content_types-&gt;[0];<br>
}<br>
sub accepted_content_types_qvalue {<br>
&nbsp;&nbsp;&nbsp; my $self = shift;<br>
&nbsp;&nbsp;&nbsp; return $self-&gt;{content_types_qvalue} if
$self-&gt;{content_types_qvalue};<br>
&nbsp;&nbsp;&nbsp; my %types;<br>
&nbsp;&nbsp;&nbsp; if ($self-&gt;method eq &quot;GET&quot; &amp;&amp;
$self-&gt;param('content-type')) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $types{
$self-&gt;param('content-type') } = 2;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; # This is taken from chansen's
Apache2::UploadProgress.<br>
&nbsp;&nbsp;&nbsp; if ( $self-&gt;header('Accept') ) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $self-&gt;accept_only(1)
unless keys %types;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my $accept_header =
$self-&gt;header('Accept');<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my
$counter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach my $pair (
split_header_words($accept_header) ) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my (
$type, $qvalue ) = @{$pair}[ 0, 3 ];<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; next
if $types{$type};<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
$qvalue = 1 unless defined $qvalue;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
$types{$type} = sprintf '%.3f', $qvalue;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; return $self-&gt;{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-&gt;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 &quot;RESTful Web Services&quot;
book.&nbsp; I think it was touted as a &quot;way to be sure the right
type was returned&quot;.&nbsp; I hadn't gotten to seeing if it'd work
with REST stuff here.&nbsp; Color me interested ....</body>
</html>