X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=blobdiff_plain;f=lib%2FCatalyst%2FRequest%2FPartData.pm;h=d6358f334e86aa5047afb534e13e1f661d94d17c;hp=7089373044c6d9b0af92d8e91b039b533d2ea396;hb=b0ff1be8caade25b5485bf174f0224b2066a3b8f;hpb=80ba671f681862620befead95d299c8dfc91cbaf diff --git a/lib/Catalyst/Request/PartData.pm b/lib/Catalyst/Request/PartData.pm index 7089373..d6358f3 100644 --- a/lib/Catalyst/Request/PartData.pm +++ b/lib/Catalyst/Request/PartData.pm @@ -2,6 +2,7 @@ package Catalyst::Request::PartData; use Moose; use HTTP::Headers; +use Encode; has [qw/raw_data name size/] => (is=>'ro', required=>1); @@ -11,7 +12,59 @@ has headers => ( handles=>[qw/content_type content_encoding content_type_charset/]); sub build_from_part_data { - my ($class, $part_data) = @_; + my ($class, $c, $part_data) = @_; + + # If the headers are complex, we need to work harder to figure out what to do + if(my $hdrs = $class->part_data_has_complex_headers($part_data)) { + + # Ok so its one of two possibilities. If I can inspect the headers and + # Figure out what to do, the I will return data. Otherwise I will return + # a PartData object and expect you do deal with it. + # For now if I can find a charset in the content type I will just decode and + # assume I got it right (patches and bug reports welcomed). + + # Any of these headers means I can't decode + + if( + $hdrs->content_encoding + ) { + return $class->new( + raw_data => $part_data->{data}, + name => $part_data->{name}, + size => $part_data->{size}, + headers => HTTP::Headers->new(%{ $part_data->{headers} })); + } + + my ($ct, $charset) = $hdrs->content_type_charset; + + if($ct) { + # Good news, we probably have data we can return. If there is a charset + # then use that to decode otherwise use the default decoding. + if($charset) { + return Encode::decode($charset, $part_data->{data}) + } else { + if($c and $c->encoding and !$c->config->{skip_body_param_unicode_decoding}) { + return $c->_handle_param_unicode_decoding($part_data->{data}); + } else { + return $part_data->{data} + } + } + } else { + # I have no idea what to do with this now.. + return $class->new( + raw_data => $part_data->{data}, + name => $part_data->{name}, + size => $part_data->{size}, + headers => HTTP::Headers->new(%{ $part_data->{headers} })); + } + } else { + if($c and $c->encoding and !$c->config->{skip_body_param_unicode_decoding}) { + return $c->_handle_param_unicode_decoding($part_data->{data}); + } else { + return $part_data->{data} + } + } + return $part_data->{data} unless $class->part_data_has_complex_headers($part_data); return $class->new( raw_data => $part_data->{data}, @@ -22,7 +75,16 @@ sub build_from_part_data { sub part_data_has_complex_headers { my ($class, $part_data) = @_; - return scalar keys %{$part_data->{headers}} > 1 ? 1:0; + my %h = %{$part_data->{headers}}; + my $hdrs = HTTP::Headers->new(%h); + + # Remove non threatening headers. + $hdrs->remove_header('Content-Length', 'Expires', 'Last-Modified', 'Content-Language'); + + # If we still have more than one (Content-Disposition) header we need to understand + # that and deal with it. + + return $hdrs->header_field_names > 1 ? $hdrs :0; } __PACKAGE__->meta->make_immutable;