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) {
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;