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);
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 */
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 */
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 */
*/
/* 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
#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
}
#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));
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));
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))) {
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);
}
}
(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;
char *alt;
char *desc;
off_t size;
- time_t lm;
+ ap_time_t lm;
struct ent *next;
int ascending;
char key;
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^^");
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 {
{
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);
}
/* "%% [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);
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)
}
/* "%% [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);
{
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);
}
/* "%% [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);
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)
}
/* "%% [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);
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)
ap_rvputs(r, "Server Built: ",
ap_get_server_built(), "<br>\n<hr>\n", NULL);
ap_rvputs(r, "Current Time: ",
- ap_ht_time(r->pool, nowtime, DEFAULT_TIME_FORMAT, 0), "<br>\n", NULL);
+ ap_ht_time(r->pool, ap_now(), DEFAULT_TIME_FORMAT, 0), "<br>\n", NULL);
ap_rprintf(r, "\n%d connections currently being processed\n",
server_status->nelts);
{
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;
* 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
* 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
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)
*/
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;
}
}
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;
}
}
{
char *etag;
char *weak;
- int diff;
/*
* Make an ETag header out of various pieces of information. We use
* 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,
*/
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);
}
/* 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;
}
}
/* //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);
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);
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());
* 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);
}
* 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;
}
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);
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
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);
}
{
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;
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);
}
#include "httpd.h"
#include "http_config.h"
#include "http_log.h"
+#include "http_request.h"
typedef struct {
int active;
{
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;
*/
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:
};
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;
}
#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
-#if !defined(WIN32) && !defined(MPE)
-#include <sys/time.h>
-#endif
-#ifdef HAVE_SYS_TIMES_H
-#include <sys/times.h>
-#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 {
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 */
{
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;
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=/",
}
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;
}
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();
*/
#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.
}
}
-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;
*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);
}
return 0; /* We only get here if mask is corrupted (exceeds 256) */
}
+
/*
* Parses an HTTP date in one of three standard forms:
*
* 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',
('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;
}
* 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")) {