From: dgaudet Date: Sun, 9 Jan 2000 05:18:31 +0000 (+0000) Subject: time overhaul: X-Git-Tag: 1.3.10~21 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=faff1f01dd44936eb7e4b553f42e872edd9f2f2b;p=apache time overhaul: - ap_time_t is a 64-bit scalar, microseconds since epoch - ap_exploded_time_t corresponds to struct tm with a few extras probably broken on anything except linux. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@84413 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/include/http_protocol.h b/include/http_protocol.h index bb6cd99d73..13a7ac287f 100644 --- a/include/http_protocol.h +++ b/include/http_protocol.h @@ -118,7 +118,7 @@ API_EXPORT(void) ap_send_error_response(request_rec *r, int recursive_error); API_EXPORT(int) ap_set_content_length(request_rec *r, long length); API_EXPORT(int) ap_set_keepalive(request_rec *r); -API_EXPORT(ap_time_t *) ap_rationalize_mtime(request_rec *r, ap_time_t *mtime); +API_EXPORT(ap_time_t) ap_rationalize_mtime(request_rec *r, ap_time_t mtime); API_EXPORT(char *) ap_make_etag(request_rec *r, int force_weak); API_EXPORT(void) ap_set_etag(request_rec *r); API_EXPORT(void) ap_set_last_modified(request_rec *r); diff --git a/include/http_request.h b/include/http_request.h index ed51f915fe..7e0fa711b8 100644 --- a/include/http_request.h +++ b/include/http_request.h @@ -104,7 +104,7 @@ API_EXPORT(void) ap_internal_redirect(const char *new_uri, request_rec *); API_EXPORT(void) ap_internal_redirect_handler(const char *new_uri, request_rec *); API_EXPORT(int) ap_some_auth_required(request_rec *r); API_EXPORT(int) ap_is_initial_req(request_rec *r); -API_EXPORT(ap_time_t *) ap_update_mtime(request_rec *r, ap_time_t *dependency_mtime); +API_EXPORT(void) ap_update_mtime(request_rec *r, ap_time_t dependency_mtime); #ifdef CORE_PRIVATE /* Function called by main.c to handle first-level request */ diff --git a/include/httpd.h b/include/httpd.h index fc3b3de01c..0c54134c19 100644 --- a/include/httpd.h +++ b/include/httpd.h @@ -668,7 +668,7 @@ struct request_rec { int proto_num; /* Number version of protocol; 1.1 = 1001 */ const char *hostname; /* Host, as set by full URI or Host: */ - ap_time_t *request_time; /* When the request started */ + ap_time_t request_time; /* When the request started */ const char *status_line; /* Status line, if set by script */ int status; /* In any case */ @@ -704,7 +704,7 @@ struct request_rec { int sent_bodyct; /* byte count in stream is for body */ long bytes_sent; /* body byte count, for easy access */ - ap_time_t *mtime; /* Time the resource was last modified */ + ap_time_t mtime; /* Time the resource was last modified */ /* HTTP/1.1 connection-level features */ @@ -914,9 +914,9 @@ struct server_rec { */ /* Time */ -API_EXPORT(char *) ap_get_time(void); + API_EXPORT(char *) ap_field_noparam(ap_context_t *p, const char *intype); -API_EXPORT(char *) ap_ht_time(ap_context_t *p, ap_time_t *t, const char *fmt, int gmt); +API_EXPORT(char *) ap_ht_time(ap_context_t *p, ap_time_t t, const char *fmt, int gmt); /* String handling. The *_nc variants allow you to use non-const char **s as arguments (unfortunately C won't automatically convert a char ** to a const diff --git a/include/util_date.h b/include/util_date.h index a11a464fff..b74849899b 100644 --- a/include/util_date.h +++ b/include/util_date.h @@ -76,7 +76,7 @@ extern "C" { #define BAD_DATE (time_t)0 API_EXPORT(int) ap_checkmask(const char *data, const char *mask); -API_EXPORT(ap_time_t *) ap_parseHTTPdate(const char *date, ap_context_t *cont); +API_EXPORT(ap_time_t) ap_parseHTTPdate(const char *date); #ifdef __cplusplus } diff --git a/modules/filters/mod_include.c b/modules/filters/mod_include.c index 224757e665..c48241bb10 100644 --- a/modules/filters/mod_include.c +++ b/modules/filters/mod_include.c @@ -124,9 +124,7 @@ static void add_include_vars(request_rec *r, char *timefmt) #endif /* ndef WIN32 */ ap_table_t *e = r->subprocess_env; char *t; - ap_time_t *date = r->request_time; - ap_time_t *mtime = NULL; - + ap_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)); @@ -1023,7 +1021,7 @@ static int handle_config(ap_file_t *in, request_rec *r, char *error, char *tf, parse_string(r, tag_val, error, MAX_STRING_LEN, 0); } else if (!strcmp(tag, "timefmt")) { - ap_time_t *date = r->request_time; + ap_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)); @@ -1170,7 +1168,6 @@ static int handle_flastmod(ap_file_t *in, request_rec *r, const char *error, con char *tag_val; struct stat finfo; char parsed_string[MAX_STRING_LEN]; - ap_time_t *mtime = NULL; while (1) { if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) { @@ -1182,8 +1179,9 @@ static int handle_flastmod(ap_file_t *in, request_rec *r, const char *error, con else { parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 0); if (!find_file(r, "flastmod", tag, parsed_string, &finfo, error)) { - ap_make_time(&mtime, r->pool); - ap_set_ansitime(mtime, finfo.st_mtime); + ap_time_t mtime; + + ap_ansi_time_to_ap_time(&mtime, finfo.st_mtime); ap_rputs(ap_ht_time(r->pool, mtime, tf, 0), r); } } @@ -2346,7 +2344,6 @@ static int send_parsed_file(request_rec *r) (enum xbithack *) ap_get_module_config(r->per_dir_config, &includes_module); int errstatus; request_rec *parent; - ap_time_t *mtime = NULL; if (!(ap_allow_options(r) & OPT_INCLUDES)) { return DECLINED; diff --git a/modules/generators/mod_autoindex.c b/modules/generators/mod_autoindex.c index fb6dc1cc12..a9bd62ad21 100644 --- a/modules/generators/mod_autoindex.c +++ b/modules/generators/mod_autoindex.c @@ -678,7 +678,7 @@ struct ent { char *alt; char *desc; off_t size; - time_t lm; + ap_time_t lm; struct ent *next; int ascending; char key; @@ -1162,7 +1162,7 @@ static struct ent *make_autoindex_entry(char *name, int autoindex_opts, request_rec *rr = ap_sub_req_lookup_file(name, r); if (rr->finfo.protection != 0) { - ap_get_ansitime(rr->finfo.mtime, (ap_int64_t *)&p->lm); + p->lm = rr->finfo.mtime; if (S_ISDIR(rr->finfo.protection)) { if (!(p->icon = find_icon(d, rr, 1))) { p->icon = find_default_icon(d, "^^DIRECTORY^^"); @@ -1404,11 +1404,10 @@ static void output_directories(struct ent **ar, int n, if (!(autoindex_opts & SUPPRESS_LAST_MOD)) { if (ar[x]->lm != -1) { char time_str[MAX_STRING_LEN]; - ap_time_t *ts = NULL; - ap_make_time(&ts, r->pool); - ap_set_ansitime(ts, ar[x]->lm); + ap_exploded_time_t ts; + ap_explode_localtime(&ts, ar[x]->lm); ap_strftime(time_str, &rv, MAX_STRING_LEN, - "%d-%b-%Y %H:%M ", ts); + "%d-%b-%Y %H:%M ", &ts); ap_rputs(time_str, r); } else { diff --git a/modules/generators/mod_cgi.c b/modules/generators/mod_cgi.c index ae70aff76d..8338bcd570 100644 --- a/modules/generators/mod_cgi.c +++ b/modules/generators/mod_cgi.c @@ -168,6 +168,7 @@ static int log_scripterror(request_rec *r, cgi_server_conf * conf, int ret, { ap_file_t *f = NULL; struct stat finfo; + char time_str[AP_CTIME_LEN]; ap_log_rerror(APLOG_MARK, show_errno|APLOG_ERR, errno, r, "%s: %s", error, r->filename); @@ -181,7 +182,8 @@ static int log_scripterror(request_rec *r, cgi_server_conf * conf, int ret, } /* "%% [Wed Jun 19 10:53:21 1996] GET /cgi-bin/printenv HTTP/1.0" */ - ap_fprintf(f, "%%%% [%s] %s %s%s%s %s\n", ap_get_time(), r->method, r->uri, + ap_ctime(time_str, ap_now()); + ap_fprintf(f, "%%%% [%s] %s %s%s%s %s\n", time_str, r->method, r->uri, r->args ? "?" : "", r->args ? r->args : "", r->protocol); /* "%% 500 /usr/local/apache/cgi-bin */ ap_fprintf(f, "%%%% %d %s\n", ret, r->filename); @@ -201,6 +203,7 @@ static int log_script(request_rec *r, cgi_server_conf * conf, int ret, ap_file_t *f = NULL; int i; struct stat finfo; + char time_str[AP_CTIME_LEN]; if (!conf->logname || ((stat(ap_server_root_relative(r->pool, conf->logname), &finfo) == 0) @@ -227,7 +230,8 @@ static int log_script(request_rec *r, cgi_server_conf * conf, int ret, } /* "%% [Wed Jun 19 10:53:21 1996] GET /cgi-bin/printenv HTTP/1.0" */ - ap_fprintf(f, "%%%% [%s] %s %s%s%s %s\n", ap_get_time(), r->method, r->uri, + ap_ctime(time_str, ap_now()); + ap_fprintf(f, "%%%% [%s] %s %s%s%s %s\n", time_str, r->method, r->uri, r->args ? "?" : "", r->args ? r->args : "", r->protocol); /* "%% 500 /usr/local/apache/cgi-bin" */ ap_fprintf(f, "%%%% %d %s\n", ret, r->filename); diff --git a/modules/generators/mod_cgid.c b/modules/generators/mod_cgid.c index b3933aa2e2..8ea591d87e 100644 --- a/modules/generators/mod_cgid.c +++ b/modules/generators/mod_cgid.c @@ -668,6 +668,7 @@ static int log_scripterror(request_rec *r, cgid_server_conf * conf, int ret, { ap_file_t *f = NULL; struct stat finfo; + char time_str[AP_CTIME_LEN]; ap_log_rerror(APLOG_MARK, show_errno|APLOG_ERR, errno, r, "%s: %s", error, r->filename); @@ -681,7 +682,8 @@ static int log_scripterror(request_rec *r, cgid_server_conf * conf, int ret, } /* "%% [Wed Jun 19 10:53:21 1996] GET /cgid-bin/printenv HTTP/1.0" */ - ap_fprintf(f, "%%%% [%s] %s %s%s%s %s\n", ap_get_time(), r->method, r->uri, + ap_ctime(time_str, ap_now()); + ap_fprintf(f, "%%%% [%s] %s %s%s%s %s\n", time_str, r->method, r->uri, r->args ? "?" : "", r->args ? r->args : "", r->protocol); /* "%% 500 /usr/local/apache/cgid-bin */ ap_fprintf(f, "%%%% %d %s\n", ret, r->filename); @@ -701,6 +703,7 @@ static int log_script(request_rec *r, cgid_server_conf * conf, int ret, ap_file_t *f = NULL; int i; struct stat finfo; + char time_str[AP_CTIME_LEN]; if (!conf->logname || ((stat(ap_server_root_relative(r->pool, conf->logname), &finfo) == 0) @@ -716,7 +719,8 @@ static int log_script(request_rec *r, cgid_server_conf * conf, int ret, } /* "%% [Wed Jun 19 10:53:21 1996] GET /cgid-bin/printenv HTTP/1.0" */ - ap_fprintf(f, "%%%% [%s] %s %s%s%s %s\n", ap_get_time(), r->method, r->uri, + ap_ctime(time_str, ap_now()); + ap_fprintf(f, "%%%% [%s] %s %s%s%s %s\n", time_str, r->method, r->uri, r->args ? "?" : "", r->args ? r->args : "", r->protocol); /* "%% 500 /usr/local/apache/cgid-bin" */ ap_fprintf(f, "%%%% %d %s\n", ret, r->filename); diff --git a/modules/generators/mod_status.c b/modules/generators/mod_status.c index 1752c049c9..0738e281a9 100644 --- a/modules/generators/mod_status.c +++ b/modules/generators/mod_status.c @@ -82,10 +82,6 @@ static int status_handler(request_rec *r) int i; ap_array_header_t *server_status; ap_status_table_row_t *status_rows; - ap_time_t *nowtime = NULL; - - ap_make_time(&nowtime, r->pool); - ap_current_time(nowtime); r->allowed = (1 << M_GET); if (r->method_number != M_GET) @@ -110,7 +106,7 @@ static int status_handler(request_rec *r) ap_rvputs(r, "Server Built: ", ap_get_server_built(), "
\n
\n", NULL); ap_rvputs(r, "Current Time: ", - ap_ht_time(r->pool, nowtime, DEFAULT_TIME_FORMAT, 0), "
\n", NULL); + ap_ht_time(r->pool, ap_now(), DEFAULT_TIME_FORMAT, 0), "
\n", NULL); ap_rprintf(r, "\n%d connections currently being processed\n", server_status->nelts); diff --git a/modules/http/http_core.c b/modules/http/http_core.c index 84c806c03b..9dee32299b 100644 --- a/modules/http/http_core.c +++ b/modules/http/http_core.c @@ -2453,7 +2453,6 @@ static int default_handler(request_rec *r) { core_dir_config *d = (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); - ap_time_t *temp; int rangestatus, errstatus; ap_file_t *fd = NULL; ap_status_t status; diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c index 093e3f025a..99d12d99e3 100644 --- a/modules/http/http_protocol.c +++ b/modules/http/http_protocol.c @@ -368,9 +368,9 @@ API_EXPORT(int) ap_set_keepalive(request_rec *r) * to limit the number of calls to time(). We don't check for futurosity * unless the mtime is at least as new as the reference. */ -API_EXPORT(ap_time_t *) ap_rationalize_mtime(request_rec *r, ap_time_t *mtime) +API_EXPORT(ap_time_t) ap_rationalize_mtime(request_rec *r, ap_time_t mtime) { - ap_time_t *now; + ap_time_t now; /* For all static responses, it's almost certain that the file was * last modified before the beginning of the request. So there's @@ -381,26 +381,15 @@ API_EXPORT(ap_time_t *) ap_rationalize_mtime(request_rec *r, ap_time_t *mtime) * were given a time in the future, we return the current time - the * Last-Modified can't be in the future. */ - if (ap_timecmp(mtime, r->request_time) == APR_LESS) { - now = r->request_time; - } - else { - ap_make_time(&now, r->pool); - ap_current_time(now); - } - if (ap_timecmp(mtime, now) == APR_MORE) { - return now; - } - else { - return mtime; - } + now = (mtime < r->request_time) ? r->request_time : ap_now(); + return (mtime > now) ? now : mtime; } API_EXPORT(int) ap_meets_conditions(request_rec *r) { const char *etag = ap_table_get(r->headers_out, "ETag"); const char *if_match, *if_modified_since, *if_unmodified, *if_nonematch; - ap_time_t *mtime; + ap_time_t mtime; /* Check for conditional requests --- note that we only want to do * this if we are successful so far and we are not processing a @@ -417,13 +406,8 @@ API_EXPORT(int) ap_meets_conditions(request_rec *r) return OK; } - if (r->mtime == NULL) { - ap_make_time(&mtime, r->pool); - ap_current_time(mtime); - } - else { - mtime = r->mtime; - } + /* XXX: we should define a "time unset" constant */ + mtime = (r->mtime != 0) ? r->mtime : ap_now(); /* If an If-Match request-header field was given * AND the field value is not "*" (meaning match anything) @@ -445,9 +429,9 @@ API_EXPORT(int) ap_meets_conditions(request_rec *r) */ if_unmodified = ap_table_get(r->headers_in, "If-Unmodified-Since"); if (if_unmodified != NULL) { - ap_time_t *ius = ap_parseHTTPdate(if_unmodified, r->pool); + ap_time_t ius = ap_parseHTTPdate(if_unmodified); - if ((ius != NULL) && (ap_timecmp(mtime, ius) == APR_MORE)) { + if ((ius != BAD_DATE) && (mtime > ius)) { return HTTP_PRECONDITION_FAILED; } } @@ -498,10 +482,9 @@ API_EXPORT(int) ap_meets_conditions(request_rec *r) else if ((r->method_number == M_GET) && ((if_modified_since = ap_table_get(r->headers_in, "If-Modified-Since")) != NULL)) { - ap_time_t *ims = ap_parseHTTPdate(if_modified_since, r->pool); + ap_time_t ims = ap_parseHTTPdate(if_modified_since); - if (!ap_timecmp(ims, mtime) < APR_LESS && - !ap_timecmp(ims, r->request_time) > APR_MORE) { + if ((ims >= mtime) && (ims <= r->request_time)) { return HTTP_NOT_MODIFIED; } } @@ -519,7 +502,6 @@ API_EXPORT(char *) ap_make_etag(request_rec *r, int force_weak) { char *etag; char *weak; - int diff; /* * Make an ETag header out of various pieces of information. We use @@ -534,8 +516,7 @@ API_EXPORT(char *) ap_make_etag(request_rec *r, int force_weak) * would be incorrect. */ - ap_timediff(r->request_time, r->mtime, &diff); - weak = ((diff > 1) && !force_weak) ? "" : "W/"; + weak = ((r->request_time - r->mtime > AP_USEC_PER_SEC) && !force_weak) ? "" : "W/"; if (r->finfo.protection != 0) { etag = ap_psprintf(r->pool, @@ -603,9 +584,9 @@ API_EXPORT(void) ap_set_etag(request_rec *r) */ API_EXPORT(void) ap_set_last_modified(request_rec *r) { - ap_time_t *mod_time = ap_rationalize_mtime(r, r->mtime); - char *datestr; - ap_timestr(&datestr, mod_time, APR_UTCTIME, r->pool); + ap_time_t mod_time = ap_rationalize_mtime(r, r->mtime); + char *datestr = ap_palloc(r->pool, AP_RFC822_DATE_LEN); + ap_rfc822_date(datestr, mod_time); ap_table_setn(r->headers_out, "Last-Modified", datestr); } @@ -822,7 +803,7 @@ static int read_request_line(request_rec *r) /* this is a hack to make sure that request time is set, * it's not perfect, but it's better than nothing */ - ap_current_time(r->request_time); + r->request_time = ap_now(); return 0; } } @@ -841,7 +822,7 @@ static int read_request_line(request_rec *r) /* //ap_bsetflag(conn->client, B_SAFEREAD, 0); */ - ap_current_time(r->request_time); + r->request_time = ap_now(); r->the_request = ap_pstrdup(r->pool, l); r->method = ap_getword_white(r->pool, &ll); ap_update_connection_status(conn->id, "Method", r->method); @@ -975,8 +956,6 @@ request_rec *ap_read_request(conn_rec *conn) r->status = HTTP_REQUEST_TIME_OUT; /* Until we get a request */ r->the_request = NULL; - ap_make_time(&r->request_time, r->pool); - ap_make_time(&r->mtime, r->pool); #ifdef CHARSET_EBCDIC ap_bsetflag(r->connection->client, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 1); @@ -1362,7 +1341,8 @@ API_EXPORT(void) ap_basic_http_header(request_rec *r) ap_rvputs(r, protocol, " ", r->status_line, "\015\012", NULL); - ap_timestr(&date, r->request_time, APR_UTCTIME, r->pool); + date = ap_palloc(r->pool, AP_RFC822_DATE_LEN); + ap_rfc822_date(date, r->request_time); ap_send_header_field(r, "Date", date); ap_send_header_field(r, "Server", ap_get_server_version()); @@ -1645,7 +1625,8 @@ API_EXPORT(void) ap_send_http_header(request_rec *r) * some other part of the server configuration. */ if (r->no_cache && !ap_table_get(r->headers_out, "Expires")) { - ap_timestr(&date, r->request_time, APR_UTCTIME, r->pool); + date = ap_palloc(r->pool, AP_RFC822_DATE_LEN); + ap_rfc822_date(date, r->request_time); ap_table_addn(r->headers_out, "Expires", date); } diff --git a/modules/http/http_request.c b/modules/http/http_request.c index 6965c14499..55adcc633f 100644 --- a/modules/http/http_request.c +++ b/modules/http/http_request.c @@ -1374,10 +1374,9 @@ API_EXPORT(int) ap_is_initial_req(request_rec *r) * Function to set the r->mtime field to the specified value if it's later * than what's already there. */ -API_EXPORT(ap_time_t *) ap_update_mtime(request_rec *r, ap_time_t *dependency_mtime) +API_EXPORT(void) ap_update_mtime(request_rec *r, ap_time_t dependency_mtime) { - if (ap_timecmp(r->mtime, dependency_mtime) == APR_LESS) { - r->mtime = dependency_mtime; + if (r->mtime < dependency_mtime) { + r->mtime = dependency_mtime; } - return r->mtime; } diff --git a/modules/loggers/mod_log_config.c b/modules/loggers/mod_log_config.c index 13d4a667f5..a25d6253d8 100644 --- a/modules/loggers/mod_log_config.c +++ b/modules/loggers/mod_log_config.c @@ -380,34 +380,46 @@ static const char *log_env_var(request_rec *r, char *a) static const char *log_request_time(request_rec *r, char *a) { - int timz; - ap_int32_t mday, year, hour, min, sec, month; - ap_time_t *t; + ap_exploded_time_t xt; + ap_status_t retcode; char tstr[MAX_STRING_LEN]; - ap_int32_t retcode; - - ap_make_time(&t, r->pool); - ap_get_gmtoff(&timz, t, r->pool); + /* + hi. i think getting the time again at the end of the request + just for logging is dumb. i know it's "required" for CLF. + folks writing log parsing tools don't realise that out of order + times have always been possible (consider what happens if one + process calculates the time to log, but then there's a context + switch before it writes and before that process is run again the + log rotation occurs) and they should just fix their tools rather + than force the server to pay extra cpu cycles. if you've got + a problem with this, you can set the define. -djg + */ +#ifdef I_INSIST_ON_EXTRA_CYCLES_FOR_CLF_COMPLIANCE + ap_explode_localtime(&xt, ap_now()); +#else + ap_explode_localtime(&xt, r->request_time); +#endif if (a && *a) { /* Custom format */ - ap_strftime(tstr, &retcode, MAX_STRING_LEN, a, t); + ap_strftime(tstr, &retcode, MAX_STRING_LEN, a, &xt); } else { /* CLF format */ - char sign = (timz < 0 ? '-' : '+'); + char sign; + int timz; + + timz = xt.tm_gmtoff; + if (timz < 0) { + timz = -timz; + sign = '-'; + } + else { + sign = '+'; + } - if (timz < 0) { - timz = -timz; - } - ap_get_mday(t, &mday); - ap_get_year(t, &year); - ap_get_hour(t, &month); - ap_get_hour(t, &hour); - ap_get_min(t, &min); - ap_get_sec(t, &sec); ap_snprintf(tstr, sizeof(tstr), "[%02d/%s/%d:%02d:%02d:%02d %c%.2d%.2d]", - mday, ap_month_snames[month], year+1900, - hour, min, sec, - sign, timz / 60, timz % 60); + xt.tm_mday, ap_month_snames[xt.tm_mon], xt.tm_year+1900, + xt.tm_hour, xt.tm_min, xt.tm_sec, + sign, timz / (60*60), timz % (60*60)); } return ap_pstrdup(r->pool, tstr); @@ -415,13 +427,7 @@ static const char *log_request_time(request_rec *r, char *a) static const char *log_request_duration(request_rec *r, char *a) { - ap_time_t *currtime = NULL; - ap_int32_t diff; - ap_make_time(&currtime, r->pool); - ap_current_time(currtime); - - ap_timediff(currtime, r->request_time, &diff); - return ap_psprintf(r->pool, "%ld", diff); + return ap_psprintf(r->pool, "%ld", (ap_now() - r->request_time) / AP_USEC_PER_SEC); } /* These next two routines use the canonical name:port so that log diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c index 39475598cb..9a46df7691 100644 --- a/modules/mappers/mod_rewrite.c +++ b/modules/mappers/mod_rewrite.c @@ -3264,22 +3264,16 @@ static void rewritelog(request_rec *r, int level, const char *text, ...) static char *current_logtime(request_rec *r) { - int timz; - ap_time_t *t; + ap_exploded_time_t t; char tstr[80]; - char sign; - ap_int32_t len; + ap_size_t len; - ap_make_time(&t, r->pool); - ap_get_gmtoff(&timz, t, r->pool); - sign = (timz < 0 ? '-' : '+'); - if (timz < 0) { - timz = -timz; - } + ap_explode_localtime(&t, ap_now()); - ap_strftime(tstr, &len, 80, "[%d/%b/%Y:%H:%M:%S ", t); + ap_strftime(tstr, &len, 80, "[%d/%b/%Y:%H:%M:%S ", &t); ap_snprintf(tstr + strlen(tstr), 80-strlen(tstr), "%c%.2d%.2d]", - sign, timz/60, timz%60); + t.tm_gmtoff < 0 ? '-' : '+', + t.tm_gmtoff / (60*60), t.tm_gmtoff % (60*60)); return ap_pstrdup(r->pool, tstr); } @@ -3556,14 +3550,7 @@ static char *lookup_variable(request_rec *r, char *var) { const char *result; char resultbuf[LONG_STRING_LEN]; - ap_time_t *tm = NULL; - ap_int32_t tmvalue = 0; - ap_int32_t year; - ap_int32_t mon; - ap_int32_t mday; - ap_int32_t hour; - ap_int32_t min; - ap_int32_t sec; + ap_exploded_time_t tm; request_rec *rsub; #ifndef WIN32 struct passwd *pw; @@ -3671,51 +3658,41 @@ static char *lookup_variable(request_rec *r, char *var) result = resultbuf; } +/* XXX: wow this has gotta be slow if you actually use it for a lot, recalculates exploded time for each variable */ /* underlaying Unix system stuff */ else if (strcasecmp(var, "TIME_YEAR") == 0) { - ap_make_init_time(&tm, r->pool); - ap_explode_time(tm, APR_LOCALTIME); - ap_get_year(tm, &year); - ap_snprintf(resultbuf, sizeof(resultbuf), "%02d%02d", - (year / 100) + 19, year % 100); + ap_explode_localtime(&tm, ap_now()); + ap_snprintf(resultbuf, sizeof(resultbuf), "%04d", tm.tm_year + 1900); result = resultbuf; } #define MKTIMESTR(format, tmfield) \ - ap_make_init_time(&tm, r->pool); \ - ap_explode_time(tm, APR_LOCALTIME); \ - ap_get_tmfield(tm, &tmvalue); \ - ap_snprintf(resultbuf, sizeof(resultbuf), format, tmvalue); \ + ap_explode_localtime(&tm, ap_now()); \ + ap_snprintf(resultbuf, sizeof(resultbuf), format, tm.tmfield); \ result = resultbuf; else if (strcasecmp(var, "TIME_MON") == 0) { - MKTIMESTR("%02d", mon+1) + MKTIMESTR("%02d", tm_mon+1) } else if (strcasecmp(var, "TIME_DAY") == 0) { - MKTIMESTR("%02d", mday) + MKTIMESTR("%02d", tm_mday) } else if (strcasecmp(var, "TIME_HOUR") == 0) { - MKTIMESTR("%02d", hour) + MKTIMESTR("%02d", tm_hour) } else if (strcasecmp(var, "TIME_MIN") == 0) { - MKTIMESTR("%02d", min) + MKTIMESTR("%02d", tm_min) } else if (strcasecmp(var, "TIME_SEC") == 0) { - MKTIMESTR("%02d", sec) + MKTIMESTR("%02d", tm_sec) } else if (strcasecmp(var, "TIME_WDAY") == 0) { - MKTIMESTR("%d", wday) + MKTIMESTR("%d", tm_wday) } else if (strcasecmp(var, "TIME") == 0) { - ap_make_init_time(&tm, r->pool); - ap_explode_time(tm, APR_LOCALTIME); - ap_get_year(tm, &year); - ap_get_mon(tm, &mon); - ap_get_mday(tm, &mday); - ap_get_hour(tm, &hour); - ap_get_min(tm, &min); - ap_get_sec(tm, &sec); + ap_explode_localtime(&tm, ap_now()); ap_snprintf(resultbuf, sizeof(resultbuf), - "%02d%02d%02d%02d%02d%02d%02d", (year / 100) + 19, - (year % 100), mon+1, mday, hour, min, sec); + "%04d%02d%02d%02d%02d%02d", tm.tm_year + 1900, + tm.tm_mon+1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); result = resultbuf; rewritelog(r, 1, "RESULT='%s'", result); } diff --git a/modules/metadata/mod_expires.c b/modules/metadata/mod_expires.c index c0f8ab3491..3577bf0c67 100644 --- a/modules/metadata/mod_expires.c +++ b/modules/metadata/mod_expires.c @@ -196,6 +196,7 @@ #include "httpd.h" #include "http_config.h" #include "http_log.h" +#include "http_request.h" typedef struct { int active; @@ -402,12 +403,10 @@ static int add_expires(request_rec *r) { expires_dir_config *conf; char *code; - char *timestr = NULL; - ap_ansi_time_t base; - time_t additional; - time_t expires; - ap_time_t *finaltime = NULL; - char age[20]; + ap_time_t base; + ap_time_t additional; + ap_time_t expires; + char *timestr; if (ap_is_HTTP_ERROR(r->status)) /* Don't add Expires headers to errors */ return DECLINED; @@ -459,14 +458,14 @@ static int add_expires(request_rec *r) */ return DECLINED; } - ap_get_ansitime(r->finfo.mtime, &base); + base = r->finfo.mtime; additional = atoi(&code[1]); break; case 'A': /* there's been some discussion and it's possible that * 'access time' will be stored in request structure */ - ap_get_ansitime(r->request_time, &base); + base = r->request_time; additional = atoi(&code[1]); break; default: @@ -479,14 +478,11 @@ static int add_expires(request_rec *r) }; expires = base + additional; - ap_snprintf(age, sizeof(age), "max-age=%d", (int) expires - (int) r->request_time); - ap_table_setn(r->headers_out, "Cache-Control", ap_pstrdup(r->pool, age)); - tzset(); /* redundant? called implicitly by localtime, at least - * under FreeBSD - */ - ap_make_time(&finaltime, r->pool); - ap_set_ansitime(finaltime, expires); - ap_timestr(×tr, finaltime, APR_UTCTIME, r->pool); + ap_table_setn(r->headers_out, "Cache-Control", + ap_psprintf(r->pool, "max-age=%qd", + (expires - r->request_time) / AP_USEC_PER_SEC)); + timestr = ap_palloc(r->pool, AP_RFC822_DATE_LEN); + ap_rfc822_date(timestr, expires); ap_table_setn(r->headers_out, "Expires", timestr); return OK; } diff --git a/modules/metadata/mod_usertrack.c b/modules/metadata/mod_usertrack.c index ce794b883c..fb2c731254 100644 --- a/modules/metadata/mod_usertrack.c +++ b/modules/metadata/mod_usertrack.c @@ -102,18 +102,13 @@ #include "httpd.h" #include "http_config.h" #include "http_core.h" -#if !defined(WIN32) && !defined(MPE) -#include -#endif -#ifdef HAVE_SYS_TIMES_H -#include -#endif +#include "http_request.h" module MODULE_VAR_EXPORT usertrack_module; typedef struct { int always; - time_t expires; + int expires; } cookie_log_state; typedef struct { @@ -121,11 +116,6 @@ typedef struct { char *cookie_name; } cookie_dir_rec; -/* Define this to allow post-2000 cookies. Cookies use two-digit dates, - * so it might be dicey. (Netscape does it correctly, but others may not) - */ -#define MILLENIAL_COOKIES - /* Make Cookie: Now we have to generate something that is going to be * pretty unique. We can base it on the pid, time, hostip */ @@ -135,13 +125,6 @@ static void make_cookie(request_rec *r) { cookie_log_state *cls = ap_get_module_config(r->server->module_config, &usertrack_module); -#if !defined(HAVE_GETTIMEOFDAY) && defined(HAVE_TIMES) - clock_t mpe_times; - struct tms mpe_tms; -#elif !defined(WIN32) - struct timeval tv; - struct timezone tz = {0, 0}; -#endif /* 1024 == hardcoded constant */ char cookiebuf[1024]; char *new_cookie; @@ -151,61 +134,21 @@ static void make_cookie(request_rec *r) dcfg = ap_get_module_config(r->per_dir_config, &usertrack_module); -#if !defined(HAVE_GETTIMEOFDAY) && defined(HAVE_TIMES) -/* We lack gettimeofday(), so we must use time() to obtain the epoch - seconds, and then times() to obtain CPU clock ticks (milliseconds). - Combine this together to obtain a hopefully unique cookie ID. */ - - mpe_times = times(&mpe_tms); - - ap_snprintf(cookiebuf, sizeof(cookiebuf), "%s.%d%ld%ld", rname, - (int) getpid(), - (long) r->request_time, (long) mpe_tms.tms_utime); -#elif defined(WIN32) - /* - * We lack gettimeofday() and we lack times(). So we'll use a combination - * of time() and GetTickCount(), which returns milliseconds since Windows - * was started. It should be relatively unique. - */ - - ap_snprintf(cookiebuf, sizeof(cookiebuf), "%s.%d%ld%ld", rname, - (int) getpid(), - (long) r->request_time, (long) GetTickCount()); - -#else - gettimeofday(&tv, &tz); - - ap_snprintf(cookiebuf, sizeof(cookiebuf), "%s.%d%ld%d", rname, - (int) getpid(), - (long) tv.tv_sec, (int) tv.tv_usec / 1000); -#endif + /* XXX: hmm, this should really tie in with mod_unique_id */ + ap_snprintf(cookiebuf, sizeof(cookiebuf), "%s.%qd", rname, ap_now()); if (cls->expires) { - ap_time_t *when = NULL; - ap_int64_t req_time; - char *temp_cookie = NULL; - ap_size_t retsize; - - ap_make_time(&when, r->pool); - ap_get_ansitime(when, &req_time); -#ifndef MILLENIAL_COOKIES - /* - * Only two-digit date string, so we can't trust "00" or more. - * Therefore, we knock it all back to just before midnight on - * 1/1/2000 (which is 946684799) - */ - - if (req_time + cls->expires > 946684799) { - ap_set_ansitime(when, 946684799); - } - else -#endif - ap_set_ansitime(when, req_time + cls->expires); + ap_exploded_time_t tms; + + ap_explode_gmt(&tms, r->request_time + cls->expires * AP_USEC_PER_SEC); /* Cookie with date; as strftime '%a, %d-%h-%y %H:%M:%S GMT' */ - ap_strftime(temp_cookie, &retsize, MAX_STRING_LEN, "%a, %d-%h-%y %H:%M:%S GMT", when); - new_cookie = ap_psprintf(r->pool, "%s=%s; path=/; expires=%s", - dcfg->cookie_name, cookiebuf, temp_cookie); + new_cookie = ap_psprintf(r->pool, + "%s=%s; path=/; expires=%s, %.2d-%s-%.2d %.2d:%.2d:%.2d GMT", + dcfg->cookie_name, cookiebuf, ap_day_snames[tms.tm_wday], + tms.tm_mday, ap_month_snames[tms.tm_mon], + tms.tm_year % 100, + tms.tm_hour, tms.tm_min, tms.tm_sec); } else { new_cookie = ap_psprintf(r->pool, "%s=%s; path=/", diff --git a/server/log.c b/server/log.c index 48dee5edd1..0832613f84 100644 --- a/server/log.c +++ b/server/log.c @@ -359,7 +359,11 @@ static void log_error_core(const char *file, int line, int level, } if (logf && ((level & APLOG_STARTUP) != APLOG_STARTUP)) { - len = ap_snprintf(errstr, MAX_STRING_LEN, "[%s] ", ap_get_time()); + errstr[0] = '['; + ap_ctime(errstr + 1, ap_now()); + errstr[1 + AP_CTIME_LEN - 1] = ']'; + errstr[1 + AP_CTIME_LEN ] = ' '; + len = 1 + AP_CTIME_LEN + 1; } else { len = 0; } @@ -581,9 +585,12 @@ API_EXPORT(void) ap_log_reason(const char *reason, const char *file, request_rec API_EXPORT(void) ap_log_assert(const char *szExp, const char *szFile, int nLine) { + char time_str[AP_CTIME_LEN]; + + ap_ctime(time_str, ap_now()); ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "[%s] file %s, line %d, assertion \"%s\" failed", - ap_get_time(), szFile, nLine, szExp); + time_str, szFile, nLine, szExp); #ifndef WIN32 /* unix assert does an abort leading to a core dump */ abort(); diff --git a/server/util.c b/server/util.c index 17581f61c5..0a2342beb4 100644 --- a/server/util.c +++ b/server/util.c @@ -92,18 +92,6 @@ extern int fclose(FILE *); */ #define TEST_CHAR(c, f) (test_char_table[(unsigned)(c)] & (f)) -API_EXPORT(char *) ap_get_time() -{ - ap_time_t *t = NULL; - char *time_string = NULL; - - ap_make_time(&t, NULL); - ap_current_time(t); - - ap_timestr(&time_string, t, APR_LOCALTIME, NULL); - return (time_string); -} - /* * Examine a field value (such as a media-/content-type) string and return * it sans any parameters; e.g., strip off any ';charset=foo' and the like. @@ -124,25 +112,22 @@ API_EXPORT(char *) ap_field_noparam(ap_context_t *p, const char *intype) } } -API_EXPORT(char *) ap_ht_time(ap_context_t *p, ap_time_t *t, const char *fmt, int gmt) +API_EXPORT(char *) ap_ht_time(ap_context_t *p, ap_time_t t, const char *fmt, int gmt) { ap_int32_t retcode; char ts[MAX_STRING_LEN]; char tf[MAX_STRING_LEN]; + ap_exploded_time_t xt; if (gmt) { - ap_explode_time(t, APR_UTCTIME); - } - else { - ap_explode_time(t, APR_LOCALTIME); - } - if(gmt) { + const char *f; + char *strp; + + ap_explode_gmt(&xt, t); /* Convert %Z to "GMT" and %z to "+0000"; * on hosts that do not have a time zone string in struct tm, * strftime must assume its argument is local time. */ - const char *f; - char *strp; for(strp = tf, f = fmt; strp < tf + sizeof(tf) - 6 && (*strp = *f) ; f++, strp++) { if (*f != '%') continue; @@ -169,9 +154,12 @@ API_EXPORT(char *) ap_ht_time(ap_context_t *p, ap_time_t *t, const char *fmt, in *strp = '\0'; fmt = tf; } + else { + ap_explode_localtime(&xt, t); + } /* check return code? */ - ap_strftime(ts, &retcode, MAX_STRING_LEN, fmt, t); + ap_strftime(ts, &retcode, MAX_STRING_LEN, fmt, &xt); ts[MAX_STRING_LEN - 1] = '\0'; return ap_pstrdup(p, ts); } diff --git a/server/util_date.c b/server/util_date.c index ba0251efc7..2864ed244b 100644 --- a/server/util_date.c +++ b/server/util_date.c @@ -125,6 +125,7 @@ API_EXPORT(int) ap_checkmask(const char *data, const char *mask) return 0; /* We only get here if mask is corrupted (exceeds 256) */ } + /* * Parses an HTTP date in one of three standard forms: * @@ -172,16 +173,12 @@ API_EXPORT(int) ap_checkmask(const char *data, const char *mask) * but many changes since then. * */ -API_EXPORT(ap_time_t *) ap_parseHTTPdate(const char *date, ap_context_t *cont) +API_EXPORT(ap_time_t) ap_parseHTTPdate(const char *date) { - ap_int32_t year; - ap_int32_t mday; - ap_int32_t hour; - ap_int32_t min; - ap_int32_t sec; + ap_exploded_time_t ds; + ap_time_t result; int mint, mon; const char *monstr, *timstr; - ap_time_t *temp; static const int months[12] = { ('J' << 16) | ('a' << 8) | 'n', ('F' << 16) | ('e' << 8) | 'b', @@ -192,99 +189,96 @@ API_EXPORT(ap_time_t *) ap_parseHTTPdate(const char *date, ap_context_t *cont) ('N' << 16) | ('o' << 8) | 'v', ('D' << 16) | ('e' << 8) | 'c'}; if (!date) - return NULL; + return BAD_DATE; while (*date && ap_isspace(*date)) /* Find first non-whitespace char */ ++date; if (*date == '\0') - return NULL; + return BAD_DATE; if ((date = strchr(date, ' ')) == NULL) /* Find space after weekday */ - return NULL; + return BAD_DATE; ++date; /* Now pointing to first char after space, which should be */ /* start of the actual date information for all 3 formats. */ if (ap_checkmask(date, "## @$$ #### ##:##:## *")) { /* RFC 1123 format */ - year = ((date[7] - '0') * 10 + (date[8] - '0') - 19) * 100; - if (year < 0) - return NULL; + ds.tm_year = ((date[7] - '0') * 10 + (date[8] - '0') - 19) * 100; + if (ds.tm_year < 0) + return BAD_DATE; - year += ((date[9] - '0') * 10) + (date[10] - '0'); + ds.tm_year += ((date[9] - '0') * 10) + (date[10] - '0'); - mday = ((date[0] - '0') * 10) + (date[1] - '0'); + ds.tm_mday = ((date[0] - '0') * 10) + (date[1] - '0'); monstr = date + 3; timstr = date + 12; } else if (ap_checkmask(date, "##-@$$-## ##:##:## *")) { /* RFC 850 format */ - year = ((date[7] - '0') * 10) + (date[8] - '0'); - if (year < 70) - year += 100; + ds.tm_year = ((date[7] - '0') * 10) + (date[8] - '0'); + if (ds.tm_year < 70) + ds.tm_year += 100; - mday = ((date[0] - '0') * 10) + (date[1] - '0'); + ds.tm_mday = ((date[0] - '0') * 10) + (date[1] - '0'); monstr = date + 3; timstr = date + 10; } else if (ap_checkmask(date, "@$$ ~# ##:##:## ####*")) { /* asctime format */ - year = ((date[16] - '0') * 10 + (date[17] - '0') - 19) * 100; - if (year < 0) - return NULL; + ds.tm_year = ((date[16] - '0') * 10 + (date[17] - '0') - 19) * 100; + if (ds.tm_year < 0) + return BAD_DATE; - year += ((date[18] - '0') * 10) + (date[19] - '0'); + ds.tm_year += ((date[18] - '0') * 10) + (date[19] - '0'); if (date[4] == ' ') - mday = 0; + ds.tm_mday = 0; else - mday = (date[4] - '0') * 10; + ds.tm_mday = (date[4] - '0') * 10; - mday += (date[5] - '0'); + ds.tm_mday += (date[5] - '0'); monstr = date; timstr = date + 7; } else - return NULL; + return BAD_DATE; - if (mday <= 0 || mday > 31) - return NULL; + if (ds.tm_mday <= 0 || ds.tm_mday > 31) + return BAD_DATE; - hour = ((timstr[0] - '0') * 10) + (timstr[1] - '0'); - min = ((timstr[3] - '0') * 10) + (timstr[4] - '0'); - sec = ((timstr[6] - '0') * 10) + (timstr[7] - '0'); + ds.tm_hour = ((timstr[0] - '0') * 10) + (timstr[1] - '0'); + ds.tm_min = ((timstr[3] - '0') * 10) + (timstr[4] - '0'); + ds.tm_sec = ((timstr[6] - '0') * 10) + (timstr[7] - '0'); - if ((hour > 23) || (min > 59) || (sec > 61)) - return NULL; + if ((ds.tm_hour > 23) || (ds.tm_min > 59) || (ds.tm_sec > 61)) + return BAD_DATE; mint = (monstr[0] << 16) | (monstr[1] << 8) | monstr[2]; for (mon = 0; mon < 12; mon++) if (mint == months[mon]) break; if (mon == 12) - return NULL; + return BAD_DATE; - if ((mday == 31) && (mon == 3 || mon == 5 || mon == 8 || mon == 10)) - return NULL; + if ((ds.tm_mday == 31) && (mon == 3 || mon == 5 || mon == 8 || mon == 10)) + return BAD_DATE; /* February gets special check for leapyear */ if ((mon == 1) && - ((mday > 29) - || ((mday == 29) - && ((year & 3) - || (((year % 100) == 0) - && (((year % 400) != 100))))))) - return NULL; - - ap_make_time(&temp, cont); - ap_set_year(temp, year); - ap_set_mday(temp, mday); - ap_set_hour(temp, hour); - ap_set_min(temp, min); - ap_set_sec(temp, sec); - ap_set_mon(temp, mon); - - return temp; + ((ds.tm_mday > 29) + || ((ds.tm_mday == 29) + && ((ds.tm_year & 3) + || (((ds.tm_year % 100) == 0) + && (((ds.tm_year % 400) != 100))))))) + return BAD_DATE; + + ds.tm_mon = mon; + + if (ap_implode_time(&result, &ds) != APR_SUCCESS) { + return BAD_DATE; + } + return result; } diff --git a/server/util_script.c b/server/util_script.c index 3997644cf8..9095b57b7b 100644 --- a/server/util_script.c +++ b/server/util_script.c @@ -589,9 +589,7 @@ API_EXPORT(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, * pass it on blindly because of restrictions on future values. */ else if (!strcasecmp(w, "Last-Modified")) { - ap_time_t *mtime = ap_parseHTTPdate(l, r->pool); - - ap_update_mtime(r, mtime); + ap_update_mtime(r, ap_parseHTTPdate(l)); ap_set_last_modified(r); } else if (!strcasecmp(w, "Set-Cookie")) {