comparison src/http/modules/ngx_http_autoindex_module.c @ 106:45f7329b4bd0 NGINX_0_3_0

nginx 0.3.0 *) Change: the 10-days live time limit of worker process was eliminated. The limit was introduced because of millisecond timers overflow.
author Igor Sysoev <http://sysoev.ru>
date Fri, 07 Oct 2005 00:00:00 +0400
parents f63280c59dd5
children 408f195b3482
comparison
equal deleted inserted replaced
105:531d62c2a28d 106:45f7329b4bd0
37 ngx_flag_t localtime; 37 ngx_flag_t localtime;
38 ngx_flag_t exact_size; 38 ngx_flag_t exact_size;
39 } ngx_http_autoindex_loc_conf_t; 39 } ngx_http_autoindex_loc_conf_t;
40 40
41 41
42 #define NGX_HTTP_AUTOINDEX_NAME_LEN 50 42 #define NGX_HTTP_AUTOINDEX_PREALLOCATE 50
43
44 #define NGX_HTTP_AUTOINDEX_NAME_LEN 50
43 45
44 46
45 static int ngx_libc_cdecl ngx_http_autoindex_cmp_entries(const void *one, 47 static int ngx_libc_cdecl ngx_http_autoindex_cmp_entries(const void *one,
46 const void *two); 48 const void *two);
47 static ngx_int_t ngx_http_autoindex_error(ngx_http_request_t *r, 49 static ngx_int_t ngx_http_autoindex_error(ngx_http_request_t *r,
48 ngx_dir_t *dir, u_char *name); 50 ngx_dir_t *dir, ngx_str_t *name);
49 static ngx_int_t ngx_http_autoindex_init(ngx_cycle_t *cycle); 51 static ngx_int_t ngx_http_autoindex_init(ngx_cycle_t *cycle);
50 static void *ngx_http_autoindex_create_loc_conf(ngx_conf_t *cf); 52 static void *ngx_http_autoindex_create_loc_conf(ngx_conf_t *cf);
51 static char *ngx_http_autoindex_merge_loc_conf(ngx_conf_t *cf, 53 static char *ngx_http_autoindex_merge_loc_conf(ngx_conf_t *cf,
52 void *parent, void *child); 54 void *parent, void *child);
53 55
129 131
130 132
131 static ngx_int_t 133 static ngx_int_t
132 ngx_http_autoindex_handler(ngx_http_request_t *r) 134 ngx_http_autoindex_handler(ngx_http_request_t *r)
133 { 135 {
134 u_char *last, scale; 136 u_char *last, *filename, scale;
135 off_t length; 137 off_t length;
136 size_t len, copy; 138 size_t len, copy, allocated;
137 ngx_tm_t tm; 139 ngx_tm_t tm;
138 ngx_int_t rc, size;
139 ngx_uint_t i, level;
140 ngx_err_t err; 140 ngx_err_t err;
141 ngx_buf_t *b; 141 ngx_buf_t *b;
142 ngx_int_t rc, size;
143 ngx_str_t path;
144 ngx_dir_t dir;
145 ngx_uint_t i, level;
146 ngx_pool_t *pool;
142 ngx_chain_t out; 147 ngx_chain_t out;
143 ngx_str_t dname, fname;
144 ngx_dir_t dir;
145 ngx_pool_t *pool;
146 ngx_array_t entries; 148 ngx_array_t entries;
147 ngx_http_core_loc_conf_t *clcf;
148 ngx_http_autoindex_entry_t *entry; 149 ngx_http_autoindex_entry_t *entry;
149 ngx_http_autoindex_loc_conf_t *alcf; 150 ngx_http_autoindex_loc_conf_t *alcf;
150 151
151 static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", 152 static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
152 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; 153 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
164 165
165 if (!alcf->enable) { 166 if (!alcf->enable) {
166 return NGX_DECLINED; 167 return NGX_DECLINED;
167 } 168 }
168 169
169 /* TODO: pool should be temporary pool */ 170 /* NGX_DIR_MASK_LEN is lesser than NGX_HTTP_AUTOINDEX_PREALLOCATE */
170 pool = r->pool; 171
171 172 last = ngx_http_map_uri_to_path(r, &path, NGX_HTTP_AUTOINDEX_PREALLOCATE);
172 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 173 if (last == NULL) {
173 174 return NGX_HTTP_INTERNAL_SERVER_ERROR;
174 if (clcf->alias) { 175 }
175 dname.data = ngx_palloc(pool, clcf->root.len + r->uri.len 176
176 + NGX_DIR_MASK_LEN + 1 177 allocated = path.len;
177 - clcf->name.len); 178 path.len = last - path.data - 1;
178 if (dname.data == NULL) { 179 path.data[path.len] = '\0';
179 return NGX_HTTP_INTERNAL_SERVER_ERROR;
180 }
181
182 last = ngx_cpymem(dname.data, clcf->root.data, clcf->root.len);
183 last = ngx_cpystrn(last, r->uri.data + clcf->name.len,
184 r->uri.len - clcf->name.len + 1);
185
186 } else {
187 dname.data = ngx_palloc(pool, clcf->root.len + r->uri.len
188 + NGX_DIR_MASK_LEN);
189 if (dname.data == NULL) {
190 return NGX_HTTP_INTERNAL_SERVER_ERROR;
191 }
192
193 last = ngx_cpymem(dname.data, clcf->root.data, clcf->root.len);
194 last = ngx_cpystrn(last, r->uri.data, r->uri.len);
195 }
196
197 dname.len = last - dname.data;
198 180
199 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 181 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
200 "http autoindex: \"%s\"", dname.data); 182 "http autoindex: \"%s\"", path.data);
201 183
202 184 if (ngx_open_dir(&path, &dir) == NGX_ERROR) {
203 if (ngx_open_dir(&dname, &dir) == NGX_ERROR) {
204 err = ngx_errno; 185 err = ngx_errno;
205 186
206 if (err == NGX_ENOENT 187 if (err == NGX_ENOENT
207 || err == NGX_ENOTDIR 188 || err == NGX_ENOTDIR
208 || err == NGX_ENAMETOOLONG) 189 || err == NGX_ENAMETOOLONG)
218 level = NGX_LOG_CRIT; 199 level = NGX_LOG_CRIT;
219 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; 200 rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
220 } 201 }
221 202
222 ngx_log_error(level, r->connection->log, err, 203 ngx_log_error(level, r->connection->log, err,
223 ngx_open_dir_n " \"%s\" failed", dname.data); 204 ngx_open_dir_n " \"%s\" failed", path.data);
224 205
225 return rc; 206 return rc;
226 } 207 }
227 208
228 #if (NGX_SUPPRESS_WARN) 209 #if (NGX_SUPPRESS_WARN)
210
229 /* MSVC thinks 'entries' may be used without having been initialized */ 211 /* MSVC thinks 'entries' may be used without having been initialized */
230 ngx_memzero(&entries, sizeof(ngx_array_t)); 212 ngx_memzero(&entries, sizeof(ngx_array_t));
213
231 #endif 214 #endif
232 215
233 if (ngx_array_init(&entries, pool, 50, sizeof(ngx_http_autoindex_entry_t)) 216 /* TODO: pool should be temporary pool */
234 == NGX_ERROR) 217 pool = r->pool;
218
219 if (ngx_array_init(&entries, pool, 40, sizeof(ngx_http_autoindex_entry_t))
220 != NGX_OK)
235 { 221 {
236 return ngx_http_autoindex_error(r, &dir, dname.data); 222 return ngx_http_autoindex_error(r, &dir, &path);
237 } 223 }
238 224
239 r->headers_out.status = NGX_HTTP_OK; 225 r->headers_out.status = NGX_HTTP_OK;
240 r->headers_out.content_type.len = sizeof("text/html") - 1; 226 r->headers_out.content_type.len = sizeof("text/html") - 1;
241 r->headers_out.content_type.data = (u_char *) "text/html"; 227 r->headers_out.content_type.data = (u_char *) "text/html";
244 230
245 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { 231 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
246 return rc; 232 return rc;
247 } 233 }
248 234
249 fname.len = 0; 235 filename = path.data;
250 #if (NGX_SUPPRESS_WARN) 236 filename[path.len] = '/';
251 fname.data = NULL;
252 #endif
253 237
254 for ( ;; ) { 238 for ( ;; ) {
255 ngx_set_errno(0); 239 ngx_set_errno(0);
256 240
257 if (ngx_read_dir(&dir) == NGX_ERROR) { 241 if (ngx_read_dir(&dir) == NGX_ERROR) {
258 err = ngx_errno; 242 err = ngx_errno;
259 243
260 if (err != NGX_ENOMOREFILES) { 244 if (err != NGX_ENOMOREFILES) {
261 ngx_log_error(NGX_LOG_CRIT, r->connection->log, err, 245 ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
262 ngx_read_dir_n " \"%s\" failed", dname.data); 246 ngx_read_dir_n " \"%V\" failed", &path);
263 return ngx_http_autoindex_error(r, &dir, dname.data); 247 return ngx_http_autoindex_error(r, &dir, &path);
264 } 248 }
265 249
266 break; 250 break;
267 } 251 }
268 252
275 continue; 259 continue;
276 } 260 }
277 261
278 if (!dir.valid_info) { 262 if (!dir.valid_info) {
279 263
280 if (dname.len + 1 + len + 1 > fname.len) { 264 /* 1 byte for '/' and 1 byte for terminating '\0' */
281 fname.len = dname.len + 1 + len + 1 + 32; 265
282 266 if (path.len + 1 + len + 1 > allocated) {
283 fname.data = ngx_palloc(pool, fname.len); 267 allocated = path.len + 1 + len + 1
284 if (fname.data == NULL) { 268 + NGX_HTTP_AUTOINDEX_PREALLOCATE;
285 return ngx_http_autoindex_error(r, &dir, dname.data); 269
270 filename = ngx_palloc(pool, allocated);
271 if (filename == NULL) {
272 return ngx_http_autoindex_error(r, &dir, &path);
286 } 273 }
287 274
288 last = ngx_cpystrn(fname.data, dname.data, 275 last = ngx_cpystrn(filename, path.data, path.len + 1);
289 dname.len + 1);
290 *last++ = '/'; 276 *last++ = '/';
291 } 277 }
292 278
293 ngx_cpystrn(last, ngx_de_name(&dir), len + 1); 279 ngx_cpystrn(last, ngx_de_name(&dir), len + 1);
294 280
295 if (ngx_de_info(fname.data, &dir) == NGX_FILE_ERROR) { 281 if (ngx_de_info(filename, &dir) == NGX_FILE_ERROR) {
296 err = ngx_errno; 282 err = ngx_errno;
297 283
298 if (err != NGX_ENOENT) { 284 if (err != NGX_ENOENT) {
299 ngx_log_error(NGX_LOG_CRIT, r->connection->log, err, 285 ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
300 ngx_de_info_n " \"%s\" failed", fname.data); 286 ngx_de_info_n " \"%s\" failed", filename);
301 return ngx_http_autoindex_error(r, &dir, dname.data); 287 return ngx_http_autoindex_error(r, &dir, &path);
302 } 288 }
303 289
304 if (ngx_de_link_info(fname.data, &dir) == NGX_FILE_ERROR) { 290 if (ngx_de_link_info(filename, &dir) == NGX_FILE_ERROR) {
305 ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, 291 ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
306 ngx_de_link_info_n " \"%s\" failed", 292 ngx_de_link_info_n " \"%s\" failed",
307 fname.data); 293 filename);
308 return ngx_http_autoindex_error(r, &dir, dname.data); 294 return ngx_http_autoindex_error(r, &dir, &path);
309 } 295 }
310 } 296 }
311 } 297 }
312 298
313 entry = ngx_array_push(&entries); 299 entry = ngx_array_push(&entries);
314 if (entry == NULL) { 300 if (entry == NULL) {
315 return ngx_http_autoindex_error(r, &dir, dname.data); 301 return ngx_http_autoindex_error(r, &dir, &path);
316 } 302 }
317 303
318 entry->name.len = len; 304 entry->name.len = len;
319 305
320 entry->name.data = ngx_palloc(pool, len + 1); 306 entry->name.data = ngx_palloc(pool, len + 1);
321 if (entry->name.data == NULL) { 307 if (entry->name.data == NULL) {
322 return ngx_http_autoindex_error(r, &dir, dname.data); 308 return ngx_http_autoindex_error(r, &dir, &path);
323 } 309 }
324 310
325 ngx_cpystrn(entry->name.data, ngx_de_name(&dir), len + 1); 311 ngx_cpystrn(entry->name.data, ngx_de_name(&dir), len + 1);
326 312
327 entry->escape = 2 * ngx_escape_uri(NULL, ngx_de_name(&dir), len, 313 entry->escape = 2 * ngx_escape_uri(NULL, ngx_de_name(&dir), len,
338 entry->size = ngx_de_size(&dir); 324 entry->size = ngx_de_size(&dir);
339 } 325 }
340 326
341 if (ngx_close_dir(&dir) == NGX_ERROR) { 327 if (ngx_close_dir(&dir) == NGX_ERROR) {
342 ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, 328 ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
343 ngx_close_dir_n " \"%s\" failed", dname.data); 329 ngx_close_dir_n " \"%s\" failed", &path);
344 } 330 }
345 331
346 len = sizeof(title) - 1 332 len = sizeof(title) - 1
347 + r->uri.len 333 + r->uri.len
348 + sizeof(header) - 1 334 + sizeof(header) - 1
584 570
585 #endif 571 #endif
586 572
587 573
588 static ngx_int_t 574 static ngx_int_t
589 ngx_http_autoindex_error(ngx_http_request_t *r, ngx_dir_t *dir, u_char *name) 575 ngx_http_autoindex_error(ngx_http_request_t *r, ngx_dir_t *dir, ngx_str_t *name)
590 { 576 {
591 if (ngx_close_dir(dir) == NGX_ERROR) { 577 if (ngx_close_dir(dir) == NGX_ERROR) {
592 ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, 578 ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
593 ngx_close_dir_n " \"%s\" failed", name); 579 ngx_close_dir_n " \"%V\" failed", name);
594 } 580 }
595 581
596 return NGX_HTTP_INTERNAL_SERVER_ERROR; 582 return NGX_HTTP_INTERNAL_SERVER_ERROR;
597 } 583 }
598 584