You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Alexei Kosut <ak...@nueva.pvt.k12.ca.us> on 1996/04/03 10:39:16 UTC

For review... patch

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, <Location>. This directive acts almost identically to
<Directory>, except it takes a URL instead of a filename. These are
parsed, in the order they appear, prior to parsing the <Directory>
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 <Location http:> to protect HTTP proxy
requests, or <Location /~> for all user requests, or <Location
/one/two/three.html>, 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 = "</Location> outside of any <Location> 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 "<Location> sections don't nest";
+     if (cmd->limited != -1) return "Can't have <Location> within <Limit>";
+
+     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 <VirtualHost> business */

  char *end_virthost_magic = "</Virtualhost> out of place";
***************
*** 707,712 ****
--- 756,763 ----

  { "<Directory", dirsection, NULL, RSRC_CONF, RAW_ARGS, NULL },
  { "</Directory>", end_dirsection, NULL, ACCESS_CONF, NO_ARGS, NULL },
+ { "<Location", urlsection, NULL, RSRC_CONF, RAW_ARGS, NULL },
+ { "</Location>", end_urlsection, NULL, ACCESS_CONF, NO_ARGS, NULL },
  { "<Limit", limit, NULL, OR_ALL, RAW_ARGS, NULL },
  { "</Limit>", 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 <ak...@nueva.pvt.k12.ca.us>
URL: http://www.nueva.pvt.k12.ca.us/~akosut/
Lefler on IRC, DALnet <http://www.dal.net/>

    "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