/*
 * Mod Defender for HAProxy
 *
 * Support for the Mod Defender code on non-Apache platforms.
 *
 * Copyright 2017 HAProxy Technologies, Dragan Dosen <ddosen@haproxy.com>
 *
 * Parts of code based on Apache HTTP Server source
 * Copyright 2015 The Apache Software Foundation (http://www.apache.org/)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 3 of the License, or (at your option) any later version.
 *
 */
#include <limits.h>

#include <http_core.h>
#include <http_main.h>
#include <http_log.h>

#include <apr_lib.h>
#include <apr_strings.h>
#include <apr_fnmatch.h>

#include "standalone.h"

#define MAX_ARGC 64
#define MAX_INCLUDE_DIR_DEPTH 128

#define SLASHES "/"

#define FILTER_POOL apr_hook_global_pool
#define TRIE_INITIAL_SIZE 4

typedef struct filter_trie_node filter_trie_node;

typedef struct {
	int c;
	filter_trie_node *child;
} filter_trie_child_ptr;

struct filter_trie_node {
	ap_filter_rec_t *frec;
	filter_trie_child_ptr *children;
	int nchildren;
	int size;
};

typedef struct {
	const char *fname;
} fnames;

AP_DECLARE_DATA const char *ap_server_root = "/";

void (*logger)(int level, char *str) = NULL;

static void str_tolower(char *str)
{
	while (*str) {
		*str = apr_tolower(*str);
		++str;
	}
}

static char x2c(const char *what)
{
	char digit;

#if !APR_CHARSET_EBCDIC
	digit = ((what[0] >= 'A') ? ((what[0] & 0xdf) - 'A') + 10
	        : (what[0] - '0'));
	digit *= 16;
	digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10
	         : (what[1] - '0'));
#else /*APR_CHARSET_EBCDIC*/
	char xstr[5];
	xstr[0]='0';
	xstr[1]='x';
	xstr[2]=what[0];
	xstr[3]=what[1];
	xstr[4]='\0';
	digit = apr_xlate_conv_byte(ap_hdrs_from_ascii,
	                            0xFF & strtol(xstr, NULL, 16));
#endif /*APR_CHARSET_EBCDIC*/
	return (digit);
}

static int unescape_url(char *url, const char *forbid, const char *reserved)
{
	int badesc, badpath;
	char *x, *y;

	badesc = 0;
	badpath = 0;
	/* Initial scan for first '%'. Don't bother writing values before
	 * seeing a '%' */
	y = strchr(url, '%');
	if (y == NULL) {
		return OK;
	}
	for (x = y; *y; ++x, ++y) {
		if (*y != '%') {
			*x = *y;
		}
		else {
			if (!apr_isxdigit(*(y + 1)) || !apr_isxdigit(*(y + 2))) {
				badesc = 1;
				*x = '%';
			}
			else {
				char decoded;
				decoded = x2c(y + 1);
				if ((decoded == '\0')
				    || (forbid && ap_strchr_c(forbid, decoded))) {
					badpath = 1;
					*x = decoded;
					y += 2;
				}
				else if (reserved && ap_strchr_c(reserved, decoded)) {
					*x++ = *y++;
					*x++ = *y++;
					*x = *y;
				}
				else {
					*x = decoded;
					y += 2;
				}
			}
		}
	}
	*x = '\0';
	if (badesc) {
		return HTTP_BAD_REQUEST;
	}
	else if (badpath) {
		return HTTP_NOT_FOUND;
	}
	else {
		return OK;
	}
}

AP_DECLARE(int) ap_unescape_url(char *url)
{
	/* Traditional */
	return unescape_url(url, SLASHES, NULL);
}

AP_DECLARE(void) ap_get_server_revision(ap_version_t *version)
{
	version->major = AP_SERVER_MAJORVERSION_NUMBER;
	version->minor = AP_SERVER_MINORVERSION_NUMBER;
	version->patch = AP_SERVER_PATCHLEVEL_NUMBER;
	version->add_string = AP_SERVER_ADD_STRING;
}

static void log_error_core(const char *file, int line, int module_index,
                           int level,
                           apr_status_t status, const server_rec *s,
                           const conn_rec *c,
                           const request_rec *r, apr_pool_t *pool,
                           const char *fmt, va_list args)
{
	char errstr[MAX_STRING_LEN];

	apr_vsnprintf(errstr, MAX_STRING_LEN, fmt, args);

	if (logger != NULL)
		logger(level, errstr);
}

AP_DECLARE(void) ap_log_error_(const char *file, int line, int module_index,
                               int level, apr_status_t status,
                               const server_rec *s, const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	log_error_core(file, line, module_index, level, status, s, NULL, NULL,
	               NULL, fmt, args);
	va_end(args);
}

AP_DECLARE(void) ap_log_rerror_(const char *file, int line, int module_index,
                                int level, apr_status_t status,
                                const request_rec *r, const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	log_error_core(file, line, module_index, level, status, r->server, NULL, r,
	               NULL, fmt, args);
	va_end(args);
}

AP_DECLARE(void) ap_log_cerror_(const char *file, int line, int module_index,
                                int level, apr_status_t status,
                                const conn_rec *c, const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	log_error_core(file, line, module_index, level, status, c->base_server, c,
	               NULL, NULL, fmt, args);
	va_end(args);
}

AP_DECLARE(piped_log *) ap_open_piped_log(apr_pool_t *p, const char *program)
{
	return NULL;
}

AP_DECLARE(apr_file_t *) ap_piped_log_write_fd(piped_log *pl)
{
	return NULL;
}

static cmd_parms default_parms =
{NULL, 0, 0, NULL, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};

AP_DECLARE(char *) ap_server_root_relative(apr_pool_t *p, const char *file)
{
	char *newpath = NULL;
	apr_status_t rv;
	rv = apr_filepath_merge(&newpath, ap_server_root, file,
	                        APR_FILEPATH_TRUENAME, p);
	if (newpath && (rv == APR_SUCCESS || APR_STATUS_IS_EPATHWILD(rv)
	                                  || APR_STATUS_IS_ENOENT(rv)
	                                  || APR_STATUS_IS_ENOTDIR(rv))) {
		return newpath;
	}
	else {
		return NULL;
	}
}

AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_t *next,
                                        apr_bucket_brigade *bb,
                                        ap_input_mode_t mode,
                                        apr_read_type_e block,
                                        apr_off_t readbytes)
{
	if (next) {
		return next->frec->filter_func.in_func(next, bb, mode, block,
		                                       readbytes);
	}
	return AP_NOBODY_READ;
}

static void
argstr_to_table(char *str, apr_table_t *parms)
{
	char *key;
	char *value;
	char *strtok_state;

	if (str == NULL) {
		return;
	}

	key = apr_strtok(str, "&", &strtok_state);
	while (key) {
		value = strchr(key, '=');
		if (value) {
			*value = '\0';      /* Split the string in two */
			value++;            /* Skip passed the = */
		}
		else {
			value = "1";
		}
		ap_unescape_url(key);
		ap_unescape_url(value);
		apr_table_set(parms, key, value);
		key = apr_strtok(NULL, "&", &strtok_state);
	}
}

AP_DECLARE(void) ap_args_to_table(request_rec *r, apr_table_t **table)
{
	apr_table_t *t = apr_table_make(r->pool, 10);
	argstr_to_table(apr_pstrdup(r->pool, r->args), t);
	*table = t;
}

/* Link a trie node to its parent
 */
static void trie_node_link(apr_pool_t *p, filter_trie_node *parent,
                           filter_trie_node *child, int c)
{
	int i, j;

	if (parent->nchildren == parent->size) {
		filter_trie_child_ptr *new;
		parent->size *= 2;
		new = (filter_trie_child_ptr *)apr_palloc(p, parent->size *
		                                          sizeof(filter_trie_child_ptr));
		memcpy(new, parent->children, parent->nchildren *
		       sizeof(filter_trie_child_ptr));
		parent->children = new;
	}

	for (i = 0; i < parent->nchildren; i++) {
		if (c == parent->children[i].c) {
			return;
		}
		else if (c < parent->children[i].c) {
			break;
		}
	}
	for (j = parent->nchildren; j > i; j--) {
		parent->children[j].c = parent->children[j - 1].c;
		parent->children[j].child = parent->children[j - 1].child;
	}
	parent->children[i].c = c;
	parent->children[i].child = child;

	parent->nchildren++;
}

/* Allocate a new node for a trie.
 * If parent is non-NULL, link the new node under the parent node with
 * key 'c' (or, if an existing child node matches, return that one)
 */
static filter_trie_node *trie_node_alloc(apr_pool_t *p,
                                         filter_trie_node *parent, char c)
{
	filter_trie_node *new_node;
	if (parent) {
		int i;
		for (i = 0; i < parent->nchildren; i++) {
			if (c == parent->children[i].c) {
				return parent->children[i].child;
			}
			else if (c < parent->children[i].c) {
				break;
			}
		}
		new_node = (filter_trie_node *)apr_palloc(p, sizeof(filter_trie_node));
		trie_node_link(p, parent, new_node, c);
	}
	else { /* No parent node */
		new_node = (filter_trie_node *)apr_palloc(p,
		           sizeof(filter_trie_node));
	}

	new_node->frec = NULL;
	new_node->nchildren = 0;
	new_node->size = TRIE_INITIAL_SIZE;
	new_node->children = (filter_trie_child_ptr *)apr_palloc(p,
	                     new_node->size * sizeof(filter_trie_child_ptr));
	return new_node;
}

static filter_trie_node *registered_output_filters = NULL;
static filter_trie_node *registered_input_filters = NULL;


static apr_status_t filter_cleanup(void *ctx)
{
	registered_output_filters = NULL;
	registered_input_filters = NULL;
	return APR_SUCCESS;
}

static ap_filter_rec_t *register_filter(const char *name,
                                        ap_filter_func filter_func,
                                        ap_init_filter_func filter_init,
                                        ap_filter_type ftype,
                                        filter_trie_node **reg_filter_set)
{
	ap_filter_rec_t *frec;
	char *normalized_name;
	const char *n;
	filter_trie_node *node;

	if (!*reg_filter_set) {
		*reg_filter_set = trie_node_alloc(FILTER_POOL, NULL, 0);
	}

	normalized_name = apr_pstrdup(FILTER_POOL, name);
	str_tolower(normalized_name);

	node = *reg_filter_set;
	for (n = normalized_name; *n; n++) {
		filter_trie_node *child = trie_node_alloc(FILTER_POOL, node, *n);
		if (apr_isalpha(*n)) {
			trie_node_link(FILTER_POOL, node, child, apr_toupper(*n));
		}
		node = child;
	}
	if (node->frec) {
		frec = node->frec;
	}
	else {
		frec = apr_pcalloc(FILTER_POOL, sizeof(*frec));
		node->frec = frec;
		frec->name = normalized_name;
	}
	frec->filter_func = filter_func;
	frec->filter_init_func = filter_init;
	frec->ftype = ftype;

	apr_pool_cleanup_register(FILTER_POOL, NULL, filter_cleanup,
	                          apr_pool_cleanup_null);
	return frec;
}

AP_DECLARE(ap_filter_rec_t *) ap_register_input_filter(const char *name,
                                                       ap_in_filter_func filter_func,
                                                       ap_init_filter_func filter_init,
                                                       ap_filter_type ftype)
{
	ap_filter_func f;
	f.in_func = filter_func;
	return register_filter(name, f, filter_init, ftype,
	                       &registered_input_filters);
}

