From d61f33817cc79e00e7b0fedbd8f2692160fe24e5 Mon Sep 17 00:00:00 2001 From: Glenn Strauss Date: Sun, 16 Sep 2018 17:27:54 -0400 Subject: [PATCH] [multiple] code reuse: employ array_match_*() --- src/gw_backend.c | 14 +++------ src/mod_access.c | 65 +++++++---------------------------------- src/mod_alias.c | 30 +++++++------------ src/mod_auth.c | 22 +++++--------- src/mod_cgi.c | 30 +++++-------------- src/mod_deflate.c | 21 +------------ src/mod_expire.c | 63 ++++++++++++--------------------------- src/mod_flv_streaming.c | 14 +-------- src/mod_ssi.c | 11 +------ src/mod_staticfile.c | 10 +------ 10 files changed, 62 insertions(+), 218 deletions(-) diff --git a/src/gw_backend.c b/src/gw_backend.c index 43563333..4b3de6b5 100644 --- a/src/gw_backend.c +++ b/src/gw_backend.c @@ -2271,16 +2271,12 @@ handler_t gw_check_extension(server *srv, connection *con, gw_plugin_data *p, in /* check if extension-mapping matches */ if (p->conf.ext_mapping) { - for (size_t k = 0; k < p->conf.ext_mapping->used; ++k) { - data_string *ds = (data_string *)p->conf.ext_mapping->data[k]; - size_t ct_len = buffer_string_length(ds->key); - if (s_len < ct_len) continue; - + data_string *ds = + (data_string *)array_match_key_suffix(p->conf.ext_mapping, fn); + if (NULL != ds) { /* found a mapping */ - if (0 == memcmp(fn->ptr+s_len-ct_len, ds->key->ptr, ct_len)) { /* check if we know the extension */ - - /* we can reuse k here */ + size_t k; for (k = 0; k < exts->used; ++k) { extension = exts->exts[k]; @@ -2293,8 +2289,6 @@ handler_t gw_check_extension(server *srv, connection *con, gw_plugin_data *p, in /* found nothing */ extension = NULL; } - break; - } } } diff --git a/src/mod_access.c b/src/mod_access.c index 3c36e404..1377c854 100644 --- a/src/mod_access.c +++ b/src/mod_access.c @@ -146,46 +146,23 @@ static int mod_access_patch_connection(server *srv, connection *con, plugin_data */ URIHANDLER_FUNC(mod_access_uri_handler) { plugin_data *p = p_d; - int s_len; - size_t k; + const buffer *match; if (buffer_is_empty(con->uri.path)) return HANDLER_GO_ON; mod_access_patch_connection(srv, con, p); - s_len = buffer_string_length(con->uri.path); - if (con->conf.log_request_handling) { log_error_write(srv, __FILE__, __LINE__, "s", "-- mod_access_uri_handler called"); } - for (k = 0; k < p->conf.access_allow->used; ++k) { - data_string *ds = (data_string *)p->conf.access_allow->data[k]; - int ct_len = buffer_string_length(ds->value); - int allowed = 0; - - if (ct_len > s_len) continue; - if (buffer_is_empty(ds->value)) continue; - - /* if we have a case-insensitive FS we have to lower-case the URI here too */ - - if (con->conf.force_lowercase_filenames) { - if (0 == strncasecmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) { - allowed = 1; - } - } else { - if (0 == strncmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) { - allowed = 1; - } - } - - if (allowed) { - return HANDLER_GO_ON; - } - } + match = (!con->conf.force_lowercase_filenames) + ? array_match_value_suffix(p->conf.access_allow, con->uri.path) + : array_match_value_suffix_nc(p->conf.access_allow, con->uri.path); + if (match) return HANDLER_GO_ON; /* allowed */ - if (k > 0) { /* have access_allow but none matched */ + if (p->conf.access_allow->used) { /* have access_allow but none matched */ con->http_status = 403; con->mode = DIRECT; @@ -197,41 +174,21 @@ URIHANDLER_FUNC(mod_access_uri_handler) { return HANDLER_FINISHED; } - for (k = 0; k < p->conf.access_deny->used; k++) { - data_string *ds = (data_string *)p->conf.access_deny->data[k]; - int ct_len = buffer_string_length(ds->value); - int denied = 0; - - - if (ct_len > s_len) continue; - if (buffer_is_empty(ds->value)) continue; - - /* if we have a case-insensitive FS we have to lower-case the URI here too */ - - if (con->conf.force_lowercase_filenames) { - if (0 == strncasecmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) { - denied = 1; - } - } else { - if (0 == strncmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) { - denied = 1; - } - } - - if (denied) { + match = (!con->conf.force_lowercase_filenames) + ? array_match_value_suffix(p->conf.access_deny, con->uri.path) + : array_match_value_suffix_nc(p->conf.access_deny, con->uri.path); + if (match) { /* denied */ con->http_status = 403; con->mode = DIRECT; if (con->conf.log_request_handling) { log_error_write(srv, __FILE__, __LINE__, "sb", - "url denied as we match:", ds->value); + "url denied as we match:", match); } return HANDLER_FINISHED; - } } - /* not found */ return HANDLER_GO_ON; } diff --git a/src/mod_alias.c b/src/mod_alias.c index eec14f24..cd9414ff 100644 --- a/src/mod_alias.c +++ b/src/mod_alias.c @@ -155,34 +155,31 @@ static int mod_alias_patch_connection(server *srv, connection *con, plugin_data PHYSICALPATH_FUNC(mod_alias_physical_handler) { plugin_data *p = p_d; - int uri_len, basedir_len; char *uri_ptr; - size_t k; + size_t uri_len = buffer_string_length(con->physical.path); + size_t basedir_len, alias_len; + data_string *ds; - if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON; + if (0 == uri_len) return HANDLER_GO_ON; mod_alias_patch_connection(srv, con, p); - /* not to include the tailing slash */ + /* do not include trailing slash on basedir */ basedir_len = buffer_string_length(con->physical.basedir); if ('/' == con->physical.basedir->ptr[basedir_len-1]) --basedir_len; - uri_len = buffer_string_length(con->physical.path) - basedir_len; + uri_len -= basedir_len; uri_ptr = con->physical.path->ptr + basedir_len; - for (k = 0; k < p->conf.alias->used; k++) { - data_string *ds = (data_string *)p->conf.alias->data[k]; - int alias_len = buffer_string_length(ds->key); + ds = (!con->conf.force_lowercase_filenames) + ? (data_string *)array_match_key_prefix_klen(p->conf.alias, uri_ptr, uri_len) + : (data_string *)array_match_key_prefix_nc_klen(p->conf.alias, uri_ptr, uri_len); + if (NULL == ds) { return HANDLER_GO_ON; } - if (alias_len > uri_len) continue; - if (buffer_is_empty(ds->key)) continue; - - if (0 == (con->conf.force_lowercase_filenames ? - strncasecmp(uri_ptr, ds->key->ptr, alias_len) : - strncmp(uri_ptr, ds->key->ptr, alias_len))) { /* matched */ /* check for path traversal in url-path following alias if key * does not end in slash, but replacement value ends in slash */ + alias_len = buffer_string_length(ds->key); if (uri_ptr[alias_len] == '.') { char *s = uri_ptr + alias_len + 1; if (*s == '.') ++s; @@ -202,11 +199,6 @@ PHYSICALPATH_FUNC(mod_alias_physical_handler) { buffer_copy_buffer(con->physical.path, srv->tmp_buf); return HANDLER_GO_ON; - } - } - - /* not found */ - return HANDLER_GO_ON; } /* this function is called at dlopen() time and inits the callbacks */ diff --git a/src/mod_auth.c b/src/mod_auth.c index 8496cccc..06006bb1 100644 --- a/src/mod_auth.c +++ b/src/mod_auth.c @@ -378,25 +378,21 @@ static int mod_auth_patch_connection(server *srv, connection *con, plugin_data * #undef PATCH static handler_t mod_auth_uri_handler(server *srv, connection *con, void *p_d) { - size_t k; plugin_data *p = p_d; + data_auth *dauth; mod_auth_patch_connection(srv, con, p); if (p->conf.auth_require == NULL) return HANDLER_GO_ON; /* search auth directives for first prefix match against URL path */ - for (k = 0; k < p->conf.auth_require->used; k++) { - const data_auth * const dauth = (data_auth *)p->conf.auth_require->data[k]; - const buffer *path = dauth->key; + /* if we have a case-insensitive FS we have to lower-case the URI here too */ + dauth = (!con->conf.force_lowercase_filenames) + ? (data_auth *)array_match_key_prefix(p->conf.auth_require, con->uri.path) + : (data_auth *)array_match_key_prefix_nc(p->conf.auth_require, con->uri.path); + if (NULL == dauth) return HANDLER_GO_ON; - if (buffer_string_length(con->uri.path) < buffer_string_length(path)) continue; - - /* if we have a case-insensitive FS we have to lower-case the URI here too */ - - if (!con->conf.force_lowercase_filenames - ? 0 == strncmp(con->uri.path->ptr, path->ptr, buffer_string_length(path)) - : 0 == strncasecmp(con->uri.path->ptr, path->ptr, buffer_string_length(path))) { + { const http_auth_scheme_t * const scheme = dauth->require->scheme; if (p->conf.auth_extern_authn) { buffer *vb = http_header_env_get(con, CONST_STR_LEN("REMOTE_USER")); @@ -405,11 +401,7 @@ static handler_t mod_auth_uri_handler(server *srv, connection *con, void *p_d) { } } return scheme->checkfn(srv, con, scheme->p_d, dauth->require, p->conf.auth_backend); - } } - - /* nothing to do for us */ - return HANDLER_GO_ON; } int mod_auth_plugin_init(plugin *p); diff --git a/src/mod_cgi.c b/src/mod_cgi.c index 6e02bcee..f97618dc 100644 --- a/src/mod_cgi.c +++ b/src/mod_cgi.c @@ -835,23 +835,6 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, handler_ } } -static buffer * cgi_get_handler(array *a, buffer *fn) { - size_t k, s_len = buffer_string_length(fn); - for (k = 0; k < a->used; ++k) { - data_string *ds = (data_string *)a->data[k]; - size_t ct_len = buffer_string_length(ds->key); - - if (buffer_is_empty(ds->key)) continue; - if (s_len < ct_len) continue; - - if (0 == strncmp(fn->ptr + s_len - ct_len, ds->key->ptr, ct_len)) { - return ds->value; - } - } - - return NULL; -} - #define PATCH(x) \ p->conf.x = s->x; static int mod_cgi_patch_connection(server *srv, connection *con, plugin_data *p) { @@ -899,18 +882,19 @@ static int mod_cgi_patch_connection(server *srv, connection *con, plugin_data *p URIHANDLER_FUNC(cgi_is_handled) { plugin_data *p = p_d; - buffer *fn = con->physical.path; stat_cache_entry *sce = NULL; struct stat stbuf; struct stat *st; - buffer *cgi_handler; + data_string *ds; if (con->mode != DIRECT) return HANDLER_GO_ON; - - if (buffer_is_empty(fn)) return HANDLER_GO_ON; + if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON; mod_cgi_patch_connection(srv, con, p); + ds = (data_string *)array_match_key_suffix(p->conf.cgi, con->physical.path); + if (NULL == ds) return HANDLER_GO_ON; + if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) { st = &sce->st; } else { @@ -923,11 +907,11 @@ URIHANDLER_FUNC(cgi_is_handled) { if (!S_ISREG(st->st_mode)) return HANDLER_GO_ON; if (p->conf.execute_x_only == 1 && (st->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0) return HANDLER_GO_ON; - if (NULL != (cgi_handler = cgi_get_handler(p->conf.cgi, fn))) { + { handler_ctx *hctx = cgi_handler_ctx_init(); hctx->remote_conn = con; hctx->plugin_data = p; - hctx->cgi_handler = cgi_handler; + hctx->cgi_handler = ds->value; memcpy(&hctx->conf, &p->conf, sizeof(plugin_config)); hctx->conf.upgrade = hctx->conf.upgrade diff --git a/src/mod_deflate.c b/src/mod_deflate.c index 3bf5a0fe..f74def16 100644 --- a/src/mod_deflate.c +++ b/src/mod_deflate.c @@ -1092,26 +1092,7 @@ CONNECTION_FUNC(mod_deflate_handle_response_start) { /* Check mimetype in response header "Content-Type" */ if (NULL != (vb = http_header_response_get(con, HTTP_HEADER_CONTENT_TYPE, CONST_STR_LEN("Content-Type")))) { - int found = 0; - size_t m; - for (m = 0; m < p->conf.mimetypes->used; ++m) { - data_string *mimetype = (data_string *)p->conf.mimetypes->data[m]; - if (0 == strncmp(mimetype->value->ptr, vb->ptr, buffer_string_length(mimetype->value))) { - /* mimetype found */ - found = 1; - break; - } - } - if (!found) return HANDLER_GO_ON; - -#if 0 - if (0 == strncasecmp(vb->ptr, "application/x-javascript", 24)) { - /*reset compress type to deflate for javascript - * prevent buggy IE6 SP1 doesn't work for js in IFrame - */ - compression_type = HTTP_ACCEPT_ENCODING_DEFLATE; - } -#endif + if (NULL == array_match_value_prefix(p->conf.mimetypes, vb)) return HANDLER_GO_ON; } else { /* If no Content-Type set, compress only if first p->conf.mimetypes value is "" */ data_string *mimetype = (data_string *)p->conf.mimetypes->data[0]; diff --git a/src/mod_expire.c b/src/mod_expire.c index ce75aed2..0acb0e2a 100644 --- a/src/mod_expire.c +++ b/src/mod_expire.c @@ -270,6 +270,13 @@ SETDEFAULTS_FUNC(mod_expire_set_defaults) { for (k = 0; k < s->expire_mimetypes->used; k++) { data_string *ds = (data_string *)s->expire_mimetypes->data[k]; + size_t klen = buffer_string_length(ds->key); + + /*(omit trailing '*', if present, from prefix match)*/ + /*(not usually a good idea to modify array keys + * since doing so might break array_get_element_klen() search, + * but array use in this module only walks array)*/ + if (klen && ds->key->ptr[klen-1] == '*') buffer_string_set_length(ds->key, klen-1); /* parse lines */ if (-1 == mod_expire_get_offset(srv, p, ds->value, NULL)) { @@ -320,8 +327,7 @@ static int mod_expire_patch_connection(server *srv, connection *con, plugin_data CONNECTION_FUNC(mod_expire_handler) { plugin_data *p = p_d; buffer *vb; - size_t s_len; - size_t k; + data_string *ds; /* Add caching headers only to http_status 200 OK or 206 Partial Content */ if (con->http_status != 200 && con->http_status != 206) return HANDLER_GO_ON; @@ -336,52 +342,19 @@ CONNECTION_FUNC(mod_expire_handler) { mod_expire_patch_connection(srv, con, p); - s_len = buffer_string_length(con->uri.path); - /* check expire.url */ - for (k = 0; k < p->conf.expire_url->used; k++) { - size_t ct_len; - data_string *ds = (data_string *)p->conf.expire_url->data[k]; - ct_len = buffer_string_length(ds->key); - - if (ct_len > s_len) continue; - if (buffer_is_empty(ds->key)) continue; - - if (0 == strncmp(con->uri.path->ptr, ds->key->ptr, ct_len)) { - vb = ds->value; - break; - } + ds = (data_string *)array_match_key_prefix(p->conf.expire_url, con->uri.path); + if (NULL != ds) { + vb = ds->value; } - /* check expire.mimetypes (if no match with expire.url) */ - if (k == p->conf.expire_url->used) { - const char *mimetype; + else { + /* check expire.mimetypes (if no match with expire.url) */ vb = http_header_response_get(con, HTTP_HEADER_CONTENT_TYPE, CONST_STR_LEN("Content-Type")); - if (NULL != vb) { - mimetype = vb->ptr; - s_len = buffer_string_length(vb); - } else { - mimetype = ""; - s_len = 0; - } - for (k = 0; k < p->conf.expire_mimetypes->used; k++) { - size_t ct_len; - data_string *ds = (data_string *)p->conf.expire_mimetypes->data[k]; - ct_len = buffer_string_length(ds->key); - - if (ct_len > s_len) continue; - if (buffer_is_empty(ds->key)) continue; - - /*(omit trailing '*', if present, from prefix match)*/ - if (ds->key->ptr[ct_len-1] == '*') --ct_len; - - if (0 == strncmp(mimetype, ds->key->ptr, ct_len)) { - vb = ds->value; - break; - } - } - if (k == p->conf.expire_mimetypes->used) { - vb = NULL; - } + ds = (NULL != vb) + ? (data_string *)array_match_key_prefix(p->conf.expire_mimetypes, vb) + : (data_string *)array_match_key_prefix_klen(p->conf.expire_mimetypes, CONST_STR_LEN("")); + if (NULL == ds) return HANDLER_GO_ON; + vb = ds->value; } if (NULL != vb) { diff --git a/src/mod_flv_streaming.c b/src/mod_flv_streaming.c index 77f58caf..f15efe1c 100644 --- a/src/mod_flv_streaming.c +++ b/src/mod_flv_streaming.c @@ -185,8 +185,6 @@ static int split_get_params(array *get_params, buffer *qrystr) { URIHANDLER_FUNC(mod_flv_streaming_path_handler) { plugin_data *p = p_d; - int s_len; - size_t k; UNUSED(srv); @@ -196,16 +194,7 @@ URIHANDLER_FUNC(mod_flv_streaming_path_handler) { mod_flv_streaming_patch_connection(srv, con, p); - s_len = buffer_string_length(con->physical.path); - - for (k = 0; k < p->conf.extensions->used; k++) { - data_string *ds = (data_string *)p->conf.extensions->data[k]; - int ct_len = buffer_string_length(ds->value); - - if (ct_len > s_len) continue; - if (buffer_is_empty(ds->value)) continue; - - if (0 == strncmp(con->physical.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) { + if (array_match_value_suffix(p->conf.extensions, con->physical.path)) { data_string *get_param; off_t start = 0, len = -1; char *err = NULL; @@ -249,7 +238,6 @@ URIHANDLER_FUNC(mod_flv_streaming_path_handler) { con->file_finished = 1; return HANDLER_FINISHED; - } } /* not found */ diff --git a/src/mod_ssi.c b/src/mod_ssi.c index 6f1b4913..0a734aee 100644 --- a/src/mod_ssi.c +++ b/src/mod_ssi.c @@ -1290,24 +1290,15 @@ static int mod_ssi_patch_connection(server *srv, connection *con, plugin_data *p URIHANDLER_FUNC(mod_ssi_physical_path) { plugin_data *p = p_d; - size_t k; if (con->mode != DIRECT) return HANDLER_GO_ON; - if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON; mod_ssi_patch_connection(srv, con, p); - for (k = 0; k < p->conf.ssi_extension->used; k++) { - data_string *ds = (data_string *)p->conf.ssi_extension->data[k]; - - if (buffer_is_empty(ds->value)) continue; - - if (buffer_is_equal_right_len(con->physical.path, ds->value, buffer_string_length(ds->value))) { + if (array_match_value_suffix(p->conf.ssi_extension, con->physical.path)) { con->plugin_ctx[p->id] = handler_ctx_init(p); con->mode = p->id; - break; - } } return HANDLER_GO_ON; diff --git a/src/mod_staticfile.c b/src/mod_staticfile.c index f72ee3fd..bf783a21 100644 --- a/src/mod_staticfile.c +++ b/src/mod_staticfile.c @@ -156,8 +156,6 @@ static int mod_staticfile_patch_connection(server *srv, connection *con, plugin_ URIHANDLER_FUNC(mod_staticfile_subrequest) { plugin_data *p = p_d; - size_t k; - data_string *ds; /* someone else has done a decision for us */ if (con->http_status != 0) return HANDLER_GO_ON; @@ -187,17 +185,11 @@ URIHANDLER_FUNC(mod_staticfile_subrequest) { } /* ignore certain extensions */ - for (k = 0; k < p->conf.exclude_ext->used; k++) { - ds = (data_string *)p->conf.exclude_ext->data[k]; - - if (buffer_is_empty(ds->value)) continue; - - if (buffer_is_equal_right_len(con->physical.path, ds->value, buffer_string_length(ds->value))) { + if (array_match_value_suffix(p->conf.exclude_ext, con->physical.path)) { if (con->conf.log_request_handling) { log_error_write(srv, __FILE__, __LINE__, "s", "-- NOT handling file as static file, extension forbidden"); } return HANDLER_GO_ON; - } }