You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2018/02/12 13:55:14 UTC
svn commit: r1823968 - /httpd/httpd/patches/trunk/hostgroup-v1.0.diff
Author: icing
Date: Mon Feb 12 13:55:14 2018
New Revision: 1823968
URL: http://svn.apache.org/viewvc?rev=1823968&view=rev
Log:
hostgroup patch v1.0
Added:
httpd/httpd/patches/trunk/hostgroup-v1.0.diff
Added: httpd/httpd/patches/trunk/hostgroup-v1.0.diff
URL: http://svn.apache.org/viewvc/httpd/httpd/patches/trunk/hostgroup-v1.0.diff?rev=1823968&view=auto
==============================================================================
--- httpd/httpd/patches/trunk/hostgroup-v1.0.diff (added)
+++ httpd/httpd/patches/trunk/hostgroup-v1.0.diff Mon Feb 12 13:55:14 2018
@@ -0,0 +1,547 @@
+Index: include/ap_mmn.h
+===================================================================
+--- include/ap_mmn.h (revision 1823929)
++++ include/ap_mmn.h (working copy)
+@@ -562,6 +562,7 @@
+ * 20171014.2 (2.5.1-dev) Add "use_specific_errors" to listen_rec and
+ * ap_accept_error_is_nonfatal()
+ * 20171014.3 (2.5.1-dev) AP_DECLARE ap_parse_vhost_addrs() as public
++ * 20171014.4 (2.5.1-dev) Adding child, sibling and parent pointers to server_rec
+ */
+
+ #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
+Index: include/http_config.h
+===================================================================
+--- include/http_config.h (revision 1823929)
++++ include/http_config.h (working copy)
+@@ -950,6 +950,7 @@
+ #define NOT_IN_FILES 0x10 /**< Forbidden in <Files> or <If>*/
+ #define NOT_IN_HTACCESS 0x20 /**< Forbidden in .htaccess files */
+ #define NOT_IN_PROXY 0x40 /**< Forbidden in <Proxy> */
++#define BUT_IN_HOSTGROUP 0x80 /**< Allowed in <HostGroup> */
+ /** Forbidden in <Directory>/<Location>/<Files><If>*/
+ #define NOT_IN_DIR_LOC_FILE (NOT_IN_DIRECTORY|NOT_IN_LOCATION|NOT_IN_FILES)
+ /** Forbidden in <Directory>/<Location>/<Files><If><Proxy>*/
+@@ -956,6 +957,7 @@
+ #define NOT_IN_DIR_CONTEXT (NOT_IN_LIMIT|NOT_IN_DIR_LOC_FILE|NOT_IN_PROXY)
+ /** Forbidden in <VirtualHost>/<Limit>/<Directory>/<Location>/<Files>/<If><Proxy>*/
+ #define GLOBAL_ONLY (NOT_IN_VIRTUALHOST|NOT_IN_DIR_CONTEXT)
++#define GLOBAL_AND_HOSTGROUP (GLOBAL_ONLY|BUT_IN_HOSTGROUP)
+
+ /** @} */
+
+@@ -1164,16 +1166,29 @@
+ * Setup a virtual host
+ * @param p The pool to allocate all memory from
+ * @param hostname The hostname of the virtual hsot
+- * @param main_server The main server for this Apache configuration
++ * @param parent The main server for this Apache configuration or a host group
+ * @param ps Place to store the new server_rec
+ * return Error string on error, NULL on success
+ */
+ AP_CORE_DECLARE(const char *) ap_init_virtual_host(apr_pool_t *p,
+ const char *hostname,
+- server_rec *main_server,
++ server_rec *parent,
+ server_rec **ps);
+
+ /**
++ * Setup a host group
++ * @param p The pool to allocate all memory from
++ * @param groupname The name of the group, must be unique
++ * @param parent The main server for this Apache configuration
++ * @param ps Place to store the new server_rec
++ * return Error string on error, NULL on success
++ */
++AP_CORE_DECLARE(const char *) ap_init_host_group(apr_pool_t *p,
++ const char *groupname,
++ server_rec *parent,
++ server_rec **ps);
++
++/**
+ * Process a config file for Apache
+ * @param s The server rec to use for the command parms
+ * @param fname The name of the config file
+Index: include/httpd.h
+===================================================================
+--- include/httpd.h (revision 1823929)
++++ include/httpd.h (working copy)
+@@ -1388,6 +1388,13 @@
+ * inherited (0) from the base server (either first
+ * server on the same IP:port or main server) */
+ unsigned int keep_alive_timeout_set:1;
++
++ /** This first server_rec defined inside this one */
++ server_rec *child;
++ /** The next server_rec with the same parent */
++ server_rec *sibling;
++ /** The parent server_rec, NULL for the base server */
++ server_rec *parent;
+ };
+
+ /**
+Index: server/config.c
+===================================================================
+--- server/config.c (revision 1823929)
++++ server/config.c (working copy)
+@@ -309,9 +309,9 @@
+ return (ap_conf_vector_t *)conf_vector;
+ }
+
+-static ap_conf_vector_t *create_server_config(apr_pool_t *p, server_rec *s)
++static void init_server_config(apr_pool_t *p, server_rec *s)
+ {
+- void **conf_vector = apr_pcalloc(p, sizeof(void *) * conf_vector_length);
++ void **conf_vector = (void **)s->module_config;
+ module *modp;
+
+ for (modp = ap_top_module; modp; modp = modp->next) {
+@@ -318,8 +318,6 @@
+ if (modp->create_server_config)
+ conf_vector[modp->module_index] = (*modp->create_server_config)(p, s);
+ }
+-
+- return (ap_conf_vector_t *)conf_vector;
+ }
+
+ static void merge_server_configs(apr_pool_t *p, ap_conf_vector_t *base,
+@@ -2271,44 +2269,46 @@
+ return OK;
+ }
+
++static void link_server_rec(server_rec *parent, server_rec *s);
++static server_rec *init_server_rec(apr_pool_t *p, server_rec *parent, process_rec *process);
++
+ AP_CORE_DECLARE(const char *) ap_init_virtual_host(apr_pool_t *p,
+ const char *hostname,
+- server_rec *main_server,
++ server_rec *parent,
+ server_rec **ps)
+ {
+- server_rec *s = (server_rec *) apr_pcalloc(p, sizeof(server_rec));
+-
+- /* TODO: this crap belongs in http_core */
+- s->process = main_server->process;
+- s->server_admin = NULL;
+- s->server_hostname = NULL;
+- s->server_scheme = NULL;
+- s->error_fname = NULL;
+- s->timeout = 0;
+- s->keep_alive_timeout = 0;
+- s->keep_alive = -1;
+- s->keep_alive_max = -1;
+- s->error_log = main_server->error_log;
+- s->log.level = APLOG_UNSET;
+- s->log.module_levels = NULL;
+- /* useful default, otherwise we get a port of 0 on redirects */
+- s->port = main_server->port;
+- s->next = NULL;
+-
++ server_rec *s = init_server_rec(p, parent, NULL);
++ const char *err;
++
+ s->is_virtual = 1;
+- s->names = apr_array_make(p, 4, sizeof(char **));
+- s->wild_names = apr_array_make(p, 4, sizeof(char **));
++ err = ap_parse_vhost_addrs(p, hostname, s);
++ if (!err) {
++ link_server_rec(parent, s);
++ }
++ *ps = s;
++ return err;
++}
+
+- s->module_config = create_empty_config(p);
+- s->lookup_defaults = ap_create_per_dir_config(p);
+-
+- s->limit_req_line = main_server->limit_req_line;
+- s->limit_req_fieldsize = main_server->limit_req_fieldsize;
+- s->limit_req_fields = main_server->limit_req_fields;
+-
++AP_CORE_DECLARE(const char *) ap_init_host_group(apr_pool_t *p,
++ const char *groupname,
++ server_rec *parent,
++ server_rec **ps)
++{
++ server_rec *s;
++
++ for (s = parent->child; s; s = s->sibling) {
++ if (s->server_hostname
++ && !apr_strnatcasecmp(groupname, s->server_hostname)) {
++ return apr_psprintf(p, "HostGroup/VirtualHost already defined: %s", groupname);
++ }
++ }
++
++ s = init_server_rec(p, parent, NULL);
++ s->server_hostname = apr_pstrdup(p, groupname);
++ link_server_rec(parent, s);
+ *ps = s;
+-
+- return ap_parse_vhost_addrs(p, hostname, s);
++
++ return NULL;
+ }
+
+ AP_DECLARE(struct ap_logconf *) ap_new_log_config(apr_pool_t *p,
+@@ -2351,47 +2351,68 @@
+ }
+ }
+
+-AP_DECLARE(void) ap_fixup_virtual_hosts(apr_pool_t *p, server_rec *main_server)
++static void merge_server_recs(apr_pool_t *p, server_rec *from, server_rec *to)
+ {
+- server_rec *virt;
+- core_dir_config *dconf =
+- ap_get_core_module_config(main_server->lookup_defaults);
+- dconf->log = &main_server->log;
++ merge_server_configs(p, from->module_config, to);
++ to->lookup_defaults = ap_merge_per_dir_configs(p, from->lookup_defaults,
++ to->lookup_defaults);
++
++ if (to->server_admin == NULL)
++ to->server_admin = from->server_admin;
++
++ if (to->timeout == 0)
++ to->timeout = from->timeout;
++
++ if (to->keep_alive_timeout == 0)
++ to->keep_alive_timeout = from->keep_alive_timeout;
++
++ if (to->keep_alive == -1)
++ to->keep_alive = from->keep_alive;
++
++ if (to->keep_alive_max == -1)
++ to->keep_alive_max = from->keep_alive_max;
++
++ ap_merge_log_config(&from->log, &to->log);
+
+- for (virt = main_server->next; virt; virt = virt->next) {
+- merge_server_configs(p, main_server->module_config, virt);
++ /* Certain things are only inherited from hostgroups to descendants */
++ if (from->parent) {
++ if (!to->server_hostname)
++ to->server_hostname = from->server_hostname;
+
+- virt->lookup_defaults =
+- ap_merge_per_dir_configs(p, main_server->lookup_defaults,
+- virt->lookup_defaults);
++ if (!to->names || apr_is_empty_array(to->names))
++ to->names = from->names;
+
+- if (virt->server_admin == NULL)
+- virt->server_admin = main_server->server_admin;
++ if (!to->wild_names || apr_is_empty_array(to->wild_names))
++ to->wild_names = from->wild_names;
++ }
++}
+
+- if (virt->timeout == 0)
+- virt->timeout = main_server->timeout;
++static void fixup_host_groups_inside(apr_pool_t *p, server_rec *s)
++{
++ server_rec *child;
++
++ /* Just in case we ever want to nest these, do recursion. */
++ for (child = s->child; child; child = child->sibling) {
++ merge_server_recs(p, s, child);
++ fixup_host_groups_inside(p, child);
++ }
++ ap_core_reorder_directories(p, s);
++}
+
+- if (virt->keep_alive_timeout == 0)
+- virt->keep_alive_timeout = main_server->keep_alive_timeout;
++AP_DECLARE(void) ap_fixup_virtual_hosts(apr_pool_t *p, server_rec *main_server)
++{
++ server_rec *virt;
++ core_dir_config *dconf;
++
++ dconf = ap_get_core_module_config(main_server->lookup_defaults);
++ dconf->log = &main_server->log;
+
+- if (virt->keep_alive == -1)
+- virt->keep_alive = main_server->keep_alive;
+-
+- if (virt->keep_alive_max == -1)
+- virt->keep_alive_max = main_server->keep_alive_max;
+-
+- ap_merge_log_config(&main_server->log, &virt->log);
+-
++ fixup_host_groups_inside(p, main_server);
++
++ for (virt = main_server->next; virt; virt = virt->next) {
+ dconf = ap_get_core_module_config(virt->lookup_defaults);
+ dconf->log = &virt->log;
+-
+- /* XXX: this is really something that should be dealt with by a
+- * post-config api phase
+- */
+- ap_core_reorder_directories(p, virt);
+ }
+-
+- ap_core_reorder_directories(p, main_server);
+ }
+
+ /*****************************************************************
+@@ -2405,46 +2426,93 @@
+ ap_init_vhost_config(p);
+ }
+
+-static server_rec *init_server_config(process_rec *process, apr_pool_t *p)
++static void link_server_rec(server_rec *parent, server_rec *s)
+ {
++ server_rec **pchild, *root;
++
++ pchild = &parent->child;
++ while (*pchild) {
++ pchild = &((*pchild)->sibling);
++ }
++ *pchild = s;
++
++ if (s->is_virtual) {
++ /* VirtualHosts immediately apppear on the server->next list of the root server */
++ root = parent;
++ while (root->parent) {
++ root = root->parent;
++ }
++ s->next = root->next;
++ root->next = s;
++ }
++}
++
++static server_rec *init_server_rec(apr_pool_t *p, server_rec *parent, process_rec *process)
++{
+ apr_status_t rv;
+ server_rec *s = (server_rec *) apr_pcalloc(p, sizeof(server_rec));
+
+- apr_file_open_stderr(&s->error_log, p);
+- s->process = process;
+- s->port = 0;
+- s->server_admin = DEFAULT_ADMIN;
+- s->server_hostname = NULL;
+- s->server_scheme = NULL;
+- s->error_fname = DEFAULT_ERRORLOG;
+- s->log.level = DEFAULT_LOGLEVEL;
+- s->log.module_levels = NULL;
+- s->limit_req_line = DEFAULT_LIMIT_REQUEST_LINE;
+- s->limit_req_fieldsize = DEFAULT_LIMIT_REQUEST_FIELDSIZE;
+- s->limit_req_fields = DEFAULT_LIMIT_REQUEST_FIELDS;
+- s->timeout = apr_time_from_sec(DEFAULT_TIMEOUT);
+- s->keep_alive_timeout = apr_time_from_sec(DEFAULT_KEEPALIVE_TIMEOUT);
+- s->keep_alive_max = DEFAULT_KEEPALIVE;
+- s->keep_alive = 1;
+- s->next = NULL;
+- s->addrs = apr_pcalloc(p, sizeof(server_addr_rec));
++ s->module_config = create_empty_config(p);
++ s->lookup_defaults = create_default_per_dir_config(p);
++
++ if (parent) {
++ s->process = parent->process;
++ s->parent = parent;
++
++ /* Mark some fields unset, so config is retrieved at parent */
++ s->error_log = parent->error_log;
++ s->log.level = APLOG_UNSET;
++
++ /* Inherit some fields right away */
++ /* FIXME: should this not all happen at server_rec merging when all config
++ * directives for the parent server are in effect? */
++ s->limit_req_line = parent->limit_req_line;
++ s->limit_req_fieldsize = parent->limit_req_fieldsize;
++ s->limit_req_fields = parent->limit_req_fields;
+
+- /* NOT virtual host; don't match any real network interface */
+- rv = apr_sockaddr_info_get(&s->addrs->host_addr,
+- NULL, APR_UNSPEC, 0, 0, p);
+- if (rv != APR_SUCCESS) {
+- /* should we test here for rv being an EAIERR? */
+- ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, rv, NULL, APLOGNO(00530)
+- "initialisation: bug or getaddrinfo fail");
+- return NULL;
++ /* useful default, otherwise we get a port of 0 on redirects */
++ s->port = parent->port;
++ s->keep_alive_max = -1;
++ s->keep_alive = -1;
++
++ /* only child server_recs have these */
++ s->names = apr_array_make(p, 4, sizeof(char **));
++ s->wild_names = apr_array_make(p, 4, sizeof(char **));
+ }
++ else {
++ apr_file_open_stderr(&s->error_log, p);
++ s->process = process;
++
++ s->server_admin = DEFAULT_ADMIN;
++ s->error_fname = DEFAULT_ERRORLOG;
++ s->log.level = DEFAULT_LOGLEVEL;
+
+- s->addrs->host_port = 0; /* matches any port */
+- s->addrs->virthost = ""; /* must be non-NULL */
+- s->names = s->wild_names = NULL;
++ s->limit_req_line = DEFAULT_LIMIT_REQUEST_LINE;
++ s->limit_req_fieldsize = DEFAULT_LIMIT_REQUEST_FIELDSIZE;
++ s->limit_req_fields = DEFAULT_LIMIT_REQUEST_FIELDS;
+
+- s->module_config = create_server_config(p, s);
+- s->lookup_defaults = create_default_per_dir_config(p);
++ s->timeout = apr_time_from_sec(DEFAULT_TIMEOUT);
++ s->keep_alive_timeout = apr_time_from_sec(DEFAULT_KEEPALIVE_TIMEOUT);
++ s->keep_alive_max = DEFAULT_KEEPALIVE;
++ s->keep_alive = 1;
++
++ s->addrs = apr_pcalloc(p, sizeof(server_addr_rec));
++ /* NOT virtual host; don't match any real network interface */
++ rv = apr_sockaddr_info_get(&s->addrs->host_addr,
++ NULL, APR_UNSPEC, 0, 0, p);
++ if (rv != APR_SUCCESS) {
++ /* should we test here for rv being an EAIERR? */
++ ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, rv, NULL, APLOGNO(00530)
++ "initialisation: bug or getaddrinfo fail");
++ return NULL;
++ }
++
++ s->addrs->host_port = 0; /* matches any port */
++ s->addrs->virthost = ""; /* must be non-NULL */
++ s->names = s->wild_names = NULL;
++
++ init_server_config(p, s);
++ }
+
+ return s;
+ }
+@@ -2488,7 +2556,7 @@
+ {
+ const char *confname, *error;
+ apr_pool_t *p = process->pconf;
+- server_rec *s = init_server_config(process, p);
++ server_rec *s = init_server_rec(p, NULL, process);
+ if (s == NULL) {
+ return s;
+ }
+Index: server/core.c
+===================================================================
+--- server/core.c (revision 1823929)
++++ server/core.c (working copy)
+@@ -1285,6 +1285,12 @@
+ " cannot occur within <VirtualHost> section", NULL);
+ }
+
++ if ((forbidden & NOT_IN_VIRTUALHOST) && cmd->server->parent
++ && !(forbidden & BUT_IN_HOSTGROUP)) {
++ return apr_pstrcat(cmd->pool, cmd->cmd->name, gt,
++ " cannot occur within <HostGroup> section", NULL);
++ }
++
+ if ((forbidden & NOT_IN_DIR_CONTEXT) && cmd->limited != -1) {
+ return apr_pstrcat(cmd->pool, cmd->cmd->name, gt,
+ " cannot occur within <Limit> or <LimitExcept> "
+@@ -2854,12 +2860,12 @@
+ return ap_exists_directive(cmd->temp_pool, name);
+ }
+
+-/* httpd.conf commands... beginning with the <VirtualHost> business */
++/* httpd.conf commands... beginning with the <HostGroup> business */
+
+-static const char *virtualhost_section(cmd_parms *cmd, void *dummy,
+- const char *arg)
++static const char *hostgroup_section(cmd_parms *cmd, void *dummy,
++ const char *arg)
+ {
+- server_rec *main_server = cmd->server, *s;
++ server_rec *parent = cmd->server, *s;
+ const char *errmsg;
+ const char *endp = ap_strrchr_c(arg, '>');
+ apr_pool_t *p = cmd->pool;
+@@ -2879,23 +2885,68 @@
+ return missing_container_arg(cmd);
+ }
+
++ /* We could allow it inside itself - one day maybe. */
++ if (parent->parent) {
++ return "<HostGroup> doesn't nest!";
++ }
++
++ errmsg = ap_init_host_group(p, arg, parent, &s);
++ if (errmsg) {
++ return errmsg;
++ }
++
++ s->defn_name = cmd->directive->filename;
++ s->defn_line_number = cmd->directive->line_num;
++
++ cmd->server = s;
++
++ errmsg = ap_walk_config(cmd->directive->first_child, cmd,
++ s->lookup_defaults);
++
++ cmd->server = parent;
++
++ return errmsg;
++}
++
++static const char *virtualhost_section(cmd_parms *cmd, void *dummy,
++ const char *arg)
++{
++ server_rec *parent = cmd->server, *s;
++ const char *errmsg;
++ const char *endp = ap_strrchr_c(arg, '>');
++ apr_pool_t *p = cmd->pool;
++
++ if (!parent->parent || parent->is_virtual) {
++ errmsg = ap_check_cmd_context(cmd, GLOBAL_AND_HOSTGROUP);
++ if (errmsg != NULL) {
++ return errmsg;
++ }
++ }
++
++ if (endp == NULL) {
++ return unclosed_directive(cmd);
++ }
++
++ arg = apr_pstrndup(cmd->temp_pool, arg, endp - arg);
++
++ if (!arg[0]) {
++ return missing_container_arg(cmd);
++ }
++
+ /* FIXME: There's another feature waiting to happen here -- since you
+ can now put multiple addresses/names on a single <VirtualHost>
+ you might want to use it to group common definitions and then
+ define other "subhosts" with their individual differences. But
+ personally I'd rather just do it with a macro preprocessor. -djg */
+- if (main_server->is_virtual) {
++ if (parent->is_virtual) {
+ return "<VirtualHost> doesn't nest!";
+ }
+
+- errmsg = ap_init_virtual_host(p, arg, main_server, &s);
++ errmsg = ap_init_virtual_host(p, arg, parent, &s);
+ if (errmsg) {
+ return errmsg;
+ }
+
+- s->next = main_server->next;
+- main_server->next = s;
+-
+ s->defn_name = cmd->directive->filename;
+ s->defn_line_number = cmd->directive->line_num;
+
+@@ -2904,7 +2955,7 @@
+ errmsg = ap_walk_config(cmd->directive->first_child, cmd,
+ s->lookup_defaults);
+
+- cmd->server = main_server;
++ cmd->server = parent;
+
+ return errmsg;
+ }
+@@ -4450,6 +4501,9 @@
+ AP_INIT_RAW_ARGS("<Location", urlsection, NULL, RSRC_CONF,
+ "Container for directives affecting resources accessed through the "
+ "specified URL paths"),
++AP_INIT_RAW_ARGS("<HostGroup", hostgroup_section, NULL, RSRC_CONF,
++ "Container to map directives all contained virtual hosts, takes one "
++ "unique name that defaults to ServerName of all contained hosts."),
+ AP_INIT_RAW_ARGS("<VirtualHost", virtualhost_section, NULL, RSRC_CONF,
+ "Container to map directives to a particular virtual host, takes one or "
+ "more host addresses"),