Plack-Middleware-XSLT
view release on metacpan or search on metacpan
lib/Plack/Middleware/XSLT.pm view on Meta::CPAN
my $res = $self->app->($env);
Plack::Util::response_cb($res, sub {
my $res = shift;
my $xsl_file = $env->{'xslt.style'};
return if !defined($xsl_file) || $xsl_file eq '';
if (!$xslt) {
if ($self->cache) {
require XML::LibXSLT::Cache;
$xslt = XML::LibXSLT::Cache->new;
}
else {
$xslt = XML::LibXSLT->new;
}
}
my $path = $self->path;
$xsl_file = File::Spec->catfile($path, $xsl_file)
if defined($path) && !File::Spec->file_name_is_absolute($xsl_file);
my $stylesheet = $xslt->parse_stylesheet_file($xsl_file);
my $media_type = $stylesheet->media_type();
my $encoding = $stylesheet->output_encoding();
my $headers = Plack::Util::headers($res->[1]);
$headers->remove('Content-Encoding');
$headers->remove('Transfer-Encoding');
$headers->set('Content-Type', "$media_type; charset=$encoding");
if ($res->[2]) {
my ($output, $error) = $self->_xform($stylesheet, $res->[2]);
if (defined($error)) {
# Try to convert error to HTTP response.
my ($status, $message);
for my $line (split(/\n/, $error)) {
if ($line =~ /^(\d\d\d)(?:\s+(.*))?\z/) {
$status = $1;
$message = defined($2) ? $2 : '';
last;
}
}
die($error) if !defined($status);
$res->[0] = $status;
$headers->set('Content-Type', 'text/plain');
$headers->set('Content-Length', length($message));
$res->[2] = [ $message ];
}
else {
$headers->set('Content-Length', length($output));
$res->[2] = [ $output ];
}
}
else {
# PSGI streaming
my ($done, @chunks);
return sub {
my $chunk = shift;
return undef if $done;
if (defined($chunk)) {
push(@chunks, $chunk);
return '';
}
else {
$done = 1;
my ($output, $error) =
$self->_xform($stylesheet, \@chunks);
die($error) if defined($error);
return $output;
}
}
}
});
}
sub _xform {
my ($self, $stylesheet, $body) = @_;
if (!$parser) {
my $options = $self->parser_options;
$parser = $options
? XML::LibXML->new($options)
: XML::LibXML->new;
}
my ($doc, $output, $error);
if (ref($body) eq 'ARRAY') {
$doc = $parser->parse_string(join('', @$body));
}
else {
$doc = $parser->parse_fh($body);
}
my $result = try {
$stylesheet->transform($doc) or die("XSLT transform failed: $!");
}
catch {
$error = defined($_) ? $_ : 'Unknown error';
undef;
};
$output = $stylesheet->output_as_bytes($result)
if $result;
return ($output, $error);
}
sub _cache_hits {
my $self = shift;
( run in 0.573 second using v1.01-cache-2.11-cpan-39bf76dae61 )