From 2f138afb70a7b3435e66c8479ffb402ebf3c009a Mon Sep 17 00:00:00 2001 From: Adrian Perez Date: Thu, 9 Sep 2010 16:42:46 +0200 Subject: [PATCH] Implement fancyindex_ignore configuration directive Adds a new "fancyindex_ignore string1 [string2 [... stringN]]" directive which sets a lists of files which are not to be shown in generated listings. If Nginx is built with PCRE support, strings are interpreted as regular expressions, and files which match one of the regular expressions in this list will not be sent in listings. --- README.rst | 10 +++ ngx_http_fancyindex_module.c | 120 +++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) diff --git a/README.rst b/README.rst index 9b68656..896961b 100644 --- a/README.rst +++ b/README.rst @@ -138,6 +138,16 @@ fancyindex_css_href The link is inserted after the built-in CSS rules, so you can override the default styles. +fancyindex_ignore +~~~~~~~~~~~~~~~~~ +:Syntax: *fancyindex_ignore string1 [string2 [... stringN]]* +:Default: No default. +:Context: http, server, location +:Description: + Specifies a list of file names which will be not be shown in generated + listings. If Nginx was built with PCRE support strings are interpreted as + regular expressions. + .. _nginx: http://nginx.net .. vim:ft=rst:spell:spelllang=en: diff --git a/ngx_http_fancyindex_module.c b/ngx_http_fancyindex_module.c index 4d9da11..bd53f90 100644 --- a/ngx_http_fancyindex_module.c +++ b/ngx_http_fancyindex_module.c @@ -46,6 +46,8 @@ typedef struct { ngx_str_t header; /**< File name for header, or empty if none. */ ngx_str_t footer; /**< File name for footer, or empty if none. */ ngx_str_t css_href; /**< Link to a CSS stylesheet, or empty if none. */ + + ngx_array_t *ignore; /**< List of files to ignore in listings. */ } ngx_http_fancyindex_loc_conf_t; @@ -106,6 +108,10 @@ static void *ngx_http_fancyindex_create_loc_conf(ngx_conf_t *cf); static char *ngx_http_fancyindex_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); +static char *ngx_http_fancyindex_ignore(ngx_conf_t *cf, + ngx_command_t *cmd, + void *conf); + /* * These are used only once per handler invocation. We can tell GCC to * inline them always, if possible (see how ngx_force_inline is defined @@ -165,6 +171,13 @@ static ngx_command_t ngx_http_fancyindex_commands[] = { offsetof(ngx_http_fancyindex_loc_conf_t, css_href), NULL }, + { ngx_string("fancyindex_ignore"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, + ngx_http_fancyindex_ignore, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL }, + ngx_null_command }; @@ -361,6 +374,35 @@ make_content_buf( if (ngx_de_name(&dir)[0] == '.') continue; +#if NGX_PCRE + { + ngx_str_t str = { len, ngx_de_name(&dir) }; + + if (alcf->ignore && ngx_regex_exec_array(alcf->ignore, &str, + r->connection->log) + != NGX_DECLINED) + { + continue; + } + } +#else /* !NGX_PCRE */ + if (alcf->ignore) { + u_int match_found = 0; + ngx_str_t *s = alcf->ignore->elts; + + for (i = 0; i < alcf->ignore->nelts; i++, s++) { + if (ngx_strcmp(ngx_de_name(&dir), s->data) == 0) { + match_found = 1; + break; + } + } + + if (match_found) { + continue; + } + } +#endif /* NGX_PCRE */ + if (!dir.valid_info) { /* 1 byte for '/' and 1 byte for terminating '\0' */ if (path.len + 1 + len + 1 > allocated) { @@ -830,6 +872,7 @@ ngx_http_fancyindex_create_loc_conf(ngx_conf_t *cf) conf->enable = NGX_CONF_UNSET; conf->localtime = NGX_CONF_UNSET; conf->exact_size = NGX_CONF_UNSET; + conf->ignore = NGX_CONF_UNSET_PTR; return conf; } @@ -848,10 +891,87 @@ ngx_http_fancyindex_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) ngx_conf_merge_str_value(conf->header, prev->header, ""); ngx_conf_merge_str_value(conf->footer, prev->footer, ""); + ngx_conf_merge_ptr_value(conf->ignore, prev->ignore, NULL); + return NGX_CONF_OK; } +static char* +ngx_http_fancyindex_ignore(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_fancyindex_loc_conf_t *alcf = conf; + ngx_str_t *value; + +#if (NGX_PCRE) + ngx_uint_t i; + ngx_regex_elt_t *re; + ngx_regex_compile_t rc; + u_char errstr[NGX_MAX_CONF_ERRSTR]; + + if (alcf->ignore == NGX_CONF_UNSET_PTR) { + alcf->ignore = ngx_array_create(cf->pool, 2, sizeof(ngx_regex_elt_t)); + if (alcf->ignore == NULL) { + return NGX_CONF_ERROR; + } + } + + value = cf->args->elts; + + ngx_memzero(&rc, sizeof(ngx_regex_compile_t)); + + rc.err.data = errstr; + rc.err.len = NGX_MAX_CONF_ERRSTR; + rc.pool = cf->pool; + + for (i = 1; i < cf->args->nelts; i++) { + re = ngx_array_push(alcf->ignore); + if (re == NULL) { + return NGX_CONF_ERROR; + } + + rc.pattern = value[i]; + rc.options = NGX_REGEX_CASELESS; + + if (ngx_regex_compile(&rc) != NGX_OK) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err); + return NGX_CONF_ERROR; + } + + re->name = value[i].data; + re->regex = rc.regex; + } + + return NGX_CONF_OK; +#else /* !NGX_PCRE */ + ngx_uint_t i; + ngx_str_t *str; + + if (alcf->ignore == NGX_CONF_UNSET_PTR) { + alcf->ignore = ngx_array_create(cf->pool, 2, sizeof(ngx_str_t)); + if (alcf->ignore == NULL) { + return NGX_CONF_ERROR; + } + } + + value = cf->args->elts; + + for (i = 1; i < cf->args->nelts; i++) { + str = ngx_array_push(alcf->ignore); + if (str == NULL) { + return NGX_CONF_ERROR; + } + + str->data = value[i].data; + str->len = value[i].len; + } + + return NGX_CONF_OK; +#endif /* NGX_PCRE */ + +} + + static ngx_int_t ngx_http_fancyindex_init(ngx_conf_t *cf) {