]> granicus.if.org Git - apache/commitdiff
First step in getting Apache to use APR's time libraries. This gets a good
authorRyan Bloom <rbb@apache.org>
Mon, 20 Dec 1999 16:38:39 +0000 (16:38 +0000)
committerRyan Bloom <rbb@apache.org>
Mon, 20 Dec 1999 16:38:39 +0000 (16:38 +0000)
number of them, but I think there are more time values still in the Apache
code.  This works under Linux, but has not been tested anywhere else.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@84338 13f79535-47bb-0310-9956-ffa450edef68

13 files changed:
include/http_protocol.h
include/http_request.h
include/httpd.h
include/util_date.h
modules/filters/mod_include.c
modules/http/http_core.c
modules/http/http_protocol.c
modules/http/http_request.c
modules/loggers/mod_log_config.c
modules/mappers/mod_negotiation.c
server/util.c
server/util_date.c
server/util_script.c

index 24dae34ec1d2a830cd8f35092fdb73e03b37e14b..bb6cd99d730f1eb6a91f5b37519eb1b2f78f5305 100644 (file)
@@ -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(time_t) ap_rationalize_mtime(request_rec *r, 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);
index bf66f868b2a6c59e0e6db94a74c293c7b8a891eb..ed51f915fe2224ef946d620140a2eb0d700c9312 100644 (file)
@@ -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(time_t) ap_update_mtime(request_rec *r, time_t dependency_mtime);
+API_EXPORT(ap_time_t *) ap_update_mtime(request_rec *r, ap_time_t *dependency_mtime);
 
 #ifdef CORE_PRIVATE
 /* Function called by main.c to handle first-level request */
index a3b816aa52bbfb192184da1c6a7604bbfdce1ee3..7f39de0a3a701f1966bef424b553c5db6a0a706d 100644 (file)
@@ -71,6 +71,7 @@ extern "C" {
 #include "ap_config.h"
 #include "apr_general.h"
 #include "apr_lib.h"
+#include "apr_time.h"
 #include "buff.h"
 #include "ap.h"
 
@@ -667,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: */
 
-    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 */
@@ -703,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 */
-    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 */
 
@@ -913,14 +914,10 @@ struct server_rec {
  */
 
 /* Time */
-extern API_VAR_EXPORT const char ap_month_snames[12][4];
-extern API_VAR_EXPORT const char ap_day_snames[7][4];
-
 API_EXPORT(struct tm *) ap_get_gmtoff(int *tz);
 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, time_t t, const char *fmt, int gmt);
-API_EXPORT(char *) ap_gm_timestr_822(ap_context_t *p, time_t t);
+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
index 8e2051024e649f5a506c90d41babf511851fb64f..0504e5e5fdbad7a0539e154c8571a862c8f27b4c 100644 (file)
@@ -71,12 +71,13 @@ extern "C" {
 #include <sys/types.h>
 #endif
 #include <time.h>
+#include "apr_time.h"
 
 #define BAD_DATE (time_t)0
 
 API_EXPORT(int) ap_checkmask(const char *data, const char *mask);
 API_EXPORT(time_t) ap_tm2sec(const struct tm *t);
-API_EXPORT(time_t) ap_parseHTTPdate(const char *date);
+API_EXPORT(ap_time_t *) ap_parseHTTPdate(const char *date, ap_context_t *cont);
 
 #ifdef __cplusplus
 }
index 984ddd99da26bd2455dda3fee81f8ca5d9f5e1fe..ecb577b21193cdfcd5cee830d497e1d4f8826f54 100644 (file)
@@ -124,12 +124,16 @@ static void add_include_vars(request_rec *r, char *timefmt)
 #endif /* ndef WIN32 */
     ap_table_t *e = r->subprocess_env;
     char *t;
-    time_t date = r->request_time;
+    ap_time_t *date = r->request_time;
+    ap_time_t *mtime = NULL;
+
+    ap_make_time(&mtime, r->pool);
+    ap_set_curtime(mtime, r->finfo.st_mtime); 
 
     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_ht_time(r->pool, mtime, timefmt, 0));
     ap_table_setn(e, "DOCUMENT_URI", r->uri);
     ap_table_setn(e, "DOCUMENT_PATH_INFO", r->path_info);
 #ifndef WIN32
