[Catalyst] Catalyst, REST and Firefox

Christopher H. Laco claco at chrislaco.com
Thu Jan 17 18:03:27 GMT 2008


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 heade=
r:
>>
>> text/xml,application/xml,application/xhtml+xml,text/html;q=3D0.9,text/pl=
ain;q=3D0.8,image/png,*/*;q=3D0.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?
>>
>> -=3DChris
>>
> =

> I have a subclass of Action::Serialize that does this:
> =

> my $default       =3D $controller->config->{serialize}{default};
> my $pcontent_type =3D $c->req->preferred_content_type;
> my $content_types =3D $c->req->accepted_content_types_qvalue;
> my $ordered_content_types =3D $c->req->accepted_content_types;
> my $max_qvalue =3D $content_types->{$pcontent_type};
> my %max_qvalue_content_types =3D map {
>         $content_types->{$_} eq $max_qvalue ? ($_ =3D> $default) : ()
> } keys %$content_types;
> my $content_type =3D $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 =3D shift;
>     if ($self->flavour) {
>         my $type =3D $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 =3D 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') } =3D 2;
>     }
> =

>     # This is taken from chansen's Apache2::UploadProgress.
>     if ( $self->header('Accept') ) {
>         $self->accept_only(1) unless keys %types;
> =

>         my $accept_header =3D $self->header('Accept');
>         my $counter       =3D 0;
> =

>         foreach my $pair ( split_header_words($accept_header) ) {
>             my ( $type, $qvalue ) =3D @{$pair}[ 0, 3 ];
>             next if $types{$type};
>             $qvalue =3D 1 unless defined $qvalue;
>             $types{$type} =3D sprintf '%.3f', $qvalue;
>         }
>     }
>     return $self->{content_types_qvalue} =3D \%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=3D 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.

-=3DChris

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 187 bytes
Desc: OpenPGP digital signature
Url : http://lists.scsys.co.uk/pipermail/catalyst/attachments/20080117/d010=
3666/signature.pgp


More information about the Catalyst mailing list