1/* 2 * Copyright 2010 Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Christophe Huriaux, c.huriaux@gmail.com 7 */ 8 9#include <HttpTime.h> 10 11#include <new> 12 13#include <cstdio> 14 15 16#define PRINT(x) printf x 17 18 19static const char* kRfc1123Format = "%a, %d %b %Y %H:%M:%S GMT"; 20static const char* kCookieFormat = "%a, %d-%b-%Y %H:%M:%S GMT"; 21static const char* kRfc1036Format = "%A, %d-%b-%y %H:%M:%S GMT"; 22static const char* kAscTimeFormat = "%a %d %b %H:%M:%S %Y"; 23static const uint16 kTimetToStringMaxLength = 128; 24 25using namespace BPrivate; 26 27 28BHttpTime::BHttpTime() 29 : 30 fDate(0), 31 fDateFormat(B_HTTP_TIME_FORMAT_PREFERRED) 32{ 33} 34 35 36BHttpTime::BHttpTime(time_t date) 37 : 38 fDate(date), 39 fDateFormat(B_HTTP_TIME_FORMAT_PREFERRED) 40{ 41} 42 43 44BHttpTime::BHttpTime(const BString& dateString) 45 : 46 fDateString(dateString), 47 fDate(0), 48 fDateFormat(B_HTTP_TIME_FORMAT_PREFERRED) 49{ 50} 51 52 53// #pragma mark Date modification 54 55 56void 57BHttpTime::SetString(const BString& string) 58{ 59 fDateString = string; 60} 61 62 63void 64BHttpTime::SetDate(time_t date) 65{ 66 fDate = date; 67} 68 69 70// #pragma mark Date conversion 71 72 73time_t 74BHttpTime::Parse() 75{ 76 struct tm expireTime; 77 78 if (fDateString.Length() < 4) 79 return 0; 80 81 if (fDateString[3] == ',') { 82 if (strptime(fDateString.String(), kRfc1123Format, &expireTime) 83 == NULL) { 84 strptime(fDateString.String(), kCookieFormat, &expireTime); 85 fDateFormat = B_HTTP_TIME_FORMAT_COOKIE; 86 } else 87 fDateFormat = B_HTTP_TIME_FORMAT_RFC1123; 88 } else if (fDateString[3] == ' ') { 89 strptime(fDateString.String(), kRfc1036Format, &expireTime); 90 fDateFormat = B_HTTP_TIME_FORMAT_RFC1036; 91 } else { 92 strptime(fDateString.String(), kAscTimeFormat, &expireTime); 93 fDateFormat = B_HTTP_TIME_FORMAT_ASCTIME; 94 } 95 96// return timegm(&expireTime); 97// TODO: The above was used initially. See http://en.wikipedia.org/wiki/Time.h 98// stippi: I don't know how Christophe had this code compiling initially, 99// since Haiku does not appear to implement timegm(). 100return mktime(&expireTime); 101} 102 103 104BString 105BHttpTime::ToString(int8 format) 106{ 107 BString expirationFinal; 108 struct tm* expirationTm = localtime(&fDate); 109 char expirationString[kTimetToStringMaxLength + 1]; 110 size_t strLength; 111 112 switch ((format == B_HTTP_TIME_FORMAT_PARSED)?fDateFormat:format) { 113 default: 114 case B_HTTP_TIME_FORMAT_RFC1123: 115 strLength = strftime(expirationString, kTimetToStringMaxLength, 116 kRfc1123Format, expirationTm); 117 break; 118 119 case B_HTTP_TIME_FORMAT_RFC1036: 120 strLength = strftime(expirationString, kTimetToStringMaxLength, 121 kRfc1036Format, expirationTm); 122 break; 123 124 case B_HTTP_TIME_FORMAT_ASCTIME: 125 strLength = strftime(expirationString, kTimetToStringMaxLength, 126 kAscTimeFormat, expirationTm); 127 break; 128 } 129 130 expirationFinal.SetTo(expirationString, strLength); 131 return expirationFinal; 132} 133