summaryrefslogtreecommitdiff
path: root/src/common/util.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2007-06-02 15:26:57 +0000
committerNick Mathewson <nickm@torproject.org>2007-06-02 15:26:57 +0000
commitaee7f016242c0fea9243be1c82a67b804bfb6792 (patch)
tree6e28814091a4325047b48c2d95131f21ef25a846 /src/common/util.c
parent80954dcd2faefe477bd0a3b646ffd3dce3c56481 (diff)
downloadtor-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.c58
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
* ===== */