Browse Source

2010-07-09 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	Fixed the bug that aria2 cannot handle %2F in FTP URI properly.
	If directory component starts with %2F which percent-encode of
	'/', client should issue CWD to absolute path, but aria2 does not
	do that. It just issues relative path and download fails.
	* src/FtpConnection.cc
	* test/FtpConnectionTest.cc
Tatsuhiro Tsujikawa 15 years ago
parent
commit
52a6ea008e
3 changed files with 35 additions and 7 deletions
  1. 9 0
      ChangeLog
  2. 7 3
      src/FtpConnection.cc
  3. 19 4
      test/FtpConnectionTest.cc

+ 9 - 0
ChangeLog

@@ -1,3 +1,12 @@
+2010-07-09  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Fixed the bug that aria2 cannot handle %2F in FTP URI properly.
+	If directory component starts with %2F which percent-encode of
+	'/', client should issue CWD to absolute path, but aria2 does not
+	do that. It just issues relative path and download fails.
+	* src/FtpConnection.cc
+	* test/FtpConnectionTest.cc
+
 2010-07-09  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 
 	Increased DOMAIN_EVICTION_TRIGGER to 2000

+ 7 - 3
src/FtpConnection.cc

@@ -150,10 +150,14 @@ bool FtpConnection::sendCwd()
                     util::itos(cuid_).c_str(), baseWorkingDir_.c_str());
     }
     std::string request = "CWD ";
-    if(baseWorkingDir_ != "/") {
-      request += baseWorkingDir_;
+    if(util::startsWith(util::toUpper(req_->getDir()), "/%2F")) {
+      request += util::percentDecode(req_->getDir().substr(1));
+    } else {
+      if(baseWorkingDir_ != "/") {
+        request += baseWorkingDir_;
+      }
+      request += util::percentDecode(req_->getDir());
     }
-    request += util::percentDecode(req_->getDir());
     request += "\r\n";
     if(logger_->info()) {
       logger_->info(MSG_SENDING_REQUEST,

+ 19 - 4
test/FtpConnectionTest.cc

@@ -30,6 +30,7 @@ class FtpConnectionTest:public CppUnit::TestFixture {
   CPPUNIT_TEST(testReceivePwdResponse_badStatus);
   CPPUNIT_TEST(testSendCwd);
   CPPUNIT_TEST(testSendCwd_baseWorkingDir);
+  CPPUNIT_TEST(testSendCwd_absDir);
   CPPUNIT_TEST(testSendSize);
   CPPUNIT_TEST(testReceiveSizeResponse);
   CPPUNIT_TEST(testSendRetr);
@@ -41,6 +42,7 @@ private:
   SharedHandle<FtpConnection> ftp_;
   SharedHandle<Option> option_;
   SharedHandle<AuthConfigFactory> authConfigFactory_;
+  SharedHandle<Request> req_;
 public:
   void setUp()
   {
@@ -55,8 +57,8 @@ public:
     listenSocket->getAddrInfo(addrinfo);
     listenPort_ = addrinfo.second;
 
-    SharedHandle<Request> req(new Request());
-    req->setUri("ftp://localhost/dir%20sp/hello%20world.img");
+    req_.reset(new Request());
+    req_->setUri("ftp://localhost/dir%20sp/hello%20world.img");
 
     clientSocket_.reset(new SocketCore());
     clientSocket_->establishConnection("localhost", listenPort_);
@@ -65,9 +67,9 @@ public:
     clientSocket_->setBlockingMode();
 
     serverSocket_.reset(listenSocket->acceptConnection());
-    ftp_.reset(new FtpConnection(1, clientSocket_, req,
+    ftp_.reset(new FtpConnection(1, clientSocket_, req_,
                                  authConfigFactory_->createAuthConfig
-                                 (req, option_.get()),
+                                 (req_, option_.get()),
                                  option_.get()));
   }
 
@@ -83,6 +85,7 @@ public:
   void testReceivePwdResponse_badStatus();
   void testSendCwd();
   void testSendCwd_baseWorkingDir();
+  void testSendCwd_absDir();
   void testSendSize();
   void testReceiveSizeResponse();
   void testSendRetr();
@@ -282,6 +285,18 @@ void FtpConnectionTest::testSendCwd_baseWorkingDir()
   CPPUNIT_ASSERT_EQUAL(std::string("CWD /base/dir sp\r\n"), std::string(data));
 }
 
+void FtpConnectionTest::testSendCwd_absDir()
+{
+  req_->setUri("http://localhost/%2fdir/file");
+  ftp_->setBaseWorkingDir("/base");
+  ftp_->sendCwd();
+  char data[32];
+  size_t len = sizeof(data);
+  serverSocket_->readData(data, len);
+  data[len] = '\0';
+  CPPUNIT_ASSERT_EQUAL(std::string("CWD /dir\r\n"), std::string(data));
+}
+
 void FtpConnectionTest::testSendSize()
 {
   ftp_->sendSize();