[Catalyst] Catalyst, REST and Firefox
Thomas L. Shinnick
tshinnic at io.com
Thu Jan 17 21:10:57 GMT 2008
At 12:03 PM 1/17/2008, Christopher H. Laco wrote:
>Jonas Alves wrote:
>>On Jan 17, 2008 2:32 PM, Christopher H. Laco <claco at chrislaco.com> wrote:
>>>I've touched on this before, and posted about it on UP:
>>>http://use.perl.org/~jk2addict/journal/35411
>>>
>>>In 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?
>>>
>>>-=Chris
>>I 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
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 ....
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20080117/29c40286/attachment.htm
More information about the Catalyst
mailing list