changeset 1373:fdea12ffb24a

discard request body before going to keep-alive state and use lingering timeouts
author Igor Sysoev <igor@sysoev.ru>
date Tue, 07 Aug 2007 10:53:27 +0000
parents 2cc9b6651f75
children aabbf66b61ea
files src/http/ngx_http_request.c src/http/ngx_http_request_body.c
diffstat 2 files changed, 67 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1921,8 +1921,16 @@ ngx_http_set_keepalive(ngx_http_request_
     c = r->connection;
     rev = c->read;
 
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "set http keepalive handler");
 
+    if (r->discard_body) {
+        r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
+        ngx_add_timer(rev, clcf->lingering_timeout);
+        return;
+    }
+
     c->log->action = "closing request";
 
     hc = r->http_connection;
@@ -1966,8 +1974,6 @@ ngx_http_set_keepalive(ngx_http_request_
         }
     }
 
-    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
     ngx_http_request_done(r, 0);
 
     c->data = hc;
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -442,12 +442,12 @@ ngx_http_discard_request_body(ngx_http_r
         ngx_del_timer(rev);
     }
 
-    r->discard_body = 1;
-
     if (r->headers_in.content_length_n <= 0) {
         return NGX_OK;
     }
 
+    r->discard_body = 1;
+
     size = r->header_in->last - r->header_in->pos;
 
     if (size) {
@@ -467,26 +467,75 @@ ngx_http_discard_request_body(ngx_http_r
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
-    return ngx_http_read_discarded_request_body(r);
+    (void) ngx_http_read_discarded_request_body(r);
+
+    return NGX_OK;
 }
 
 
 static void
 ngx_http_read_discarded_request_body_handler(ngx_http_request_t *r)
 {
-    ngx_int_t  rc;
+    ngx_int_t                  rc;
+    ngx_msec_t                 timer;
+    ngx_event_t               *rev;
+    ngx_connection_t          *c;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    c = r->connection;
+    rev = c->read;
+
+    if (rev->timedout) {
+        c->timedout = 1;
+        c->error = 1;
+        ngx_http_finalize_request(r, 0);
+        return;
+    }
+
+    if (r->lingering_time) {
+        timer = r->lingering_time - ngx_time();
+
+        if (timer <= 0) {
+            r->discard_body = 0;
+            ngx_http_finalize_request(r, 0);
+            return;
+        }
+
+    } else {
+        timer = 0;
+    }
 
     rc = ngx_http_read_discarded_request_body(r);
 
-    if (rc == NGX_AGAIN) {
-        if (ngx_handle_read_event(r->connection->read, 0) == NGX_ERROR) {
-            ngx_http_finalize_request(r, rc);
-            return;
+    if (rc == NGX_OK) {
+
+        r->discard_body = 0;
+
+        if (r->done) {
+            ngx_http_finalize_request(r, 0);
         }
+
+        return;
     }
 
-    if (rc != NGX_OK) {
+    /* rc == NGX_AGAIN */
+
+    if (ngx_handle_read_event(rev, 0) == NGX_ERROR) {
         ngx_http_finalize_request(r, rc);
+        return;
+    }
+
+    if (timer) {
+
+        clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+        timer *= 1000;
+
+        if (timer > clcf->lingering_timeout) {
+            timer = clcf->lingering_timeout;
+        }
+
+        ngx_add_timer(rev, timer);
     }
 }
 
@@ -514,14 +563,7 @@ ngx_http_read_discarded_request_body(ngx
         n = r->connection->recv(r->connection, buffer, size);
 
         if (n == NGX_ERROR) {
-
             r->connection->error = 1;
-
-            /*
-             * if a client request body is discarded then we already set
-             * some HTTP response code for client and we can ignore the error
-             */
-
             return NGX_OK;
         }
 
@@ -533,5 +575,5 @@ ngx_http_read_discarded_request_body(ngx
 
     } while (r->connection->read->ready);
 
-    return NGX_OK;
+    return NGX_AGAIN;
 }