static ap_filter_t *add_any_filter_handle(ap_filter_rec_t *frec, void *ctx,
                                          request_rec *r, conn_rec *c,
                                          ap_filter_t **r_filters,
                                          ap_filter_t **p_filters,
                                          ap_filter_t **c_filters)
{
	apr_pool_t *p = frec->ftype < AP_FTYPE_CONNECTION && r ? r->pool : c->pool;
	ap_filter_t *f = apr_palloc(p, sizeof(*f));
	ap_filter_t **outf;

	if (frec->ftype < AP_FTYPE_PROTOCOL) {
		if (r) {
			outf = r_filters;
		}
		else {
			ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(00080)
			              "a content filter was added without a request: %s", frec->name);
			return NULL;
		}
	}
	else if (frec->ftype < AP_FTYPE_CONNECTION) {
		if (r) {
			outf = p_filters;
		}
		else {
			ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(00081)
			              "a protocol filter was added without a request: %s", frec->name);
			return NULL;
		}
	}
	else {
		outf = c_filters;
	}

	f->frec = frec;
	f->ctx = ctx;
	/* f->r must always be NULL for connection filters */
	f->r = frec->ftype < AP_FTYPE_CONNECTION ? r : NULL;
	f->c = c;
	f->next = NULL;

	if (INSERT_BEFORE(f, *outf)) {
		f->next = *outf;

		if (*outf) {
			ap_filter_t *first = NULL;

			if (r) {
				/* If we are adding our first non-connection filter,
				 * Then don't try to find the right location, it is
				 * automatically first.
				 */
				if (*r_filters != *c_filters) {
					first = *r_filters;
					while (first && (first->next != (*outf))) {
						first = first->next;
					}
				}
			}
			if (first && first != (*outf)) {
				first->next = f;
			}
		}
		*outf = f;
	}
	else {
		ap_filter_t *fscan = *outf;
		while (!INSERT_BEFORE(f, fscan->next))
			fscan = fscan->next;

		f->next = fscan->next;
		fscan->next = f;
	}

	if (frec->ftype < AP_FTYPE_CONNECTION && (*r_filters == *c_filters)) {
		*r_filters = *p_filters;
	}
	return f;
}

static ap_filter_t *add_any_filter(const char *name, void *ctx,
                                   request_rec *r, conn_rec *c,
                                   const filter_trie_node *reg_filter_set,
                                   ap_filter_t **r_filters,
                                   ap_filter_t **p_filters,
                                   ap_filter_t **c_filters)
{
	if (reg_filter_set) {
		const char *n;
		const filter_trie_node *node;

		node = reg_filter_set;
		for (n = name; *n; n++) {
			int start, end;
			start = 0;
			end = node->nchildren - 1;
			while (end >= start) {
				int middle = (end + start) / 2;
				char ch = node->children[middle].c;
				if (*n == ch) {
					node = node->children[middle].child;
					break;
				}
				else if (*n < ch) {
					end = middle - 1;
				}
				else {
					start = middle + 1;
				}
			}
			if (end < start) {
				node = NULL;
				break;
			}
		}

		if (node && node->frec) {
			return add_any_filter_handle(node->frec, ctx, r, c, r_filters,
			                             p_filters, c_filters);
		}
	}

	ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, r ? r->connection : c, APLOGNO(00082)
	              "an unknown filter was not added: %s", name);
	return NULL;
}

AP_DECLARE(ap_filter_t *) ap_add_input_filter(const char *name, void *ctx,
                                              request_rec *r, conn_rec *c)
{
	return add_any_filter(name, ctx, r, c, registered_input_filters,
	                      r ? &r->input_filters : NULL,
	                      r ? &r->proto_input_filters : NULL,
	                      &c->input_filters);
}

static void remove_any_filter(ap_filter_t *f, ap_filter_t **r_filt, ap_filter_t **p_filt,
                              ap_filter_t **c_filt)
{
	ap_filter_t **curr = r_filt ? r_filt : c_filt;
	ap_filter_t *fscan = *curr;

	if (p_filt && *p_filt == f)
		*p_filt = (*p_filt)->next;

	if (*curr == f) {
		*curr = (*curr)->next;
		return;
	}

	while (fscan->next != f) {
		if (!(fscan = fscan->next)) {
			return;
		}
	}

	fscan->next = f->next;
}

AP_DECLARE(void) ap_remove_input_filter(ap_filter_t *f)
{
	remove_any_filter(f, f->r ? &f->r->input_filters : NULL,
	                  f->r ? &f->r->proto_input_filters : NULL,
	                  &f->c->input_filters);
}

static int cfg_closefile(ap_configfile_t *cfp)
{
#ifdef DEBUG
	ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL,
	             "Done with config file %s", cfp->name);
#endif
	return (cfp->close == NULL) ? 0 : cfp->close(cfp->param);
}

/* we can't use apr_file_* directly because of linking issues on Windows */
static apr_status_t cfg_close(void *param)
{
	return apr_file_close(param);
}

static apr_status_t cfg_getch(char *ch, void *param)
{
	return apr_file_getc(ch, param);
}

static apr_status_t cfg_getstr(void *buf, apr_size_t bufsiz, void *param)
{
	return apr_file_gets(buf, bufsiz, param);
}

