|
|
cff857 |
Fix pipelined response deadlock in tests
|
|
|
cff857 |
|
|
|
cff857 |
There's a race condition that can cause mod_perl's test suite to hang
|
|
|
cff857 |
in t/filter/in_str_declined.t. The problem is that the response handler
|
|
|
cff857 |
starts generating response body, and so triggers header output, before
|
|
|
cff857 |
it reads the request body. If LWP::Protocol::http, which is the client
|
|
|
cff857 |
for this test, receives a complete set of response headers, it will stop
|
|
|
cff857 |
sending the request body. (However, if the request body is no more than
|
|
|
cff857 |
8192 octets then it will send the whole body before it starts looking
|
|
|
cff857 |
for a response. The failure only shows up with an appreciably large
|
|
|
cff857 |
request body.)
|
|
|
cff857 |
|
|
|
cff857 |
RFC 2616 doesn't explicitly address this sort of pipelining, but the
|
|
|
cff857 |
start of section 6 does say "After receiving and interpreting a request
|
|
|
cff857 |
message, a server responds with an HTTP response message.", which can be
|
|
|
cff857 |
read as prohibiting sending any part of the response before the entire
|
|
|
cff857 |
request has been received.
|
|
|
cff857 |
|
|
|
cff857 |
The attached patch fixes this issue by making all the POST handlers in
|
|
|
cff857 |
the test suite read the body before doing anything that generates output
|
|
|
cff857 |
(specifically plan()).
|
|
|
cff857 |
|
|
|
cff857 |
-zefram
|
|
|
cff857 |
|
|
|
cff857 |
CPAN RT#82409
|
|
|
cff857 |
Debian bug #676754
|
|
|
cff857 |
|
|
|
cff857 |
--- a/t/filter/TestFilter/in_str_declined.pm 2011-02-08 02:00:11.000000000 +0000
|
|
|
cff857 |
+++ b/t/filter/TestFilter/in_str_declined.pm 2013-01-04 16:08:14.000000000 +0000
|
|
|
cff857 |
@@ -35,13 +35,17 @@
|
|
|
cff857 |
sub response {
|
|
|
cff857 |
my $r = shift;
|
|
|
cff857 |
|
|
|
cff857 |
+ my $data;
|
|
|
cff857 |
+ if ($r->method_number == Apache2::Const::M_POST) {
|
|
|
cff857 |
+ # consume the data so the input filter is invoked
|
|
|
cff857 |
+ $data = TestCommon::Utils::read_post($r);
|
|
|
cff857 |
+ }
|
|
|
cff857 |
+
|
|
|
cff857 |
plan $r, tests => 2;
|
|
|
cff857 |
|
|
|
cff857 |
$r->content_type('text/plain');
|
|
|
cff857 |
|
|
|
cff857 |
if ($r->method_number == Apache2::Const::M_POST) {
|
|
|
cff857 |
- # consume the data so the input filter is invoked
|
|
|
cff857 |
- my $data = TestCommon::Utils::read_post($r);
|
|
|
cff857 |
ok t_cmp(length $data, 20000, "the request body received ok");
|
|
|
cff857 |
}
|
|
|
cff857 |
|
|
|
cff857 |
--- a/t/filter/TestFilter/in_str_declined_read.pm 2011-02-08 02:00:11.000000000 +0000
|
|
|
cff857 |
+++ b/t/filter/TestFilter/in_str_declined_read.pm 2013-01-04 16:06:28.000000000 +0000
|
|
|
cff857 |
@@ -31,14 +31,19 @@
|
|
|
cff857 |
sub response {
|
|
|
cff857 |
my $r = shift;
|
|
|
cff857 |
|
|
|
cff857 |
+ my $err;
|
|
|
cff857 |
+ if ($r->method_number == Apache2::Const::M_POST) {
|
|
|
cff857 |
+ # this should fail, because of the failing filter
|
|
|
cff857 |
+ eval { TestCommon::Utils::read_post($r) };
|
|
|
cff857 |
+ $err = $@;
|
|
|
cff857 |
+ }
|
|
|
cff857 |
+
|
|
|
cff857 |
plan $r, tests => 1;
|
|
|
cff857 |
|
|
|
cff857 |
$r->content_type('text/plain');
|
|
|
cff857 |
|
|
|
cff857 |
if ($r->method_number == Apache2::Const::M_POST) {
|
|
|
cff857 |
- # this should fail, because of the failing filter
|
|
|
cff857 |
- eval { TestCommon::Utils::read_post($r) };
|
|
|
cff857 |
- ok $@;
|
|
|
cff857 |
+ ok $err;
|
|
|
cff857 |
}
|
|
|
cff857 |
|
|
|
cff857 |
Apache2::Const::OK;
|
|
|
cff857 |
--- a/t/filter/TestFilter/in_str_msg.pm 2011-02-08 02:00:11.000000000 +0000
|
|
|
cff857 |
+++ b/t/filter/TestFilter/in_str_msg.pm 2013-01-04 16:08:27.000000000 +0000
|
|
|
cff857 |
@@ -76,10 +76,10 @@
|
|
|
cff857 |
sub response {
|
|
|
cff857 |
my $r = shift;
|
|
|
cff857 |
|
|
|
cff857 |
- plan $r, tests => 1;
|
|
|
cff857 |
-
|
|
|
cff857 |
my $received = TestCommon::Utils::read_post($r);
|
|
|
cff857 |
|
|
|
cff857 |
+ plan $r, tests => 1;
|
|
|
cff857 |
+
|
|
|
cff857 |
ok t_cmp($received, $expected,
|
|
|
cff857 |
"request filter must have upcased the data");
|
|
|
cff857 |
|
|
|
cff857 |
--- a/t/response/TestModperl/post_utf8.pm 2011-02-08 02:00:12.000000000 +0000
|
|
|
cff857 |
+++ b/t/response/TestModperl/post_utf8.pm 2013-01-04 16:04:39.000000000 +0000
|
|
|
cff857 |
@@ -29,14 +29,14 @@
|
|
|
cff857 |
# $r->content_type("text/plain; charset=utf-8");
|
|
|
cff857 |
# $r->print("expected: $expected_utf8\n");
|
|
|
cff857 |
|
|
|
cff857 |
+ my $received = TestCommon::Utils::read_post($r) || "";
|
|
|
cff857 |
+
|
|
|
cff857 |
# utf encode/decode was added only in 5.8.0
|
|
|
cff857 |
# XXX: currently binmode is only available with perlio (used on the
|
|
|
cff857 |
# server side on the tied/perlio STDOUT)
|
|
|
cff857 |
plan $r, tests => 2,
|
|
|
cff857 |
need need_min_perl_version(5.008), need_perl('perlio');
|
|
|
cff857 |
|
|
|
cff857 |
- my $received = TestCommon::Utils::read_post($r) || "";
|
|
|
cff857 |
-
|
|
|
cff857 |
# workaround for perl-5.8.0, which doesn't decode correctly a
|
|
|
cff857 |
# tainted variable
|
|
|
cff857 |
require ModPerl::Util;
|