diff src/http/ngx_http_upstream.c @ 631:b6a5942a4e6a NGINX_0_8_46

nginx 0.8.46 *) Change: now the "proxy_no_cache", "fastcgi_no_cache", "uwsgi_no_cache", and "scgi_no_cache" directives affect on a cached response saving only. *) Feature: the "proxy_cache_bypass", "fastcgi_cache_bypass", "uwsgi_cache_bypass", and "scgi_cache_bypass" directives. *) Bugfix: nginx did not free memory in cache keys zones if there was an error during working with backend: the memory was freed only after inactivity time or on memory low condition.
author Igor Sysoev <http://sysoev.ru>
date Mon, 19 Jul 2010 00:00:00 +0400
parents 016632f0fb18
children cde3626b2d0d
line wrap: on
line diff
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -633,11 +633,17 @@ ngx_http_upstream_cache(ngx_http_request
 
     if (c == NULL) {
 
-        if (u->conf->no_cache) {
-            rc = ngx_http_cache(r, u->conf->no_cache);
-            if (rc != NGX_OK) {
-                return rc;
-            }
+        switch (ngx_http_test_predicates(r, u->conf->cache_bypass)) {
+
+        case NGX_ERROR:
+            return NGX_ERROR;
+
+        case NGX_DECLINED:
+            u->cache_status = NGX_HTTP_CACHE_BYPASS;
+            return NGX_DECLINED;
+
+        default: /* NGX_OK */
+            break;
         }
 
         if (!(r->method & u->conf->cache_methods)) {
@@ -648,18 +654,10 @@ ngx_http_upstream_cache(ngx_http_request
             u->method = ngx_http_core_get_method;
         }
 
-        c = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t));
-        if (c == NULL) {
+        if (ngx_http_file_cache_new(r) != NGX_OK) {
             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;
         }
@@ -670,6 +668,8 @@ ngx_http_upstream_cache(ngx_http_request
 
         u->cacheable = 1;
 
+        c = r->cache;
+
         c->min_uses = u->conf->cache_min_uses;
         c->body_start = u->conf->buffer_size;
         c->file_cache = u->conf->cache->data;
@@ -2098,6 +2098,47 @@ ngx_http_upstream_send_response(ngx_http
         r->cache->file.fd = NGX_INVALID_FILE;
     }
 
+    switch (ngx_http_test_predicates(r, u->conf->no_cache)) {
+
+    case NGX_ERROR:
+        ngx_http_upstream_finalize_request(r, u, 0);
+        return;
+
+    case NGX_DECLINED:
+        u->cacheable = 0;
+        break;
+
+    default: /* NGX_OK */
+
+        if (u->cache_status == NGX_HTTP_CACHE_BYPASS) {
+
+            if (ngx_http_file_cache_new(r) != NGX_OK) {
+                ngx_http_upstream_finalize_request(r, u, 0);
+                return;
+            }
+
+            if (u->create_key(r) != NGX_OK) {
+                ngx_http_upstream_finalize_request(r, u, 0);
+                return;
+            }
+
+            /* TODO: add keys */
+
+            r->cache->min_uses = u->conf->cache_min_uses;
+            r->cache->body_start = u->conf->buffer_size;
+            r->cache->file_cache = u->conf->cache->data;
+
+            if (ngx_http_file_cache_create(r) != NGX_OK) {
+                ngx_http_upstream_finalize_request(r, u, 0);
+                return;
+            }
+
+            u->cacheable = 1;
+        }
+
+        break;
+    }
+
     if (u->cacheable) {
         time_t  now, valid;