Received: by taz.hyperreal.com (8.6.12/8.6.5) id AAA01322; Wed, 3 Apr 1996 00:39:15 -0800 Received: from mail.barrnet.net by taz.hyperreal.com (8.6.12/8.6.5) with ESMTP id AAA01317; Wed, 3 Apr 1996 00:39:13 -0800 Received: from ace.nueva.pvt.k12.ca.us (ace.nueva.pvt.k12.ca.us [198.31.42.1]) by mail.barrnet.net (8.7.5/MAIL-RELAY-LEN) with ESMTP id AAA08482 for ; Wed, 3 Apr 1996 00:39:18 -0800 (PST) Received: from localhost by ace.nueva.pvt.k12.ca.us with SMTP (1.37.109.16/15.5+ECS 3.3+HPL1.1) id AA251800756; Wed, 3 Apr 1996 00:39:16 -0800 Date: Wed, 3 Apr 1996 00:39:16 -0800 (PST) From: Alexei Kosut To: new-httpd@hyperreal.com Subject: For review... patch Message-Id: Mime-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-new-httpd@apache.org Precedence: bulk Reply-To: new-httpd@hyperreal.com Status: O X-Status: Hi. At the bottom of this email is a patch that implements a feature that I think Apache's been missing for possibly a long time: It adds a new directive, . This directive acts almost identically to , except it takes a URL instead of a filename. These are parsed, in the order they appear, prior to parsing the sections and .htaccess files. Though maybe they should be parsed afterwards (which would have the effect of overriding them, instead of vice versa - I'm not sure). Regardless, you might use to protect HTTP proxy requests, or for all user requests, or , or whatever else you want. I think it's useful. Especially as Apache starts to process requests that have no file related to them (proxy requests, the status module, etc..) At any rate, I submit the patch for review. Unless someone objects, I'll plan to commit it on Friday evening. Index: http_core.c =================================================================== RCS file: /export/home/cvs/apache/src/http_core.c,v retrieving revision 1.9 diff -c -r1.9 http_core.c *** http_core.c 1996/04/02 10:20:48 1.9 --- http_core.c 1996/04/03 08:22:30 *************** *** 135,140 **** --- 135,141 ---- conf->access_name = is_virtual ? NULL : DEFAULT_ACCESS_FNAME; conf->document_root = is_virtual ? NULL : DOCUMENT_LOCATION; conf->sec = make_array (a, 40, sizeof(void *)); + conf->sec_url = make_array (a, 40, sizeof(void *)); return (void *)conf; } *************** *** 150,155 **** --- 151,157 ---- if (!conf->access_name) conf->access_name = base->access_name; if (!conf->document_root) conf->document_root = base->document_root; conf->sec = append_arrays (p, virt->sec, base->sec); + conf->sec_url = append_arrays (p, virt->sec_url, base->sec_url); return conf; } *************** *** 167,172 **** --- 169,183 ---- *new_space = dir_config; } + void add_per_url_conf (server_rec *s, void *url_config) + { + core_server_config *sconf = get_module_config (s->module_config, + &core_module); + void **new_space = (void **) push_array (sconf->sec_url); + + *new_space = url_config; + } + /***************************************************************** * * There are some elements of the core config structures in which *************** *** 513,518 **** --- 524,567 ---- return errmsg; } + static char *end_url_magic = " outside of any section"; + + char *end_urlsection (cmd_parms *cmd, void *dummy) { + return end_url_magic; + } + + char *urlsection (cmd_parms *cmd, void *dummy, char *arg) + { + char *errmsg, *endp = strrchr (arg, '>'); + int old_overrides = cmd->override; + char *old_path = cmd->path; + core_dir_config *conf; + + void *new_url_conf = create_per_dir_config (cmd->pool); + + if (endp) *endp = '\0'; + + if (cmd->path) return " sections don't nest"; + if (cmd->limited != -1) return "Can't have within "; + + cmd->path = getword_conf (cmd->pool, &arg); + /* We don't want anything else, since it just gets zapped anyhow... */ + cmd->override = OR_AUTHCFG|OR_LIMIT|ACCESS_CONF; + + errmsg = srm_command_loop (cmd, new_url_conf); + + conf = (core_dir_config *)get_module_config(new_url_conf, &core_module); + conf->d = pstrdup(cmd->pool, cmd->path); /* No mangling, please */ + + add_per_url_conf (cmd->server, new_url_conf); + + cmd->path = old_path; + cmd->override = old_overrides; + + if (errmsg == end_url_magic) return NULL; + return errmsg; + } + /* httpd.conf commands... beginning with the business */ char *end_virthost_magic = " out of place"; *************** *** 707,712 **** --- 756,763 ---- { "", end_dirsection, NULL, ACCESS_CONF, NO_ARGS, NULL }, + { "", end_urlsection, NULL, ACCESS_CONF, NO_ARGS, NULL }, { "", endlimit, NULL, OR_ALL, RAW_ARGS, NULL }, { "AuthType", set_string_slot, (void*)XtOffsetOf(core_dir_config, auth_type), Index: http_core.h =================================================================== RCS file: /export/home/cvs/apache/src/http_core.h,v retrieving revision 1.5 diff -c -r1.5 http_core.h *** http_core.h 1996/03/21 03:50:15 1.5 --- http_core.h 1996/04/03 08:22:31 *************** *** 168,173 **** --- 168,174 ---- char *access_name; array_header *sec; + array_header *sec_url; } core_server_config; #endif Index: http_request.c =================================================================== RCS file: /export/home/cvs/apache/src/http_request.c,v retrieving revision 1.4 diff -c -r1.4 http_request.c *** http_request.c 1996/03/31 01:06:59 1.4 --- http_request.c 1996/04/03 08:22:34 *************** *** 192,206 **** core_server_config *sconf = get_module_config (r->server->module_config, &core_module); array_header *sec_array = copy_array (r->pool, sconf->sec); core_dir_config **sec = (core_dir_config **)sec_array->elts; int num_sec = sec_array->nelts; - void *per_dir_defaults = r->server->lookup_defaults; char *test_filename = pstrdup (r->pool, r->filename); int num_dirs, res; int i; /* Go down the directory hierarchy. Where we have to check for symlinks, * do so. Where a .htaccess file has permission to override anything, * try to find one. If either of these things fails, we could poke --- 192,261 ---- core_server_config *sconf = get_module_config (r->server->module_config, &core_module); array_header *sec_array = copy_array (r->pool, sconf->sec); + array_header *url_array = copy_array (r->pool, sconf->sec_url); + void *per_dir_defaults = r->server->lookup_defaults; core_dir_config **sec = (core_dir_config **)sec_array->elts; int num_sec = sec_array->nelts; char *test_filename = pstrdup (r->pool, r->filename); + core_dir_config **url = (core_dir_config **)url_array->elts; + int num_url = url_array->nelts; + char *test_location = pstrdup (r->pool, r->uri); + int num_dirs, res; int i; + /* First, go through the location entries, and check for matches. */ + + if (num_url) { + void *this_conf, *entry_config; + core_dir_config *entry_core; + char *entry_url; + int j; + + /* + * we apply the directive sections in some order; should really try them + * with the most general first. + */ + for (j = 0; j < num_url; ++j) { + + entry_config = url[j]; + if (!entry_config) continue; + + entry_core =(core_dir_config *) + get_module_config(entry_config, &core_module); + entry_url = entry_core->d; + + this_conf = NULL; + if (is_matchexp(entry_url)) { + if (!strcmp_match(test_location, entry_url)) + this_conf = entry_config; + } + else if (!strncmp (test_location, entry_url, strlen(entry_url))) + this_conf = entry_config; + + if (this_conf) + per_dir_defaults = merge_per_dir_configs (r->pool, + per_dir_defaults, this_conf); + } + + } + + /* Are we dealing with a file? If not, we can (hopefuly) safely assume + * we have a handler that doesn't require one, but for safety's sake, + * and so we have something find_types() can get something out of, + * fake one. But don't run through the directory entries. + */ + + if (test_filename == NULL) { + r->filename = pstrdup(r->pool, r->uri); + r->finfo.st_mode = 0; /* Not really a file... */ + r->per_dir_config = per_dir_defaults; + + return OK; + } + /* Go down the directory hierarchy. Where we have to check for symlinks, * do so. Where a .htaccess file has permission to override anything, * try to find one. If either of these things fails, we could poke *************** *** 217,226 **** char *entry_dir; int j; - /* - * we apply the directive sections in some order; should really try them - * with the most general first. - */ for (j = 0; j < num_sec; ++j) { entry_config = sec[j]; --- 272,277 ---- *************** *** 231,240 **** entry_dir = entry_core->d; this_conf = NULL; ! if (is_matchexp(entry_dir)) ! if (strcmp_match(test_filename, entry_dir) == 0) this_conf = entry_config; ! else if (strcmp (test_filename, entry_dir) == 0) this_conf = entry_config; if (this_conf) --- 282,292 ---- entry_dir = entry_core->d; this_conf = NULL; ! if (is_matchexp(entry_dir)) { ! if (!strcmp_match(test_filename, entry_dir)) this_conf = entry_config; ! } ! else if (!strncmp (test_filename, entry_dir, strlen(entry_dir))) this_conf = entry_config; if (this_conf) -- Alexei Kosut URL: http://www.nueva.pvt.k12.ca.us/~akosut/ Lefler on IRC, DALnet "Right. Fair. Decent. Either the person saying them believes in those concepts or not. If not, then those words mean that he's got somebody standing behind me with a knife in his hand. And if he *does* beleive them, then those words mean I'm going to win." - From _Xenocide_, by Orson Scott Card