diff --git a/ChangeLog b/ChangeLog index b959afae..20a1ffea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2006-06-18 Tatsuhiro Tsujikawa + + * src/TorrentMan.cc (setupInternal1): Fixed peerId generation bug. + + * src/SimpleLogger.h (writeHeader): New function. + * src/SimpleLogger.cc (writeHeader): New function. + (writeLog): Fixed the bug that causes segfaults if exception message + contains an unescaped "%" character. + + * src/TrackerWatcherCommand.cc (execute): Added a short sleep + when a tracker request fails. + + * src/Request.cc (parseUrl): Query string is now handled properly. + + * Release 0.5.1 + 2006-06-12 Tatsuhiro Tsujikawa To add Time class which represents a specific instant in time and diff --git a/TODO b/TODO index 1dd4db50..9d56f738 100644 --- a/TODO +++ b/TODO @@ -13,5 +13,4 @@ * Distinguish seeder from leecher * Add Mainline-compatible DHT support * Add Message stream encryption support -* Add announce-list support * Refacturing HttpConnection and FtpConnection diff --git a/src/Request.cc b/src/Request.cc index b97bd26a..2673c274 100644 --- a/src/Request.cc +++ b/src/Request.cc @@ -57,6 +57,8 @@ bool Request::redirectUrl(const string& url) { bool Request::parseUrl(const string& url) { currentUrl = url; + string tempUrl = url; + string query; host = ""; port = 0; dir = ""; @@ -64,21 +66,26 @@ bool Request::parseUrl(const string& url) { if(url.find_first_not_of(SAFE_CHARS) != string::npos) { return false; } - string::size_type hp = url.find("://"); + string::size_type startQueryIndex = tempUrl.find("?"); + if(startQueryIndex != string::npos) { + query = tempUrl.substr(startQueryIndex); + tempUrl.erase(startQueryIndex); + } + string::size_type hp = tempUrl.find("://"); if(hp == string::npos) return false; - protocol = url.substr(0, hp); + protocol = tempUrl.substr(0, hp); int defPort; if((defPort = defaultPorts[protocol]) == 0) { return false; } hp += 3; - if(url.size() <= hp) return false; - string::size_type hep = url.find("/", hp); + if(tempUrl.size() <= hp) return false; + string::size_type hep = tempUrl.find("/", hp); if(hep == string::npos) { - hep = url.size(); + hep = tempUrl.size(); } pair hostAndPort; - Util::split(hostAndPort, url.substr(hp, hep-hp), ':'); + Util::split(hostAndPort, tempUrl.substr(hp, hep-hp), ':'); host = hostAndPort.first; if(hostAndPort.second != "") { port = (int)strtol(hostAndPort.second.c_str(), NULL, 10); @@ -89,15 +96,16 @@ bool Request::parseUrl(const string& url) { // If port is not specified, then we set it to default port of its protocol.. port = defPort; } - string::size_type direp = url.find_last_of("/"); + string::size_type direp = tempUrl.find_last_of("/"); if(direp == string::npos || direp <= hep) { dir = "/"; direp = hep; } else { - dir = url.substr(hep, direp-hep); + dir = tempUrl.substr(hep, direp-hep); } - if(url.size() > direp+1) { - file = url.substr(direp+1); + if(tempUrl.size() > direp+1) { + file = tempUrl.substr(direp+1); } + file += query; return true; } diff --git a/src/SegmentMan.cc b/src/SegmentMan.cc index 96a5a682..72929270 100644 --- a/src/SegmentMan.cc +++ b/src/SegmentMan.cc @@ -34,8 +34,8 @@ SegmentMan::SegmentMan():totalSize(0), isSplittable(true), downloadStarted(false), - errors(0), dir("."), + errors(0), splitter(NULL), diskWriter(NULL) { logger = LogFactory::getInstance(); diff --git a/src/SimpleLogger.cc b/src/SimpleLogger.cc index f09e456e..3f49cb05 100644 --- a/src/SimpleLogger.cc +++ b/src/SimpleLogger.cc @@ -62,7 +62,11 @@ void SimpleLogger::closeFile() { fclose(file); } } - + +void SimpleLogger::writeHeader(string date, string level) const { + fprintf(file, "%s - %s - ", date.c_str(), level.c_str()); +} + void SimpleLogger::writeLog(int level, const char* msg, va_list ap, Exception* e) const { string levelStr; @@ -84,9 +88,11 @@ void SimpleLogger::writeLog(int level, const char* msg, va_list ap, Exception* e char datestr[26]; ctime_r(&now, datestr); datestr[strlen(datestr)-1] = '\0'; - vfprintf(file, string(string(datestr)+" - "+levelStr+" - "+Util::replace(msg, "\r", "")+"\n").c_str(), ap); + writeHeader(datestr, levelStr); + vfprintf(file, string(Util::replace(msg, "\r", "")+"\n").c_str(), ap); if(e != NULL) { - fprintf(file, string(string(datestr)+" - "+levelStr+" - exception: "+Util::replace(e->getMsg(), "\r", "")+"\n").c_str()); + writeHeader(datestr, levelStr); + fprintf(file, "exception: %s\n", Util::replace(e->getMsg(), "\r", "").c_str()); } fflush(file); } diff --git a/src/SimpleLogger.h b/src/SimpleLogger.h index 82c0cf4c..ceb2ba15 100644 --- a/src/SimpleLogger.h +++ b/src/SimpleLogger.h @@ -26,6 +26,7 @@ class SimpleLogger:public Logger { private: + void writeHeader(string date, string level) const; void writeLog(int level, const char* msg, va_list ap, Exception* e = NULL) const; FILE* file; public: diff --git a/src/TorrentMan.cc b/src/TorrentMan.cc index b520224b..22ac23d0 100644 --- a/src/TorrentMan.cc +++ b/src/TorrentMan.cc @@ -399,7 +399,8 @@ void TorrentMan::readFileEntry(FileEntries& fileEntries, Directory** pTopDir, co void TorrentMan::setupInternal1(const string& metaInfoFile) { peerId = "-aria2-"; - for(int i = 0; i < 20-(int)peerId.size(); i++) { + int randomSize = 20-peerId.size(); + for(int i = 0; i < randomSize; i++) { peerId += Util::itos((int)(((double)10)*random()/(RAND_MAX+1.0))); } diff --git a/src/TrackerWatcherCommand.cc b/src/TrackerWatcherCommand.cc index a4875114..4ad394e6 100644 --- a/src/TrackerWatcherCommand.cc +++ b/src/TrackerWatcherCommand.cc @@ -22,6 +22,8 @@ #include "TrackerWatcherCommand.h" #include "InitiateConnectionCommandFactory.h" #include "Util.h" +#include "SleepCommand.h" +#include "prefs.h" TrackerWatcherCommand::TrackerWatcherCommand(int cuid, TorrentDownloadEngine* e, @@ -35,6 +37,11 @@ bool TrackerWatcherCommand::execute() { // we assume the tracker request has failed. e->torrentMan->trackers = 0; e->segmentMan->init(); + // sleep a few seconds. + SleepCommand* sleepCommand = + new SleepCommand(cuid, e, this, e->option->getAsInt(PREF_RETRY_WAIT)); + e->commands.push_back(sleepCommand); + return false; } if(e->torrentMan->trackers == 0 && (e->torrentMan->connections < MAX_PEER_UPDATE || diff --git a/test/RequestTest.cc b/test/RequestTest.cc index ede11933..9e639d33 100644 --- a/test/RequestTest.cc +++ b/test/RequestTest.cc @@ -15,6 +15,10 @@ class RequestTest:public CppUnit::TestFixture { CPPUNIT_TEST(testSetUrl8); CPPUNIT_TEST(testSetUrl9); CPPUNIT_TEST(testSetUrl10); + CPPUNIT_TEST(testSetUrl11); + CPPUNIT_TEST(testSetUrl12); + CPPUNIT_TEST(testSetUrl13); + CPPUNIT_TEST(testSetUrl14); CPPUNIT_TEST(testRedirectUrl); CPPUNIT_TEST(testRedirectUrl2); CPPUNIT_TEST(testResetUrl); @@ -32,6 +36,10 @@ public: void testSetUrl8(); void testSetUrl9(); void testSetUrl10(); + void testSetUrl11(); + void testSetUrl12(); + void testSetUrl13(); + void testSetUrl14(); void testRedirectUrl(); void testRedirectUrl2(); void testResetUrl(); @@ -150,6 +158,51 @@ void RequestTest::testSetUrl10() { CPPUNIT_ASSERT(!v); } +void RequestTest::testSetUrl11() { + Request req; + bool v = req.setUrl("http://host?query/"); + + CPPUNIT_ASSERT(v); + CPPUNIT_ASSERT_EQUAL(string("http"), req.getProtocol()); + CPPUNIT_ASSERT_EQUAL(string("host"), req.getHost()); + CPPUNIT_ASSERT_EQUAL(string("/"), req.getDir()); + CPPUNIT_ASSERT_EQUAL(string("?query/"), req.getFile()); +} + +void RequestTest::testSetUrl12() { + Request req; + bool v = req.setUrl("http://host?query"); + + CPPUNIT_ASSERT(v); + CPPUNIT_ASSERT_EQUAL(string("http"), req.getProtocol()); + CPPUNIT_ASSERT_EQUAL(string("host"), req.getHost()); + CPPUNIT_ASSERT_EQUAL(string("/"), req.getDir()); + CPPUNIT_ASSERT_EQUAL(string("?query"), req.getFile()); +} + +void RequestTest::testSetUrl13() { + Request req; + bool v = req.setUrl("http://host/?query"); + + CPPUNIT_ASSERT(v); + CPPUNIT_ASSERT_EQUAL(string("http"), req.getProtocol()); + CPPUNIT_ASSERT_EQUAL(string("host"), req.getHost()); + CPPUNIT_ASSERT_EQUAL(string("/"), req.getDir()); + CPPUNIT_ASSERT_EQUAL(string("?query"), req.getFile()); +} + +void RequestTest::testSetUrl14() { + Request req; + bool v = req.setUrl("http://host:8080/abc?query"); + + CPPUNIT_ASSERT(v); + CPPUNIT_ASSERT_EQUAL(string("http"), req.getProtocol()); + CPPUNIT_ASSERT_EQUAL(string("host"), req.getHost()); + CPPUNIT_ASSERT_EQUAL(8080, req.getPort()); + CPPUNIT_ASSERT_EQUAL(string("/"), req.getDir()); + CPPUNIT_ASSERT_EQUAL(string("abc?query"), req.getFile()); +} + void RequestTest::testRedirectUrl() { Request req; bool v = req.setUrl("http://aria.rednoah.com:8080/aria2/index.html");