ソースを参照

2006-06-18 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

	* 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.
Tatsuhiro Tsujikawa 19 年 前
コミット
70ff0c0b3b
9 ファイル変更107 行追加16 行削除
  1. 16 0
      ChangeLog
  2. 0 1
      TODO
  3. 18 10
      src/Request.cc
  4. 1 1
      src/SegmentMan.cc
  5. 9 3
      src/SimpleLogger.cc
  6. 1 0
      src/SimpleLogger.h
  7. 2 1
      src/TorrentMan.cc
  8. 7 0
      src/TrackerWatcherCommand.cc
  9. 53 0
      test/RequestTest.cc

+ 16 - 0
ChangeLog

@@ -1,3 +1,19 @@
+2006-06-18  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
+
+	* 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  <tujikawa at rednoah dot com>
 	
 	To add Time class which represents a specific instant in time and

+ 0 - 1
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

+ 18 - 10
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<string, string> 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;
 }

+ 1 - 1
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();

+ 9 - 3
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);
 }

+ 1 - 0
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:

+ 2 - 1
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)));
   }
 

+ 7 - 0
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 ||

+ 53 - 0
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");