diff options
author | Joe Orton <jorton@apache.org> | 2005-09-25 20:00:43 +0200 |
---|---|---|
committer | Joe Orton <jorton@apache.org> | 2005-09-25 20:00:43 +0200 |
commit | 18c24c857dcc7bb54bde154f4711530299c162f4 (patch) | |
tree | 378718f07d6699efe598e7832281ed2bbed0c698 /server/connection.c | |
parent | * add svn:ignore to modules/database (diff) | |
download | apache2-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.c | 26 |
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; |