diff options
author | Nick Mathewson <nickm@torproject.org> | 2007-06-02 15:26:57 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2007-06-02 15:26:57 +0000 |
commit | aee7f016242c0fea9243be1c82a67b804bfb6792 (patch) | |
tree | 6e28814091a4325047b48c2d95131f21ef25a846 /src/common/util.c | |
parent | 80954dcd2faefe477bd0a3b646ffd3dce3c56481 (diff) | |
download | tor-aee7f016242c0fea9243be1c82a67b804bfb6792.tar.gz tor-aee7f016242c0fea9243be1c82a67b804bfb6792.zip |
r13154@catbus: nickm | 2007-06-02 11:26:44 -0400
Server-side support for If-Modified-Since in HTTP requsts for v1 stuff, and for network-status documents.
svn:r10451
Diffstat (limited to 'src/common/util.c')
-rw-r--r-- | src/common/util.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/common/util.c b/src/common/util.c index 14013edb10..74279cee7a 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -1127,6 +1127,64 @@ parse_iso_time(const char *cp, time_t *t) return 0; } +/** Given a <b>date</b> in one of the three formats allowed by HTTP (ugh), + * parse it into <b>tm</b>. Return 0 on success, negative on failure. */ +int +parse_http_time(const char *date, struct tm *tm) +{ + const char *cp; + char month[4]; + char wkday[4]; + int i; + + tor_assert(tm); + memset(tm, 0, sizeof(*tm)); + + /* First, try RFC1123 or RFC850 format: skip the weekday. */ + if ((cp = strchr(date, ','))) { + ++cp; + if (sscanf(date, "%2d %3s %4d %2d:%2d:%2d GMT", + &tm->tm_mday, month, &tm->tm_year, + &tm->tm_hour, &tm->tm_min, &tm->tm_sec) == 6) { + /* rfc1123-date */ + tm->tm_year -= 1900; + } else if (sscanf(date, "%2d-%3s-%2d %2d:%2d:%2d GMT", + &tm->tm_mday, month, &tm->tm_year, + &tm->tm_hour, &tm->tm_min, &tm->tm_sec) == 6) { + /* rfc850-date */ + } else { + return -1; + } + } else { + /* No comma; possibly asctime() format. */ + if (sscanf(date, "%3s %3s %2d %2d:%2d:%2d %4d", + wkday, month, &tm->tm_mday, + &tm->tm_hour, &tm->tm_min, &tm->tm_sec, &tm->tm_year) == 7) { + tm->tm_year -= 1900; + } else { + return -1; + } + } + + month[4] = '\0'; + /* Okay, now decode the month. */ + for (i = 0; i < 12; ++i) { + if (!strcasecmp(MONTH_NAMES[i], month)) { + tm->tm_mon = i+1; + } + } + + if (tm->tm_year < 0 || + tm->tm_mon < 1 || tm->tm_mon > 12 || + tm->tm_mday < 0 || tm->tm_mday > 31 || + tm->tm_hour < 0 || tm->tm_hour > 23 || + tm->tm_min < 0 || tm->tm_min > 59 || + tm->tm_sec < 0 || tm->tm_sec > 61) + return -1; /* Out of range, or bad month. */ + + return 0; +} + /* ===== * File helpers * ===== */ |