Skip to content

Commit

Permalink
Moved response_cb() to Plack::Util as a function so the inlined
Browse files Browse the repository at this point in the history
middleware components, either with enable sub {} or with the plain
perl code ref can make use of it.
  • Loading branch information
miyagawa committed Jul 14, 2010
1 parent f607bba commit 0944475
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 53 deletions.
54 changes: 1 addition & 53 deletions lib/Plack/Component.pm
Expand Up @@ -42,59 +42,7 @@ sub to_app {

sub response_cb {
my($self, $res, $cb) = @_;

my $body_filter = sub {
my($cb, $res) = @_;
my $filter_cb = $cb->($res);
# If response_cb returns a callback, treat it as a $body filter
if (defined $filter_cb && ref $filter_cb eq 'CODE') {
Plack::Util::header_remove($res->[1], 'Content-Length');
if (defined $res->[2]) {
if (ref $res->[2] eq 'ARRAY') {
for my $line (@{$res->[2]}) {
$line = $filter_cb->($line);
}
# Send EOF.
my $eof = $filter_cb->( undef );
push @{ $res->[2] }, $eof if defined $eof;
} else {
my $body = $res->[2];
my $getline = sub { $body->getline };
$res->[2] = Plack::Util::inline_object
getline => sub { $filter_cb->($getline->()) },
close => sub { $body->close };
}
} else {
return $filter_cb;
}
}
};

if (ref $res eq 'ARRAY') {
$body_filter->($cb, $res);
return $res;
} elsif (ref $res eq 'CODE') {
return sub {
my $respond = shift;
my $cb = $cb; # To avoid the nested closure leak for 5.8.x
$res->(sub {
my $res = shift;
my $filter_cb = $body_filter->($cb, $res);
if ($filter_cb) {
my $writer = $respond->($res);
if ($writer) {
return Plack::Util::inline_object
write => sub { $writer->write($filter_cb->(@_)) },
close => sub { $writer->write($filter_cb->(undef)); $writer->close };
}
} else {
return $respond->($res);
}
});
};
}

return $res;
Plack::Util::response_cb($res, $cb);
}

1;
Expand Down
57 changes: 57 additions & 0 deletions lib/Plack/Util.pm
Expand Up @@ -236,6 +236,63 @@ sub inline_object {
bless {%args}, 'Plack::Util::Prototype';
}

sub response_cb {
my($res, $cb) = @_;

my $body_filter = sub {
my($cb, $res) = @_;
my $filter_cb = $cb->($res);
# If response_cb returns a callback, treat it as a $body filter
if (defined $filter_cb && ref $filter_cb eq 'CODE') {
Plack::Util::header_remove($res->[1], 'Content-Length');
if (defined $res->[2]) {
if (ref $res->[2] eq 'ARRAY') {
for my $line (@{$res->[2]}) {
$line = $filter_cb->($line);
}
# Send EOF.
my $eof = $filter_cb->( undef );
push @{ $res->[2] }, $eof if defined $eof;
} else {
my $body = $res->[2];
my $getline = sub { $body->getline };
$res->[2] = Plack::Util::inline_object
getline => sub { $filter_cb->($getline->()) },
close => sub { $body->close };
}
} else {
return $filter_cb;
}
}
};

if (ref $res eq 'ARRAY') {
$body_filter->($cb, $res);
return $res;
} elsif (ref $res eq 'CODE') {
return sub {
my $respond = shift;
my $cb = $cb; # To avoid the nested closure leak for 5.8.x
$res->(sub {
my $res = shift;
my $filter_cb = $body_filter->($cb, $res);
if ($filter_cb) {
my $writer = $respond->($res);
if ($writer) {
return Plack::Util::inline_object
write => sub { $writer->write($filter_cb->(@_)) },
close => sub { $writer->write($filter_cb->(undef)); $writer->close };
}
} else {
return $respond->($res);
}
});
};
}

return $res;
}

package Plack::Util::Prototype;

our $AUTOLOAD;
Expand Down

0 comments on commit 0944475

Please sign in to comment.