summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-08-04 01:11:15 +0000
committerNick Mathewson <nickm@torproject.org>2004-08-04 01:11:15 +0000
commit14d5478f2995e6d9e654acbeb4f36e9a57cc9194 (patch)
treecdb41d5d5ce1e687410bf887effd8a6b90bf8c55
parent8b55f73bbee6b282a451e87820cd8f38f13046ac (diff)
downloadtor-14d5478f2995e6d9e654acbeb4f36e9a57cc9194.tar.gz
tor-14d5478f2995e6d9e654acbeb4f36e9a57cc9194.zip
Add functions to format and parse RFC1123-style times, for HTTP protocol.
svn:r2129
-rw-r--r--src/common/util.c51
-rw-r--r--src/common/util.h3
-rw-r--r--src/or/test.c12
3 files changed, 66 insertions, 0 deletions
diff --git a/src/common/util.c b/src/common/util.c
index ed5b6a06f4..252f566dee 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -914,6 +914,57 @@ time_t tor_timegm (struct tm *tm) {
return ret;
}
+/* strftime is locale-specific, so we need to replace those parts */
+static const char *WEEKDAY_NAMES[] =
+ { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
+static const char *MONTH_NAMES[] =
+ { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+void tor_format_rfc1123_time(char *buf, time_t t) {
+ struct tm *tm = gmtime(&t);
+
+ strftime(buf, RFC1123_TIME_LEN+1, "XXX, %d XXX %Y %H:%M:%S GMT", tm);
+ tor_assert(tm->tm_wday >= 0 && tm->tm_wday <= 6);
+ memcpy(buf, WEEKDAY_NAMES[tm->tm_wday], 3);
+ tor_assert(tm->tm_wday >= 0 && tm->tm_mon <= 11);
+ memcpy(buf+8, MONTH_NAMES[tm->tm_mon], 3);
+}
+
+int tor_parse_rfc1123_time(const char *buf, time_t *t) {
+ struct tm tm;
+ char month[4];
+ char weekday[4];
+ int i, m;
+
+ if (strlen(buf) != RFC1123_TIME_LEN)
+ return -1;
+ memset(&tm, 0, sizeof(tm));
+ if (sscanf(buf, "%3s, %d %3s %d %d:%d:%d GMT", weekday,
+ &tm.tm_mday, month, &tm.tm_year, &tm.tm_hour,
+ &tm.tm_min, &tm.tm_sec) < 7) {
+ log_fn(LOG_WARN, "Got invalid RFC1123 time \"%s\"", buf);
+ return -1;
+ }
+
+ m = -1;
+ for (i = 0; i < 12; ++i) {
+ if (!strcmp(month, MONTH_NAMES[i])) {
+ m = i;
+ break;
+ }
+ }
+ if (m<0) {
+ log_fn(LOG_WARN, "Got invalid RFC1123 time \"%s\"", buf);
+ return -1;
+ }
+
+ tm.tm_mon = m;
+ tm.tm_year -= 1900;
+ *t = tor_timegm(&tm);
+ return 0;
+}
+
/*
* Low-level I/O.
*/
diff --git a/src/common/util.h b/src/common/util.h
index 2d4702312a..8ee05b2fc1 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -201,6 +201,9 @@ void tv_addms(struct timeval *a, long ms);
void tv_add(struct timeval *a, struct timeval *b);
int tv_cmp(struct timeval *a, struct timeval *b);
time_t tor_timegm(struct tm *tm);
+#define RFC1123_TIME_LEN 29
+void tor_format_rfc1123_time(char *buf, time_t t);
+int tor_parse_rfc1123_time(const char *buf, time_t *t);
int write_all(int fd, const char *buf, size_t count, int isSocket);
int read_all(int fd, char *buf, size_t count, int isSocket);
diff --git a/src/or/test.c b/src/or/test.c
index f76e66d2d8..dd39513702 100644
--- a/src/or/test.c
+++ b/src/or/test.c
@@ -439,6 +439,9 @@ test_util() {
struct timeval start, end;
struct tm a_time;
smartlist_t *sl;
+ char timestr[RFC1123_TIME_LEN+1];
+ time_t t_res;
+ int i;
start.tv_sec = 5;
start.tv_usec = 5000;
@@ -479,6 +482,15 @@ test_util() {
a_time.tm_mday = 10;
test_eq((time_t) 1076393695UL, tor_timegm(&a_time));
+ tor_format_rfc1123_time(timestr, 0);
+ test_streq("Thu, 01 Jan 1970 00:00:00 GMT", timestr);
+ tor_format_rfc1123_time(timestr, (time_t)1091580502UL);
+ test_streq("Wed, 04 Aug 2004 00:48:22 GMT", timestr);
+
+ t_res = 0;
+ i = tor_parse_rfc1123_time(timestr, &t_res);
+ test_eq(i,0);
+ test_eq(t_res, (time_t)1091580502UL);
/* Test smartlist */
sl = smartlist_create();