comparison src/http/modules/ngx_http_index_handler.c @ 144:ef8c87afcfc5

nginx-0.0.1-2003-10-12-20:49:16 import
author Igor Sysoev <igor@sysoev.ru>
date Sun, 12 Oct 2003 16:49:16 +0000
parents cd54bcbaf3b5
children 5afee0074707
comparison
equal deleted inserted replaced
143:5526213be452 144:ef8c87afcfc5
8 ngx_array_t indices; 8 ngx_array_t indices;
9 size_t max_index_len; 9 size_t max_index_len;
10 } ngx_http_index_conf_t; 10 } ngx_http_index_conf_t;
11 11
12 12
13 typedef struct {
14 int index;
15 unsigned tested:1;
16 } ngx_http_index_ctx_t;
17
18
13 #define NGX_HTTP_DEFAULT_INDEX "index.html" 19 #define NGX_HTTP_DEFAULT_INDEX "index.html"
14 20
15 21
16 static int ngx_http_index_test_dir(ngx_http_request_t *r); 22 static int ngx_http_index_test_dir(ngx_http_request_t *r,
23 ngx_http_index_ctx_t *ctx);
24 static int ngx_http_index_error(ngx_http_request_t *r,
25 ngx_http_index_ctx_t *ctx, ngx_err_t err);
26
17 static int ngx_http_index_init(ngx_cycle_t *cycle); 27 static int ngx_http_index_init(ngx_cycle_t *cycle);
18 static void *ngx_http_index_create_conf(ngx_conf_t *cf); 28 static void *ngx_http_index_create_conf(ngx_conf_t *cf);
19 static char *ngx_http_index_merge_conf(ngx_conf_t *cf, 29 static char *ngx_http_index_merge_conf(ngx_conf_t *cf,
20 void *parent, void *child); 30 void *parent, void *child);
21 static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, 31 static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
56 NULL /* init child */ 66 NULL /* init child */
57 }; 67 };
58 68
59 69
60 /* 70 /*
61 Try to open the first index file before the directory existence test 71 * Try to open the first index file before the test of the directory existence
62 because the valid requests should be many more than invalid ones. 72 * because the valid requests should be many more than invalid ones.
63 If open() failed then stat() should be more quickly because some data 73 * If open() failed then stat() should be more quickly because some data
64 is already cached in the kernel. 74 * is already cached in the kernel.
65 Besides Win32 has ERROR_PATH_NOT_FOUND (NGX_ENOTDIR). 75 * Besides Win32 has ERROR_PATH_NOT_FOUND (NGX_ENOTDIR).
66 Unix has ENOTDIR error, although it less helpfull - it shows only 76 * Unix has ENOTDIR error, although it less helpfull - it shows only
67 that path contains the usual file in place of the directory. 77 * that path contains the usual file in place of the directory.
68 */ 78 */
69 79
70 int ngx_http_index_handler(ngx_http_request_t *r) 80 int ngx_http_index_handler(ngx_http_request_t *r)
71 { 81 {
72 int i, rc, test_dir, path_not_found; 82 int i, rc, test_dir, path_not_found;
73 char *name, *file; 83 char *name, *file;
74 ngx_str_t redirect, *index; 84 ngx_str_t redirect, *index;
75 ngx_err_t err; 85 ngx_err_t err;
76 ngx_fd_t fd; 86 ngx_fd_t fd;
87 ngx_http_index_ctx_t *ctx;
77 ngx_http_index_conf_t *icf; 88 ngx_http_index_conf_t *icf;
78 ngx_http_core_loc_conf_t *clcf; 89 ngx_http_core_loc_conf_t *clcf;
79 90
91 if (r->uri.data[r->uri.len - 1] != '/') {
92 return NGX_DECLINED;
93 }
94
95 ctx = ngx_http_get_module_ctx(r, ngx_http_index_module);
96 if (ctx == NULL) {
97 ngx_http_create_ctx(r, ctx, ngx_http_index_module,
98 sizeof(ngx_http_index_ctx_t),
99 NGX_HTTP_INTERNAL_SERVER_ERROR);
100 }
101
80 icf = ngx_http_get_module_loc_conf(r, ngx_http_index_module); 102 icf = ngx_http_get_module_loc_conf(r, ngx_http_index_module);
81 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 103 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
82 104
83 ngx_test_null(r->path.data, 105 if (r->path.data == NULL) {
84 ngx_palloc(r->pool, 106 r->path_allocated = clcf->doc_root.len + r->uri.len
85 clcf->doc_root.len + r->uri.len 107 + icf->max_index_len;
86 + icf->max_index_len), 108 ngx_test_null(r->path.data,
87 NGX_HTTP_INTERNAL_SERVER_ERROR); 109 ngx_palloc(r->pool, r->path_allocated),
88 110 NGX_HTTP_INTERNAL_SERVER_ERROR);
89 redirect.data = ngx_cpymem(r->path.data, clcf->doc_root.data, 111
90 clcf->doc_root.len); 112 redirect.data = ngx_cpymem(r->path.data, clcf->doc_root.data,
91 file = ngx_cpystrn(redirect.data, r->uri.data, r->uri.len + 1); 113 clcf->doc_root.len);
92 r->path.len = file - r->path.data; 114 file = ngx_cpystrn(redirect.data, r->uri.data, r->uri.len + 1);
93 115 r->path.len = file - r->path.data;
94 test_dir = 1; 116
95 path_not_found = 1; 117 } else{
118 redirect.data = r->path.data + r->path.len;
119 file = redirect.data + r->uri.len;
120 }
96 121
97 index = icf->indices.elts; 122 index = icf->indices.elts;
98 for (i = 0; i < icf->indices.nelts; i++) { 123 for (/* void */; ctx->index < icf->indices.nelts; ctx->index++) {
99 124
100 if (index[i].data[0] != '/') { 125 if (index[ctx->index].data[0] == '/') {
101 ngx_memcpy(file, index[i].data, index[i].len + 1); 126 name = index[ctx->index].data;
127
128 } else {
129 ngx_memcpy(file, index[ctx->index].data, index[ctx->index].len + 1);
102 name = r->path.data; 130 name = r->path.data;
103
104 } else {
105 name = index[i].data;
106 } 131 }
107 132
108 fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN); 133 fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN);
134
135 if (fd == NGX_AGAIN) {
136 return NGX_AGAIN;
137 }
138
109 if (fd == NGX_INVALID_FILE) { 139 if (fd == NGX_INVALID_FILE) {
110 err = ngx_errno; 140 err = ngx_errno;
111 141
112 ngx_log_error(NGX_LOG_DEBUG, r->connection->log, err, 142 ngx_log_error(NGX_LOG_DEBUG, r->connection->log, err,
113 "DEBUG: " ngx_open_file_n " %s failed", name); 143 "DEBUG: " ngx_open_file_n " %s failed", name);
114 144
115 if (err == NGX_ENOTDIR) { 145 if (err == NGX_ENOTDIR) {
116 path_not_found = 1; 146 return ngx_http_index_error(r, ctx, err);
117 147
118 } else if (err == NGX_EACCES) { 148 } else if (err == NGX_EACCES) {
119 r->path_err = err; 149 return ngx_http_index_error(r, ctx, err);
120 return NGX_HTTP_FORBIDDEN;
121 } 150 }
122 151
123 if (test_dir) { 152 if (!ctx->tested) {
124 if (path_not_found) { 153 rc = ngx_http_index_test_dir(r, ctx);
125 r->path_err = err; 154
126 return NGX_HTTP_NOT_FOUND;
127 }
128
129 rc = ngx_http_index_test_dir(r);
130 if (rc != NGX_OK) { 155 if (rc != NGX_OK) {
131 return rc; 156 return rc;
132 } 157 }
133 158
134 test_dir = 0; 159 ctx->tested = 1;
135 } 160 }
136 161
137 if (err == NGX_ENOENT) { 162 if (err == NGX_ENOENT) {
138 continue; 163 continue;
139 } 164 }
145 } 170 }
146 171
147 r->file.name.data = name; 172 r->file.name.data = name;
148 r->file.fd = fd; 173 r->file.fd = fd;
149 174
150 if (index[i].data[0] == '/') { 175 if (index[ctx->index].data[0] == '/') {
151 r->file.name.len = index[i].len; 176 r->file.name.len = index[ctx->index].len;
152 redirect.len = index[i].len; 177 redirect.len = index[ctx->index].len;
153 redirect.data = index[i].data; 178 redirect.data = index[ctx->index].data;
154 179
155 } else { 180 } else {
156 redirect.len = r->uri.len + index[i].len; 181 redirect.len = r->uri.len + index[ctx->index].len;
157 r->file.name.len = clcf->doc_root.len + r->uri.len + index[i].len; 182 r->file.name.len = clcf->doc_root.len + r->uri.len
183 + index[ctx->index].len;
158 } 184 }
159 185
160 return ngx_http_internal_redirect(r, &redirect, NULL); 186 return ngx_http_internal_redirect(r, &redirect, NULL);
161 } 187 }
162 188
163 return NGX_DECLINED; 189 return NGX_DECLINED;
164 } 190 }
165 191
166 192
167 static int ngx_http_index_test_dir(ngx_http_request_t *r) 193 static int ngx_http_index_test_dir(ngx_http_request_t *r,
168 { 194 ngx_http_index_ctx_t *ctx)
195 {
196 ngx_err_t err;
197
169 r->path.data[r->path.len - 1] = '\0'; 198 r->path.data[r->path.len - 1] = '\0';
170 r->path.data[r->path.len] = '\0'; 199 r->path.data[r->path.len] = '\0';
171 200
172 ngx_log_debug(r->connection->log, "IS_DIR: %s" _ r->path.data); 201 ngx_log_debug(r->connection->log, "IS_DIR: %s" _ r->path.data);
173 202
174 #if 0
175 if (r->path_err == NGX_EACCES) {
176 return NGX_HTTP_FORBIDDEN;
177 }
178 #endif
179
180 if (ngx_file_type(r->path.data, &r->file.info) == -1) { 203 if (ngx_file_type(r->path.data, &r->file.info) == -1) {
181 204
182 r->path_err = ngx_errno; 205 err = ngx_errno;
183 206
184 if (r->path_err == NGX_ENOENT) { 207 if (err == NGX_ENOENT) {
185 r->path.data[r->path.len - 1] = '/'; 208 r->path.data[r->path.len - 1] = '/';
186 return NGX_HTTP_NOT_FOUND; 209 return ngx_http_index_error(r, ctx, err);
187 } 210 }
188 211
189 ngx_log_error(NGX_LOG_CRIT, r->connection->log, r->path_err, 212 ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
190 ngx_file_type_n " %s failed", r->path.data); 213 ngx_file_type_n " %s failed", r->path.data);
191 214
192 return NGX_HTTP_INTERNAL_SERVER_ERROR; 215 return NGX_HTTP_INTERNAL_SERVER_ERROR;
193 } 216 }
194 217
195 r->path.data[r->path.len - 1] = '/'; 218 r->path.data[r->path.len - 1] = '/';
196 219
197 if (ngx_is_dir(r->file.info)) { 220 if (ngx_is_dir(r->file.info)) {
198 return NGX_OK; 221 return NGX_OK;
199 222 }
200 } else { 223
201 return NGX_HTTP_NOT_FOUND; 224 /* THINK: not reached ??? */
202 } 225 return ngx_http_index_error(r, ctx, 0);
226 }
227
228
229 static int ngx_http_index_error(ngx_http_request_t *r,
230 ngx_http_index_ctx_t *ctx, ngx_err_t err)
231 {
232 if (err == NGX_EACCES) {
233 ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
234 "\"%s\" is forbidden", r->path.data);
235
236 return NGX_HTTP_FORBIDDEN;
237 }
238
239 ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
240 "\"%s\" is not found", r->path.data);
241 return NGX_HTTP_NOT_FOUND;
203 } 242 }
204 243
205 244
206 static int ngx_http_index_init(ngx_cycle_t *cycle) 245 static int ngx_http_index_init(ngx_cycle_t *cycle)
207 { 246 {
210 ngx_http_core_main_conf_t *cmcf; 249 ngx_http_core_main_conf_t *cmcf;
211 250
212 ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index]; 251 ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index];
213 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; 252 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
214 253
215 ngx_test_null(h, ngx_push_array(&cmcf->index_handlers), NGX_ERROR); 254 ngx_test_null(h, ngx_push_array(
216 255 &cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].handlers),
256 NGX_ERROR);
217 *h = ngx_http_index_handler; 257 *h = ngx_http_index_handler;
218 258
219 return NGX_OK; 259 return NGX_OK;
220 } 260 }
221 261