@@ -1021,13 +1025,17 @@ 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")) {
-            time_t date = r->request_time;
+            ap_time_t *date = r->request_time;
+            ap_time_t *mtime = NULL;
+
+            ap_make_time(&mtime, r->pool);
+            ap_set_curtime(mtime, r->finfo.st_mtime);
 
             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));
+                      ap_ht_time(r->pool, mtime, tf, 0));
         }
         else if (!strcmp(tag, "sizefmt")) {
             parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 0);
@@ -1168,6 +1176,7 @@ 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))) {
@@ -1179,7 +1188,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_rputs(ap_ht_time(r->pool, finfo.st_mtime, tf, 0), r);
+                ap_make_time(&mtime, r->pool);
+                ap_set_curtime(mtime, finfo.st_mtime);
+                ap_rputs(ap_ht_time(r->pool, mtime, tf, 0), r);
             }
         }
     }
@@ -2341,6 +2352,7 @@ 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;
@@ -2372,7 +2384,9 @@ static int send_parsed_file(request_rec *r)
         && (r->finfo.st_mode & S_IXGRP)
 #endif
         ) {
-        ap_update_mtime(r, r->finfo.st_mtime);
+        ap_make_time(&mtime, r->pool);
+        ap_set_curtime(mtime, r->finfo.st_mtime);
+        ap_update_mtime(r, mtime);
         ap_set_last_modified(r);
     }
     if ((errstatus = ap_meets_conditions(r)) != OK) {
index 9129eaf6845e46262fb6a0c5bdf505329f6b3b3e..8bc42d3f604b2d2c69870b67356139efeee3e1d4 100644 (file)
@@ -2453,6 +2453,7 @@ 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;
@@ -2506,8 +2507,9 @@ static int default_handler(request_rec *r)
                     "file permissions deny server access: %s", r->filename);
         return FORBIDDEN;
     }
-       
-    ap_update_mtime(r, r->finfo.st_mtime);
+    ap_make_time(&temp, r->pool);      
+    ap_set_curtime(temp, r->finfo.st_mtime);
+    ap_update_mtime(r, temp);
     ap_set_last_modified(r);
     ap_set_etag(r);
     ap_table_setn(r->headers_out, "Accept-Ranges", "bytes");
index 21a1bac48d13ca4ed2354408533b235380131f3f..0e53623bb5de9edd0bd968d3f44b871d2de956a0 100644 (file)
@@ -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(time_t) ap_rationalize_mtime(request_rec *r, time_t mtime)
+API_EXPORT(ap_time_t *) ap_rationalize_mtime(request_rec *r, ap_time_t *mtime)
 {
-    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,15 +381,26 @@ API_EXPORT(time_t) ap_rationalize_mtime(request_rec *r, time_t mtime)
      * were given a time in the future, we return the current time - the
      * Last-Modified can't be in the future.
      */
-    now = (mtime < r->request_time) ? r->request_time : time(NULL);
-    return (mtime > now) ? now : mtime;
+    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;
+    }
 }
 
 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;
-    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
@@ -406,7 +417,13 @@ API_EXPORT(int) ap_meets_conditions(request_rec *r)
         return OK;
     }
 
-    mtime = (r->mtime != 0) ? r->mtime : time(NULL);
+    if (r->mtime == NULL) {
+        ap_make_time(&mtime, r->pool);
+        ap_current_time(mtime);
+    }
+    else {
+        mtime = r->mtime;
+    }
 
     /* If an If-Match request-header field was given
      * AND the field value is not "*" (meaning match anything)
@@ -428,9 +445,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) {
-            time_t ius = ap_parseHTTPdate(if_unmodified);
+            ap_time_t *ius = ap_parseHTTPdate(if_unmodified, r->pool);
 
-            if ((ius != BAD_DATE) && (mtime > ius)) {
+            if ((ius != NULL) && (ap_timecmp(mtime, ius) == APR_MORE)) {
                 return HTTP_PRECONDITION_FAILED;
             }
         }
@@ -481,9 +498,10 @@ 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)) {
-        time_t ims = ap_parseHTTPdate(if_modified_since);
+        ap_time_t *ims = ap_parseHTTPdate(if_modified_since, r->pool);
 
-        if ((ims >= mtime) && (ims <= r->request_time)) {
+        if (!ap_timecmp(ims, mtime) < APR_LESS && 
+            !ap_timecmp(ims, r->request_time) > APR_MORE) {
             return HTTP_NOT_MODIFIED;
         }
     }
@@ -501,6 +519,7 @@ 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
@@ -515,7 +534,8 @@ API_EXPORT(char *) ap_make_etag(request_rec *r, int force_weak)
      * would be incorrect.
      */
     
