diff src/http/modules/proxy/ngx_http_proxy_cache.c @ 176:c0552e5ab567

nginx-0.0.1-2003-11-09-23:03:38 import; separate building
author Igor Sysoev <igor@sysoev.ru>
date Sun, 09 Nov 2003 20:03:38 +0000
parents e92c2c647c57
children 4db54fdbcbe7
line wrap: on
line diff
--- a/src/http/modules/proxy/ngx_http_proxy_cache.c
+++ b/src/http/modules/proxy/ngx_http_proxy_cache.c
@@ -5,12 +5,14 @@
 #include <ngx_http_proxy_handler.h>
 
 
+static int ngx_http_proxy_process_cached_response(ngx_http_proxy_ctx_t *p,
+                                                  int rc);
 static int ngx_http_proxy_process_cached_header(ngx_http_proxy_ctx_t *p);
+static void ngx_http_proxy_cache_look_complete_request(ngx_http_proxy_ctx_t *p);
 
 
 int ngx_http_proxy_get_cached_response(ngx_http_proxy_ctx_t *p)
 {
-    int                              rc;
     char                            *last;
     ngx_http_request_t              *r;
     ngx_http_proxy_cache_t          *c;
@@ -54,44 +56,69 @@ int ngx_http_proxy_get_cached_response(n
 
     c->ctx.buf = p->header_in; 
 
-    rc = ngx_http_cache_get_file(r, &c->ctx);
+    return ngx_http_proxy_process_cached_response(p,
+                                          ngx_http_cache_get_file(r, &c->ctx));
+}
 
-    switch (rc) {
-    case NGX_HTTP_CACHE_STALE:
-        p->stale = 1;
-        p->state->cache = NGX_HTTP_PROXY_CACHE_EXPR;
-        break;
-
-    case NGX_HTTP_CACHE_AGED:
-        p->stale = 1;
-        p->state->cache = NGX_HTTP_PROXY_CACHE_AGED;
-        break;
 
-    case NGX_OK:
-        p->state->cache = NGX_HTTP_PROXY_CACHE_HIT;
-        break;
+static int ngx_http_proxy_process_cached_response(ngx_http_proxy_ctx_t *p,
+                                                  int rc)
+{
+    if (rc == NGX_OK) {
+        p->state->cache_state = NGX_HTTP_PROXY_CACHE_HIT;
+        p->header_in->pos = p->header_in->start + p->cache->ctx.header_size;
 
-    default:
-        p->state->cache = NGX_HTTP_PROXY_CACHE_MISS;
-    }
-
-    if (rc == NGX_OK
-        || rc == NGX_HTTP_CACHE_STALE
-        || rc == NGX_HTTP_CACHE_AGED)
-    {
-        p->header_in->pos = p->header_in->start + c->ctx.header_size;
         if (ngx_http_proxy_process_cached_header(p) == NGX_ERROR) {
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
-        p->header_in->pos = p->header_in->start + c->ctx.header_size;
+
+        p->valid_header_in = 1;
+
+        return ngx_http_proxy_send_cached_response(p);
+    }
+
+    if (rc == NGX_HTTP_CACHE_STALE) {
+        p->state->cache_state = NGX_HTTP_PROXY_CACHE_EXPR;
+
+    } else if (rc == NGX_HTTP_CACHE_AGED) {
+        p->state->cache_state = NGX_HTTP_PROXY_CACHE_AGED;
+    }
+
+    if (rc == NGX_HTTP_CACHE_STALE || rc == NGX_HTTP_CACHE_AGED) {
+        p->header_in->pos = p->header_in->start + p->cache->ctx.header_size;
+
+        if (ngx_http_proxy_process_cached_header(p) == NGX_ERROR) {
+            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        }
+
+        p->header_in->pos = p->header_in->start + p->cache->ctx.header_size;
         p->header_in->last = p->header_in->pos;
 
+        p->stale = 1;
+        p->valid_header_in = 1;
+
     } else if (rc == NGX_DECLINED) {
-        p->header_in->pos = p->header_in->start + c->ctx.header_size;
+        p->state->cache_state = NGX_HTTP_PROXY_CACHE_MISS;
+        p->header_in->pos = p->header_in->start + p->cache->ctx.header_size;
         p->header_in->last = p->header_in->pos;
     }
 
-    return rc;
+    if (p->lcf->busy_lock) {
+        p->try_busy_lock = 1;
+
+        p->header_in->pos = p->header_in->start;
+        p->header_in->last = p->header_in->start;
+
+        p->busy_lock.time = 0;
+        p->busy_lock.event = p->request->connection->read;
+        p->busy_lock.event_handler = ngx_http_proxy_busy_lock_handler;
+        p->busy_lock.md5 = p->cache->ctx.md5;
+
+        ngx_http_proxy_cache_busy_lock(p);
+        return NGX_DONE;
+    }
+
+    return ngx_http_proxy_request_upstream(p);
 }
 
 
@@ -141,6 +168,7 @@ static int ngx_http_proxy_process_cached
     ngx_log_debug(r->connection->log, "http cache status %d '%s'" _ 
                   c->status _ c->status_line.data);
 
+    /* TODO: ngx_init_table */
     c->headers_in.headers = ngx_create_table(r->pool, 20);
 
     for ( ;; ) {
@@ -216,29 +244,110 @@ static int ngx_http_proxy_process_cached
 }
 
 
-#if 0
+void ngx_http_proxy_cache_busy_lock(ngx_http_proxy_ctx_t *p)
+{
+    int  rc, ft_type;
 
-static void ngx_http_proxy_cache_busy_lock(ngx_http_proxy_ctx_t *p)
-{
-    rc = ngx_http_busy_lock(p->lcf->busy_lock, p->cache->ctx.md5);
+    rc = ngx_http_busy_lock_cachable(p->lcf->busy_lock, &p->busy_lock,
+                                     p->try_busy_lock);
 
     if (rc == NGX_OK) {
-        ngx_http_proxy_request_upstream(p);
+        if (p->try_busy_lock) {
+            p->busy_locked = 1;
+            p->header_in->pos = p->header_in->start + p->cache->ctx.header_size;
+            p->header_in->last = p->header_in->pos;
+
+            ngx_http_proxy_request_upstream(p);
+            return;
+        }
+
+        ngx_http_proxy_cache_look_complete_request(p);
+        return;
     }
 
+    p->try_busy_lock = 0;
+
+    if (p->cache->ctx.file.fd != NGX_INVALID_FILE
+        && !p->cache->ctx.file.info_valid)
+    {
+        if (ngx_stat_fd(p->cache->ctx.file.fd, &p->cache->ctx.file.info)
+                                                             == NGX_FILE_ERROR)
+        {
+            ngx_log_error(NGX_LOG_CRIT, p->request->connection->log, ngx_errno,
+                          ngx_stat_fd_n " \"%s\" failed",
+                          p->cache->ctx.file.name.data);
+            ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return;
+        }
+
+        p->cache->ctx.file.info_valid = 1;
+    }
+
+
     if (rc == NGX_AGAIN) {
-        if (p->busy_lock_time) {
-            ngx_add_timer(p->request->connection->read, 1000);
-            return;
+        return;
+    }
+
+    if (rc == NGX_DONE) {
+        ft_type = NGX_HTTP_PROXY_FT_BUSY_LOCK;
+
+    } else {
+        /* rc == NGX_ERROR */
+        ft_type = NGX_HTTP_PROXY_FT_MAX_WAITING;
+    }
+    
+    if (p->stale && (p->lcf->use_stale & ft_type)) {
+        ngx_http_proxy_finalize_request(p,
+                                        ngx_http_proxy_send_cached_response(p));
+        return;
+    }
+    
+    ngx_http_proxy_finalize_request(p, NGX_HTTP_SERVICE_UNAVAILABLE);
+}
+
+
+static void ngx_http_proxy_cache_look_complete_request(ngx_http_proxy_ctx_t *p)
+{
+    int                    rc;
+    ngx_http_cache_ctx_t  *ctx;
+
+    if (!(ctx = ngx_pcalloc(p->request->pool, sizeof(ngx_http_cache_ctx_t)))) {
+        ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return;
+    }
+
+    *ctx = p->cache->ctx;
+
+    rc = ngx_http_cache_open_file(p->request, ctx,
+                                  ngx_file_uniq(p->cache->ctx.file.info));
+
+    if (rc == NGX_HTTP_CACHE_THE_SAME) {
+        p->try_busy_lock = 1;
+        p->busy_lock.time = 0;
+        ngx_http_proxy_cache_busy_lock(p);
+        return;
+    }
+
+ngx_log_debug(p->request->connection->log, "OLD: %d, NEW: %d" _
+              p->cache->ctx.file.fd _ ctx->file.fd);
+
+    if (p->cache->ctx.file.fd != NGX_INVALID_FILE) {
+        if (ngx_close_file(p->cache->ctx.file.fd) == NGX_FILE_ERROR) {
+            ngx_log_error(NGX_LOG_ALERT, p->request->connection->log, ngx_errno,
+                          ngx_close_file_n " \"%s\" failed",
+                          p->cache->ctx.file.name.data);
         }
     }
 
-    rc == NGX_ERROR
-    check waitn
+    p->cache->ctx = *ctx;
+
+    p->status = 0;
+    p->status_count = 0;
+
+    ngx_http_proxy_finalize_request(p,
+                                ngx_http_proxy_process_cached_response(p, rc));
 }
 
-#endif
-
 
 int ngx_http_proxy_send_cached_response(ngx_http_proxy_ctx_t *p)
 {
@@ -435,8 +544,8 @@ int ngx_http_proxy_is_cachable(ngx_http_
         /* FIXME: time_t == int_64_t, we can use fpu */ 
 
         p->state->reason = NGX_HTTP_PROXY_CACHE_LMF;
-        p->cache->ctx.expires = ngx_time()
-              + (((int64_t) (date - last_modified)) * p->lcf->lm_factor) / 100;
+        p->cache->ctx.expires = (time_t) (ngx_time()
+             + (((int64_t) (date - last_modified)) * p->lcf->lm_factor) / 100);
         return 1;
     }
 
@@ -460,6 +569,9 @@ int ngx_http_proxy_update_cache(ngx_http
 
     ep = p->upstream->event_pipe;
 
+ngx_log_debug(p->request->connection->log, "LEN: " OFF_FMT ", " OFF_FMT _
+              p->cache->ctx.length _ ep->read_length);
+
     if (p->cache->ctx.length == -1) {
         /* TODO: test rc */
         ngx_write_file(&ep->temp_file->file,