Mercurial > hg > nginx
comparison src/http/modules/ngx_http_index_handler.c @ 46:f84a648211f4
nginx-0.0.1-2003-01-10-20:45:47 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 10 Jan 2003 17:45:47 +0000 |
parents | f1ee46c036a4 |
children | d81326c3b21b |
comparison
equal
deleted
inserted
replaced
45:f1ee46c036a4 | 46:f84a648211f4 |
---|---|
11 #include <ngx_http_config.h> | 11 #include <ngx_http_config.h> |
12 #include <ngx_http_core_module.h> | 12 #include <ngx_http_core_module.h> |
13 #include <ngx_http_index_handler.h> | 13 #include <ngx_http_index_handler.h> |
14 | 14 |
15 | 15 |
16 static int ngx_http_index_test_dir(ngx_http_request_t *r); | |
16 static int ngx_http_index_init(ngx_pool_t *pool); | 17 static int ngx_http_index_init(ngx_pool_t *pool); |
17 static void *ngx_http_index_create_conf(ngx_pool_t *pool); | 18 static void *ngx_http_index_create_conf(ngx_pool_t *pool); |
18 static char *ngx_http_index_merge_conf(ngx_pool_t *p, | 19 static char *ngx_http_index_merge_conf(ngx_pool_t *p, |
19 void *parent, void *child); | 20 void *parent, void *child); |
20 static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, | 21 static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, |
22 | 23 |
23 | 24 |
24 static ngx_command_t ngx_http_index_commands[] = { | 25 static ngx_command_t ngx_http_index_commands[] = { |
25 | 26 |
26 {ngx_string("index"), | 27 {ngx_string("index"), |
27 NGX_CONF_ANY, | 28 NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_ANY, |
28 ngx_http_index_set_index, | 29 ngx_http_index_set_index, |
29 NGX_HTTP_LOC_CONF, | 30 NGX_HTTP_LOC_CONF_OFFSET, |
30 0}, | 31 0}, |
31 | 32 |
32 {ngx_string(""), 0, NULL, 0, 0} | 33 {ngx_string(""), 0, NULL, 0, 0} |
33 }; | 34 }; |
34 | 35 |
58 NGX_HTTP_MODULE_TYPE, /* module type */ | 59 NGX_HTTP_MODULE_TYPE, /* module type */ |
59 ngx_http_index_init /* init module */ | 60 ngx_http_index_init /* init module */ |
60 }; | 61 }; |
61 | 62 |
62 | 63 |
64 /* | |
65 If the first index file is local (i.e. 'index.html', not '/index.html') then | |
66 try to open it before the test of the directory existence because | |
67 the valid requests should be many more then invalid ones. If open() | |
68 is failed then stat() should be more quickly because some data | |
69 is already cached in the kernel. Besides Win32 has ERROR_PATH_NOT_FOUND | |
70 and Unix has ENOTDIR error (although it less helpfull). | |
71 */ | |
72 | |
63 int ngx_http_index_handler(ngx_http_request_t *r) | 73 int ngx_http_index_handler(ngx_http_request_t *r) |
64 { | 74 { |
65 int i, len; | 75 int i, rc, test_dir; |
66 char *name, *file; | 76 char *name, *file; |
67 ngx_str_t loc, *index; | 77 ngx_str_t loc, *index; |
68 ngx_err_t err; | 78 ngx_err_t err; |
69 ngx_fd_t fd; | 79 ngx_fd_t fd; |
70 | 80 |
71 ngx_http_index_conf_t *cf; | 81 ngx_http_index_conf_t *cf; |
72 ngx_http_core_loc_conf_t *core_cf; | 82 ngx_http_core_loc_conf_t *core_cf; |
73 | 83 |
74 cf = (ngx_http_index_conf_t *) | 84 cf = (ngx_http_index_conf_t *) |
75 ngx_http_get_module_loc_conf(r, ngx_http_index_module_ctx); | 85 ngx_http_get_module_loc_conf(r, ngx_http_index_module); |
76 | 86 |
77 core_cf = (ngx_http_core_loc_conf_t *) | 87 core_cf = (ngx_http_core_loc_conf_t *) |
78 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); | 88 ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
79 | 89 |
80 ngx_test_null(r->path.data, | 90 ngx_test_null(r->path.data, |
81 ngx_palloc(r->pool, | 91 ngx_palloc(r->pool, |
82 core_cf->doc_root.len + r->uri.len | 92 core_cf->doc_root.len + r->uri.len |
83 + cf->max_index_len), | 93 + cf->max_index_len), |
86 loc.data = ngx_cpystrn(r->path.data, core_cf->doc_root.data, | 96 loc.data = ngx_cpystrn(r->path.data, core_cf->doc_root.data, |
87 core_cf->doc_root.len + 1); | 97 core_cf->doc_root.len + 1); |
88 file = ngx_cpystrn(loc.data, r->uri.data, r->uri.len + 1); | 98 file = ngx_cpystrn(loc.data, r->uri.data, r->uri.len + 1); |
89 r->path.len = file - r->path.data; | 99 r->path.len = file - r->path.data; |
90 | 100 |
101 if (cf->test_dir) { | |
102 rc = ngx_http_index_test_dir(r); | |
103 if (rc != NGX_OK) { | |
104 return rc; | |
105 } | |
106 | |
107 test_dir = 0; | |
108 | |
109 } else { | |
110 test_dir = 1; | |
111 } | |
112 | |
91 index = (ngx_str_t *) cf->indices->elts; | 113 index = (ngx_str_t *) cf->indices->elts; |
92 for (i = 0; i < cf->indices->nelts; i++) { | 114 for (i = 0; i < cf->indices->nelts; i++) { |
93 | 115 |
94 if (index[i].data[0] != '/') { | 116 if (index[i].data[0] != '/') { |
95 if (!r->path_not_found) { | |
96 continue; | |
97 } | |
98 | |
99 ngx_memcpy(file, index[i].data, index[i].len + 1); | 117 ngx_memcpy(file, index[i].data, index[i].len + 1); |
100 name = r->path.data; | 118 name = r->path.data; |
101 | 119 |
102 } else { | 120 } else { |
103 name = index[i].data; | 121 name = index[i].data; |
104 } | 122 } |
105 | 123 |
106 fd = ngx_open_file(name, NGX_FILE_RDONLY); | 124 fd = ngx_open_file(name, NGX_FILE_RDONLY); |
107 if (fd == NGX_INVALID_FILE) { | 125 if (fd == NGX_INVALID_FILE) { |
108 err = ngx_errno; | 126 err = ngx_errno; |
127 | |
128 ngx_log_error(NGX_LOG_ERR, r->connection->log, err, | |
129 ngx_open_file_n " %s failed", name); | |
130 | |
131 #if (WIN32) | |
132 if (err == ERROR_PATH_NOT_FOUND) { | |
133 #else | |
134 if (err == NGX_ENOTDIR) { | |
135 #endif | |
136 r->path_not_found = 1; | |
137 } | |
138 | |
139 if (test_dir) { | |
140 if (r->path_not_found) { | |
141 return NGX_HTTP_NOT_FOUND; | |
142 } | |
143 | |
144 rc = ngx_http_index_test_dir(r); | |
145 if (rc != NGX_OK) { | |
146 return rc; | |
147 } | |
148 | |
149 test_dir = 0; | |
150 | |
151 if (r->path_not_found) { | |
152 continue; | |
153 } | |
154 } | |
155 | |
109 if (err == NGX_ENOENT) { | 156 if (err == NGX_ENOENT) { |
110 continue; | 157 continue; |
111 } | 158 } |
112 #if (WIN32) | |
113 if (err == ERROR_PATH_NOT_FOUND) { | |
114 r->path_not_found = 1; | |
115 continue; | |
116 } | |
117 #else | |
118 if (err == NGX_ENOTDIR) { | |
119 r->path_not_found = 1; | |
120 continue; | |
121 } | |
122 #endif | |
123 | 159 |
124 ngx_log_error(NGX_LOG_ERR, r->connection->log, err, | 160 ngx_log_error(NGX_LOG_ERR, r->connection->log, err, |
125 ngx_open_file_n " %s failed", name); | 161 ngx_open_file_n " %s failed", name); |
126 | 162 |
127 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 163 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
146 | 182 |
147 return NGX_DECLINED; | 183 return NGX_DECLINED; |
148 } | 184 } |
149 | 185 |
150 | 186 |
187 static int ngx_http_index_test_dir(ngx_http_request_t *r) | |
188 { | |
189 ngx_err_t err; | |
190 | |
191 r->path.data[r->path.len - 1] = '\0'; | |
192 | |
193 ngx_log_debug(r->connection->log, "IS_DIR: %s" _ r->path.data); | |
194 | |
195 if (ngx_file_type(r->path.data, &r->file.info) == -1) { | |
196 err = ngx_errno; | |
197 if (err == NGX_ENOENT) { | |
198 return NGX_HTTP_NOT_FOUND; | |
199 } | |
200 | |
201 if (err == NGX_EACCESS) { | |
202 return NGX_HTTP_FORBIDDEN; | |
203 } | |
204 | |
205 ngx_log_error(NGX_LOG_ERR, r->connection->log, err, | |
206 "ngx_http_index_is_dir: " | |
207 "stat() %s failed", r->path.data); | |
208 | |
209 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
210 } | |
211 | |
212 if (ngx_is_dir(r->file.info)) { | |
213 r->path.data[r->path.len - 1] = '/'; | |
214 return NGX_OK; | |
215 | |
216 } else { | |
217 return NGX_HTTP_NOT_FOUND; | |
218 } | |
219 } | |
220 | |
221 | |
151 static int ngx_http_index_init(ngx_pool_t *pool) | 222 static int ngx_http_index_init(ngx_pool_t *pool) |
152 { | 223 { |
153 ngx_http_handler_pt *h; | 224 ngx_http_handler_pt *h; |
154 | 225 |
155 ngx_test_null(h, ngx_push_array(&ngx_http_index_handlers), NGX_ERROR); | 226 ngx_test_null(h, ngx_push_array(&ngx_http_index_handlers), NGX_ERROR); |
166 | 237 |
167 ngx_test_null(conf, ngx_pcalloc(pool, sizeof(ngx_http_index_conf_t)), | 238 ngx_test_null(conf, ngx_pcalloc(pool, sizeof(ngx_http_index_conf_t)), |
168 NGX_CONF_ERROR); | 239 NGX_CONF_ERROR); |
169 | 240 |
170 ngx_test_null(conf->indices, | 241 ngx_test_null(conf->indices, |
171 ngx_create_array(pool, sizeof(ngx_str_t), 3), | 242 ngx_create_array(pool, 3, sizeof(ngx_str_t)), |
172 NGX_CONF_ERROR); | 243 NGX_CONF_ERROR); |
173 | 244 |
174 return conf; | 245 return conf; |
175 } | 246 } |
176 | 247 |
177 | 248 |
249 /* STUB */ | |
178 static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child) | 250 static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child) |
179 { | 251 { |
180 ngx_http_index_conf_t *prev = (ngx_http_index_conf_t *) parent; | 252 ngx_http_index_conf_t *prev = (ngx_http_index_conf_t *) parent; |
181 ngx_http_index_conf_t *conf = (ngx_http_index_conf_t *) child; | 253 ngx_http_index_conf_t *conf = (ngx_http_index_conf_t *) child; |
182 ngx_str_t *index; | 254 ngx_str_t *index; |
183 | 255 |
184 ngx_test_null(index, ngx_push_array(conf->indices), NGX_CONF_ERROR); | 256 if (conf->max_index_len == 0) { |
185 index->len = sizeof(NGX_HTTP_INDEX) - 1; | 257 ngx_test_null(index, ngx_push_array(conf->indices), NGX_CONF_ERROR); |
186 index->data = NGX_HTTP_INDEX; | 258 index->len = sizeof(NGX_HTTP_INDEX) - 1; |
187 conf->max_index_len = sizeof(NGX_HTTP_INDEX); | 259 index->data = NGX_HTTP_INDEX; |
260 conf->max_index_len = sizeof(NGX_HTTP_INDEX); | |
261 } | |
262 | |
263 /* TODO: set conf->test_dir if first index is started with '/' */ | |
188 | 264 |
189 return NULL; | 265 return NULL; |
190 } | 266 } |
191 | 267 |
192 | 268 |
219 int i; | 295 int i; |
220 ngx_str_t *index, *value; | 296 ngx_str_t *index, *value; |
221 | 297 |
222 value = (ngx_str_t *) cf->args->elts; | 298 value = (ngx_str_t *) cf->args->elts; |
223 for (i = 1; i < cf->args->nelts; i++) { | 299 for (i = 1; i < cf->args->nelts; i++) { |
224 ngx_test_null(index, ngx_push_array(icf->indices), NULL); | 300 ngx_test_null(index, ngx_push_array(icf->indices), NGX_CONF_ERROR); |
225 index->len = value[i].len; | 301 index->len = value[i].len; |
226 index->data = value[i].data; | 302 index->data = value[i].data; |
227 | 303 |
228 if (icf->max_index_len < index->len) { | 304 if (icf->max_index_len < index->len) { |
229 icf->max_index_len = index->len; | 305 icf->max_index_len = index->len; |