diff --git a/ngx_http_fancyindex_module.c b/ngx_http_fancyindex_module.c index d25b2f8..6920e44 100644 --- a/ngx_http_fancyindex_module.c +++ b/ngx_http_fancyindex_module.c @@ -210,85 +210,62 @@ bailout: -static ngx_int_t -ngx_http_fancyindex_handler(ngx_http_request_t *r) +static inline ngx_int_t +make_content_buf( + ngx_http_request_t *r, ngx_buf_t **pb, + ngx_http_fancyindex_loc_conf_t *alcf) { - u_char *last, *filename, scale; - off_t length; - size_t len, copy, allocated, root; - ngx_tm_t tm; - ngx_err_t err; - ngx_buf_t *b; - ngx_int_t rc, size; - ngx_str_t path; - ngx_str_t readme_path; - ngx_dir_t dir; - ngx_uint_t i, level; - ngx_pool_t *pool; - ngx_time_t *tp; - ngx_chain_t out; - ngx_array_t entries; - ngx_http_fancyindex_entry_t *entry; - ngx_http_fancyindex_loc_conf_t *alcf; + ngx_http_fancyindex_entry_t *entry; - static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", }; + off_t length; + size_t len, root, copy, allocated; + u_char *filename, *last, scale; + ngx_tm_t tm; + ngx_array_t entries; + ngx_time_t *tp; + ngx_uint_t i; + ngx_int_t size; + ngx_str_t path; + ngx_str_t readme_path; + ngx_dir_t dir; + ngx_buf_t *b; - if (r->uri.data[r->uri.len - 1] != '/') { - return NGX_DECLINED; - } + static char *months[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", + }; - /* TODO: Win32 */ - if (r->zero_in_uri) { - return NGX_DECLINED; - } - - if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { - return NGX_DECLINED; - } - - alcf = ngx_http_get_module_loc_conf(r, ngx_http_fancyindex_module); - - if (!alcf->enable) { - return NGX_DECLINED; - } - - /* NGX_DIR_MASK_LEN is lesser than NGX_HTTP_FANCYINDEX_PREALLOCATE */ - - last = ngx_http_map_uri_to_path(r, &path, &root, - NGX_HTTP_FANCYINDEX_PREALLOCATE); - if (last == NULL) { + /* + * NGX_DIR_MASK_LEN is lesser than NGX_HTTP_FANCYINDEX_PREALLOCATE + */ + if ((last = ngx_http_map_uri_to_path(r, &path, &root, + NGX_HTTP_FANCYINDEX_PREALLOCATE)) == NULL) return NGX_HTTP_INTERNAL_SERVER_ERROR; - } allocated = path.len; - path.len = last - path.data - 1; + path.len = last - path.data - 1; path.data[path.len] = '\0'; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http fancyindex: \"%s\"", path.data); if (ngx_open_dir(&path, &dir) == NGX_ERROR) { - err = ngx_errno; + ngx_int_t rc, err = ngx_errno; + ngx_uint_t level; - if (err == NGX_ENOENT - || err == NGX_ENOTDIR - || err == NGX_ENAMETOOLONG) - { + if (err == NGX_ENOENT || err == NGX_ENOTDIR || err == NGX_ENAMETOOLONG) { level = NGX_LOG_ERR; rc = NGX_HTTP_NOT_FOUND; - } else if (err == NGX_EACCES) { level = NGX_LOG_ERR; rc = NGX_HTTP_FORBIDDEN; - } else { level = NGX_LOG_CRIT; rc = NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_log_error(level, r->connection->log, err, - ngx_open_dir_n " \"%s\" failed", path.data); + ngx_open_dir_n " \"%s\" failed", path.data); return rc; } @@ -298,40 +275,26 @@ ngx_http_fancyindex_handler(ngx_http_request_t *r) ngx_memzero(&entries, sizeof(ngx_array_t)); #endif /* NGX_SUPPRESS_WARN */ - /* TODO: pool should be temporary pool */ - pool = r->pool; - if (ngx_array_init(&entries, pool, 40, sizeof(ngx_http_fancyindex_entry_t)) - != NGX_OK) - { + if (ngx_array_init(&entries, r->pool, 40, + sizeof(ngx_http_fancyindex_entry_t)) != NGX_OK) return ngx_http_fancyindex_error(r, &dir, &path); - } - - r->headers_out.status = NGX_HTTP_OK; - r->headers_out.content_type_len = nfi_sizeof_ssz("text/html"); - r->headers_out.content_type.data = (u_char *) "text/html"; - - rc = ngx_http_send_header(r); - - if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { - return rc; - } filename = path.data; filename[path.len] = '/'; - for ( ;; ) { + /* Read directory entries and their associated information. */ + for (;;) { ngx_set_errno(0); if (ngx_read_dir(&dir) == NGX_ERROR) { - err = ngx_errno; + ngx_int_t err = ngx_errno; if (err != NGX_ENOMOREFILES) { ngx_log_error(NGX_LOG_CRIT, r->connection->log, err, - ngx_read_dir_n " \"%V\" failed", &path); + ngx_read_dir_n " \"%V\" failed", &path); return ngx_http_fancyindex_error(r, &dir, &path); } - break; } @@ -340,22 +303,17 @@ ngx_http_fancyindex_handler(ngx_http_request_t *r) len = ngx_de_namelen(&dir); - if (ngx_de_name(&dir)[0] == '.') { + if (ngx_de_name(&dir)[0] == '.') continue; - } if (!dir.valid_info) { - /* 1 byte for '/' and 1 byte for terminating '\0' */ - if (path.len + 1 + len + 1 > allocated) { allocated = path.len + 1 + len + 1 - + NGX_HTTP_FANCYINDEX_PREALLOCATE; + + NGX_HTTP_FANCYINDEX_PREALLOCATE; - filename = ngx_palloc(pool, allocated); - if (filename == NULL) { + if ((filename = ngx_palloc(r->pool, allocated)) == NULL) return ngx_http_fancyindex_error(r, &dir, &path); - } last = ngx_cpystrn(filename, path.data, path.len + 1); *last++ = '/'; @@ -364,65 +322,55 @@ ngx_http_fancyindex_handler(ngx_http_request_t *r) ngx_cpystrn(last, ngx_de_name(&dir), len + 1); if (ngx_de_info(filename, &dir) == NGX_FILE_ERROR) { - err = ngx_errno; + ngx_int_t err = ngx_errno; if (err != NGX_ENOENT) { ngx_log_error(NGX_LOG_CRIT, r->connection->log, err, - ngx_de_info_n " \"%s\" failed", filename); + ngx_de_info_n " \"%s\" failed", filename); return ngx_http_fancyindex_error(r, &dir, &path); } if (ngx_de_link_info(filename, &dir) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, - ngx_de_link_info_n " \"%s\" failed", - filename); + ngx_de_link_info_n " \"%s\" failed", filename); return ngx_http_fancyindex_error(r, &dir, &path); } } } - entry = ngx_array_push(&entries); - if (entry == NULL) { + if ((entry = ngx_array_push(&entries)) == NULL) return ngx_http_fancyindex_error(r, &dir, &path); - } - entry->name.len = len; - - entry->name.data = ngx_palloc(pool, len + 1); - if (entry->name.data == NULL) { + entry->name.len = len; + entry->name.data = ngx_palloc(r->pool, len + 1); + if (entry->name.data == NULL) return ngx_http_fancyindex_error(r, &dir, &path); - } ngx_cpystrn(entry->name.data, ngx_de_name(&dir), len + 1); + entry->escape = 2 * ngx_escape_uri(NULL, + ngx_de_name(&dir), len, NGX_ESCAPE_HTML); - entry->escape = 2 * ngx_escape_uri(NULL, ngx_de_name(&dir), len, - NGX_ESCAPE_HTML); - - if (r->utf8) { - entry->utf_len = ngx_utf_length(entry->name.data, entry->name.len); - } else { - entry->utf_len = len; - } - - entry->dir = ngx_de_is_dir(&dir); - entry->mtime = ngx_de_mtime(&dir); - entry->size = ngx_de_size(&dir); + entry->dir = ngx_de_is_dir(&dir); + entry->mtime = ngx_de_mtime(&dir); + entry->size = ngx_de_size(&dir); + entry->utf_len = (r->utf8) + ? ngx_utf_length(entry->name.data, entry->name.len) + : len; } if (ngx_close_dir(&dir) == NGX_ERROR) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, - ngx_close_dir_n " \"%s\" failed", &path); + ngx_close_dir_n " \"%s\" failed", &path); } /* - * FIXME: When adding header and/or footer from external resources we - * are wasting some bytes here because we allocate space for *all* - * built-in template pieces. + * Calculate needed buffer length. */ - len = NFI_TEMPLATE_SIZE - + r->uri.len /* URI is included two times: as