/* Read one line from open ap_configfile_t, strip LF, increase line number */
/* If custom handler does not define a getstr() function, read char by char */
static apr_status_t cfg_getline_core(char *buf, apr_size_t bufsize,
                                     apr_size_t offset, ap_configfile_t *cfp)
{
	apr_status_t rc;
	/* If a "get string" function is defined, use it */
	if (cfp->getstr != NULL) {
		char *cp;
		char *cbuf = buf + offset;
		apr_size_t cbufsize = bufsize - offset;

		while (1) {
			++cfp->line_number;
			rc = cfp->getstr(cbuf, cbufsize, cfp->param);
			if (rc == APR_EOF) {
				if (cbuf != buf + offset) {
					*cbuf = '\0';
					break;
				}
				else {
					return APR_EOF;
				}
			}
			if (rc != APR_SUCCESS) {
				return rc;
			}

			/*
			 *  check for line continuation,
			 *  i.e. match [^\\]\\[\r]\n only
			 */
			cp = cbuf;
			cp += strlen(cp);
			if (cp > buf && cp[-1] == LF) {
				cp--;
				if (cp > buf && cp[-1] == CR)
					cp--;
				if (cp > buf && cp[-1] == '\\') {
					cp--;
					/*
					 * line continuation requested -
					 * then remove backslash and continue
					 */
					cbufsize -= (cp-cbuf);
					cbuf = cp;
					continue;
				}
			}
			else if (cp - buf >= bufsize - 1) {
				return APR_ENOSPC;
			}
			break;
		}
	} else {
		/* No "get string" function defined; read character by character */
		apr_size_t i = offset;

		if (bufsize < 2) {
			/* too small, assume caller is crazy */
			return APR_EINVAL;
		}
		buf[offset] = '\0';

		while (1) {
			char c;
			rc = cfp->getch(&c, cfp->param);
			if (rc == APR_EOF) {
				if (i > offset)
					break;
				else
					return APR_EOF;
			}
			if (rc != APR_SUCCESS)
				return rc;
			if (c == LF) {
				++cfp->line_number;
				/* check for line continuation */
				if (i > 0 && buf[i-1] == '\\') {
					i--;
					continue;
				}
				else {
					break;
				}
			}
			buf[i] = c;
			++i;
			if (i >= bufsize - 1) {
				return APR_ENOSPC;
			}
		}
		buf[i] = '\0';
	}
	return APR_SUCCESS;
}

static int cfg_trim_line(char *buf)
{
	char *start, *end;
	/*
	 * Leading and trailing white space is eliminated completely
	 */
	start = buf;
	while (apr_isspace(*start))
		++start;
	/* blast trailing whitespace */
	end = &start[strlen(start)];
	while (--end >= start && apr_isspace(*end))
		*end = '\0';
	/* Zap leading whitespace by shifting */
	if (start != buf)
		memmove(buf, start, end - start + 2);
#ifdef DEBUG_CFG_LINES
	ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, APLOGNO(00555) "Read config: '%s'", buf);
#endif
	return end - start + 1;
}

/* Read one line from open ap_configfile_t, strip LF, increase line number */
/* If custom handler does not define a getstr() function, read char by char */
static apr_status_t cfg_getline(char *buf, apr_size_t bufsize,
                                ap_configfile_t *cfp)
{
	apr_status_t rc = cfg_getline_core(buf, bufsize, 0, cfp);
	if (rc == APR_SUCCESS)
		cfg_trim_line(buf);
	return rc;
}

static char *substring_conf(apr_pool_t *p, const char *start, int len,
                            char quote)
{
	char *result = apr_palloc(p, len + 1);
	char *resp = result;
	int i;

	for (i = 0; i < len; ++i) {
		if (start[i] == '\\' && (start[i + 1] == '\\'
		                         || (quote && start[i + 1] == quote)))
			*resp++ = start[++i];
		else
			*resp++ = start[i];
	}

	*resp++ = '\0';
#if RESOLVE_ENV_PER_TOKEN
	return (char *)ap_resolve_env(p,result);
#else
	return result;
#endif
}

static char *getword_conf(apr_pool_t *p, const char **line)
{
	const char *str = *line, *strend;
	char *res;
	char quote;

	while (apr_isspace(*str))
		++str;

	if (!*str) {
		*line = str;
		return "";
	}

	if ((quote = *str) == '"' || quote == '\'') {
		strend = str + 1;
		while (*strend && *strend != quote) {
			if (*strend == '\\' && strend[1] &&
			    (strend[1] == quote || strend[1] == '\\')) {
				strend += 2;
			}
			else {
				++strend;
			}
		}
		res = substring_conf(p, str + 1, strend - str - 1, quote);

		if (*strend == quote)
			++strend;
	}
	else {
		strend = str;
		while (*strend && !apr_isspace(*strend))
			++strend;

		res = substring_conf(p, str, strend - str, 0);
	}

	while (apr_isspace(*strend))
		++strend;
	*line = strend;
	return res;
}

/* Open a ap_configfile_t as FILE, return open ap_configfile_t struct pointer */
static apr_status_t pcfg_openfile(ap_configfile_t **ret_cfg,
                                  apr_pool_t *p, const char *name)
{
	ap_configfile_t *new_cfg;
	apr_file_t *file = NULL;
	apr_finfo_t finfo;
	apr_status_t status;
#ifdef DEBUG
	char buf[120];
#endif

	if (name == NULL) {
		ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, APLOGNO(00552)
		             "Internal error: pcfg_openfile() called with NULL filename");
		return APR_EBADF;
	}

	status = apr_file_open(&file, name, APR_READ | APR_BUFFERED,
	                       APR_OS_DEFAULT, p);
#ifdef DEBUG
	ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, APLOGNO(00553)
	             "Opening config file %s (%s)",
	             name, (status != APR_SUCCESS) ?
	             apr_strerror(status, buf, sizeof(buf)) : "successful");
#endif
	if (status != APR_SUCCESS)
		return status;

	status = apr_file_info_get(&finfo, APR_FINFO_TYPE, file);
	if (status != APR_SUCCESS)
		return status;

	if (finfo.filetype != APR_REG &&
		strcmp(name, "/dev/null") != 0) {
		ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, APLOGNO(00554)
		             "Access to file %s denied by server: not a regular file",
		             name);
		apr_file_close(file);
		return APR_EBADF;
	}

	new_cfg = apr_palloc(p, sizeof(*new_cfg));
	new_cfg->param = file;
	new_cfg->name = apr_pstrdup(p, name);
	new_cfg->getch = cfg_getch;
	new_cfg->getstr = cfg_getstr;
	new_cfg->close = cfg_close;
	new_cfg->line_number = 0;
	*ret_cfg = new_cfg;
	return APR_SUCCESS;
}

static const command_rec *find_command(const char *name,
                                       const command_rec *cmds)
{
	while (cmds->name) {
		if (strcasecmp(name, cmds->name) == 0)
			return cmds;
		++cmds;
	}

	return NULL;
}

