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 &lt;Files&gt; or &lt;If&gt;*/
+ #define  NOT_IN_HTACCESS        0x20 /**< Forbidden in .htaccess files */
+ #define  NOT_IN_PROXY           0x40 /**< Forbidden in &lt;Proxy&gt; */
++#define  BUT_IN_HOSTGROUP       0x80 /**< Allowed in &lt;HostGroup&gt; */
+ /** Forbidden in &lt;Directory&gt;/&lt;Location&gt;/&lt;Files&gt;&lt;If&gt;*/
+ #define  NOT_IN_DIR_LOC_FILE    (NOT_IN_DIRECTORY|NOT_IN_LOCATION|NOT_IN_FILES)
+ /** Forbidden in &lt;Directory&gt;/&lt;Location&gt;/&lt;Files&gt;&lt;If&gt;&lt;Proxy&gt;*/
+@@ -956,6 +957,7 @@
+ #define  NOT_IN_DIR_CONTEXT     (NOT_IN_LIMIT|NOT_IN_DIR_LOC_FILE|NOT_IN_PROXY)
+ /** Forbidden in &lt;VirtualHost&gt;/&lt;Limit&gt;/&lt;Directory&gt;/&lt;Location&gt;/&lt;Files&gt;/&lt;If&gt;&lt;Proxy&gt;*/
+ #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"),