You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by gr...@apache.org on 2004/11/26 22:21:43 UTC
svn commit: r106662 - /httpd/httpd/trunk/modules/http/http_core.c
Author: gregames
Date: Fri Nov 26 13:21:42 2004
New Revision: 106662
URL: http://svn.apache.org/viewcvs?view=rev&rev=106662
Log:
ap_process_http_async_connection (used by the Event MPM):
fix CLOSE_WAITs/leaked connections. The logic to deal with ap_read_request
failures got lost when merging in the HTTP pipelining fix. If ap_read_request
fails, the connection state should get set to CONN_STATE_LINGER so the MPM will
invoke lingering close. Test case: client sends a Connection: keepalive header
then closes the connection before the keepalive timeout pops.
Also add a comment to make the pipelining flow more obvious.
Modified:
httpd/httpd/trunk/modules/http/http_core.c
Modified: httpd/httpd/trunk/modules/http/http_core.c
Url: http://svn.apache.org/viewcvs/httpd/httpd/trunk/modules/http/http_core.c?view=diff&rev=106662&p1=httpd/httpd/trunk/modules/http/http_core.c&r1=106661&p2=httpd/httpd/trunk/modules/http/http_core.c&r2=106662
==============================================================================
--- httpd/httpd/trunk/modules/http/http_core.c (original)
+++ httpd/httpd/trunk/modules/http/http_core.c Fri Nov 26 13:21:42 2004
@@ -235,44 +235,41 @@
{
request_rec *r;
conn_state_t *cs = c->cs;
-
- switch (cs->state) {
- case CONN_STATE_READ_REQUEST_LINE:
+
+ AP_DEBUG_ASSERT(cs->state == CONN_STATE_READ_REQUEST_LINE);
+
+ while (cs->state == CONN_STATE_READ_REQUEST_LINE) {
ap_update_child_status(c->sbh, SERVER_BUSY_READ, NULL);
- while ((r = ap_read_request(c)) != NULL) {
- c->keepalive = AP_CONN_UNKNOWN;
+
+ if ((r = ap_read_request(c))) {
+ c->keepalive = AP_CONN_UNKNOWN;
/* process the request if it was read without error */
+
ap_update_child_status(c->sbh, SERVER_BUSY_WRITE, r);
-
if (r->status == HTTP_OK)
ap_process_request(r);
if (ap_extended_status)
ap_increment_counts(c->sbh, r);
- if (c->keepalive != AP_CONN_KEEPALIVE || c->aborted) {
+ if (c->keepalive != AP_CONN_KEEPALIVE || c->aborted
+ || ap_graceful_stop_signalled()) {
cs->state = CONN_STATE_LINGER;
- break;
}
- else {
+ else if (!c->data_in_input_filters) {
cs->state = CONN_STATE_CHECK_REQUEST_LINE_READABLE;
}
- apr_pool_destroy(r->pool);
+ /* else we are pipelining. Stay in READ_REQUEST_LINE state
+ * and stay in the loop
+ */
- if (ap_graceful_stop_signalled())
- break;
-
- if (c->data_in_input_filters) {
- continue;
- }
- break;
+ apr_pool_destroy(r->pool);
+ }
+ else { /* ap_read_request failed - client may have closed */
+ cs->state = CONN_STATE_LINGER;
}
- break;
- default:
- AP_DEBUG_ASSERT(0);
- cs->state = CONN_STATE_LINGER;
}
return OK;