aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/http/ngx_http_core_module.c8
-rw-r--r--src/http/ngx_http_request.c125
-rw-r--r--src/http/ngx_http_request.h1
-rw-r--r--src/http/ngx_http_request_body.c2
4 files changed, 109 insertions, 27 deletions
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index e79dd1cd2..988d8f0e8 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -1260,10 +1260,6 @@ ngx_http_core_content_phase(ngx_http_request_t *r,
rc = ph->handler(r);
- if (rc == NGX_DONE) {
- return NGX_OK;
- }
-
if (rc != NGX_DECLINED) {
ngx_http_finalize_request(r, rc);
return NGX_OK;
@@ -2126,6 +2122,7 @@ ngx_http_subrequest(ngx_http_request_t *r,
sr->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
r->main->subrequests++;
+ r->main->count++;
*psr = sr;
@@ -2178,6 +2175,7 @@ ngx_http_internal_redirect(ngx_http_request_t *r,
#endif
r->internal = 1;
+ r->main->count++;
ngx_http_handler(r);
@@ -2192,6 +2190,8 @@ ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name)
ngx_http_core_loc_conf_t **clcfp;
ngx_http_core_main_conf_t *cmcf;
+ r->main->count++;
+
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
if (cscf->named_locations) {
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 4cd1d8f61..f071cf523 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -36,6 +36,9 @@ static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r,
u_char *host, size_t len);
static void ngx_http_request_handler(ngx_event_t *ev);
+static void ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc);
+static void ngx_http_terminate_handler(ngx_http_request_t *r);
+static void ngx_http_finalize_connection(ngx_http_request_t *r);
static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r);
static void ngx_http_writer(ngx_http_request_t *r);
static void ngx_http_request_finalizer(ngx_http_request_t *r);
@@ -46,7 +49,7 @@ static void ngx_http_set_lingering_close(ngx_http_request_t *r);
static void ngx_http_lingering_close_handler(ngx_event_t *ev);
static ngx_int_t ngx_http_post_action(ngx_http_request_t *r);
static void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error);
-static void ngx_http_request_done(ngx_http_request_t *r, ngx_int_t error);
+static void ngx_http_free_request(ngx_http_request_t *r, ngx_int_t error);
static void ngx_http_log_request(ngx_http_request_t *r);
static void ngx_http_close_connection(ngx_connection_t *c);
@@ -478,6 +481,7 @@ ngx_http_init_request(ngx_event_t *rev)
c->destroyed = 0;
r->main = r;
+ r->count = 1;
tp = ngx_timeofday();
r->start_sec = tp->sec;
@@ -1828,17 +1832,17 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
ngx_http_request_t *pr;
ngx_http_core_loc_conf_t *clcf;
+ c = r->connection;
+
+ ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0,
+ "http finalize request: %d, \"%V?%V\" a:%d, c:%d",
+ rc, &r->uri, &r->args, r == c->data, r->main->count);
+
if (rc == NGX_DONE) {
- /* the request pool may be already destroyed */
+ ngx_http_finalize_connection(r);
return;
}
- c = r->connection;
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http finalize request: %d, \"%V?%V\" %d",
- rc, &r->uri, &r->args, r == c->data);
-
if (rc == NGX_OK && r->filter_finalize) {
c->error = 1;
return;
@@ -1860,15 +1864,11 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
|| rc == NGX_HTTP_CLIENT_CLOSED_REQUEST
|| c->error)
{
- if (rc > 0 && r->headers_out.status == 0) {
- r->headers_out.status = rc;
- }
-
if (ngx_http_post_action(r) == NGX_OK) {
return;
}
- ngx_http_close_request(r, 0);
+ ngx_http_terminate_request(r, rc);
return;
}
@@ -1877,7 +1877,7 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
|| rc == NGX_HTTP_NO_CONTENT)
{
if (rc == NGX_HTTP_CLOSE) {
- ngx_http_close_request(r, rc);
+ ngx_http_terminate_request(r, rc);
return;
}
@@ -1903,7 +1903,7 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
if (r->buffered || r->postponed) {
if (ngx_http_set_write_handler(r) != NGX_OK) {
- ngx_http_close_request(r->main, 0);
+ ngx_http_terminate_request(r, 0);
}
return;
@@ -1921,6 +1921,8 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
if (r == c->data) {
+ r->main->count--;
+
if (!r->logged) {
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
@@ -1955,7 +1957,8 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
}
if (ngx_http_post_request(pr) != NGX_OK) {
- ngx_http_close_request(r->main, 0);
+ r->main->count++;
+ ngx_http_terminate_request(r, 0);
return;
}
@@ -1969,7 +1972,7 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
if (r->buffered || c->buffered || r->postponed) {
if (ngx_http_set_write_handler(r) != NGX_OK) {
- ngx_http_close_request(r, 0);
+ ngx_http_terminate_request(r, 0);
}
return;
@@ -2010,6 +2013,68 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
return;
}
+ ngx_http_finalize_connection(r);
+}
+
+
+static void
+ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc)
+{
+ ngx_http_cleanup_t *cln;
+ ngx_http_request_t *mr;
+
+ mr = r->main;
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http terminate request count: %d", mr->count);
+
+ cln = mr->cleanup;
+ mr->cleanup = NULL;
+
+ while (cln) {
+ if (cln->handler) {
+ cln->handler(cln->data);
+ }
+
+ cln = cln->next;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http terminate cleanup count: %d", mr->count);
+
+ if (mr->write_event_handler) {
+ mr->posted_requests = NULL;
+ mr->write_event_handler = ngx_http_terminate_handler;
+ (void) ngx_http_post_request(mr);
+ return;
+ }
+
+ ngx_http_close_request(mr, rc);
+}
+
+
+static void
+ngx_http_terminate_handler(ngx_http_request_t *r)
+{
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http terminate handler count: %d", r->count);
+
+ r->count = 1;
+
+ ngx_http_close_request(r, 0);
+}
+
+
+static void
+ngx_http_finalize_connection(ngx_http_request_t *r)
+{
+ ngx_http_core_loc_conf_t *clcf;
+
+ if (r->main->count != 1) {
+ ngx_http_close_request(r, 0);
+ return;
+ }
+
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
if (!ngx_terminate
@@ -2319,7 +2384,7 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
}
}
- ngx_http_request_done(r, 0);
+ ngx_http_free_request(r, 0);
c->data = hc;
@@ -2766,19 +2831,33 @@ ngx_http_post_action(ngx_http_request_t *r)
static void
-ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error)
+ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc)
{
ngx_connection_t *c;
+ r = r->main;
c = r->connection;
- ngx_http_request_done(r->main, error);
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+ "http request count: %d", r->count);
+
+ if (r->count == 0) {
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0, "http request count is zero");
+ }
+
+ r->count--;
+
+ if (r->count) {
+ return;
+ }
+
+ ngx_http_free_request(r, rc);
ngx_http_close_connection(c);
}
static void
-ngx_http_request_done(ngx_http_request_t *r, ngx_int_t error)
+ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc)
{
ngx_log_t *log;
struct linger linger;
@@ -2813,8 +2892,8 @@ ngx_http_request_done(ngx_http_request_t *r, ngx_int_t error)
#endif
- if (error && r->headers_out.status == 0) {
- r->headers_out.status = error;
+ if (rc > 0 && (r->headers_out.status == 0 || r->connection->sent == 0)) {
+ r->headers_out.status = rc;
}
log->action = "logging request";
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 51f8419b4..7b984fb27 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -502,6 +502,7 @@ struct ngx_http_request_s {
#endif
unsigned subrequests:8;
+ unsigned count:8;
/* used to parse HTTP headers */
diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
index 9d47300f5..775bb2642 100644
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -37,6 +37,8 @@ ngx_http_read_client_request_body(ngx_http_request_t *r,
ngx_http_request_body_t *rb;
ngx_http_core_loc_conf_t *clcf;
+ r->main->count++;
+
if (r->request_body || r->discard_body) {
post_handler(r);
return NGX_OK;