Avoiding weaken here is no more dangerous than the existing
circular refs (e.g. psgix.io) we create and manage throughout
the lifetime of the connection. So, trust ourselves to maintain
the data structure properly and avoid triggering extra memory
usage.
While we're at it, avoid having anonymous subroutines capture
more variables than necessary to simplify reference auditing.
use Plack::HTTPParser qw(parse_http_request); # XS or pure Perl
use HTTP::Status qw(status_message);
use HTTP::Date qw(time2str);
use Plack::HTTPParser qw(parse_http_request); # XS or pure Perl
use HTTP::Status qw(status_message);
use HTTP::Date qw(time2str);
-use Scalar::Util qw(weaken);
use IO::Handle;
use constant {
CHUNK_START => -1, # [a-f0-9]+\r\n
use IO::Handle;
use constant {
CHUNK_START => -1, # [a-f0-9]+\r\n
-sub response_done ($$) {
+sub response_done_cb ($$) {
- my $env = $self->{env};
- $self->{env} = undef;
- $self->write("0\r\n\r\n") if $alive == 2;
- $self->write(sub { $alive ? next_request($self) : $self->close });
+ sub {
+ my $env = $self->{env};
+ $self->{env} = undef;
+ $self->write("0\r\n\r\n") if $alive == 2;
+ $self->write(sub{$alive ? next_request($self) : $self->close});
+ }
-sub getline_response {
- my ($self, $body, $write, $close) = @_;
- $self->{forward} = $body;
- weaken($self);
+sub getline_response ($$$) {
+ my ($self, $write, $close) = @_;
my $pull = $self->{pull} = sub { getline_cb($self, $write, $close) };
$pull->();
}
my $pull = $self->{pull} = sub { getline_cb($self, $write, $close) };
$pull->();
}
sub response_write {
my ($self, $env, $res) = @_;
my $alive = response_header_write($self, $env, $res);
sub response_write {
my ($self, $env, $res) = @_;
my $alive = response_header_write($self, $env, $res);
+ my $close = response_done_cb($self, $alive);
my $write = $alive == 2 ? chunked_wcb($self) : identity_wcb($self);
my $write = $alive == 2 ? chunked_wcb($self) : identity_wcb($self);
- my $close = sub { response_done($self, $alive) };
if (defined(my $body = $res->[2])) {
if (ref $body eq 'ARRAY') {
$write->($_) foreach @$body;
$close->();
} else {
if (defined(my $body = $res->[2])) {
if (ref $body eq 'ARRAY') {
$write->($_) foreach @$body;
$close->();
} else {
- getline_response($self, $body, $write, $close);
+ $self->{forward} = $body;
+ getline_response($self, $write, $close);
}
} else {
# this is returned to the calling application:
}
} else {
# this is returned to the calling application: