2008-11-05 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

Handle date before epoch.
	To create *bad* Time object, call Time::null().
	* src/CookieParser.cc
	* src/FtpConnection.cc
	* src/FtpConnection.h
	* src/FtpNegotiationCommand.cc
	* src/RequestGroup.cc
	* src/TimeA2.cc
	* src/TimeA2.h
	* test/CookieParserTest.cc
	* test/FtpConnectionTest.cc
	* test/TimeTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2008-11-05 10:30:43 +00:00
parent 7513095042
commit 4797b0e72d
11 changed files with 74 additions and 34 deletions

View File

@ -1,3 +1,18 @@
2008-11-05 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Handle date before epoch.
To create *bad* Time object, call Time::null().
* src/CookieParser.cc
* src/FtpConnection.cc
* src/FtpConnection.h
* src/FtpNegotiationCommand.cc
* src/RequestGroup.cc
* src/TimeA2.cc
* src/TimeA2.h
* test/CookieParserTest.cc
* test/FtpConnectionTest.cc
* test/TimeTest.cc
2008-11-04 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Added support for following envrionment variables: http_proxy,

View File

@ -33,14 +33,17 @@
*/
/* copyright --> */
#include "CookieParser.h"
#include "Util.h"
#include "A2STR.h"
#include "TimeA2.h"
#include <strings.h>
#include <utility>
#include <istream>
#include <map>
#include "Util.h"
#include "A2STR.h"
#include "TimeA2.h"
namespace aria2 {
const std::string CookieParser::C_SECURE("secure");
@ -76,20 +79,17 @@ Cookie CookieParser::parse(const std::string& cookieStr, const std::string& defa
Util::split(nv, *itr, '=');
values[nv.first] = nv.second;
}
time_t expiry = -1;
time_t expiry = 0;
if(values.find(C_EXPIRES) != values.end()) {
expiry = Time::parseHTTPDate(values[C_EXPIRES]).getTime();
}
if(expiry == -1) {
return Cookie(nameValue.first, nameValue.second,
values[C_PATH], values[C_DOMAIN],
values.find(C_SECURE) != values.end());
} else {
return Cookie(nameValue.first, nameValue.second,
expiry,
values[C_PATH], values[C_DOMAIN],
values.find(C_SECURE) != values.end());
Time expiryTime = Time::parseHTTPDate(values[C_EXPIRES]);
if(expiryTime.good()) {
expiry = expiryTime.getTime();
}
}
return Cookie(nameValue.first, nameValue.second,
expiry,
values[C_PATH], values[C_DOMAIN],
values.find(C_SECURE) != values.end());
}

View File

@ -369,7 +369,7 @@ unsigned int FtpConnection::receiveMdtmResponse(Time& time)
if(strlen(buf) == 14) {
time = Time::parse(buf, "%Y%m%d%H%M%S");
} else {
time.setTimeInSec(-1);
time = Time::null();
}
}
return response.first;

View File

@ -105,7 +105,7 @@ public:
// time-val and store it in time.
// If a code other than 213 is returned, time is not touched.
// Expect MDTM reply is YYYYMMDDhhmmss in GMT. If status is 213 but returned
// date cannot be parsed, then executes time.setTimeInSec(-1).
// date cannot be parsed, then assign Time::null() to given time.
// If reply is not received yet, returns 0.
unsigned int receiveMdtmResponse(Time& time);
unsigned int receivePasvResponse(std::pair<std::string, uint16_t>& dest);

View File

@ -283,7 +283,7 @@ bool FtpNegotiationCommand::sendMdtm()
bool FtpNegotiationCommand::recvMdtm()
{
Time lastModifiedTime(-1);
Time lastModifiedTime = Time::null();
unsigned int status = ftp->receiveMdtmResponse(lastModifiedTime);
if(status == 0) {
return false;

View File

@ -123,7 +123,7 @@ RequestGroup::RequestGroup(const Option* option,
_forceHaltRequested(false),
_singleHostMultiConnectionEnabled(true),
_uriSelector(new InOrderURISelector()),
_lastModifiedTime(-1),
_lastModifiedTime(Time::null()),
_fileNotFoundCount(0),
_option(option),
_logger(LogFactory::getInstance())

View File

@ -42,19 +42,24 @@
namespace aria2 {
Time::Time() {
Time::Time():_good(true)
{
reset();
}
Time::Time(const Time& time) {
Time::Time(const Time& time)
{
tv = time.tv;
_good = time._good;
}
Time::Time(time_t sec) {
Time::Time(time_t sec):_good(true)
{
setTimeInSec(sec);
}
Time::Time(const struct timeval& tv) {
Time::Time(const struct timeval& tv):_good(true)
{
this->tv = tv;
}
@ -64,6 +69,7 @@ Time& Time::operator=(const Time& time)
{
if(this != &time) {
tv = time.tv;
_good = time._good;
}
return *this;
}
@ -152,7 +158,12 @@ void Time::setTimeInSec(time_t sec) {
bool Time::good() const
{
return tv.tv_sec >= 0;
return _good;
}
bool Time::bad() const
{
return !_good;
}
Time Time::parse(const std::string& datetime, const std::string& format)
@ -161,7 +172,7 @@ Time Time::parse(const std::string& datetime, const std::string& format)
memset(&tm, 0, sizeof(tm));
char* r = strptime(datetime.c_str(), format.c_str(), &tm);
if(r != datetime.c_str()+datetime.size()) {
return Time(-1);
return Time::null();
}
time_t thetime = timegm(&tm);
if(thetime == -1) {
@ -190,9 +201,9 @@ Time Time::parseRFC850Ext(const std::string& datetime)
Time Time::parseHTTPDate(const std::string& datetime)
{
Time (*funcs[])(const std::string&) = {
&parseRFC850,
&parseRFC1123,
&parseRFC850Ext,
&parseRFC850,
};
for(Time (**funcsp)(const std::string&) = &funcs[0];
funcsp != &funcs[arrayLength(funcs)]; ++funcsp) {
@ -201,7 +212,14 @@ Time Time::parseHTTPDate(const std::string& datetime)
return t;
}
}
return Time(-1);
return Time::null();
}
Time Time::null()
{
Time t(0);
t._good = false;
return t;
}
} // namespace aria2

View File

@ -49,6 +49,8 @@ class Time {
private:
struct timeval tv;
bool _good;
struct timeval getCurrentTime() const;
public:
// The time value is initialized so that it represents the time at which
@ -95,6 +97,9 @@ public:
bool good() const;
// Returns !good()
bool bad() const;
// Currently timezone is assumed as GMT.
static Time parse(const std::string& datetime, const std::string& format);
@ -111,6 +116,8 @@ public:
// Try parseRFC1123, parseRFC850Ex, parseRFC850 in that order and returns
// the first "good" Time object returned by these functions.
static Time parseHTTPDate(const std::string& datetime);
static Time null();
};
} // namespace aria2

View File

@ -52,10 +52,11 @@ void CookieParserTest::testParse()
c = CookieParser().parse(str3);
CPPUNIT_ASSERT(!c.good());
std::string str4 = "UID=300; expires=Wed, 01-Jan-1890 00:00:00 GMT;";
std::string str4 = "UID=300; expires=Wed, 01-Jan-1890 00:00:00 GMT";
c = CookieParser().parse(str4, "localhost", "/");
CPPUNIT_ASSERT(c.good());
CPPUNIT_ASSERT(c.isSessionCookie());
CPPUNIT_ASSERT(!c.isSessionCookie());
CPPUNIT_ASSERT_EQUAL((time_t)-2524521600, c.getExpiry());
std::string str5 = "k=v; expires=Sun, 10-Jun-07 11:00:00 GMT";
c = CookieParser().parse(str5);

View File

@ -149,14 +149,14 @@ void FtpConnectionTest::testReceiveMdtmResponse()
Time t;
_serverSocket->writeData("213 20080908\r\n");
CPPUNIT_ASSERT_EQUAL((unsigned int)213, _ftp->receiveMdtmResponse(t));
CPPUNIT_ASSERT_EQUAL((time_t)-1, t.getTime());
CPPUNIT_ASSERT(t.bad());
}
{
// invalid month: 19
Time t;
_serverSocket->writeData("213 20081908124312\r\n");
CPPUNIT_ASSERT_EQUAL((unsigned int)213, _ftp->receiveMdtmResponse(t));
CPPUNIT_ASSERT_EQUAL((time_t)-1, t.getTime());
CPPUNIT_ASSERT(t.bad());
}
{
Time t;

View File

@ -64,9 +64,8 @@ void TimeTest::testParseHTTPDate()
CPPUNIT_ASSERT_EQUAL((time_t)1220714793,
Time::parseHTTPDate
("Sat, 06-Sep-08 15:26:33 GMT").getTime());
CPPUNIT_ASSERT_EQUAL((time_t)-1,
Time::parseHTTPDate
("Sat, 2008-09-06 15:26:33 GMT").getTime());
CPPUNIT_ASSERT(Time::parseHTTPDate
("Sat, 2008-09-06 15:26:33 GMT").bad());
}
void TimeTest::testOperatorLess()