Skip to content

Commit

Permalink
import content_type_charset from HTTP::Headers. #5
Browse files Browse the repository at this point in the history
  • Loading branch information
miyagawa committed Jun 19, 2015
1 parent 86fa5d4 commit bd48c88
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
73 changes: 73 additions & 0 deletions lib/HTTP/Headers/Fast.pm
Expand Up @@ -405,6 +405,79 @@ sub content_type {
wantarray ? @ct : $ct[0];
}

sub content_type_charset {
my $self = shift;
my $h = $self->{'content-type'};
$h = $h->[0] if ref($h);
$h = "" unless defined $h;
my @v = _split_header_words($h);
if (@v) {
my($ct, undef, %ct_param) = @{$v[0]};
my $charset = $ct_param{charset};
if ($ct) {
$ct = lc($ct);
$ct =~ s/\s+//;
}
if ($charset) {
$charset = uc($charset);
$charset =~ s/^\s+//; $charset =~ s/\s+\z//;
undef($charset) if $charset eq "";
}
return $ct, $charset if wantarray;
return $charset;
}
return undef, undef if wantarray;
return undef;
}

sub _split_header_words
{
my(@val) = @_;
my @res;
for (@val) {
my @cur;
while (length) {
if (s/^\s*(=*[^\s=;,]+)//) { # 'token' or parameter 'attribute'
push(@cur, $1);
# a quoted value
if (s/^\s*=\s*\"([^\"\\]*(?:\\.[^\"\\]*)*)\"//) {
my $val = $1;
$val =~ s/\\(.)/$1/g;
push(@cur, $val);
# some unquoted value
}
elsif (s/^\s*=\s*([^;,\s]*)//) {
my $val = $1;
$val =~ s/\s+$//;
push(@cur, $val);
# no value, a lone token
}
else {
push(@cur, undef);
}
}
elsif (s/^\s*,//) {
push(@res, [@cur]) if @cur;
@cur = ();
}
elsif (s/^\s*;// || s/^\s+//) {
# continue
}
else {
die "This should not happen: '$_'";
}
}
push(@res, \@cur) if @cur;
}

for my $arr (@res) {
for (my $i = @$arr - 2; $i >= 0; $i -= 2) {
$arr->[$i] = lc($arr->[$i]);
}
}
return @res;
}

sub content_is_html {
my $self = shift;
return $self->content_type eq 'text/html' || $self->content_is_xhtml;
Expand Down
12 changes: 12 additions & 0 deletions t/charset.t
@@ -0,0 +1,12 @@
use strict;

use Test::More;
plan tests => 2;

use HTTP::Headers::Fast;

my $h = HTTP::Headers::Fast->new;
is($h->content_type_charset, undef);

$h->content_type('text/plain; charset="iso-8859-1"');
is($h->content_type_charset, "ISO-8859-1");

0 comments on commit bd48c88

Please sign in to comment.