-    weak = ((r->request_time - r->mtime > 1) && !force_weak) ? "" : "W/";
+    ap_timediff(r->request_time, r->mtime, &diff);
+    weak = ((diff > 1) && !force_weak) ? "" : "W/";
 
     if (r->finfo.st_mode != 0) {
         etag = ap_psprintf(r->pool,
@@ -583,10 +603,10 @@ API_EXPORT(void) ap_set_etag(request_rec *r)
  */
 API_EXPORT(void) ap_set_last_modified(request_rec *r)
 {
-    time_t mod_time = ap_rationalize_mtime(r, r->mtime);
-
-    ap_table_setn(r->headers_out, "Last-Modified",
-              ap_gm_timestr_822(r->pool, mod_time));
+    ap_time_t *mod_time = ap_rationalize_mtime(r, r->mtime);
+    char *datestr;
+    ap_gm_timestr_822(&datestr, mod_time, r->pool);
+    ap_table_setn(r->headers_out, "Last-Modified", datestr);
 }
 
 /* Get the method number associated with the given string, assumed to
@@ -802,7 +822,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 
             */
-           r->request_time = time(0);
+           ap_current_time(r->request_time);
             return 0;
         }
     }
@@ -821,7 +841,7 @@ static int read_request_line(request_rec *r)
 
     /* //ap_bsetflag(conn->client, B_SAFEREAD, 0); */
 
-    r->request_time = time(NULL);
+    ap_current_time(r->request_time);
     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);