static const char *invoke_cmd(const command_rec *cmd, cmd_parms *parms,
                              void *mconfig, const char *args)
{
	int override_list_ok = 0;
	char *w, *w2, *w3;
	const char *errmsg = NULL;

	/** Have we been provided a list of acceptable directives? */
	if (parms->override_list != NULL) {
		if (apr_table_get(parms->override_list, cmd->name) != NULL) {
			override_list_ok = 1;
		}
	}

	if ((parms->override & cmd->req_override) == 0 && !override_list_ok) {
		return apr_pstrcat(parms->pool, cmd->name,
		                   " not allowed here", NULL);
	}

	parms->info = cmd->cmd_data;
	parms->cmd = cmd;

	switch (cmd->args_how) {
	case RAW_ARGS:
#ifdef RESOLVE_ENV_PER_TOKEN
		args = ap_resolve_env(parms->pool,args);
#endif
		return cmd->AP_RAW_ARGS(parms, mconfig, args);

	case TAKE_ARGV:
		{
			char *argv[MAX_ARGC];
			int argc = 0;

			do {
				w = getword_conf(parms->pool, &args);
				if (*w == '\0' && *args == '\0') {
					break;
				}
				argv[argc] = w;
				argc++;
			} while (argc < MAX_ARGC && *args != '\0');

			return cmd->AP_TAKE_ARGV(parms, mconfig, argc, argv);
		}

	case NO_ARGS:
		if (*args != 0)
			return apr_pstrcat(parms->pool, cmd->name, " takes no arguments",
			                   NULL);

		return cmd->AP_NO_ARGS(parms, mconfig);

	case TAKE1:
		w = getword_conf(parms->pool, &args);

		if (*w == '\0' || *args != 0)
			return apr_pstrcat(parms->pool, cmd->name, " takes one argument",
			                   cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);

		return cmd->AP_TAKE1(parms, mconfig, w);

	case TAKE2:
		w = getword_conf(parms->pool, &args);
		w2 = getword_conf(parms->pool, &args);

		if (*w == '\0' || *w2 == '\0' || *args != 0)
			return apr_pstrcat(parms->pool, cmd->name, " takes two arguments",
			                   cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);

		return cmd->AP_TAKE2(parms, mconfig, w, w2);

	case TAKE12:
		w = getword_conf(parms->pool, &args);
		w2 = getword_conf(parms->pool, &args);

		if (*w == '\0' || *args != 0)
			return apr_pstrcat(parms->pool, cmd->name, " takes 1-2 arguments",
			                   cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);

		return cmd->AP_TAKE2(parms, mconfig, w, *w2 ? w2 : NULL);

	case TAKE3:
		w = getword_conf(parms->pool, &args);
		w2 = getword_conf(parms->pool, &args);
		w3 = getword_conf(parms->pool, &args);

		if (*w == '\0' || *w2 == '\0' || *w3 == '\0' || *args != 0)
			return apr_pstrcat(parms->pool, cmd->name, " takes three arguments",
			                   cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);

		return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);

	case TAKE23:
		w = getword_conf(parms->pool, &args);
		w2 = getword_conf(parms->pool, &args);
		w3 = *args ? getword_conf(parms->pool, &args) : NULL;

		if (*w == '\0' || *w2 == '\0' || *args != 0)
			return apr_pstrcat(parms->pool, cmd->name,
			                   " takes two or three arguments",
			                   cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);

		return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);

	case TAKE123:
		w = getword_conf(parms->pool, &args);
		w2 = *args ? getword_conf(parms->pool, &args) : NULL;
		w3 = *args ? getword_conf(parms->pool, &args) : NULL;

		if (*w == '\0' || *args != 0)
			return apr_pstrcat(parms->pool, cmd->name,
			                   " takes one, two or three arguments",
			                   cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);

		return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);

	case TAKE13:
		w = getword_conf(parms->pool, &args);
		w2 = *args ? getword_conf(parms->pool, &args) : NULL;
		w3 = *args ? getword_conf(parms->pool, &args) : NULL;

		if (*w == '\0' || (w2 && *w2 && !w3) || *args != 0)
			return apr_pstrcat(parms->pool, cmd->name,
			                   " takes one or three arguments",
			                   cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);

		return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);

	case ITERATE:
		w = getword_conf(parms->pool, &args);

		if (*w == '\0')
			return apr_pstrcat(parms->pool, cmd->name,
			                   " requires at least one argument",
			                   cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);

		while (*w != '\0') {
			errmsg = cmd->AP_TAKE1(parms, mconfig, w);

			if (errmsg && strcmp(errmsg, DECLINE_CMD) != 0)
				return errmsg;

			w = getword_conf(parms->pool, &args);
		}

		return errmsg;

	case ITERATE2:
		w = getword_conf(parms->pool, &args);

		if (*w == '\0' || *args == 0)
			return apr_pstrcat(parms->pool, cmd->name,
			                   " requires at least two arguments",
			                   cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);

		while (*(w2 = getword_conf(parms->pool, &args)) != '\0') {

			errmsg = cmd->AP_TAKE2(parms, mconfig, w, w2);

			if (errmsg && strcmp(errmsg, DECLINE_CMD) != 0)
				return errmsg;
		}

		return errmsg;

	case FLAG:
		/*
		 * This is safe to use temp_pool here, because the 'flag' itself is not
		 * forwarded as-is
		 */
		w = getword_conf(parms->temp_pool, &args);

		if (*w == '\0' || (strcasecmp(w, "on") != 0 && strcasecmp(w, "off") != 0))
			return apr_pstrcat(parms->pool, cmd->name, " must be On or Off",
			                   NULL);

		return cmd->AP_FLAG(parms, mconfig, strcasecmp(w, "off") != 0);

	default:
		return apr_pstrcat(parms->pool, cmd->name,
		                   " is improperly configured internally (server bug)",
		                   NULL);
	}
}

static int is_directory(apr_pool_t *p, const char *path)
{
	apr_finfo_t finfo;

	if (apr_stat(&finfo, path, APR_FINFO_TYPE, p) != APR_SUCCESS)
		return 0;                /* in error condition, just return no */

	return (finfo.filetype == APR_DIR);
}

