
From dgaudet@arctic.org Sat Apr 11 14:07:11 1998
Date: Sat, 11 Apr 1998 14:02:49 -0700 (PDT)
From: Dean Gaudet <dgaudet@arctic.org>
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