@@ -955,6 +975,8 @@ 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);
@@ -1306,6 +1328,7 @@ API_EXPORT_NONSTD(int) ap_send_header_field(request_rec *r,
 API_EXPORT(void) ap_basic_http_header(request_rec *r)
 {
     char *protocol;
+    char *date = NULL;
 #ifdef CHARSET_EBCDIC
     int convert = ap_bgetflag(r->connection->client, B_EBCDIC2ASCII);
 #endif /*CHARSET_EBCDIC*/
@@ -1337,7 +1360,8 @@ API_EXPORT(void) ap_basic_http_header(request_rec *r)
 
     ap_rvputs(r, protocol, " ", r->status_line, "\015\012", NULL);
 
-    ap_send_header_field(r, "Date", ap_gm_timestr_822(r->pool, r->request_time));
+    ap_gm_timestr_822(&date, r->request_time, r->pool);
+    ap_send_header_field(r, "Date", date);
     ap_send_header_field(r, "Server", ap_get_server_version());
 
     ap_table_unset(r->headers_out, "Date");        /* Avoid bogosity */
@@ -1545,6 +1569,7 @@ API_EXPORT(void) ap_send_http_header(request_rec *r)
 {
     int i;
     const long int zero = 0L;
+    char *date = NULL;
 #ifdef CHARSET_EBCDIC
     int convert = ap_bgetflag(r->connection->client, B_EBCDIC2ASCII);
 #endif /*CHARSET_EBCDIC*/
@@ -1617,9 +1642,10 @@ API_EXPORT(void) ap_send_http_header(request_rec *r)
      * Control cachability for non-cachable responses if not already set by
      * some other part of the server configuration.
      */
-    if (r->no_cache && !ap_table_get(r->headers_out, "Expires"))
-        ap_table_addn(r->headers_out, "Expires",
-                  ap_gm_timestr_822(r->pool, r->request_time));
+    if (r->no_cache && !ap_table_get(r->headers_out, "Expires")) {
+        ap_gm_timestr_822(&date, r->request_time, r->pool);
+        ap_table_addn(r->headers_out, "Expires", date);
+    }
 
     /* Send the entire ap_table_t of header fields, terminated by an empty line. */
 
index 5c7cacfc17345a1021f42e85c3b048db746ee6f7..76904bfc2de162799d4c7b231766193f03e503ac 100644 (file)
@@ -1374,9 +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(time_t) ap_update_mtime(request_rec *r, time_t dependency_mtime)
+API_EXPORT(ap_time_t *) ap_update_mtime(request_rec *r, ap_time_t *dependency_mtime)
 {
-    if (r->mtime < dependency_mtime) {
+    if (ap_timecmp(r->mtime, dependency_mtime) == APR_LESS) {
         r->mtime = dependency_mtime;
     }
     return r->mtime;
index 4d173862e651a8f689c4b7f205d9f26136c54a19..7debb7977ef1f8d32017a94302a6832c454a49b2 100644 (file)
@@ -406,7 +406,13 @@ static const char *log_request_time(request_rec *r, char *a)
 
 static const char *log_request_duration(request_rec *r, char *a)
 {
-    return ap_psprintf(r->pool, "%ld", time(NULL) - r->request_time);
+    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);
 }
 
 /* These next two routines use the canonical name:port so that log
index 162c9971bf0f0efbb2c2c10e524f2a87108a1a74..3d69d4564ff14017333990f31a60c6adeeca8685 100644 (file)
@@ -284,13 +284,15 @@ static void set_mime_fields(var_rec *var, accept_rec *mime_info)
 
 static void set_vlist_validator(request_rec *r, request_rec *vlistr)
 {
+    ap_time_t *temp;
     /* Calculating the variant list validator is similar to
      * calculating an etag for the source of the variant list
      * information, so we use ap_make_etag().  Note that this
      * validator can be 'weak' in extreme case.
      */
-
-    ap_update_mtime (vlistr, vlistr->finfo.st_mtime);
+    ap_make_time(&temp, vlistr->pool);
+    ap_set_curtime(temp, vlistr->finfo.st_mtime);
+    ap_update_mtime(vlistr, temp);
     r->vlist_validator = ap_make_etag(vlistr, 0);
 
     /* ap_set_etag will later take r->vlist_validator into account
index 28d45b1b79b765c4ec99498e716b5c678926a9da..666d54a6c1bbcac8e361489f044231cdfb8fa835 100644 (file)
@@ -92,15 +92,6 @@ extern int fclose(FILE *);
  */
 #define TEST_CHAR(c, f)        (test_char_table[(unsigned)(c)] & (f))
 
-API_VAR_EXPORT const char ap_month_snames[12][4] =
-{
-    "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-API_VAR_EXPORT const char ap_day_snames[7][4] =
-{
-    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
-};
-
 API_EXPORT(char *) ap_get_time()
 {
     time_t t;
@@ -132,13 +123,17 @@ API_EXPORT(char *) ap_field_noparam(ap_context_t *p, const char *intype)
     }
 }
 
-API_EXPORT(char *) ap_ht_time(ap_context_t *p, 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)
 {
     char ts[MAX_STRING_LEN];
     char tf[MAX_STRING_LEN];
-    struct tm *tms;
 
-    tms = (gmt ? gmtime(&t) : localtime(&t));
+    if (gmt) {
+        ap_explode_time(t, APR_UTCTIME);
+    }
+    else {
+        ap_explode_time(t, APR_LOCALTIME);
+    }
     if(gmt) {
        /* Convert %Z to "GMT" and %z to "+0000";
         * on hosts that do not have a time zone string in struct tm,
@@ -174,66 +169,11 @@ API_EXPORT(char *) ap_ht_time(ap_context_t *p, time_t t, const char *fmt, int gm
     }
 
     /* check return code? */
-    strftime(ts, MAX_STRING_LEN, fmt, tms);
+    ap_strftime(ts, MAX_STRING_LEN, fmt, t);
     ts[MAX_STRING_LEN - 1] = '\0';
     return ap_pstrdup(p, ts);
 }
 
-API_EXPORT(char *) ap_gm_timestr_822(ap_context_t *p, time_t sec)
-{
-    struct tm *tms;
-    char *date_str = ap_palloc(p, 48 * sizeof(char));
-    char *date_str_ptr = date_str;
-    int real_year;
-
-    tms = gmtime(&sec);    
-
-    /* Assumption: this is always 3 */
-    /* i = strlen(ap_day_snames[tms->tm_wday]); */
-    memcpy(date_str_ptr, ap_day_snames[tms->tm_wday], 3);
-    date_str_ptr += 3;
-    *date_str_ptr++ = ',';
-    *date_str_ptr++ = ' ';
-    *date_str_ptr++ = tms->tm_mday / 10 + '0';
-    *date_str_ptr++ = tms->tm_mday % 10 + '0';
-    *date_str_ptr++ = ' ';
-    /* Assumption: this is also always 3 */
-    /* i = strlen(ap_month_snames[tms->tm_mon]); */
-    memcpy(date_str_ptr, ap_month_snames[tms->tm_mon], 3);
-    date_str_ptr += 3;
-    *date_str_ptr++ = ' ';
-    real_year = 1900 + tms->tm_year;
-    /* This routine isn't y10k ready. */
-    *date_str_ptr++ = real_year / 1000 + '0';
-    *date_str_ptr++ = real_year % 1000 / 100 + '0';
-    *date_str_ptr++ = real_year % 100 / 10 + '0';
-    *date_str_ptr++ = real_year % 10 + '0';
-    *date_str_ptr++ = ' ';
-    *date_str_ptr++ = tms->tm_hour / 10 + '0';
-    *date_str_ptr++ = tms->tm_hour % 10 + '0';
-    *date_str_ptr++ = ':';
-    *date_str_ptr++ = tms->tm_min / 10 + '0';
-    *date_str_ptr++ = tms->tm_min % 10 + '0';
-    *date_str_ptr++ = ':';
-    *date_str_ptr++ = tms->tm_sec / 10 + '0';
-    *date_str_ptr++ = tms->tm_sec % 10 + '0';
-    *date_str_ptr++ = ' ';
-    *date_str_ptr++ = 'G';
-    *date_str_ptr++ = 'M';
-    *date_str_ptr++ = 'T';
-    *date_str_ptr = '\0';
-
-    return date_str;
-    /* RFC date format; as strftime '%a, %d %b %Y %T GMT' */
-
-    /* The equivalent using sprintf. Use this for more legible but slower code
-    return ap_psprintf(p,
-               "%s, %.2d %s %d %.2d:%.2d:%.2d GMT", ap_day_snames[tms->tm_wday],
-               tms->tm_mday, ap_month_snames[tms->tm_mon], tms->tm_year + 1900,
-               tms->tm_hour, tms->tm_min, tms->tm_sec);
-    */
-}
-
 /* What a pain in the ass. */
 #if defined(HAVE_GMTOFF)
 API_EXPORT(struct tm *) ap_get_gmtoff(int *tz)
index 5fb04c013b1ff8ef79b22cef8071618d108578eb..78a57af5d4acaaa612ed190d6a44cee2cd14c1b9 100644 (file)
@@ -214,11 +214,16 @@ API_EXPORT(time_t) ap_tm2sec(const struct tm * t)
  * but many changes since then.
  *
  */
-API_EXPORT(time_t) ap_parseHTTPdate(const char *date)
+API_EXPORT(ap_time_t *) ap_parseHTTPdate(const char *date, ap_context_t *cont)
 {
-    struct tm ds;
+    ap_int32_t year;
+    ap_int32_t mday;
+    ap_int32_t hour;
+    ap_int32_t min;
+    ap_int32_t sec;
     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',
@@ -229,93 +234,99 @@ API_EXPORT(time_t) ap_parseHTTPdate(const char *date)
        ('N' << 16) | ('o' << 8) | 'v', ('D' << 16) | ('e' << 8) | 'c'};
 
     if (!date)
-       return BAD_DATE;
+       return NULL;
 
     while (*date && ap_isspace(*date)) /* Find first non-whitespace char */
        ++date;
 
     if (*date == '\0')
-       return BAD_DATE;
+       return NULL;
 
     if ((date = strchr(date, ' ')) == NULL)    /* Find space after weekday */
-       return BAD_DATE;
+       return NULL;
 
     ++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 */
-       ds.tm_year = ((date[7] - '0') * 10 + (date[8] - '0') - 19) * 100;
-       if (ds.tm_year < 0)
-           return BAD_DATE;
+       year = ((date[7] - '0') * 10 + (date[8] - '0') - 19) * 100;
+       if (year < 0)
+           return NULL;
 
-       ds.tm_year += ((date[9] - '0') * 10) + (date[10] - '0');
+       year += ((date[9] - '0') * 10) + (date[10] - '0');
 
-       ds.tm_mday = ((date[0] - '0') * 10) + (date[1] - '0');
+       mday = ((date[0] - '0') * 10) + (date[1] - '0');
 
        monstr = date + 3;
        timstr = date + 12;
     }
     else if (ap_checkmask(date, "##-@$$-## ##:##:## *")) {             /* RFC 850 format  */
-       ds.tm_year = ((date[7] - '0') * 10) + (date[8] - '0');
-       if (ds.tm_year < 70)
-           ds.tm_year += 100;
+       year = ((date[7] - '0') * 10) + (date[8] - '0');
+       if (year < 70)
+           year += 100;
 
-       ds.tm_mday = ((date[0] - '0') * 10) + (date[1] - '0');
+       mday = ((date[0] - '0') * 10) + (date[1] - '0');
 
        monstr = date + 3;
        timstr = date + 10;
     }
     else if (ap_checkmask(date, "@$$ ~# ##:##:## ####*")) {    /* asctime format  */
-       ds.tm_year = ((date[16] - '0') * 10 + (date[17] - '0') - 19) * 100;
-       if (ds.tm_year < 0)
-           return BAD_DATE;
+       year = ((date[16] - '0') * 10 + (date[17] - '0') - 19) * 100;
+       if (year < 0)
+           return NULL;
 
-       ds.tm_year += ((date[18] - '0') * 10) + (date[19] - '0');
+       year += ((date[18] - '0') * 10) + (date[19] - '0');
 
        if (date[4] == ' ')
-           ds.tm_mday = 0;
+           mday = 0;
        else
-           ds.tm_mday = (date[4] - '0') * 10;
+           mday = (date[4] - '0') * 10;
 
-       ds.tm_mday += (date[5] - '0');
+       mday += (date[5] - '0');
 
        monstr = date;
        timstr = date + 7;
     }
     else
-       return BAD_DATE;
+       return NULL;
 
-    if (ds.tm_mday <= 0 || ds.tm_mday > 31)
-       return BAD_DATE;
+    if (mday <= 0 || mday > 31)
+       return NULL;
 
-    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');
+    hour = ((timstr[0] - '0') * 10) + (timstr[1] - '0');
+    min  = ((timstr[3] - '0') * 10) + (timstr[4] - '0');
+    sec  = ((timstr[6] - '0') * 10) + (timstr[7] - '0');
 
-    if ((ds.tm_hour > 23) || (ds.tm_min > 59) || (ds.tm_sec > 61))
-       return BAD_DATE;
+    if ((hour > 23) || (min > 59) || (sec > 61))
+       return NULL;
 
     mint = (monstr[0] << 16) | (monstr[1] << 8) | monstr[2];
     for (mon = 0; mon < 12; mon++)
        if (mint == months[mon])
            break;
     if (mon == 12)
-       return BAD_DATE;
+       return NULL;
 
-    if ((ds.tm_mday == 31) && (mon == 3 || mon == 5 || mon == 8 || mon == 10))
-       return BAD_DATE;
+    if ((mday == 31) && (mon == 3 || mon == 5 || mon == 8 || mon == 10))
+       return NULL;
 
     /* February gets special check for leapyear */
 
     if ((mon == 1) &&
-       ((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;
-
-    return ap_tm2sec(&ds);
+       ((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;
 }
index b38216e6ffcd39c327103f2c52787b488ecef6bd..5de8b74a126feb2525087e4233743666f2128156 100644 (file)
@@ -589,7 +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")) {
-           time_t mtime = ap_parseHTTPdate(l);
+           ap_time_t *mtime = ap_parseHTTPdate(l, r->pool);
 
            ap_update_mtime(r, mtime);
            ap_set_last_modified(r);