From dgaudet@arctic.org Sat Apr 11 14:07:11 1998 Date: Sat, 11 Apr 1998 14:02:49 -0700 (PDT) From: Dean Gaudet To: new-httpd@apache.org Subject: [PATCH] WASTE_OF_TIME updated X-Comment: Visit http://www.arctic.org/~dgaudet/legal for information regarding copyright and disclaimer. Reply-To: new-httpd@apache.org The various time formatted environment variables in mod_include, and the USER_NAME variable take too much time to generate, so calculate them in a lazy fashion. The chdir_file() crap is only for folks who don't use #include virtual -- I'm not interested. Worth 10% speedup on a trivial .shtml file with no directives and only 4 bytes of data. Dean Index: modules/standard/mod_include.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_include.c,v retrieving revision 1.81 diff -u -r1.81 mod_include.c --- mod_include.c 1998/04/11 12:00:47 1.81 +++ mod_include.c 1998/04/11 20:44:55 @@ -113,31 +113,57 @@ /* ------------------------ Environment function -------------------------- */ -static void add_include_vars(request_rec *r, char *timefmt) +static const char INCLUDE_TIME_FORMAT[] = "INCLUDE_TIME_FORMAT"; + +static const char *get_envvar(request_rec *r, const char *name) { + const char *res; + table *e; + + e = r->subprocess_env; + res = ap_table_get(e, name); + if (res) { + return res; + } + if (!strcmp(name, "LAST_MODIFIED")) { + res = ap_ht_time(r->pool, r->finfo.st_mtime, + ap_table_get(e, INCLUDE_TIME_FORMAT), 0); + } + else if (!strcmp(name, "DATE_LOCAL")) { + res = ap_ht_time(r->pool, r->request_time, + ap_table_get(e, INCLUDE_TIME_FORMAT), 0); + } + else if (!strcmp(name, "DATE_GMT")) { + res = ap_ht_time(r->pool, r->request_time, + ap_table_get(e, INCLUDE_TIME_FORMAT), 1); + } #ifndef WIN32 - struct passwd *pw; + else if (!strcmp(name, "USER_NAME")) { + struct passwd *pw; + pw = getpwuid(r->finfo.st_uid); + if (pw) { + res = ap_pstrdup(r->pool, pw->pw_name); + } + else { + res = ap_psprintf(r->pool, "user#%lu", + (unsigned long) r->finfo.st_uid); + } + } #endif /* ndef WIN32 */ + if (res) { + ap_table_set(e, name, res); + } + return res; +} + +static void add_include_vars(request_rec *r) +{ table *e = r->subprocess_env; char *t; - time_t date = r->request_time; - ap_table_setn(e, "DATE_LOCAL", ap_ht_time(r->pool, date, timefmt, 0)); - ap_table_setn(e, "DATE_GMT", ap_ht_time(r->pool, date, timefmt, 1)); - ap_table_setn(e, "LAST_MODIFIED", - ap_ht_time(r->pool, r->finfo.st_mtime, timefmt, 0)); + ap_table_setn(e, INCLUDE_TIME_FORMAT, DEFAULT_TIME_FORMAT); ap_table_setn(e, "DOCUMENT_URI", r->uri); ap_table_setn(e, "DOCUMENT_PATH_INFO", r->path_info); -#ifndef WIN32 - pw = getpwuid(r->finfo.st_uid); - if (pw) { - ap_table_setn(e, "USER_NAME", ap_pstrdup(r->pool, pw->pw_name)); - } - else { - ap_table_setn(e, "USER_NAME", ap_psprintf(r->pool, "user#%lu", - (unsigned long) r->finfo.st_uid)); - } -#endif /* ndef WIN32 */ if ((t = strrchr(r->filename, '/'))) { ap_table_setn(e, "DOCUMENT_NAME", ++t); @@ -536,7 +562,7 @@ memcpy(var, start_of_var_name, l); var[l] = '\0'; - val = ap_table_get(r->subprocess_env, var); + val = get_envvar(r, var); if (val) { expansion = val; l = strlen(expansion); @@ -607,7 +633,9 @@ } ap_destroy_sub_req(rr); +#ifdef WASTE_OF_TIME ap_chdir_file(r->filename); +#endif return 0; } @@ -697,7 +725,9 @@ if (!error_fmt && ap_run_sub_req(rr)) { error_fmt = "unable to include \"%s\" in parsed file %s"; } +#ifdef WASTE_OF_TIME ap_chdir_file(r->filename); +#endif if (error_fmt) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, @@ -842,8 +872,10 @@ tag, r->filename); ap_rputs(error, r); } +#ifdef WASTE_OF_TIME /* just in case some stooge changed directories */ ap_chdir_file(r->filename); +#endif } else if (!strcmp(tag, "cgi")) { parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 0); @@ -852,8 +884,10 @@ "invalid CGI ref \"%s\" in %s", tag_val, file); ap_rputs(error, r); } +#ifdef WASTE_OF_TIME /* grumble groan */ ap_chdir_file(r->filename); +#endif } else if (!strcmp(tag, "done")) { return 0; @@ -878,7 +912,7 @@ return 1; } if (!strcmp(tag, "var")) { - char *val = ap_table_get(r->subprocess_env, tag_val); + const char *val = get_envvar(r, tag_val); if (val) { ap_rputs(val, r); @@ -933,16 +967,26 @@ } #endif + +static void set_timefmt(request_rec *r, char *value) +{ + table *e = r->subprocess_env; + + ap_table_setn(e, INCLUDE_TIME_FORMAT, ap_pstrdup(r->pool, value)); + ap_table_unset(e, "DATE_LOCAL"); + ap_table_unset(e, "DATE_GMT"); + ap_table_unset(e, "LAST_MODIFIED"); +} + + /* error and tf must point to a string with room for at * least MAX_STRING_LEN characters */ -static int handle_config(FILE *in, request_rec *r, char *error, char *tf, - int *sizefmt) +static int handle_config(FILE *in, request_rec *r, char *error, int *sizefmt) { char tag[MAX_STRING_LEN]; char *tag_val; char parsed_string[MAX_STRING_LEN]; - table *env = r->subprocess_env; while (1) { if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 0))) { @@ -952,13 +996,8 @@ parse_string(r, tag_val, error, MAX_STRING_LEN, 0); } else if (!strcmp(tag, "timefmt")) { - time_t date = r->request_time; - - parse_string(r, tag_val, tf, MAX_STRING_LEN, 0); - ap_table_setn(env, "DATE_LOCAL", ap_ht_time(r->pool, date, tf, 0)); - ap_table_setn(env, "DATE_GMT", ap_ht_time(r->pool, date, tf, 1)); - ap_table_setn(env, "LAST_MODIFIED", - ap_ht_time(r->pool, r->finfo.st_mtime, tf, 0)); + parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0); + set_timefmt(r, parsed_string); } else if (!strcmp(tag, "sizefmt")) { parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 0); @@ -1071,7 +1110,7 @@ } } -static int handle_flastmod(FILE *in, request_rec *r, const char *error, const char *tf) +static int handle_flastmod(FILE *in, request_rec *r, const char *error) { char tag[MAX_STRING_LEN]; char *tag_val; @@ -1088,7 +1127,8 @@ else { parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 0); if (!find_file(r, "flastmod", tag, parsed_string, &finfo, error)) { - ap_rputs(ap_ht_time(r->pool, finfo.st_mtime, tf, 0), r); + ap_rputs(ap_ht_time(r->pool, finfo.st_mtime, + ap_table_get(r->subprocess_env, INCLUDE_TIME_FORMAT), 0), r); } } } @@ -2017,7 +2057,12 @@ return -1; } parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 0); - ap_table_setn(r->subprocess_env, var, ap_pstrdup(r->pool, parsed_string)); + if (strcmp(var, INCLUDE_TIME_FORMAT)) { + ap_table_setn(r->subprocess_env, var, ap_pstrdup(r->pool, parsed_string)); + } + else { + set_timefmt(r, parsed_string); + } } else { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server, @@ -2040,6 +2085,11 @@ return 1; } else if (!strcmp(tag, "done")) { + /* force these to be defined */ + get_envvar(r, "DATE_LOCAL"); + get_envvar(r, "DATE_GMT"); + get_envvar(r, "LAST_MODIFIED"); + get_envvar(r, "USER_NAME"); for (i = 0; i < arr->nelts; ++i) { ap_rvputs(r, elts[i].key, "=", elts[i].val, "\n", NULL); } @@ -2063,7 +2113,6 @@ static void send_parsed_content(FILE *f, request_rec *r) { char directive[MAX_STRING_LEN], error[MAX_STRING_LEN]; - char timefmt[MAX_STRING_LEN]; int noexec = ap_allow_options(r) & OPT_INCNOEXEC; int ret, sizefmt; int if_nesting; @@ -2071,14 +2120,15 @@ int conditional_status; ap_cpystrn(error, DEFAULT_ERROR_MSG, sizeof(error)); - ap_cpystrn(timefmt, DEFAULT_TIME_FORMAT, sizeof(timefmt)); sizefmt = SIZEFMT_KMG; /* Turn printing on */ printing = conditional_status = 1; if_nesting = 0; +#ifdef WASTE_OF_TIME ap_chdir_file(r->filename); +#endif if (r->args) { /* add QUERY stuff to env cause it ain't yet */ char *arg_copy = ap_pstrdup(r->pool, r->args); @@ -2150,7 +2200,7 @@ } } else if (!strcmp(directive, "config")) { - ret = handle_config(f, r, error, timefmt, &sizefmt); + ret = handle_config(f, r, error, &sizefmt); } else if (!strcmp(directive, "set")) { ret = handle_set(f, r, error); @@ -2165,7 +2215,7 @@ ret = handle_fsize(f, r, error, sizefmt); } else if (!strcmp(directive, "flastmod")) { - ret = handle_flastmod(f, r, error, timefmt); + ret = handle_flastmod(f, r, error); } else if (!strcmp(directive, "printenv")) { ret = handle_printenv(f, r, error); @@ -2310,7 +2360,7 @@ * environment */ ap_add_common_vars(r); ap_add_cgi_vars(r); - add_include_vars(r, DEFAULT_TIME_FORMAT); + add_include_vars(r); } /* XXX: this is bogus, at some point we're going to do a subrequest, * and when we do it we're going to be subjecting code that doesn't