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;