changeset 1602:55c8aede41f5

refactor index module: remove context
author Igor Sysoev <igor@sysoev.ru>
date Tue, 23 Oct 2007 14:16:00 +0000
parents cba2bb1796e4
children 364587232429
files src/http/modules/ngx_http_index_module.c
diffstat 1 files changed, 58 insertions(+), 91 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/modules/ngx_http_index_module.c
+++ b/src/http/modules/ngx_http_index_module.c
@@ -22,25 +22,13 @@ typedef struct {
 } ngx_http_index_loc_conf_t;
 
 
-typedef struct {
-    ngx_uint_t               current;
-
-    ngx_str_t                path;
-    ngx_str_t                index;
-
-    size_t                   root;
-
-    ngx_uint_t               tested;     /* unsigned  tested:1 */
-} ngx_http_index_ctx_t;
-
-
 #define NGX_HTTP_DEFAULT_INDEX   "index.html"
 
 
 static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r,
-    ngx_http_core_loc_conf_t *clcf, ngx_http_index_ctx_t *ctx);
-static ngx_int_t ngx_http_index_error(ngx_http_request_t *r,
-    ngx_http_index_ctx_t *ctx, ngx_err_t err);
+    ngx_http_core_loc_conf_t *clcf, u_char *path, u_char *last);
+static ngx_int_t ngx_http_index_error(ngx_http_request_t *r, u_char *file,
+    ngx_err_t err);
 
 static ngx_int_t ngx_http_index_init(ngx_conf_t *cf);
 static void *ngx_http_index_create_loc_conf(ngx_conf_t *cf);
@@ -107,14 +95,13 @@ ngx_module_t  ngx_http_index_module = {
 static ngx_int_t
 ngx_http_index_handler(ngx_http_request_t *r)
 {
-    u_char                       *last;
-    size_t                        len;
+    u_char                       *p, *name;
+    size_t                        len, nlen, root, allocated;
     ngx_int_t                     rc;
     ngx_str_t                     path, uri;
     ngx_log_t                    *log;
-    ngx_uint_t                    i;
+    ngx_uint_t                    i, dir_tested;
     ngx_http_index_t             *index;
-    ngx_http_index_ctx_t         *ctx;
     ngx_open_file_info_t          of;
     ngx_http_script_code_pt       code;
     ngx_http_script_engine_t      e;
@@ -140,24 +127,14 @@ ngx_http_index_handler(ngx_http_request_
     ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module);
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
-    /*
-     * we use context because the handler supports an async file opening,
-     * and may be called several times
-     */
-
-    ctx = ngx_http_get_module_ctx(r, ngx_http_index_module);
-    if (ctx == NULL) {
-
-        ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_index_ctx_t));
-        if (ctx == NULL) {
-            return NGX_HTTP_INTERNAL_SERVER_ERROR;
-        }
-
-        ngx_http_set_ctx(r, ctx, ngx_http_index_module);
-    }
+    allocated = 0;
+    root = 0;
+    dir_tested = 0;
+    name = NULL;
+    path.data = NULL;
 
     index = ilcf->indices->elts;
