diff src/http/ngx_http_upstream.c @ 518:86dad910eeb6 NGINX_0_8_11

nginx 0.8.11 *) Change: directive "gzip_disable msie6" enables gzipping for MSIE 6.0 SV1. *) Feature: file AIO support on FreeBSD and Linux. *) Feature: the "directio_alignment" directive.
author Igor Sysoev <http://sysoev.ru>
date Fri, 28 Aug 2009 00:00:00 +0400
parents 7efcdb937752
children 80f7156c2965
line wrap: on
line diff
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -18,6 +18,7 @@ static ngx_int_t ngx_http_upstream_cache
     ngx_http_variable_value_t *v, uintptr_t data);
 #endif
 
+static void ngx_http_upstream_init_request(ngx_http_request_t *r);
 static void ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx);
 static void ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r);
 static void ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r);
@@ -379,6 +380,10 @@ ngx_http_upstream_create(ngx_http_reques
     u->peer.lock = &r->connection->lock;
 #endif
 
+#if (NGX_HTTP_CACHE)
+    r->cache = NULL;
+#endif
+
     return NGX_OK;
 }
 
@@ -386,15 +391,7 @@ ngx_http_upstream_create(ngx_http_reques
 void
 ngx_http_upstream_init(ngx_http_request_t *r)
 {
-    ngx_str_t                      *host;
-    ngx_uint_t                      i;
-    ngx_connection_t               *c;
-    ngx_resolver_ctx_t             *ctx, temp;
-    ngx_http_cleanup_t             *cln;
-    ngx_http_upstream_t            *u;
-    ngx_http_core_loc_conf_t       *clcf;
-    ngx_http_upstream_srv_conf_t   *uscf, **uscfp;
-    ngx_http_upstream_main_conf_t  *umcf;
+    ngx_connection_t     *c;
 
     c = r->connection;
 
@@ -405,15 +402,6 @@ ngx_http_upstream_init(ngx_http_request_
         ngx_del_timer(c->read);
     }
 
-    u = r->upstream;
-
-    u->store = (u->conf->store || u->conf->store_lengths);
-
-    if (!u->store && !r->post_action && !u->conf->ignore_client_abort) {
-        r->read_event_handler = ngx_http_upstream_rd_check_broken_connection;
-        r->write_event_handler = ngx_http_upstream_wr_check_broken_connection;
-    }
-
     if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
 
         if (!c->write->active) {
@@ -426,10 +414,28 @@ ngx_http_upstream_init(ngx_http_request_
         }
     }
 
-    if (r->request_body) {
-        u->request_bufs = r->request_body->bufs;
+    ngx_http_upstream_init_request(r);
+}
+
+
+static void
+ngx_http_upstream_init_request(ngx_http_request_t *r)
+{
+    ngx_str_t                      *host;
+    ngx_uint_t                      i;
+    ngx_resolver_ctx_t             *ctx, temp;
+    ngx_http_cleanup_t             *cln;
+    ngx_http_upstream_t            *u;
+    ngx_http_core_loc_conf_t       *clcf;
+    ngx_http_upstream_srv_conf_t   *uscf, **uscfp;
+    ngx_http_upstream_main_conf_t  *umcf;
+
+    if (r->aio) {
+        return;
     }
 
+    u = r->upstream;
+
 #if (NGX_HTTP_CACHE)
 
     if (u->conf->cache) {
@@ -437,6 +443,13 @@ ngx_http_upstream_init(ngx_http_request_
 
         rc = ngx_http_upstream_cache(r, u);
 
+        if (rc == NGX_BUSY) {
+            r->write_event_handler = ngx_http_upstream_init_request;
+            return;
+        }
+
+        r->write_event_handler = ngx_http_request_empty_handler;
+
         if (rc == NGX_DONE) {
             return;
         }
@@ -449,6 +462,17 @@ ngx_http_upstream_init(ngx_http_request_
 
 #endif
 
+    u->store = (u->conf->store || u->conf->store_lengths);
+
+    if (!u->store && !r->post_action && !u->conf->ignore_client_abort) {
+        r->read_event_handler = ngx_http_upstream_rd_check_broken_connection;
+        r->write_event_handler = ngx_http_upstream_wr_check_broken_connection;
+    }
+
+    if (r->request_body) {
+        u->request_bufs = r->request_body->bufs;
+    }
+
     if (u->create_request(r) != NGX_OK) {
         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
         return;
@@ -456,6 +480,7 @@ ngx_http_upstream_init(ngx_http_request_
 
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
+    u->output.alignment = clcf->directio_alignment;
     u->output.pool = r->pool;
     u->output.bufs.num = 1;
     u->output.bufs.size = clcf->client_body_buffer_size;
@@ -543,7 +568,7 @@ ngx_http_upstream_init(ngx_http_request_
         }
 
         if (ctx == NGX_NO_RESOLVER) {
-            ngx_log_error(NGX_LOG_ERR, c->log, 0,
+            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                           "no resolver defined to resolve %V", host);
 
             ngx_http_finalize_request(r, NGX_HTTP_BAD_GATEWAY);
@@ -586,42 +611,47 @@ ngx_http_upstream_cache(ngx_http_request
     ngx_int_t          rc;
     ngx_http_cache_t  *c;
 
-    if (!(r->method & u->conf->cache_methods)) {
-        return NGX_DECLINED;
-    }
-
-    if (r->method & NGX_HTTP_HEAD) {
-        u->method = ngx_http_core_get_method;
-    }
-
-    c = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t));
+    c = r->cache;
+
     if (c == NULL) {
-        return NGX_ERROR;
-    }
-
-    if (ngx_array_init(&c->keys, r->pool, 4, sizeof(ngx_str_t)) != NGX_OK) {
-        return NGX_ERROR;
+
+        if (!(r->method & u->conf->cache_methods)) {
+            return NGX_DECLINED;
+        }
+
+        if (r->method & NGX_HTTP_HEAD) {
+            u->method = ngx_http_core_get_method;
+        }
+
+        c = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t));
+        if (c == NULL) {
+            return NGX_ERROR;
+        }
+
+        if (ngx_array_init(&c->keys, r->pool, 4, sizeof(ngx_str_t)) != NGX_OK) {
+            return NGX_ERROR;
+        }
+
+        r->cache = c;
+        c->file.log = r->connection->log;
+
+        if (u->create_key(r) != NGX_OK) {
+            return NGX_ERROR;
+        }
+
+        /* TODO: add keys */
+
+        ngx_http_file_cache_create_key(r);
+
+        u->cacheable = 1;
+
+        c->min_uses = u->conf->cache_min_uses;
+        c->body_start = u->conf->buffer_size;
+        c->file_cache = u->conf->cache->data;
+
+        u->cache_status = NGX_HTTP_CACHE_MISS;
     }
 
-    r->cache = c;
-    c->file.log = r->connection->log;
-
-    if (u->create_key(r) != NGX_OK) {
-        return NGX_ERROR;
-    }
-
-    /* TODO: add keys */
-
-    ngx_http_file_cache_create_key(r);
-
-    u->cacheable = 1;
-
-    c->min_uses = u->conf->cache_min_uses;
-    c->body_start = u->conf->buffer_size;
-    c->file_cache = u->conf->cache->data;
-
-    u->cache_status = NGX_HTTP_CACHE_MISS;
-
     rc = ngx_http_file_cache_open(r);
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -657,10 +687,6 @@ ngx_http_upstream_cache(ngx_http_request
 
         break;
 
-    case NGX_ERROR:
-
-        return NGX_ERROR;
-
     case NGX_HTTP_CACHE_STALE:
 
         c->valid_sec = 0;
@@ -681,12 +707,20 @@ ngx_http_upstream_cache(ngx_http_request
 
         break;
 
-    case NGX_AGAIN:
+    case NGX_HTTP_CACHE_SCARCE:
 
         u->cacheable = 0;
 
         break;
 
+    case NGX_AGAIN:
+
+        return NGX_BUSY;
+
+    case NGX_ERROR:
+
+        return NGX_ERROR;
+
     default:
 
         /* cached NGX_HTTP_BAD_GATEWAY, NGX_HTTP_GATEWAY_TIME_OUT, etc. */
@@ -2260,10 +2294,6 @@ ngx_http_upstream_process_non_buffered_r
             if (u->out_bufs || u->busy_bufs) {
                 rc = ngx_http_output_filter(r, u->out_bufs);
 
-                if (downstream->destroyed) {
-                    return;
-                }
-
                 if (rc == NGX_ERROR) {
                     ngx_http_upstream_finalize_request(r, u, 0);
                     return;
@@ -2436,11 +2466,6 @@ ngx_http_upstream_process_downstream(ngx
             }
 
             if (ngx_event_pipe(p, wev->write) == NGX_ABORT) {
-
-                if (c->destroyed) {
-                    return;
-                }
-
                 ngx_http_upstream_finalize_request(r, u, 0);
                 return;
             }
@@ -2466,11 +2491,6 @@ ngx_http_upstream_process_downstream(ngx
         }
 
         if (ngx_event_pipe(p, 1) == NGX_ABORT) {
-
-            if (c->destroyed) {
-                return;
-            }
-
             ngx_http_upstream_finalize_request(r, u, 0);
             return;
         }
@@ -2498,14 +2518,7 @@ ngx_http_upstream_process_upstream(ngx_h
         ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
 
     } else {
-        c = r->connection;
-
         if (ngx_event_pipe(u->pipe, 0) == NGX_ABORT) {
-
-            if (c->destroyed) {
-                return;
-            }
-
             ngx_http_upstream_finalize_request(r, u, 0);
             return;
         }