static char *make_full_path(apr_pool_t *a, const char *src1,
                            const char *src2)
{
	apr_size_t len1, len2;
	char *path;

	len1 = strlen(src1);
	len2 = strlen(src2);
	/* allocate +3 for '/' delimiter, trailing NULL and overallocate
	 * one extra byte to allow the caller to add a trailing '/'
	 */
	path = (char *)apr_palloc(a, len1 + len2 + 3);
	if (len1 == 0) {
		*path = '/';
		memcpy(path + 1, src2, len2 + 1);
	}
	else {
		char *next;
		memcpy(path, src1, len1);
		next = path + len1;
		if (next[-1] != '/') {
			*next++ = '/';
		}
		memcpy(next, src2, len2 + 1);
	}
	return path;
}

static int fname_alphasort(const void *fn1, const void *fn2)
{
	const fnames *f1 = fn1;
	const fnames *f2 = fn2;

	return strcmp(f1->fname,f2->fname);
}

static const char *process_resource_config(const char *fname,
                                           apr_array_header_t *ari,
                                           apr_pool_t *p,
                                           apr_pool_t *ptemp)
{
	*(char **)apr_array_push(ari) = (char *)fname;
	return NULL;
}

static const char *process_resource_config_nofnmatch(const char *fname,
                                                     apr_array_header_t *ari,
                                                     apr_pool_t *p,
                                                     apr_pool_t *ptemp,
                                                     unsigned depth,
                                                     int optional)
{
	const char *error;
	apr_status_t rv;

	if (is_directory(ptemp, fname)) {
		apr_dir_t *dirp;
		apr_finfo_t dirent;
		int current;
		apr_array_header_t *candidates = NULL;
		fnames *fnew;
		char *path = apr_pstrdup(ptemp, fname);

		if (++depth > MAX_INCLUDE_DIR_DEPTH) {
			return apr_psprintf(p, "Directory %s exceeds the maximum include "
			                    "directory nesting level of %u. You have "
			                    "probably a recursion somewhere.", path,
			                    MAX_INCLUDE_DIR_DEPTH);
		}

		/*
		 * first course of business is to grok all the directory
		 * entries here and store 'em away. Recall we need full pathnames
		 * for this.
		 */
		rv = apr_dir_open(&dirp, path, ptemp);
		if (rv != APR_SUCCESS) {
			return apr_psprintf(p, "Could not open config directory %s: %pm",
			                    path, &rv);
		}

		candidates = apr_array_make(ptemp, 1, sizeof(fnames));
		while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp) == APR_SUCCESS) {
			/* strip out '.' and '..' */
			if (strcmp(dirent.name, ".") != 0
			    && strcmp(dirent.name, "..") != 0) {
				fnew = (fnames *) apr_array_push(candidates);
				fnew->fname = make_full_path(ptemp, path, dirent.name);
			}
		}

		apr_dir_close(dirp);
		if (candidates->nelts != 0) {
			qsort((void *) candidates->elts, candidates->nelts,
			      sizeof(fnames), fname_alphasort);

			/*
			 * Now recurse these... we handle errors and subdirectories
			 * via the recursion, which is nice
			 */
			for (current = 0; current < candidates->nelts; ++current) {
				fnew = &((fnames *) candidates->elts)[current];
				error = process_resource_config_nofnmatch(fnew->fname,
				                                          ari, p, ptemp,
				                                          depth, optional);
				if (error) {
					return error;
				}
			}
		}

		return NULL;
	}

	return process_resource_config(fname, ari, p, ptemp);
}

static const char *process_resource_config_fnmatch(const char *path,
                                                   const char *fname,
                                                   apr_array_header_t *ari,
                                                   apr_pool_t *p,
                                                   apr_pool_t *ptemp,
                                                   unsigned depth,
                                                   int optional)
{
	const char *rest;
	apr_status_t rv;
	apr_dir_t *dirp;
	apr_finfo_t dirent;
	apr_array_header_t *candidates = NULL;
	fnames *fnew;
	int current;

	/* find the first part of the filename */
	rest = ap_strchr_c(fname, '/');
	if (rest) {
		fname = apr_pstrndup(ptemp, fname, rest - fname);
		rest++;
	}

	/* optimisation - if the filename isn't a wildcard, process it directly */
	if (!apr_fnmatch_test(fname)) {
		path = make_full_path(ptemp, path, fname);
		if (!rest) {
			return process_resource_config_nofnmatch(path,
			                                         ari, p,
			                                         ptemp, 0, optional);
		}
		else {
			return process_resource_config_fnmatch(path, rest,
			                                       ari, p,
			                                       ptemp, 0, optional);
		}
	}

	/*
	 * first course of business is to grok all the directory
	 * entries here and store 'em away. Recall we need full pathnames
	 * for this.
	 */
	rv = apr_dir_open(&dirp, path, ptemp);
	if (rv != APR_SUCCESS) {
		return apr_psprintf(p, "Could not open config directory %s: %pm",
		                    path, &rv);
	}

	candidates = apr_array_make(ptemp, 1, sizeof(fnames));
	while (apr_dir_read(&dirent, APR_FINFO_DIRENT | APR_FINFO_TYPE, dirp) == APR_SUCCESS) {
		/* strip out '.' and '..' */
		if (strcmp(dirent.name, ".") != 0
		    && strcmp(dirent.name, "..") != 0
		    && (apr_fnmatch(fname, dirent.name,
			                APR_FNM_PERIOD) == APR_SUCCESS)) {
			const char *full_path = make_full_path(ptemp, path, dirent.name);
			/* If matching internal to path, and we happen to match something
			 * other than a directory, skip it
			 */
			if (rest && (rv == APR_SUCCESS) && (dirent.filetype != APR_DIR)) {
				continue;
			}
			fnew = (fnames *) apr_array_push(candidates);
			fnew->fname = full_path;
		}
	}

	apr_dir_close(dirp);
	if (candidates->nelts != 0) {
		const char *error;

		qsort((void *) candidates->elts, candidates->nelts,
		      sizeof(fnames), fname_alphasort);

		/*
		 * Now recurse these... we handle errors and subdirectories
		 * via the recursion, which is nice
		 */
		for (current = 0; current < candidates->nelts; ++current) {
			fnew = &((fnames *) candidates->elts)[current];
			if (!rest) {
				error = process_resource_config_nofnmatch(fnew->fname,
				                                          ari, p,
				                                          ptemp, 0, optional);
			}
			else {
				error = process_resource_config_fnmatch(fnew->fname, rest,
				                                        ari, p,
				                                        ptemp, 0, optional);
			}
			if (error) {
				return error;
			}
		}
	}
	else {

		if (!optional) {
			return apr_psprintf(p, "No matches for the wildcard '%s' in '%s', failing "
			                    "(use IncludeOptional if required)", fname, path);
		}
	}

	return NULL;
}

