[Catalyst] Catalyst, REST and Firefox

Adam Jacob adam at hjksolutions.com
Fri Jan 18 20:46:38 GMT 2008


Jonas,

Myself, Jshirley, or Claco would gladly take patches to C::A::REST to
add this functionality.  Send us the patch, and we'll get it tested
and out the door.

Adam

On 1/17/08, Jonas Alves <jonas.alves at gmail.com> wrote:
> On Jan 17, 2008 6:03 PM, Christopher H. Laco <claco at chrislaco.com> 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.
> >
>
> Well, I don't mind to help in that too. I think that the flavour stuff
> is very useful. Especially if you need to use the REST interface from
> some lib/framework/api where isn't easy to set the Accept header. And
> I think that is much more clean than the query-string type parameter.
>
> --
> Jonas
>
> _______________________________________________
> List: Catalyst at 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/
>


-- 
HJK Solutions - We Launch Startups - http://www.hjksolutions.com
Adam Jacob, Senior Partner
T: (206) 508-4759 E: adam at hjksolutions.com



More information about the Catalyst mailing list