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;