Subject: | FCGI_KEEP_CONN not honored when false |
PoCo::FastCGI doesn't work with nginx because the webserver makes
requests with FCGI_KEEP_CONN set to false, which means the fcgi process
should disconnect after the request, but the component doesn't disconnect.
As it turns out, Apache does this too BUT then disconnects on its own
end, so it runs right over the issue.
The fix is to cause the wheel connected to the client to shutdown after
the response has been sent, via a FlushedEvent on the wheel.
The attached patch fixes the above issue, allowing PoCo::FastCGI to be
used with nginx (as well as a minor test fix).
Subject: | fastcgi_fix.patch |
diff -uwra POE-Component-FastCGI-0.1/lib/POE/Component/FastCGI/Response.pm POE-Component-FastCGI-0.2/lib/POE/Component/FastCGI/Response.pm
--- POE-Component-FastCGI-0.1/lib/POE/Component/FastCGI/Response.pm 2005-03-13 11:41:04.000000000 -0800
+++ POE-Component-FastCGI-0.2/lib/POE/Component/FastCGI/Response.pm 2009-10-15 14:17:31.000000000 -0700
@@ -77,6 +77,13 @@
close => 1,
content => join("\x0D\x0A", @headers, "") . $self->content
});
+
+ ### FCGI_KEEP_CONN: disconnect after request if NOT set:
+ my $filter = $self->{client}->get_input_filter();
+ if ($filter->{conn}->[$filter->{requestid}]->{keepconn} == 0) {
+ $self->{client}->event( FlushedEvent => "shutdown" );
+ }
+
delete $self->{client};
return 1;
}
diff -uwra POE-Component-FastCGI-0.1/lib/POE/Component/FastCGI.pm POE-Component-FastCGI-0.2/lib/POE/Component/FastCGI.pm
--- POE-Component-FastCGI-0.1/lib/POE/Component/FastCGI.pm 2005-03-13 17:47:10.000000000 -0800
+++ POE-Component-FastCGI-0.2/lib/POE/Component/FastCGI.pm 2009-10-15 01:38:35.000000000 -0700
@@ -102,6 +102,7 @@
accept => \&_accept,
input => \&_input,
error => \&_error,
+ shutdown => \&_shutdown,
},
heap => \%args,
);
@@ -186,6 +187,13 @@
undef;
}
+sub _shutdown {
+ my($heap, $wheel_id) = @_[HEAP, ARG0];
+ delete $heap->{wheels}->{$wheel_id};
+
+ undef;
+}
+
1;
=back
diff -uwra POE-Component-FastCGI-0.1/lib/POE/Filter/FastCGI.pm POE-Component-FastCGI-0.2/lib/POE/Filter/FastCGI.pm
--- POE-Component-FastCGI-0.1/lib/POE/Filter/FastCGI.pm 2005-03-13 11:41:04.000000000 -0800
+++ POE-Component-FastCGI-0.2/lib/POE/Filter/FastCGI.pm 2009-10-15 14:15:50.000000000 -0700
@@ -39,6 +39,9 @@
use constant OVERLOADED => 2;
use constant UNKNOWN_ROLE => 3;
+ # Request flag constants
+ use constant FCGI_KEEP_CONN => 1;
+
# Constant maps
@TYPE = qw(
NULL
@@ -142,6 +145,7 @@
role => $ROLE[$role],
cgi => { },
};
+ $self->{conn}->[$self->{requestid}]{keepconn} = $flags & FCGI_KEEP_CONN ? 1 : 0;
return $self->_cleanup;
}
diff -uwra POE-Component-FastCGI-0.1/t/fastcgi.t POE-Component-FastCGI-0.2/t/fastcgi.t
--- POE-Component-FastCGI-0.1/t/fastcgi.t 2005-03-13 18:08:54.000000000 -0800
+++ POE-Component-FastCGI-0.2/t/fastcgi.t 2009-10-15 14:22:02.000000000 -0700
@@ -6,6 +6,9 @@
use POE::Component::FastCGI;
ok(1);
+# silence the warning
+POE::Kernel->run();
+
ok(POE::Component::FastCGI->new(
Address => $address,
Unix => 1,
@@ -43,7 +46,3 @@
END:
unlink "/tmp/pocofcgi.test";
-# Hide POE's warning
-$SIG{__WARN__} = sub {};
-sub nothing { 1 }
-*POE::Kernel::_warn = *nothing;