about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <BOFH@YHBT.net>2023-09-10 19:52:03 +0000
committerEric Wong <BOFH@YHBT.net>2023-09-10 19:55:18 +0000
commit05028146b5e69c566663fdab9f8b92c6145a791a (patch)
tree7e5a448152029e9e19cf368194b501b934f765e5
parent7160f1b519aece0fe645d22a7d8fb954a43ad6fb (diff)
downloadunicorn-05028146b5e69c566663fdab9f8b92c6145a791a.tar.gz
This means fewer redundant tests and more chances to notice
Ruby incompatibilities.
-rw-r--r--t/integration.t22
-rw-r--r--test/unit/test_server.rb53
2 files changed, 20 insertions, 55 deletions
diff --git a/t/integration.t b/t/integration.t
index ba17dd9..7310ff2 100644
--- a/t/integration.t
+++ b/t/integration.t
@@ -7,7 +7,7 @@
 
 use v5.14; BEGIN { require './t/lib.perl' };
 use autodie;
-use Socket qw(SOL_SOCKET SO_KEEPALIVE);
+use Socket qw(SOL_SOCKET SO_KEEPALIVE SHUT_WR);
 our $srv = tcp_server();
 our $host_port = tcp_host_port($srv);
 
@@ -209,6 +209,7 @@ SKIP: {
                 defined($opt{overwrite}) and
                         print { $c } ('x' x $opt{overwrite});
                 $c->flush or die $!;
+                shutdown($c, SHUT_WR);
                 ($status, $hdr) = slurp_hdr($c);
                 is(readline($c), $blob_hash, "$sub $path");
         };
@@ -225,6 +226,8 @@ SKIP: {
         # ensure small overwrites don't get checksummed
         $ck_hash->('identity', '/rack_input', -s => $blob_size,
                         overwrite => 1); # one extra byte
+        unlike(slurp($err_log), qr/ClientShutdown/,
+                'no overreads after client SHUT_WR');
 
         # excessive overwrite truncated
         $c = tcp_start($srv);
@@ -238,8 +241,23 @@ SKIP: {
                 $! = 0;
                 while (print $c $buf and time < $end) { ++$n }
                 ok($!, 'overwrite truncated') or diag "n=$n err=$! ".time;
+                undef $c;
+        }
+
+        # client shutdown early
+        $c = tcp_start($srv);
+        $c->autoflush(0);
+        print $c "PUT /rack_input HTTP/1.0\r\nContent-Length: 16384\r\n\r\n";
+        if (1) {
+                local $SIG{PIPE} = 'IGNORE';
+                print $c 'too short body';
+                shutdown($c, SHUT_WR);
+                vec(my $rvec = '', fileno($c), 1) = 1;
+                select($rvec, undef, undef, 10) or BAIL_OUT "timed out";
+                my $buf = <$c>;
+                is($buf, undef, 'server aborted after client SHUT_WR');
+                undef $c;
         }
-        undef $c;
 
         $curl // skip 'no curl found in PATH', 1;
 
diff --git a/test/unit/test_server.rb b/test/unit/test_server.rb
index 2af12ea..7ffa48f 100644
--- a/test/unit/test_server.rb
+++ b/test/unit/test_server.rb
@@ -132,59 +132,6 @@ class WebServerTest < Test::Unit::TestCase
     assert_equal 'hello!\n', results[0], "Handler didn't really run"
   end
 
-  def test_client_shutdown_writes
-    bs = 15609315 * rand
-    sock = tcp_socket('127.0.0.1', @port)
-    sock.syswrite("PUT /hello HTTP/1.1\r\n")
-    sock.syswrite("Host: example.com\r\n")
-    sock.syswrite("Transfer-Encoding: chunked\r\n")
-    sock.syswrite("Trailer: X-Foo\r\n")
-    sock.syswrite("\r\n")
-    sock.syswrite("%x\r\n" % [ bs ])
-    sock.syswrite("F" * bs)
-    sock.syswrite("\r\n0\r\nX-")
-    "Foo: bar\r\n\r\n".each_byte do |x|
-      sock.syswrite x.chr
-      sleep 0.05
-    end
-    # we wrote the entire request before shutting down, server should
-    # continue to process our request and never hit EOFError on our sock
-    sock.shutdown(Socket::SHUT_WR)
-    buf = sock.read
-    assert_match %r{\bhello!\\n\b}, buf.split(/\r\n\r\n/, 2).last
-    next_client = Net::HTTP.get(URI.parse("http://127.0.0.1:#@port/"))
-    assert_equal 'hello!\n', next_client
-    lines = File.readlines("test_stderr.#$$.log")
-    assert lines.grep(/^Unicorn::ClientShutdown: /).empty?
-    assert_nil sock.close
-  end
-
-  def test_client_shutdown_write_truncates
-    bs = 15609315 * rand
-    sock = tcp_socket('127.0.0.1', @port)
-    sock.syswrite("PUT /hello HTTP/1.1\r\n")
-    sock.syswrite("Host: example.com\r\n")
-    sock.syswrite("Transfer-Encoding: chunked\r\n")
-    sock.syswrite("Trailer: X-Foo\r\n")
-    sock.syswrite("\r\n")
-    sock.syswrite("%x\r\n" % [ bs ])
-    sock.syswrite("F" * (bs / 2.0))
-
-    # shutdown prematurely, this will force the server to abort
-    # processing on us even during app dispatch
-    sock.shutdown(Socket::SHUT_WR)
-    IO.select([sock], nil, nil, 60) or raise "Timed out"
-    buf = sock.read
-    assert_equal "", buf
-    next_client = Net::HTTP.get(URI.parse("http://127.0.0.1:#@port/"))
-    assert_equal 'hello!\n', next_client
-    lines = File.readlines("test_stderr.#$$.log")
-    lines = lines.grep(/^Unicorn::ClientShutdown: bytes_read=\d+/)
-    assert_equal 1, lines.size
-    assert_match %r{\AUnicorn::ClientShutdown: bytes_read=\d+ true$}, lines[0]
-    assert_nil sock.close
-  end
-
   def test_client_malformed_body
     bs = 15653984
     sock = tcp_socket('127.0.0.1', @port)