static const char *process_fnmatch_configs(const char *fname,
                                           apr_array_header_t *ari,
                                           apr_pool_t *p,
                                           apr_pool_t *ptemp,
                                           int optional)
{
	if (!apr_fnmatch_test(fname)) {
		return process_resource_config_nofnmatch(fname, ari, p, ptemp, 0, optional);
	}
	else {
		apr_status_t status;
		const char *rootpath, *filepath = fname;

		/* locate the start of the directories proper */
		status = apr_filepath_root(&rootpath, &filepath, APR_FILEPATH_TRUENAME, ptemp);

		/* we allow APR_SUCCESS and APR_EINCOMPLETE */
		if (APR_ERELATIVE == status) {
			return apr_pstrcat(p, "Include must have an absolute path, ", fname, NULL);
		}
		else if (APR_EBADPATH == status) {
			return apr_pstrcat(p, "Include has a bad path, ", fname, NULL);
		}

		/* walk the filepath */
		return process_resource_config_fnmatch(rootpath, filepath, ari, p, ptemp,
		                                       0, optional);
	}
}

const char *read_module_config(server_rec *s, void *mconfig,
                               const command_rec *cmds,
                               apr_pool_t *p, apr_pool_t *ptemp,
                               const char *filename)
{
	apr_array_header_t *ari, *arr;
	ap_directive_t *newdir;
	cmd_parms *parms;

	char line[MAX_STRING_LEN];
	const char *errmsg;
	const char *err = NULL;

	ari = apr_array_make(p, 1, sizeof(char *));
	arr = apr_array_make(p, 1, sizeof(cmd_parms));

	errmsg = process_fnmatch_configs(filename, ari, p, ptemp, 0);

	if (errmsg != NULL)
		goto out;

	while (ari->nelts || arr->nelts) {

		/* similar to process_command_config() */
		if (ari->nelts) {
			char *inc = *(char **)apr_array_pop(ari);

			parms = (cmd_parms *)apr_array_push(arr);
			*parms = default_parms;
			parms->pool = p;
			parms->temp_pool = ptemp;
			parms->server = s;
			parms->override = (RSRC_CONF | ACCESS_CONF);
			parms->override_opts = OPT_ALL | OPT_SYM_OWNER | OPT_MULTI;

			if (pcfg_openfile(&parms->config_file, p, inc) != APR_SUCCESS) {
				apr_array_pop(arr);
				errmsg = apr_pstrcat(p, "Cannot open file: ", inc, NULL);
				goto out;
			}
		}

		if (arr->nelts > MAX_INCLUDE_DIR_DEPTH) {
			errmsg = apr_psprintf(p, "Exceeded the maximum include "
			                      "directory nesting level of %u. You have "
			                      "probably a recursion somewhere.",
			                      MAX_INCLUDE_DIR_DEPTH);
			goto out;
		}

		if (!(parms = (cmd_parms *)apr_array_pop(arr)))
			break;

		while (!(cfg_getline(line, MAX_STRING_LEN, parms->config_file))) {

			const command_rec *cmd;
			char *cmd_name;
			const char *args = line;
			int optional = 0;

			if (*line == '#' || *line == '\0')
				continue;

			if (!(cmd_name = getword_conf(p, &args)))
				continue;

			/* similar to invoke_cmd() */
			if (strcasecmp(cmd_name, "IncludeOptional") == 0 ||
			    strcasecmp(cmd_name, "Include") == 0)
			{
				char *w, *fullname;

				if (strcasecmp(cmd_name, "IncludeOptional") == 0)
					optional = 1;

				w = getword_conf(parms->pool, &args);

				if (*w == '\0' || *args != 0) {
					errmsg = apr_pstrcat(parms->pool, cmd_name, " takes one argument", NULL);
					goto out;
				}

				fullname = ap_server_root_relative(ptemp, w);
				errmsg = process_fnmatch_configs(fullname, ari, p, ptemp, optional);

				*(cmd_parms *)apr_array_push(arr) = *parms;

				if(errmsg != NULL)
					goto out;

				parms = NULL;
				break;
			}

			if (!(cmd = find_command(cmd_name, cmds))) {
				errmsg = apr_pstrcat(parms->pool, "Invalid command '",
				                     cmd_name, "'", NULL);
				goto out;
			}

			newdir = apr_pcalloc(p, sizeof(ap_directive_t));
			newdir->filename = parms->config_file->name;
			newdir->line_num = parms->config_file->line_number;
			newdir->directive = cmd_name;
			newdir->args = apr_pstrdup(p, args);

			parms->directive = newdir;

			if ((errmsg = invoke_cmd(cmd, parms, mconfig, args)) != NULL)
				break;
		}

		if (parms != NULL)
			cfg_closefile(parms->config_file);

		if (errmsg != NULL)
			break;
	}

	if (errmsg) {
		if (parms) {
			err = apr_psprintf(p, "Syntax error on line %d of %s: %s",
			                   parms->config_file->line_number,
			                   parms->config_file->name,
			                   errmsg);
			errmsg = err;
		}
	}

out:

	while ((parms = (cmd_parms *)apr_array_pop(arr)) != NULL)
		cfg_closefile(parms->config_file);

	return errmsg;
}

