Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 1 | |
Igor Sysoev | 7578ec9 | 2003-06-02 15:24:30 +0000 | [diff] [blame] | 2 | #include <ngx_config.h> |
| 3 | #include <ngx_core.h> |
| 4 | #include <ngx_http.h> |
| 5 | |
| 6 | |
| 7 | typedef struct { |
| 8 | ngx_array_t indices; |
| 9 | size_t max_index_len; |
| 10 | } ngx_http_index_conf_t; |
| 11 | |
| 12 | |
| 13 | #define NGX_HTTP_DEFAULT_INDEX "index.html" |
Igor Sysoev | e0268b9 | 2002-09-11 15:18:33 +0000 | [diff] [blame] | 14 | |
| 15 | |
Igor Sysoev | e79c6ac | 2003-01-10 17:45:47 +0000 | [diff] [blame] | 16 | static int ngx_http_index_test_dir(ngx_http_request_t *r); |
Igor Sysoev | b262063 | 2003-01-10 06:09:20 +0000 | [diff] [blame] | 17 | static int ngx_http_index_init(ngx_pool_t *pool); |
Igor Sysoev | e0268b9 | 2002-09-11 15:18:33 +0000 | [diff] [blame] | 18 | static void *ngx_http_index_create_conf(ngx_pool_t *pool); |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 19 | static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, |
| 20 | void *child); |
Igor Sysoev | 207ed5a | 2002-12-26 16:26:23 +0000 | [diff] [blame] | 21 | static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 22 | void *conf); |
Igor Sysoev | e0268b9 | 2002-09-11 15:18:33 +0000 | [diff] [blame] | 23 | |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame] | 24 | |
| 25 | static ngx_command_t ngx_http_index_commands[] = { |
| 26 | |
Igor Sysoev | 207ed5a | 2002-12-26 16:26:23 +0000 | [diff] [blame] | 27 | {ngx_string("index"), |
Igor Sysoev | 7578ec9 | 2003-06-02 15:24:30 +0000 | [diff] [blame] | 28 | NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
Igor Sysoev | 207ed5a | 2002-12-26 16:26:23 +0000 | [diff] [blame] | 29 | ngx_http_index_set_index, |
Igor Sysoev | e79c6ac | 2003-01-10 17:45:47 +0000 | [diff] [blame] | 30 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | 6ddfbf0 | 2003-05-15 15:42:53 +0000 | [diff] [blame] | 31 | 0, |
| 32 | NULL}, |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame] | 33 | |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 34 | ngx_null_command |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame] | 35 | }; |
Igor Sysoev | e0268b9 | 2002-09-11 15:18:33 +0000 | [diff] [blame] | 36 | |
| 37 | |
Igor Sysoev | 207ed5a | 2002-12-26 16:26:23 +0000 | [diff] [blame] | 38 | ngx_http_module_t ngx_http_index_module_ctx = { |
Igor Sysoev | a983011 | 2003-05-19 16:39:14 +0000 | [diff] [blame] | 39 | NULL, /* create main configuration */ |
| 40 | NULL, /* init main configuration */ |
Igor Sysoev | dc479b4 | 2003-03-20 16:09:44 +0000 | [diff] [blame] | 41 | |
Igor Sysoev | a983011 | 2003-05-19 16:39:14 +0000 | [diff] [blame] | 42 | NULL, /* create server configuration */ |
| 43 | NULL, /* merge server configuration */ |
| 44 | |
| 45 | ngx_http_index_create_conf, /* create location configration */ |
| 46 | ngx_http_index_merge_conf /* merge location configration */ |
Igor Sysoev | 207ed5a | 2002-12-26 16:26:23 +0000 | [diff] [blame] | 47 | }; |
| 48 | |
| 49 | |
| 50 | ngx_module_t ngx_http_index_module = { |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 51 | NGX_MODULE, |
Igor Sysoev | 207ed5a | 2002-12-26 16:26:23 +0000 | [diff] [blame] | 52 | &ngx_http_index_module_ctx, /* module context */ |
| 53 | ngx_http_index_commands, /* module directives */ |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 54 | NGX_HTTP_MODULE, /* module type */ |
Igor Sysoev | b262063 | 2003-01-10 06:09:20 +0000 | [diff] [blame] | 55 | ngx_http_index_init /* init module */ |
Igor Sysoev | e0268b9 | 2002-09-11 15:18:33 +0000 | [diff] [blame] | 56 | }; |
| 57 | |
| 58 | |
Igor Sysoev | e79c6ac | 2003-01-10 17:45:47 +0000 | [diff] [blame] | 59 | /* |
Igor Sysoev | 7578ec9 | 2003-06-02 15:24:30 +0000 | [diff] [blame] | 60 | Try to open the first index file before the directory existence test |
| 61 | because the valid requests should be many more than invalid ones. |
Igor Sysoev | de8fcea | 2003-01-19 17:53:14 +0000 | [diff] [blame] | 62 | If open() failed then stat() should be more quickly because some data |
Igor Sysoev | fd67586 | 2003-04-11 16:01:14 +0000 | [diff] [blame] | 63 | is already cached in the kernel. |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 64 | Besides Win32 has ERROR_PATH_NOT_FOUND (NGX_ENOTDIR). |
| 65 | Unix has ENOTDIR error, although it less helpfull - it shows only |
| 66 | that path contains the usual file in place of the directory. |
Igor Sysoev | e79c6ac | 2003-01-10 17:45:47 +0000 | [diff] [blame] | 67 | */ |
| 68 | |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 69 | int ngx_http_index_handler(ngx_http_request_t *r) |
| 70 | { |
Igor Sysoev | 7578ec9 | 2003-06-02 15:24:30 +0000 | [diff] [blame] | 71 | int i, rc, test_dir, path_not_found; |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 72 | char *name, *file; |
Igor Sysoev | 1393325 | 2003-05-29 13:02:09 +0000 | [diff] [blame] | 73 | ngx_str_t redirect, *index; |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 74 | ngx_err_t err; |
| 75 | ngx_fd_t fd; |
| 76 | ngx_http_index_conf_t *icf; |
| 77 | ngx_http_core_loc_conf_t *clcf; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 78 | |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 79 | icf = ngx_http_get_module_loc_conf(r, ngx_http_index_module); |
| 80 | clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
Igor Sysoev | 4e9393a | 2003-01-09 05:36:00 +0000 | [diff] [blame] | 81 | |
Igor Sysoev | b262063 | 2003-01-10 06:09:20 +0000 | [diff] [blame] | 82 | ngx_test_null(r->path.data, |
Igor Sysoev | b086905 | 2002-12-10 18:05:12 +0000 | [diff] [blame] | 83 | ngx_palloc(r->pool, |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 84 | clcf->doc_root.len + r->uri.len |
| 85 | + icf->max_index_len), |
Igor Sysoev | 0c331d9 | 2002-08-15 17:20:26 +0000 | [diff] [blame] | 86 | NGX_HTTP_INTERNAL_SERVER_ERROR); |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 87 | |
Igor Sysoev | 1393325 | 2003-05-29 13:02:09 +0000 | [diff] [blame] | 88 | redirect.data = ngx_cpymem(r->path.data, clcf->doc_root.data, |
| 89 | clcf->doc_root.len); |
| 90 | file = ngx_cpystrn(redirect.data, r->uri.data, r->uri.len + 1); |
Igor Sysoev | b262063 | 2003-01-10 06:09:20 +0000 | [diff] [blame] | 91 | r->path.len = file - r->path.data; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 92 | |
Igor Sysoev | ad22e01 | 2003-01-15 07:02:27 +0000 | [diff] [blame] | 93 | test_dir = 1; |
Igor Sysoev | 7578ec9 | 2003-06-02 15:24:30 +0000 | [diff] [blame] | 94 | path_not_found = 1; |
Igor Sysoev | e79c6ac | 2003-01-10 17:45:47 +0000 | [diff] [blame] | 95 | |
Igor Sysoev | 1393325 | 2003-05-29 13:02:09 +0000 | [diff] [blame] | 96 | index = icf->indices.elts; |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 97 | for (i = 0; i < icf->indices.nelts; i++) { |
Igor Sysoev | b262063 | 2003-01-10 06:09:20 +0000 | [diff] [blame] | 98 | |
| 99 | if (index[i].data[0] != '/') { |
Igor Sysoev | b262063 | 2003-01-10 06:09:20 +0000 | [diff] [blame] | 100 | ngx_memcpy(file, index[i].data, index[i].len + 1); |
| 101 | name = r->path.data; |
| 102 | |
| 103 | } else { |
| 104 | name = index[i].data; |
| 105 | } |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 106 | |
Igor Sysoev | 7578ec9 | 2003-06-02 15:24:30 +0000 | [diff] [blame] | 107 | fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN); |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame] | 108 | if (fd == NGX_INVALID_FILE) { |
Igor Sysoev | e0268b9 | 2002-09-11 15:18:33 +0000 | [diff] [blame] | 109 | err = ngx_errno; |
Igor Sysoev | e79c6ac | 2003-01-10 17:45:47 +0000 | [diff] [blame] | 110 | |
Igor Sysoev | ad22e01 | 2003-01-15 07:02:27 +0000 | [diff] [blame] | 111 | ngx_log_error(NGX_LOG_DEBUG, r->connection->log, err, |
| 112 | "DEBUG: " ngx_open_file_n " %s failed", name); |
Igor Sysoev | e79c6ac | 2003-01-10 17:45:47 +0000 | [diff] [blame] | 113 | |
Igor Sysoev | e79c6ac | 2003-01-10 17:45:47 +0000 | [diff] [blame] | 114 | if (err == NGX_ENOTDIR) { |
Igor Sysoev | 7578ec9 | 2003-06-02 15:24:30 +0000 | [diff] [blame] | 115 | path_not_found = 1; |
Igor Sysoev | ad22e01 | 2003-01-15 07:02:27 +0000 | [diff] [blame] | 116 | |
| 117 | } else if (err == NGX_EACCES) { |
| 118 | r->path_err = err; |
| 119 | return NGX_HTTP_FORBIDDEN; |
Igor Sysoev | e79c6ac | 2003-01-10 17:45:47 +0000 | [diff] [blame] | 120 | } |
| 121 | |
| 122 | if (test_dir) { |
Igor Sysoev | 7578ec9 | 2003-06-02 15:24:30 +0000 | [diff] [blame] | 123 | if (path_not_found) { |
Igor Sysoev | ad22e01 | 2003-01-15 07:02:27 +0000 | [diff] [blame] | 124 | r->path_err = err; |
Igor Sysoev | e79c6ac | 2003-01-10 17:45:47 +0000 | [diff] [blame] | 125 | return NGX_HTTP_NOT_FOUND; |
| 126 | } |
| 127 | |
| 128 | rc = ngx_http_index_test_dir(r); |
| 129 | if (rc != NGX_OK) { |
| 130 | return rc; |
| 131 | } |
| 132 | |
| 133 | test_dir = 0; |
Igor Sysoev | e79c6ac | 2003-01-10 17:45:47 +0000 | [diff] [blame] | 134 | } |
| 135 | |
Igor Sysoev | 207ed5a | 2002-12-26 16:26:23 +0000 | [diff] [blame] | 136 | if (err == NGX_ENOENT) { |
Igor Sysoev | e0268b9 | 2002-09-11 15:18:33 +0000 | [diff] [blame] | 137 | continue; |
Igor Sysoev | 207ed5a | 2002-12-26 16:26:23 +0000 | [diff] [blame] | 138 | } |
Igor Sysoev | e0268b9 | 2002-09-11 15:18:33 +0000 | [diff] [blame] | 139 | |
| 140 | ngx_log_error(NGX_LOG_ERR, r->connection->log, err, |
| 141 | ngx_open_file_n " %s failed", name); |
| 142 | |
| 143 | return NGX_HTTP_INTERNAL_SERVER_ERROR; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 144 | } |
Igor Sysoev | e0268b9 | 2002-09-11 15:18:33 +0000 | [diff] [blame] | 145 | |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 146 | r->file.name.data = name; |
| 147 | r->file.fd = fd; |
Igor Sysoev | e0268b9 | 2002-09-11 15:18:33 +0000 | [diff] [blame] | 148 | |
Igor Sysoev | b262063 | 2003-01-10 06:09:20 +0000 | [diff] [blame] | 149 | if (index[i].data[0] == '/') { |
| 150 | r->file.name.len = index[i].len; |
Igor Sysoev | 1393325 | 2003-05-29 13:02:09 +0000 | [diff] [blame] | 151 | redirect.len = index[i].len; |
| 152 | redirect.data = index[i].data; |
Igor Sysoev | b262063 | 2003-01-10 06:09:20 +0000 | [diff] [blame] | 153 | |
| 154 | } else { |
Igor Sysoev | 1393325 | 2003-05-29 13:02:09 +0000 | [diff] [blame] | 155 | redirect.len = r->uri.len + index[i].len; |
| 156 | r->file.name.len = clcf->doc_root.len + r->uri.len + index[i].len; |
Igor Sysoev | b262063 | 2003-01-10 06:09:20 +0000 | [diff] [blame] | 157 | } |
| 158 | |
Igor Sysoev | 1393325 | 2003-05-29 13:02:09 +0000 | [diff] [blame] | 159 | return ngx_http_internal_redirect(r, &redirect, NULL); |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 160 | } |
| 161 | |
Igor Sysoev | e0268b9 | 2002-09-11 15:18:33 +0000 | [diff] [blame] | 162 | return NGX_DECLINED; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 163 | } |
| 164 | |
Igor Sysoev | b086905 | 2002-12-10 18:05:12 +0000 | [diff] [blame] | 165 | |
Igor Sysoev | e79c6ac | 2003-01-10 17:45:47 +0000 | [diff] [blame] | 166 | static int ngx_http_index_test_dir(ngx_http_request_t *r) |
| 167 | { |
Igor Sysoev | e79c6ac | 2003-01-10 17:45:47 +0000 | [diff] [blame] | 168 | r->path.data[r->path.len - 1] = '\0'; |
Igor Sysoev | ad22e01 | 2003-01-15 07:02:27 +0000 | [diff] [blame] | 169 | r->path.data[r->path.len] = '\0'; |
Igor Sysoev | e79c6ac | 2003-01-10 17:45:47 +0000 | [diff] [blame] | 170 | |
| 171 | ngx_log_debug(r->connection->log, "IS_DIR: %s" _ r->path.data); |
| 172 | |
Igor Sysoev | ad22e01 | 2003-01-15 07:02:27 +0000 | [diff] [blame] | 173 | #if 0 |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 174 | if (r->path_err == NGX_EACCES) { |
| 175 | return NGX_HTTP_FORBIDDEN; |
| 176 | } |
Igor Sysoev | ad22e01 | 2003-01-15 07:02:27 +0000 | [diff] [blame] | 177 | #endif |
| 178 | |
Igor Sysoev | e79c6ac | 2003-01-10 17:45:47 +0000 | [diff] [blame] | 179 | if (ngx_file_type(r->path.data, &r->file.info) == -1) { |
Igor Sysoev | ad22e01 | 2003-01-15 07:02:27 +0000 | [diff] [blame] | 180 | |
| 181 | r->path_err = ngx_errno; |
| 182 | |
| 183 | if (r->path_err == NGX_ENOENT) { |
| 184 | r->path.data[r->path.len - 1] = '/'; |
Igor Sysoev | e79c6ac | 2003-01-10 17:45:47 +0000 | [diff] [blame] | 185 | return NGX_HTTP_NOT_FOUND; |
| 186 | } |
| 187 | |
Igor Sysoev | ad22e01 | 2003-01-15 07:02:27 +0000 | [diff] [blame] | 188 | ngx_log_error(NGX_LOG_CRIT, r->connection->log, r->path_err, |
Igor Sysoev | ad22e01 | 2003-01-15 07:02:27 +0000 | [diff] [blame] | 189 | ngx_file_type_n " %s failed", r->path.data); |
Igor Sysoev | e79c6ac | 2003-01-10 17:45:47 +0000 | [diff] [blame] | 190 | |
| 191 | return NGX_HTTP_INTERNAL_SERVER_ERROR; |
| 192 | } |
| 193 | |
Igor Sysoev | ad22e01 | 2003-01-15 07:02:27 +0000 | [diff] [blame] | 194 | r->path.data[r->path.len - 1] = '/'; |
| 195 | |
Igor Sysoev | e79c6ac | 2003-01-10 17:45:47 +0000 | [diff] [blame] | 196 | if (ngx_is_dir(r->file.info)) { |
Igor Sysoev | e79c6ac | 2003-01-10 17:45:47 +0000 | [diff] [blame] | 197 | return NGX_OK; |
| 198 | |
| 199 | } else { |
| 200 | return NGX_HTTP_NOT_FOUND; |
| 201 | } |
| 202 | } |
| 203 | |
| 204 | |
Igor Sysoev | b262063 | 2003-01-10 06:09:20 +0000 | [diff] [blame] | 205 | static int ngx_http_index_init(ngx_pool_t *pool) |
| 206 | { |
| 207 | ngx_http_handler_pt *h; |
| 208 | |
| 209 | ngx_test_null(h, ngx_push_array(&ngx_http_index_handlers), NGX_ERROR); |
| 210 | |
| 211 | *h = ngx_http_index_handler; |
| 212 | |
| 213 | return NGX_OK; |
| 214 | } |
| 215 | |
| 216 | |
Igor Sysoev | e0268b9 | 2002-09-11 15:18:33 +0000 | [diff] [blame] | 217 | static void *ngx_http_index_create_conf(ngx_pool_t *pool) |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 218 | { |
Igor Sysoev | e0268b9 | 2002-09-11 15:18:33 +0000 | [diff] [blame] | 219 | ngx_http_index_conf_t *conf; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 220 | |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 221 | ngx_test_null(conf, ngx_palloc(pool, sizeof(ngx_http_index_conf_t)), |
Igor Sysoev | 4e9393a | 2003-01-09 05:36:00 +0000 | [diff] [blame] | 222 | NGX_CONF_ERROR); |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 223 | |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 224 | ngx_init_array(conf->indices, pool, 3, sizeof(ngx_str_t), NGX_CONF_ERROR); |
| 225 | conf->max_index_len = 0; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 226 | |
Igor Sysoev | e0268b9 | 2002-09-11 15:18:33 +0000 | [diff] [blame] | 227 | return conf; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 228 | } |
| 229 | |
Igor Sysoev | b086905 | 2002-12-10 18:05:12 +0000 | [diff] [blame] | 230 | |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 231 | /* TODO: remove duplicate indices */ |
| 232 | |
Igor Sysoev | 4e9393a | 2003-01-09 05:36:00 +0000 | [diff] [blame] | 233 | static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child) |
| 234 | { |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 235 | ngx_http_index_conf_t *prev = parent; |
| 236 | ngx_http_index_conf_t *conf = child; |
Igor Sysoev | 4e9393a | 2003-01-09 05:36:00 +0000 | [diff] [blame] | 237 | |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 238 | int i; |
| 239 | ngx_str_t *index, *prev_index; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 240 | |
Igor Sysoev | e0268b9 | 2002-09-11 15:18:33 +0000 | [diff] [blame] | 241 | if (conf->max_index_len == 0) { |
Igor Sysoev | 207ed5a | 2002-12-26 16:26:23 +0000 | [diff] [blame] | 242 | if (prev->max_index_len != 0) { |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 243 | ngx_memcpy(conf, prev, sizeof(ngx_http_index_conf_t)); |
| 244 | return NGX_CONF_OK; |
Igor Sysoev | 207ed5a | 2002-12-26 16:26:23 +0000 | [diff] [blame] | 245 | } |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 246 | |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 247 | ngx_test_null(index, ngx_push_array(&conf->indices), NGX_CONF_ERROR); |
| 248 | index->len = sizeof(NGX_HTTP_DEFAULT_INDEX) - 1; |
| 249 | index->data = NGX_HTTP_DEFAULT_INDEX; |
| 250 | conf->max_index_len = sizeof(NGX_HTTP_DEFAULT_INDEX); |
| 251 | |
| 252 | return NGX_CONF_OK; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 253 | } |
Igor Sysoev | e0268b9 | 2002-09-11 15:18:33 +0000 | [diff] [blame] | 254 | |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 255 | if (prev->max_index_len != 0) { |
| 256 | |
| 257 | prev_index = prev->indices.elts; |
| 258 | for (i = 0; i < prev->indices.nelts; i++) { |
| 259 | ngx_test_null(index, ngx_push_array(&conf->indices), |
| 260 | NGX_CONF_ERROR); |
| 261 | index->len = prev_index[i].len; |
| 262 | index->data = prev_index[i].data; |
| 263 | } |
| 264 | } |
| 265 | |
| 266 | if (conf->max_index_len < prev->max_index_len) { |
| 267 | conf->max_index_len = prev->max_index_len; |
| 268 | } |
| 269 | |
| 270 | return NGX_CONF_OK; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 271 | } |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 272 | |
| 273 | |
Igor Sysoev | 1393325 | 2003-05-29 13:02:09 +0000 | [diff] [blame] | 274 | /* TODO: warn about duplicate indices */ |
Igor Sysoev | b086905 | 2002-12-10 18:05:12 +0000 | [diff] [blame] | 275 | |
Igor Sysoev | 207ed5a | 2002-12-26 16:26:23 +0000 | [diff] [blame] | 276 | static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 277 | void *conf) |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 278 | { |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 279 | ngx_http_index_conf_t *icf = conf; |
| 280 | |
| 281 | int i; |
Igor Sysoev | 207ed5a | 2002-12-26 16:26:23 +0000 | [diff] [blame] | 282 | ngx_str_t *index, *value; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 283 | |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 284 | value = cf->args->elts; |
| 285 | |
| 286 | if (value[1].data[0] == '/' && icf->indices.nelts == 0) { |
| 287 | ngx_snprintf(ngx_conf_errstr, sizeof(ngx_conf_errstr) - 1, |
| 288 | "first index \"%s\" must not be absolute", value[1].data); |
| 289 | return ngx_conf_errstr; |
| 290 | } |
| 291 | |
Igor Sysoev | 207ed5a | 2002-12-26 16:26:23 +0000 | [diff] [blame] | 292 | for (i = 1; i < cf->args->nelts; i++) { |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 293 | if (value[i].len == 0) { |
Igor Sysoev | 1393325 | 2003-05-29 13:02:09 +0000 | [diff] [blame] | 294 | ngx_snprintf(ngx_conf_errstr, sizeof(ngx_conf_errstr) - 1, |
Igor Sysoev | aa3436c | 2003-05-30 14:27:59 +0000 | [diff] [blame] | 295 | "index \"%s\" is invalid", value[i].data); |
Igor Sysoev | 1393325 | 2003-05-29 13:02:09 +0000 | [diff] [blame] | 296 | return ngx_conf_errstr; |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 297 | } |
| 298 | |
| 299 | ngx_test_null(index, ngx_push_array(&icf->indices), NGX_CONF_ERROR); |
Igor Sysoev | 207ed5a | 2002-12-26 16:26:23 +0000 | [diff] [blame] | 300 | index->len = value[i].len; |
| 301 | index->data = value[i].data; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 302 | |
Igor Sysoev | 6253ca1 | 2003-05-27 12:18:54 +0000 | [diff] [blame] | 303 | if (icf->max_index_len < index->len + 1) { |
| 304 | icf->max_index_len = index->len + 1; |
Igor Sysoev | 207ed5a | 2002-12-26 16:26:23 +0000 | [diff] [blame] | 305 | } |
| 306 | } |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 307 | |
Igor Sysoev | 1393325 | 2003-05-29 13:02:09 +0000 | [diff] [blame] | 308 | return NGX_CONF_OK; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 309 | } |