-    for (i = ctx->current; i < ilcf->indices->nelts; i++) {
+    for (i = 0; i < ilcf->indices->nelts; i++) {
 
         if (index[i].lengths == NULL) {
 
@@ -166,7 +143,7 @@ ngx_http_index_handler(ngx_http_request_
             }
 
             len = ilcf->max_index_len;
-            ctx->index.len = index[i].name.len;
+            nlen = index[i].name.len;
 
         } else {
             ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
@@ -184,45 +161,44 @@ ngx_http_index_handler(ngx_http_request_
                 len += lcode(&e);
             }
 
-            ctx->index.len = len;
+            nlen = len;
 
             /* 16 bytes are preallocation */
 
             len += 16;
         }
 
-        if (len > (size_t) (ctx->path.data + ctx->path.len - ctx->index.data)) {
+        if (len > (size_t) (path.data + allocated - name)) {
 
-            last = ngx_http_map_uri_to_path(r, &ctx->path, &ctx->root, len);
-            if (last == NULL) {
+            name = ngx_http_map_uri_to_path(r, &path, &root, len);
+            if (name == NULL) {
                 return NGX_ERROR;
             }
 
-            ctx->index.data = last;
+            allocated = path.len;
         }
 
-        path.data = ctx->path.data;
-
         if (index[i].values == NULL) {
 
             /* index[i].name.len includes the terminating '\0' */
 
-            ngx_memcpy(ctx->index.data, index[i].name.data, index[i].name.len);
+            ngx_memcpy(name, index[i].name.data, index[i].name.len);
 
-            path.len = (ctx->index.data + index[i].name.len - 1) - path.data;
+            path.len = (name + index[i].name.len - 1) - path.data;
 
         } else {
             e.ip = index[i].values->elts;
-            e.pos = ctx->index.data;
+            e.pos = name;
 
             while (*(uintptr_t *) e.ip) {
                 code = *(ngx_http_script_code_pt *) e.ip;
                 code((ngx_http_script_engine_t *) &e);
             }
 
-            if (*ctx->index.data == '/') {
-                ctx->index.len--;
-                return ngx_http_internal_redirect(r, &ctx->index, &r->args);
+            if (*name == '/') {
+                uri.len = nlen - 1;
+                uri.data = name;
+                return ngx_http_internal_redirect(r, &uri, &r->args);
             }
 
             path.len = e.pos - path.data;
@@ -230,8 +206,7 @@ ngx_http_index_handler(ngx_http_request_
             *e.pos++ = '\0';
         }
 
-        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
-                       "open index \"%V\"", &path);
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "open index \"%V\"", &path);
 
         of.test_dir = 0;
         of.retest = clcf->open_file_cache_retest;
@@ -240,37 +215,27 @@ ngx_http_index_handler(ngx_http_request_
 
         rc = ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool);
 
-#if 0
-        if (rc == NGX_AGAIN) {
-            ctx->current = i;
-            return NGX_AGAIN;
-        }
-#endif
-
         if (rc == NGX_ERROR) {
 
             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, of.err,
-                           ngx_open_file_n " \"%s\" failed", ctx->path.data);
+                           ngx_open_file_n " \"%s\" failed", path.data);
 
             if (of.err == 0) {
                 return NGX_HTTP_INTERNAL_SERVER_ERROR;
             }
 
-            if (of.err == NGX_ENOTDIR) {
-                return ngx_http_index_error(r, ctx, of.err);
-
-            } else if (of.err == NGX_EACCES) {
-                return ngx_http_index_error(r, ctx, of.err);
+            if (of.err == NGX_ENOTDIR || of.err == NGX_EACCES) {
+                return ngx_http_index_error(r, path.data, of.err);
             }
 
-            if (!ctx->tested) {
-                rc = ngx_http_index_test_dir(r, clcf, ctx);
+            if (!dir_tested) {
+                rc = ngx_http_index_test_dir(r, clcf, path.data, name - 1);
 
                 if (rc != NGX_OK) {
                     return rc;
                 }
 
-                ctx->tested = 1;
+                dir_tested = 1;
             }
 
             if (of.err == NGX_ENOENT) {
@@ -278,15 +243,15 @@ ngx_http_index_handler(ngx_http_request_
             }
 
             ngx_log_error(NGX_LOG_ERR, log, of.err,
-                          ngx_open_file_n " \"%s\" failed", ctx->path.data);
+                          ngx_open_file_n " \"%s\" failed", path.data);
 
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
 
-        uri.len = r->uri.len + ctx->index.len - 1;
+        uri.len = r->uri.len + nlen - 1;
 
         if (!clcf->alias) {
-            uri.data = ctx->path.data + ctx->root;
+            uri.data = path.data + root;
 
         } else {
             uri.data = ngx_palloc(r->pool, uri.len);
@@ -294,8 +259,8 @@ ngx_http_index_handler(ngx_http_request_
                 return NGX_HTTP_INTERNAL_SERVER_ERROR;
             }
 
-            last = ngx_copy(uri.data, r->uri.data, r->uri.len);
-            ngx_memcpy(last, ctx->index.data, ctx->index.len - 1);
+            p = ngx_copy(uri.data, r->uri.data, r->uri.len);
+            ngx_memcpy(p, name, nlen - 1);
         }
 
         return ngx_http_internal_redirect(r, &uri, &r->args);
@@ -307,70 +272,71 @@ ngx_http_index_handler(ngx_http_request_
 
 static ngx_int_t
 ngx_http_index_test_dir(ngx_http_request_t *r, ngx_http_core_loc_conf_t *clcf,
-    ngx_http_index_ctx_t *ctx)
+    u_char *path, u_char *last)
 {
     u_char                c;
-    ngx_str_t             path;
-    ngx_uint_t            i;
+    ngx_str_t             dir;
     ngx_open_file_info_t  of;
 
-    c = *(ctx->index.data - 1);
-    i = (c == '/') ? 1 : 0;
-    *(ctx->index.data - i) = '\0';
+    c = *last;
+    if (c != '/') {
+        /* "alias" without trailing slash */
+        c = *(++last);
+    }
+    *last = '\0';
 
-    path.len = (ctx->index.data - i) - ctx->path.data;
-    path.data = ctx->path.data;
+    dir.len = last - path;
+    dir.data = path;
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                   "http index check dir: \"%V\"", &path);
+                   "http index check dir: \"%V\"", &dir);
 
     of.test_dir = 1;
     of.retest = clcf->open_file_cache_retest;
     of.errors = clcf->open_file_cache_errors;
 
-    if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
+    if (ngx_open_cached_file(clcf->open_file_cache, &dir, &of, r->pool)
         != NGX_OK)
     {
         if (of.err) {
 
             if (of.err == NGX_ENOENT) {
-                *(ctx->index.data - i) = c;
-                return ngx_http_index_error(r, ctx, of.err);
+                *last = c;
+                return ngx_http_index_error(r, dir.data, NGX_ENOENT);
             }
 
             ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
-                          ngx_open_file_n " \"%s\" failed", path.data);
+                          ngx_open_file_n " \"%s\" failed", dir.data);
         }
 
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
-    *(ctx->index.data - i) = c;
+    *last = c;
 
     if (of.is_dir) {
         return NGX_OK;
     }
 
     ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
-                  "\"%s\" is not a directory", path.data);
+                  "\"%s\" is not a directory", dir.data);
 
     return NGX_HTTP_INTERNAL_SERVER_ERROR;
 }
 
 
 static ngx_int_t
-ngx_http_index_error(ngx_http_request_t *r, ngx_http_index_ctx_t *ctx,
-    ngx_err_t err)
+ngx_http_index_error(ngx_http_request_t *r, u_char *file, ngx_err_t err)
 {
     if (err == NGX_EACCES) {
         ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
-                      "\"%s\" is forbidden", ctx->path.data);
+                      "\"%s\" is forbidden", file);
 
         return NGX_HTTP_FORBIDDEN;
     }
 
     ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
-                  "\"%s\" is not found", ctx->path.data);
+                  "\"%s\" is not found", file);
 
     return NGX_HTTP_NOT_FOUND;
 }
@@ -472,6 +438,7 @@ ngx_http_index_set_index(ngx_conf_t *cf,
     value = cf->args->elts;
 
     for (i = 1; i < cf->args->nelts; i++) {
+
         if (value[i].data[0] == '/' && i != cf->args->nelts - 1) {
             ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
                                "only the last index in \"index\" directive "