Bug #82323
closedTypo3 8 forces HTTP keep-alive even for HTTP/1.0 clients without 'Connection: Keep-Alive' header
0%
Description
We wanted to do bench-marking with Apache's 'ab' tool and noticed that unless we use explicitly use 'keep-alive' (ab -k), results are really bad:
> ab -n1 -c1 -v4 http://typo8.example.com/ This is ApacheBench, Version 2.3 <$Revision: 1748469 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking typo8.example.com (be patient)...INFO: GET header == --- GET / HTTP/1.0 <---------------- since 'ab' uses HTTP/1.0, Keep-Alive should not be the default Host: typo8.example.com User-Agent: ApacheBench/2.3 Accept: */* --- LOG: header received: HTTP/1.1 200 OK Date: Thu, 07 Sep 2017 07:23:05 GMT Server: Apache X-Powered-By: PHP/7.0.7 Content-Language: en Expires: Fri, 08 Sep 2017 07:03:31 GMT Cache-Control: max-age=85226 Pragma: public Content-Length: 15117 X-FRAME-OPTIONS: SAMEORIGIN, SAMEORIGIN, SAMEORIGIN, SAMEORIGIN X-XSS-Protection: 1; mode=block X-UA-Compatible: IE=edge X-Content-Type-Options: nosniff Content-Type: text/html; charset=utf-8 <!DOCTYPE html> ... HTML body removed for brevity ... LOG: Response code = 200 ..done Server Software: Apache Server Hostname: typo8.example.com Server Port: 80 Document Path: / Document Length: 15117 bytes Concurrency Level: 1 Time taken for tests: 15.135 seconds <------ 15 seconds Complete requests: 1 Failed requests: 0 Total transferred: 15542 bytes HTML transferred: 15117 bytes Requests per second: 0.07 [#/sec] (mean) <--- really bad requests per second Time per request: 15135.477 [ms] (mean) Time per request: 15135.477 [ms] (mean, across all concurrent requests) Transfer rate: 1.00 [Kbytes/sec] received
Using 'telnet' to server port 80, we found out that after Typo3 returns HTML body, the server keeps the connection open for another 'KeepAliveTimeout' period (in this case 15 seconds) - which may be 'normal' for HTTP/1.1 where Keep-Alive is the default, but should not happen with HTTP/1.0 (which is what 'ab' uses).
This does not happen if we connect to static HTML file or a simple 'Hello World' PHP script:
> ab -n1 -c1 -v4 http://typo8.example.com/test.php This is ApacheBench, Version 2.3 <$Revision: 1748469 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking typo8.example.com (be patient)...INFO: GET header == --- GET /test.php HTTP/1.0 Host: typo8.example.com User-Agent: ApacheBench/2.3 Accept: */* --- LOG: header received: HTTP/1.1 200 OK Date: Thu, 07 Sep 2017 07:28:57 GMT Server: Apache X-Powered-By: PHP/7.0.7 Cache-Control: max-age=0 Expires: Thu, 07 Sep 2017 07:28:57 GMT X-FRAME-OPTIONS: SAMEORIGIN, SAMEORIGIN, SAMEORIGIN, SAMEORIGIN X-XSS-Protection: 1; mode=block X-UA-Compatible: IE=edge X-Content-Type-Options: nosniff Content-Length: 13 Connection: close Content-Type: text/html; charset=UTF-8 Hello World LOG: Response code = 200 ..done Server Software: Apache Server Hostname: typo8.example.com Server Port: 80 Document Path: /test.php Document Length: 13 bytes Concurrency Level: 1 Time taken for tests: 0.006 seconds Complete requests: 1 Failed requests: 0 Total transferred: 412 bytes HTML transferred: 13 bytes Requests per second: 166.72 [#/sec] (mean) Time per request: 5.998 [ms] (mean) Time per request: 5.998 [ms] (mean, across all concurrent requests) Transfer rate: 67.08 [Kbytes/sec] received
Since this only happens if we access Typo3 8 and not with older Typo3 versions (we tested 6.2), a simple 'test.php' or a static HTML files (all on the same Apache / PHP server), we believe the issue is with Typo3 8.
Updated by Markus Klein about 6 years ago
The thing that isn't good for sure is that TYPO3 answers a 1.0 request with a 1.1 response.
Updated by Oliver Hader almost 5 years ago
- Status changed from New to Rejected
This does not look like a TYPO3 issue to me - especially not since TYPO3 is not sending Keep-Alive
or Connection
headers in a response. The only TYPO3 TYPO3 might influence is the HTTP response status and it's version HTTP/1.1
(which is the default and not evaluated further).
The bad performance results are most probably related to the (Apache) server configuration - mentioned Keep-Alive
and Connection
headers are sent by the web-server in case directives KeepAlive
and KeepAliveTimeout
are configured.
The correct header value in a HTTP/1.1 response on a HTTP/1.0 request should be (leaving it to the client to decide whether it really does not understand HTTP/1.1):
Connection: keep-alive, close
https://tools.ietf.org/html/rfc7230#section-2.6 has similar statements
A server SHOULD send a response version equal to the highest version to which the server is conformant that has a major version less than or equal to the one received in the request. A server MUST NOT send a version to which it is not conformant. A server can send a 505 (HTTP Version Not Supported) response if it wishes, for any reason, to refuse service of the client's major protocol version.
A server MAY send an HTTP/1.0 response to a request if it is known or suspected that the client incorrectly implements the HTTP specification and is incapable of correctly processing later version responses, such as when a client fails to parse the version number correctly or when an intermediary is known to blindly forward the HTTP-version even when it doesn't conform to the given minor version of the protocol. Such protocol downgrades SHOULD NOT be performed unless triggered by specific client attributes, such as when one or more of the request header fields (e.g., User-Agent) uniquely match the values sent by a client known to be in error.
Thus, it's not related to TYPO3 and in general the HTTP behavior (of the webserver) is correct as well. The bad performance results of the initial report have other reasons (e.g. local DNS resolving on local environment, ab
behavior for HTTP/1.0 requests, ...).
Besides that: The initial report did not contain a Connection: keep-alive
line in the show headers at all... thus, the main indicator of this ticket is basically missing...