int lookup_builtin_method(const char *method, apr_size_t len)
{
	/* Note: from Apache 2 HTTP Server source. */

	/* Note: the following code was generated by the "shilka" tool from
	   the "cocom" parsing/compilation toolkit. It is an optimized lookup
	   based on analysis of the input keywords. Postprocessing was done
	   on the shilka output, but the basic structure and analysis is
	   from there. Should new HTTP methods be added, then manual insertion
	   into this code is fine, or simply re-running the shilka tool on
	   the appropriate input. */

	/* Note: it is also quite reasonable to just use our method_registry,
	   but I'm assuming (probably incorrectly) we want more speed here
	   (based on the optimizations the previous code was doing). */

	switch (len)
	{
	case 3:
		switch (method[0])
		{
		case 'P':
			return (method[1] == 'U'
			        && method[2] == 'T'
			        ? M_PUT : UNKNOWN_METHOD);
		case 'G':
			return (method[1] == 'E'
			        && method[2] == 'T'
			        ? M_GET : UNKNOWN_METHOD);
		default:
			return UNKNOWN_METHOD;
		}

	case 4:
		switch (method[0])
		{
		case 'H':
			return (method[1] == 'E'
			        && method[2] == 'A'
			        && method[3] == 'D'
			        ? M_GET : UNKNOWN_METHOD);
		case 'P':
			return (method[1] == 'O'
			        && method[2] == 'S'
			        && method[3] == 'T'
			        ? M_POST : UNKNOWN_METHOD);
		case 'M':
			return (method[1] == 'O'
			        && method[2] == 'V'
			        && method[3] == 'E'
			        ? M_MOVE : UNKNOWN_METHOD);
		case 'L':
			return (method[1] == 'O'
			        && method[2] == 'C'
			        && method[3] == 'K'
			        ? M_LOCK : UNKNOWN_METHOD);
		case 'C':
			return (method[1] == 'O'
			        && method[2] == 'P'
			        && method[3] == 'Y'
			        ? M_COPY : UNKNOWN_METHOD);
		default:
			return UNKNOWN_METHOD;
		}

	case 5:
		switch (method[2])
		{
		case 'T':
			return (memcmp(method, "PATCH", 5) == 0
			        ? M_PATCH : UNKNOWN_METHOD);
		case 'R':
			return (memcmp(method, "MERGE", 5) == 0
			        ? M_MERGE : UNKNOWN_METHOD);
		case 'C':
			return (memcmp(method, "MKCOL", 5) == 0
			        ? M_MKCOL : UNKNOWN_METHOD);
		case 'B':
			return (memcmp(method, "LABEL", 5) == 0
			        ? M_LABEL : UNKNOWN_METHOD);
		case 'A':
			return (memcmp(method, "TRACE", 5) == 0
			        ? M_TRACE : UNKNOWN_METHOD);
		default:
			return UNKNOWN_METHOD;
		}

	case 6:
		switch (method[0])
		{
		case 'U':
			switch (method[5])
			{
			case 'K':
				return (memcmp(method, "UNLOCK", 6) == 0
				        ? M_UNLOCK : UNKNOWN_METHOD);
			case 'E':
				return (memcmp(method, "UPDATE", 6) == 0
				        ? M_UPDATE : UNKNOWN_METHOD);
			default:
				return UNKNOWN_METHOD;
			}
		case 'R':
			return (memcmp(method, "REPORT", 6) == 0
			        ? M_REPORT : UNKNOWN_METHOD);
		case 'D':
			return (memcmp(method, "DELETE", 6) == 0
			        ? M_DELETE : UNKNOWN_METHOD);
		default:
			return UNKNOWN_METHOD;
		}

	case 7:
		switch (method[1])
		{
		case 'P':
			return (memcmp(method, "OPTIONS", 7) == 0
			        ? M_OPTIONS : UNKNOWN_METHOD);
		case 'O':
			return (memcmp(method, "CONNECT", 7) == 0
			        ? M_CONNECT : UNKNOWN_METHOD);
		case 'H':
			return (memcmp(method, "CHECKIN", 7) == 0
			        ? M_CHECKIN : UNKNOWN_METHOD);
		default:
			return UNKNOWN_METHOD;
		}

	case 8:
		switch (method[0])
		{
		case 'P':
			return (memcmp(method, "PROPFIND", 8) == 0
			        ? M_PROPFIND : UNKNOWN_METHOD);
		case 'C':
			return (memcmp(method, "CHECKOUT", 8) == 0
			        ? M_CHECKOUT : UNKNOWN_METHOD);
		default:
			return UNKNOWN_METHOD;
		}

	case 9:
		return (memcmp(method, "PROPPATCH", 9) == 0
                ? M_PROPPATCH : UNKNOWN_METHOD);

	case 10:
		switch (method[0])
		{
		case 'U':
			return (memcmp(method, "UNCHECKOUT", 10) == 0
			        ? M_UNCHECKOUT : UNKNOWN_METHOD);
		case 'M':
			return (memcmp(method, "MKACTIVITY", 10) == 0
			        ? M_MKACTIVITY : UNKNOWN_METHOD);
		default:
			return UNKNOWN_METHOD;
		}

	case 11:
		return (memcmp(method, "MKWORKSPACE", 11) == 0
		        ? M_MKWORKSPACE : UNKNOWN_METHOD);

	case 15:
		return (memcmp(method, "VERSION-CONTROL", 15) == 0
		        ? M_VERSION_CONTROL : UNKNOWN_METHOD);

	case 16:
		return (memcmp(method, "BASELINE-CONTROL", 16) == 0
		        ? M_BASELINE_CONTROL : UNKNOWN_METHOD);

	default:
		return UNKNOWN_METHOD;
	}

	/* NOTREACHED */
}
