Browse Source

[multiple] code reuse: employ array_match_*()

personal/stbuehler/fix-fdevent
Glenn Strauss 3 years ago
parent
commit
d61f33817c
  1. 14
      src/gw_backend.c
  2. 65
      src/mod_access.c
  3. 30
      src/mod_alias.c
  4. 22
      src/mod_auth.c
  5. 30
      src/mod_cgi.c
  6. 21
      src/mod_deflate.c
  7. 63
      src/mod_expire.c
  8. 14
      src/mod_flv_streaming.c
  9. 11
      src/mod_ssi.c
  10. 10
      src/mod_staticfile.c

14
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;
}
}
}

65
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;
}

30
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 */

22
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);

30
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

21
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];

63
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) {

14
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 */

11
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;

10
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;
}
}

Loading…
Cancel
Save