You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by Dean Gaudet <dg...@hyperreal.com> on 1997/07/01 00:50:45 UTC

cvs commit: apache/src CHANGES http_core.c http_request.c httpd.h mod_negotiation.c util.c

dgaudet     97/06/30 15:50:45

  Modified:    src       CHANGES http_core.c http_request.c httpd.h
                        mod_negotiation.c  util.c
  Log:
  directory_walk() is an expensive function, keep a little more state to
  avoid needless string counting.  Add two new functions make_dirstr_parent
  and make_dirstr_prefix which replace all existing uses of make_dirstr.
  The new functions are a little less general than make_dirstr, but
  work more efficiently (less memory, less string counting).
  
  Revision  Changes    Path
  1.316     +7 -0      apache/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache/src/CHANGES,v
  retrieving revision 1.315
  retrieving revision 1.316
  diff -C3 -r1.315 -r1.316
  *** CHANGES	1997/06/30 21:42:29	1.315
  --- CHANGES	1997/06/30 22:50:38	1.316
  ***************
  *** 1,4 ****
  --- 1,11 ----
    Changes with Apache 1.3
  +   
  +   *) directory_walk() is an expensive function, keep a little more state to
  +      avoid needless string counting.  Add two new functions make_dirstr_parent
  +      and make_dirstr_prefix which replace all existing uses of make_dirstr.
  +      The new functions are a little less general than make_dirstr, but
  +      work more efficiently (less memory, less string counting).
  +      [Dean Gaudet]
    
      *) EXTRA_LFLAGS was changed to EXTRA_LDFLAGS (and LFLAGS was changed
         to LDFLAGS) to avoid complications with lex rules in make files.
  
  
  
  1.90      +1 -1      apache/src/http_core.c
  
  Index: http_core.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_core.c,v
  retrieving revision 1.89
  retrieving revision 1.90
  diff -C3 -r1.89 -r1.90
  *** http_core.c	1997/06/29 17:53:03	1.89
  --- http_core.c	1997/06/30 22:50:39	1.90
  ***************
  *** 117,123 ****
        core_dir_config *base = (core_dir_config *)basev;
        core_dir_config *new = (core_dir_config *)newv;
        core_dir_config *conf =
  !       (core_dir_config *)pcalloc (a, sizeof(core_dir_config));
        int i;
      
        memcpy ((char *)conf, (const char *)base, sizeof(core_dir_config));
  --- 117,123 ----
        core_dir_config *base = (core_dir_config *)basev;
        core_dir_config *new = (core_dir_config *)newv;
        core_dir_config *conf =
  !       (core_dir_config *)palloc (a, sizeof(core_dir_config));
        int i;
      
        memcpy ((char *)conf, (const char *)base, sizeof(core_dir_config));
  
  
  
  1.54      +33 -18    apache/src/http_request.c
  
  Index: http_request.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_request.c,v
  retrieving revision 1.53
  retrieving revision 1.54
  diff -C3 -r1.53 -r1.54
  *** http_request.c	1997/06/28 21:46:57	1.53
  --- http_request.c	1997/06/30 22:50:39	1.54
  ***************
  *** 251,259 ****
        core_dir_config **sec = (core_dir_config **)sec_array->elts;
        int num_sec = sec_array->nelts;
        char *test_filename = pstrdup (r->pool, r->filename);
    
        int num_dirs, res;
  !     int i;
    
        /* 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,
  --- 251,260 ----
        core_dir_config **sec = (core_dir_config **)sec_array->elts;
        int num_sec = sec_array->nelts;
        char *test_filename = pstrdup (r->pool, r->filename);
  +     char *test_dirname, *test_htaccess;
    
        int num_dirs, res;
  !     int i, test_filename_len;
    
        /* 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,
  ***************
  *** 333,360 ****
    	return res;
        }
    
  !     if (test_filename[strlen(test_filename)-1] == '/')
    	--num_dirs;
    
  !     if (S_ISDIR (r->finfo.st_mode)) {
  ! 	++num_dirs;
  !     }
    
        for (i = 1; i <= num_dirs; ++i) {
            core_dir_config *core_dir =
    	  (core_dir_config *)get_module_config(per_dir_defaults, &core_module);
    	int overrides_here;
            void *this_conf = NULL, *htaccess_conf = NULL;
  ! 	char *this_dir = make_dirstr (r->pool, test_filename, i);
    	int j;
  !       
    	/* Do symlink checks first, because they are done with the
    	 * permissions appropriate to the *parent* directory...
    	 */
    	
  ! 	if ((res = check_symlinks (this_dir, core_dir->opts)))
    	{
  ! 	    log_reason("Symbolic link not allowed", this_dir, r);
    	    return res;
    	}
    	
  --- 334,367 ----
    	return res;
        }
    
  !     test_filename_len = strlen (test_filename);
  !     if (test_filename[test_filename_len-1] == '/')
    	--num_dirs;
    
  !     if (S_ISDIR (r->finfo.st_mode)) ++num_dirs;
    
  +     /* we need somewhere to scratch while building directory names and
  +      * htaccess names
  +      */
  +     test_dirname = palloc (r->pool, test_filename_len+1);
  +     test_htaccess = NULL;
        for (i = 1; i <= num_dirs; ++i) {
            core_dir_config *core_dir =
    	  (core_dir_config *)get_module_config(per_dir_defaults, &core_module);
    	int overrides_here;
            void *this_conf = NULL, *htaccess_conf = NULL;
  ! 	char *test_dirname_tail;
    	int j;
  ! 
  ! 	test_dirname_tail = make_dirstr_prefix (test_dirname, test_filename, i);
  ! 
    	/* Do symlink checks first, because they are done with the
    	 * permissions appropriate to the *parent* directory...
    	 */
    	
  ! 	if ((res = check_symlinks (test_dirname, core_dir->opts)))
    	{
  ! 	    log_reason("Symbolic link not allowed", test_dirname, r);
    	    return res;
    	}
    	
  ***************
  *** 374,380 ****
    	    entry_dir = entry_core->d;
    	
    	    if (entry_core->r) {
  ! 		if (!regexec(entry_core->r, this_dir, 0, NULL,
    			     (j == num_sec) ? 0 : REG_NOTEOL)) {
    		    /* Don't try this wildcard again --- if it ends in '*'
    		     * it'll match again, and subdirectories won't be able to
  --- 381,387 ----
    	    entry_dir = entry_core->d;
    	
    	    if (entry_core->r) {
  ! 		if (!regexec(entry_core->r, test_dirname, 0, NULL,
    			     (j == num_sec) ? 0 : REG_NOTEOL)) {
    		    /* Don't try this wildcard again --- if it ends in '*'
    		     * it'll match again, and subdirectories won't be able to
  ***************
  *** 385,395 ****
    		}
    	    }
    	    else if (entry_core->d_is_matchexp &&
  ! 		     !strcmp_match(this_dir, entry_dir)) {
    		sec[j] = NULL;	
    	        this_conf = entry_config;
    	    }
  ! 	    else if (!strcmp (this_dir, entry_dir))
    	        this_conf = entry_config;
    
    	    if (this_conf) {
  --- 392,402 ----
    		}
    	    }
    	    else if (entry_core->d_is_matchexp &&
  ! 		     !strcmp_match(test_dirname, entry_dir)) {
    		sec[j] = NULL;	
    	        this_conf = entry_config;
    	    }
  ! 	    else if (!strcmp (test_dirname, entry_dir))
    	        this_conf = entry_config;
    
    	    if (this_conf) {
  ***************
  *** 407,416 ****
    	 */
    	
    	if (overrides_here) {
  ! 	    char *config_name = make_full_path(r->pool, this_dir,
  ! 					   sconf->access_name);
    	    res = parse_htaccess (&htaccess_conf, r, overrides_here,
  ! 				  this_dir, config_name);
    	    if (res) return res;
    	}
    
  --- 414,431 ----
    	 */
    	
    	if (overrides_here) {
  ! 	    int len;
  ! 
  ! 	    if (test_htaccess == NULL) {
  ! 		/* we delayed allocating this in case there wasn't a need */
  ! 		test_htaccess = palloc (r->pool,
  ! 		    test_filename_len + 1 + strlen (sconf->access_name));
  ! 	    }
  ! 	    len = test_dirname_tail - test_dirname;
  ! 	    memcpy (test_htaccess, test_dirname, len);
  ! 	    strcpy (test_htaccess + len, sconf->access_name);
    	    res = parse_htaccess (&htaccess_conf, r, overrides_here,
  ! 				  test_dirname, test_htaccess);
    	    if (res) return res;
    	}
    
  ***************
  *** 615,621 ****
    	parse_uri(rnew, new_file);
        else
        {
  ! 	udir = make_dirstr (rnew->pool, r->uri, count_dirs (r->uri));
    	udir = escape_uri(rnew->pool, udir); /* re-escape it */
    	parse_uri (rnew, make_full_path (rnew->pool, udir, new_file));
        }
  --- 630,636 ----
    	parse_uri(rnew, new_file);
        else
        {
  ! 	udir = make_dirstr_parent (rnew->pool, r->uri);
    	udir = escape_uri(rnew->pool, udir); /* re-escape it */
    	parse_uri (rnew, make_full_path (rnew->pool, udir, new_file));
        }
  ***************
  *** 684,690 ****
        rnew->request_config = create_request_config (rnew->pool);
        rnew->htaccess = r->htaccess; /* copy htaccess cache */
        set_sub_req_protocol (rnew, r);
  !     fdir = make_dirstr (rnew->pool, r->filename, count_dirs (r->filename));
    
        /* Check for a special case... if there are no '/' characters in new_file
         * at all, then we are looking at a relative lookup in the same directory.
  --- 699,705 ----
        rnew->request_config = create_request_config (rnew->pool);
        rnew->htaccess = r->htaccess; /* copy htaccess cache */
        set_sub_req_protocol (rnew, r);
  !     fdir = make_dirstr_parent (rnew->pool, r->filename);
    
        /* Check for a special case... if there are no '/' characters in new_file
         * at all, then we are looking at a relative lookup in the same directory.
  ***************
  *** 693,699 ****
         */
    
        if (strchr (new_file, '/') == NULL) {
  ! 	char *udir = make_dirstr(rnew->pool, r->uri, count_dirs(r->uri));
    
    	rnew->uri = make_full_path (rnew->pool, udir, new_file);
    	rnew->filename = make_full_path (rnew->pool, fdir, new_file);
  --- 708,714 ----
         */
    
        if (strchr (new_file, '/') == NULL) {
  ! 	char *udir = make_dirstr_parent (rnew->pool, r->uri);
    
    	rnew->uri = make_full_path (rnew->pool, udir, new_file);
    	rnew->filename = make_full_path (rnew->pool, fdir, new_file);
  
  
  
  1.121     +3 -0      apache/src/httpd.h
  
  Index: httpd.h
  ===================================================================
  RCS file: /export/home/cvs/apache/src/httpd.h,v
  retrieving revision 1.120
  retrieving revision 1.121
  diff -C3 -r1.120 -r1.121
  *** httpd.h	1997/06/30 21:10:02	1.120
  --- httpd.h	1997/06/30 22:50:40	1.121
  ***************
  *** 712,717 ****
  --- 712,720 ----
    char *escape_shell_cmd (pool *p, const char *s);
         
    int count_dirs(const char *path);
  + char *make_dirstr_prefix (char *d, const char *s, int n);
  + char *make_dirstr_parent (pool *p, const char *s);
  + /* deprecated.  The previous two routines are preferred. */
    char *make_dirstr(pool *a, const char *s, int n);
    char *make_full_path(pool *a, const char *dir, const char *f);
         
  
  
  
  1.44      +2 -2      apache/src/mod_negotiation.c
  
  Index: mod_negotiation.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/mod_negotiation.c,v
  retrieving revision 1.43
  retrieving revision 1.44
  diff -C3 -r1.43 -r1.44
  *** mod_negotiation.c	1997/06/24 03:03:49	1.43
  --- mod_negotiation.c	1997/06/30 22:50:40	1.44
  ***************
  *** 444,450 ****
    
        new->pool = r->pool;
        new->r = r;
  !     new->dir_name = make_dirstr(r->pool, r->filename, count_dirs(r->filename));
        
        new->accepts = do_header_line (r->pool, table_get (hdrs, "Accept"));
    
  --- 444,450 ----
    
        new->pool = r->pool;
        new->r = r;
  !     new->dir_name = make_dirstr_parent (r->pool, r->filename);
        
        new->accepts = do_header_line (r->pool, table_get (hdrs, "Accept"));
    
  ***************
  *** 1899,1905 ****
        if (r->path_info && *r->path_info) {
            r->uri[find_path_info(r->uri, r->path_info)] = '\0';
        }
  !     udir = make_dirstr (r->pool, r->uri, count_dirs (r->uri));
        udir = escape_uri(r->pool, udir);
        internal_redirect(pstrcat(r->pool, udir, best->file_name, r->path_info,
                                  NULL), r);
  --- 1899,1905 ----
        if (r->path_info && *r->path_info) {
            r->uri[find_path_info(r->uri, r->path_info)] = '\0';
        }
  !     udir = make_dirstr_parent (r->pool, r->uri);
        udir = escape_uri(r->pool, udir);
        internal_redirect(pstrcat(r->pool, udir, best->file_name, r->path_info,
                                  NULL), r);
  
  
  
  1.59      +55 -0     apache/src/util.c
  
  Index: util.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/util.c,v
  retrieving revision 1.58
  retrieving revision 1.59
  diff -C3 -r1.58 -r1.59
  *** util.c	1997/06/29 17:26:59	1.58
  --- util.c	1997/06/30 22:50:41	1.59
  ***************
  *** 339,344 ****
  --- 339,399 ----
    	else x++;
    }
    
  + 
  + /*
  +  * copy at most n leading directories of s into d
  +  * d should be at least as large as s plus 1 extra byte
  +  * assumes n > 0
  +  * the return value is the ever useful pointer to the trailing \0 of d
  +  *
  +  * examples:
  +  *    /a/b, 1  ==> /
  +  *    /a/b, 2  ==> /a/
  +  *    /a/b, 3  ==> /a/b/
  +  *    /a/b, 4  ==> /a/b/
  +  */
  + char *make_dirstr_prefix (char *d, const char *s, int n)
  + {
  +     for(;;) {
  + 	*d = *s;
  + 	if (*d == '\0') {
  + 	    *d = '/';
  + 	    break;
  + 	}
  + 	if (*d == '/' && (--n) == 0 ) break;
  + 	++d;
  + 	++s;
  +     }
  +     *++d = 0;
  +     return (d);
  + }
  + 
  + 
  + /*
  +  * return the parent directory name including trailing / of the file s
  +  */
  + char *make_dirstr_parent (pool *p, const char *s)
  + {
  +     char *last_slash = strrchr (s, '/');
  +     char *d;
  +     int l;
  + 
  +     if (last_slash == NULL) {
  + 	/* XXX: well this is really broken if this happens */
  + 	return (pstrdup (p,"/"));
  +     }
  +     l = (last_slash-s)+1;
  +     d = palloc (p, l+1);
  +     memcpy (d, s, l);
  +     d[l] = 0;
  +     return (d);
  + }
  + 
  + 
  + /*
  +  * This function is deprecated.  Use one of the preceeding two functions
  +  * which are faster.
  +  */
    char *make_dirstr(pool *p, const char *s, int n) {
        register int x,f;
        char *res;