Mailing List Archive

[Bug 66058] New: Apache Benchmark (ab) does not always read the end of a chunked transfer when using keep-alive
https://bz.apache.org/bugzilla/show_bug.cgi?id=66058

Bug ID: 66058
Summary: Apache Benchmark (ab) does not always read the end of
a chunked transfer when using keep-alive
Product: Apache httpd-2
Version: 2.5-HEAD
Hardware: PC
OS: Linux
Status: NEW
Severity: major
Priority: P2
Component: All
Assignee: bugs@httpd.apache.org
Reporter: niklas@seyfarth.de
Target Milestone: ---

Created attachment 38282
--> https://bz.apache.org/bugzilla/attachment.cgi?id=38282&action=edit
Example HTTP server (PHP 8.1 + ReactPHP) to reproduce the issue

When using ApacheBench with the keep-alive (-k) and the repeat (-n times) flag
and the server sends a chunked response then ApacheBench fails (most of the
time*).

I have reproduced it with other software (OpenSwoole), so it is not caused by
my script or the library I'm using to (re)produce this bug.

Expected behavior

I would expect ApacheBench to benchmark servers sending chunked responses in a
reused connection the same way as servers not sending chunked responses like it
happens when not using 'Connection: keep-alive'.


Reproduction Notes

I have attached a small ReactPHP script that can be run standalone on the CLI
after the required dependencies have been installed. This script will start a
web-server that responds with a response that uses 'Transfer-Encoding: chunked'
and supports 'Connection: keep-alive'.

One can easily check that the script is working by opening a connection with
telnet and sending repeatedly (don't forget the two newlines at the end):

$ telnet 127.0.0.1 8080
GET / HTTP/1.1
Host: 127.0.0.1:8080
Accept: */*
Connection: keep-alive

curl also produces reasonable output:
$ curl -v --raw http://127.0.0.1:8080 http://127.0.0.1:8080
http://127.0.0.1:8080
(log omitted)

Reproduction Steps

While any server supporting keep-alive and sending a chunked response is
running (please note that '-v 4' is not required for the error to happen;
greater values for -n increase the chance of it happening*):

$ ab -v 4 -n 3 -k http://127.0.0.1:8080/
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)...INFO: GET header ==
---
GET / HTTP/1.0
Connection: Keep-Alive
Host: 127.0.0.1:8080
User-Agent: ApacheBench/2.3
Accept: */*


---
LOG: header received:
HTTP/1.0 200 OK
Server: ReactPHP/1
Date: Tue, 10 May 2022 13:16:39 GMT
Connection: keep-alive


LOG: Response code = 200
LOG: header received:
chunk
apr_pollset_poll: The timeout specified has expired (70007)
Total of 1 requests completed


ab hangs for about 30 seconds after writing 'chunk' (third last line).

Variant: When sending an interrupt during the time ApacheBench hangs the
summary is printed:

(previous log omitted)
LOG: Response code = 200
LOG: header received:
chunk
^C

Server Software: ReactPHP/1
Server Hostname: 127.0.0.1
Server Port: 8080

Document Path: /
Document Length: 0 bytes

Concurrency Level: 1
Time taken for tests: 26.229 seconds
Complete requests: 1
Failed requests: 0
Keep-Alive requests: 1
Total transferred: 105 bytes
HTML transferred: 0 bytes
Requests per second: 0.04 [#/sec] (mean)
Time per request: 26229.224 [ms] (mean)
Time per request: 26229.224 [ms] (mean, across all concurrent requests)
Transfer rate: 0.00 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 0 0 0.0 0 0
Waiting: 0 0 0.0 0 0
Total: 0 0 0.0 0 0


I've compiled ApacheBench from source using the current trunk (rev 1900571) and
reproduced the bug successfully (but the output differs):

$ /from/source/ab -n 3 -k http://127.0.0.1:8080/
This is ApacheBench, Version 2.3 <$Revision: 1900571 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd,
http://web.archive.org/web/20000304112933/http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)...apr_pollset_poll: The timeout specified
has expired (70007)


Server Software: ReactPHP/1
Server Hostname: 127.0.0.1
Server Port: 8080

Document Path: /
Document Length: 0 bytes

Number of workers: 1
Concurrency Level: 1
Concurrency achieved: 1
Rampup delay: 0 [ms]
Time taken for tests: 0.000 seconds
Complete requests: 0
Failed requests: 0
Keep-Alive requests: 0
Total transferred: 105 bytes
HTML transferred: 5 bytes


Additional Notes

*most of the time: While finding and exploring this bug and it's reason I had
cases where using -n 2 sometimes caused this issue and sometimes not, but they
are lost to the terminal output history buffer, so I couldn't include them in
this bug report. I also couldn't reproduce them later.

$ ldd /usr/bin/ab
linux-vdso.so.1 (0x00007ffc8de6f000)
libaprutil-1.so.0 => /usr/lib/libaprutil-1.so.0 (0x00007f9273371000)
libapr-1.so.0 => /usr/lib/libapr-1.so.0 (0x00007f9273333000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007f927324b000)
libssl.so.1.1 => /usr/lib/libssl.so.1.1 (0x00007f92731b4000)
libcrypto.so.1.1 => /usr/lib/libcrypto.so.1.1 (0x00007f9272ed3000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f9272cc9000)
libcrypt.so.2 => /usr/lib/libcrypt.so.2 (0x00007f9272c95000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f9272c90000)
libexpat.so.1 => /usr/lib/libexpat.so.1 (0x00007f9272c5f000)
libuuid.so.1 => /usr/lib/libuuid.so.1 (0x00007f9272c56000)
libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f9272c51000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2
(0x00007f92733b5000)

--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org