summaryrefslogtreecommitdiffstats
path: root/server/connection.c
diff options
context:
space:
mode:
authorJoe Orton <jorton@apache.org>2005-09-25 20:00:43 +0200
committerJoe Orton <jorton@apache.org>2005-09-25 20:00:43 +0200
commit18c24c857dcc7bb54bde154f4711530299c162f4 (patch)
tree378718f07d6699efe598e7832281ed2bbed0c698 /server/connection.c
parent* add svn:ignore to modules/database (diff)
downloadapache2-18c24c857dcc7bb54bde154f4711530299c162f4.tar.xz
apache2-18c24c857dcc7bb54bde154f4711530299c162f4.zip
* server/connection.c (ap_lingering_close): Fix lingering close to
really match the 1.3 behaviour: read from the client for up to ~30 seconds in total. Current behaviour will attempt only 15 read() calls then give up. PR: 35292 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@291452 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server/connection.c')
-rw-r--r--server/connection.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/server/connection.c b/server/connection.c
index 9f59497910..11b499d69f 100644
--- a/server/connection.c
+++ b/server/connection.c
@@ -101,7 +101,7 @@ AP_DECLARE(void) ap_lingering_close(conn_rec *c)
apr_size_t nbytes = sizeof(dummybuf);
apr_status_t rc;
apr_int32_t timeout;
- apr_int32_t total_linger_time = 0;
+ apr_time_t timeup = 0;
apr_socket_t *csd = ap_get_module_config(c->conn_config, &core_module);
if (!csd) {
@@ -138,25 +138,31 @@ AP_DECLARE(void) ap_lingering_close(conn_rec *c)
return;
}
- /* Read all data from the peer until we reach "end-of-file" (FIN
- * from peer) or we've exceeded our overall timeout. If the client does
- * not send us bytes within 2 seconds (a value pulled from Apache 1.3
- * which seems to work well), close the connection.
+ /* Read available data from the client whilst it continues sending
+ * it, for a maximum time of MAX_SECS_TO_LINGER. If the client
+ * does not send any data within 2 seconds (a value pulled from
+ * Apache 1.3 which seems to work well), give up.
*/
timeout = apr_time_from_sec(SECONDS_TO_LINGER);
apr_socket_timeout_set(csd, timeout);
apr_socket_opt_set(csd, APR_INCOMPLETE_READ, 1);
- while (1) {
+
+ /* The common path here is that the initial apr_socket_recv() call
+ * will return 0 bytes read; so that case must avoid the expensive
+ * apr_time_now() call and time arithmetic. */
+
+ do {
nbytes = sizeof(dummybuf);
rc = apr_socket_recv(csd, dummybuf, &nbytes);
if (rc != APR_SUCCESS || nbytes == 0)
break;
- total_linger_time += SECONDS_TO_LINGER;
- if (total_linger_time >= MAX_SECS_TO_LINGER) {
- break;
+ if (timeup == 0) {
+ /* First time through; calculate now + 30 seconds. */
+ timeup = apr_time_now() + apr_time_from_sec(MAX_SECS_TO_LINGER);
+ continue;
}
- }
+ } while (apr_time_now() < timeup);
apr_socket_close(csd);
return;