diff src/http/modules/proxy/ngx_http_proxy_upstream.c @ 188:0061d1f0908d

nginx-0.0.1-2003-11-18-11:04:34 import
author Igor Sysoev <igor@sysoev.ru>
date Tue, 18 Nov 2003 08:04:34 +0000
parents 5a9bbe99008b
children c966c09be66b
line wrap: on
line diff
--- a/src/http/modules/proxy/ngx_http_proxy_upstream.c
+++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c
@@ -19,6 +19,7 @@ static void ngx_http_proxy_process_upstr
 static void ngx_http_proxy_process_upstream_headers(ngx_event_t *rev);
 static ssize_t ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *);
 static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p);
+static void ngx_http_proxy_check_broken_connection(ngx_event_t *wev);
 static void ngx_http_proxy_process_body(ngx_event_t *ev);
 static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p, int ft_type);
 
@@ -224,6 +225,23 @@ ngx_log_debug(r->connection->log, "timer
         ngx_del_timer(r->connection->read);
     }
 
+    if ((ngx_event_flags & (NGX_USE_CLEAR_EVENT|NGX_HAVE_KQUEUE_EVENT))
+        && !r->connection->write->active)
+    {
+        /* kqueue allows to detect when client closes prematurely connection */
+
+        r->connection->write->event_handler =
+                                        ngx_http_proxy_check_broken_connection;
+
+        if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT,
+                                                NGX_CLEAR_EVENT) == NGX_ERROR)
+        {
+            ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return;
+        }
+    }
+
+
     if (!(cl = ngx_http_proxy_create_request(p))) {
         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
         return;
@@ -424,7 +442,7 @@ static void ngx_http_proxy_connect(ngx_h
 
     /* rc == NGX_OK */
 
-#if 1 /* test only */
+#if 1 /* test only, see below about "post aio operation" */
 
     if (c->read->ready) {
         /* post aio operation */
@@ -548,6 +566,11 @@ static void ngx_http_proxy_send_request_
         return;
     }
 
+    if (p->request->connection->write->eof) {
+        ngx_http_proxy_close_connection(p);
+        ngx_http_close_connection(p->request->connection);
+    }
+
     ngx_http_proxy_send_request(p);
 }
 
@@ -939,12 +962,16 @@ static void ngx_http_proxy_send_response
         return;
     }
 
+    ep->cachable = p->cachable;
+
     ep->temp_file->file.fd = NGX_INVALID_FILE;
     ep->temp_file->file.log = r->connection->log;
     ep->temp_file->path = p->lcf->temp_path;
     ep->temp_file->pool = r->pool;
-    ep->temp_file->warn = "an upstream response is buffered "
-                         "to a temporary file";
+    if (!p->cachable) {
+        ep->temp_file->warn = "an upstream response is buffered "
+                              "to a temporary file";
+    }
 
     ep->max_temp_file_size = p->lcf->max_temp_file_size;
     ep->temp_file_write_size = p->lcf->temp_file_write_size;
@@ -983,8 +1010,6 @@ static void ngx_http_proxy_send_response
      */
     p->header_in->last = p->header_in->pos;
 
-    ep->cachable = p->cachable;
-
     if (p->lcf->cyclic_temp_file) {
 
         /*
@@ -1017,6 +1042,45 @@ static void ngx_http_proxy_send_response
 }
 
 
+static void ngx_http_proxy_check_broken_connection(ngx_event_t *wev)
+{
+    ngx_connection_t      *c;
+    ngx_http_request_t    *r;
+    ngx_http_proxy_ctx_t  *p;
+
+    ngx_log_debug(wev->log, "http proxy check client");
+
+    c = wev->data;
+    r = c->data;
+    p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
+
+#if (HAVE_KQUEUE)
+    if (wev->kq_eof) {
+        wev->eof = 1;
+
+        if (wev->kq_errno) {
+            wev->error = 1;
+        }
+
+        if (!p->cachable && p->upstream->peer.connection) {
+            ngx_log_error(NGX_LOG_INFO, wev->log, wev->kq_errno,
+                          "client closed prematurely connection, "
+                          "so upstream connection is closed too");
+            ngx_http_proxy_close_connection(p);
+
+        } else {
+            ngx_log_error(NGX_LOG_INFO, wev->log, wev->kq_errno,
+                          "client closed prematurely connection");
+        }
+ 
+        if (p->upstream->peer.connection == NULL) {
+            ngx_http_close_connection(c);
+        }
+    }
+#endif
+}
+
+
 static void ngx_http_proxy_process_body(ngx_event_t *ev)
 {
     ngx_connection_t      *c;
@@ -1097,11 +1161,9 @@ static void ngx_http_proxy_process_body(
         }
  
         if (p->upstream->peer.connection == NULL) {
-            ngx_http_close_connection(c);
+            ngx_http_close_connection(r->connection);
         }
     }
-
-    return;
 }