FtpConnectionTest.cc 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. #include "FtpConnection.h"
  2. #include <iostream>
  3. #include <cstring>
  4. #include <cppunit/extensions/HelperMacros.h>
  5. #include "Exception.h"
  6. #include "Util.h"
  7. #include "SocketCore.h"
  8. #include "Request.h"
  9. #include "Option.h"
  10. #include "DlRetryEx.h"
  11. #include "DlAbortEx.h"
  12. #include "AuthConfigFactory.h"
  13. #include "AuthConfig.h"
  14. namespace aria2 {
  15. class FtpConnectionTest:public CppUnit::TestFixture {
  16. CPPUNIT_TEST_SUITE(FtpConnectionTest);
  17. CPPUNIT_TEST(testReceiveResponse);
  18. CPPUNIT_TEST(testReceiveResponse_overflow);
  19. CPPUNIT_TEST(testSendMdtm);
  20. CPPUNIT_TEST(testReceiveMdtmResponse);
  21. CPPUNIT_TEST(testSendPwd);
  22. CPPUNIT_TEST(testReceivePwdResponse);
  23. CPPUNIT_TEST(testReceivePwdResponse_unquotedResponse);
  24. CPPUNIT_TEST(testReceivePwdResponse_badStatus);
  25. CPPUNIT_TEST(testSendCwd);
  26. CPPUNIT_TEST(testSendCwd_baseWorkingDir);
  27. CPPUNIT_TEST_SUITE_END();
  28. private:
  29. SharedHandle<SocketCore> _serverSocket;
  30. uint16_t _listenPort;
  31. SharedHandle<FtpConnection> _ftp;
  32. SharedHandle<Option> _option;
  33. SharedHandle<AuthConfigFactory> _authConfigFactory;
  34. public:
  35. void setUp()
  36. {
  37. _option.reset(new Option());
  38. _authConfigFactory.reset(new AuthConfigFactory(_option.get()));
  39. //_ftpServerSocket.reset(new SocketCore());
  40. SharedHandle<SocketCore> listenSocket(new SocketCore());
  41. listenSocket->bind(0);
  42. listenSocket->beginListen();
  43. std::pair<std::string, uint16_t> addrinfo;
  44. listenSocket->getAddrInfo(addrinfo);
  45. _listenPort = addrinfo.second;
  46. SharedHandle<Request> req(new Request());
  47. req->setUrl("ftp://localhost/dir/file.img");
  48. SharedHandle<SocketCore> clientSocket(new SocketCore());
  49. clientSocket->establishConnection("127.0.0.1", _listenPort);
  50. while(!clientSocket->isWritable(0));
  51. clientSocket->setBlockingMode();
  52. _serverSocket.reset(listenSocket->acceptConnection());
  53. _ftp.reset(new FtpConnection(1, clientSocket, req,
  54. _authConfigFactory->createAuthConfig(req),
  55. _option.get()));
  56. }
  57. void tearDown() {}
  58. void testSendMdtm();
  59. void testReceiveMdtmResponse();
  60. void testReceiveResponse();
  61. void testReceiveResponse_overflow();
  62. void testSendPwd();
  63. void testReceivePwdResponse();
  64. void testReceivePwdResponse_unquotedResponse();
  65. void testReceivePwdResponse_badStatus();
  66. void testSendCwd();
  67. void testSendCwd_baseWorkingDir();
  68. };
  69. CPPUNIT_TEST_SUITE_REGISTRATION(FtpConnectionTest);
  70. void FtpConnectionTest::testReceiveResponse()
  71. {
  72. _serverSocket->writeData("100");
  73. CPPUNIT_ASSERT_EQUAL((unsigned int)0, _ftp->receiveResponse());
  74. _serverSocket->writeData(" single line response");
  75. CPPUNIT_ASSERT_EQUAL((unsigned int)0, _ftp->receiveResponse());
  76. _serverSocket->writeData("\r\n");
  77. CPPUNIT_ASSERT_EQUAL((unsigned int)100, _ftp->receiveResponse());
  78. // 2 responses in the buffer
  79. _serverSocket->writeData("101 single1\r\n"
  80. "102 single2\r\n");
  81. CPPUNIT_ASSERT_EQUAL((unsigned int)101, _ftp->receiveResponse());
  82. CPPUNIT_ASSERT_EQUAL((unsigned int)102, _ftp->receiveResponse());
  83. _serverSocket->writeData("103-multi line response\r\n");
  84. CPPUNIT_ASSERT_EQUAL((unsigned int)0, _ftp->receiveResponse());
  85. _serverSocket->writeData("103-line2\r\n");
  86. CPPUNIT_ASSERT_EQUAL((unsigned int)0, _ftp->receiveResponse());
  87. _serverSocket->writeData("103");
  88. CPPUNIT_ASSERT_EQUAL((unsigned int)0, _ftp->receiveResponse());
  89. _serverSocket->writeData(" ");
  90. CPPUNIT_ASSERT_EQUAL((unsigned int)0, _ftp->receiveResponse());
  91. _serverSocket->writeData("last\r\n");
  92. CPPUNIT_ASSERT_EQUAL((unsigned int)103, _ftp->receiveResponse());
  93. _serverSocket->writeData("104-multi\r\n"
  94. "104 \r\n"
  95. "105-multi\r\n"
  96. "105 \r\n");
  97. CPPUNIT_ASSERT_EQUAL((unsigned int)104, _ftp->receiveResponse());
  98. CPPUNIT_ASSERT_EQUAL((unsigned int)105, _ftp->receiveResponse());
  99. }
  100. void FtpConnectionTest::testSendMdtm()
  101. {
  102. _ftp->sendMdtm();
  103. char data[32];
  104. size_t len = sizeof(data);
  105. _serverSocket->readData(data, len);
  106. CPPUNIT_ASSERT_EQUAL((size_t)15, len);
  107. data[len] = '\0';
  108. CPPUNIT_ASSERT_EQUAL(std::string("MDTM file.img\r\n"), std::string(data));
  109. }
  110. void FtpConnectionTest::testReceiveMdtmResponse()
  111. {
  112. {
  113. Time t;
  114. _serverSocket->writeData("213 20080908124312");
  115. CPPUNIT_ASSERT_EQUAL((unsigned int)0, _ftp->receiveMdtmResponse(t));
  116. _serverSocket->writeData("\r\n");
  117. CPPUNIT_ASSERT_EQUAL((unsigned int)213, _ftp->receiveMdtmResponse(t));
  118. CPPUNIT_ASSERT_EQUAL((time_t)1220877792, t.getTime());
  119. }
  120. {
  121. // see milli second part is ignored
  122. Time t;
  123. _serverSocket->writeData("213 20080908124312.014\r\n");
  124. CPPUNIT_ASSERT_EQUAL((unsigned int)213, _ftp->receiveMdtmResponse(t));
  125. CPPUNIT_ASSERT_EQUAL((time_t)1220877792, t.getTime());
  126. }
  127. {
  128. // hhmmss part is missing
  129. Time t;
  130. _serverSocket->writeData("213 20080908\r\n");
  131. CPPUNIT_ASSERT_EQUAL((unsigned int)213, _ftp->receiveMdtmResponse(t));
  132. CPPUNIT_ASSERT(t.bad());
  133. }
  134. {
  135. // invalid month: 19
  136. Time t;
  137. _serverSocket->writeData("213 20081908124312\r\n");
  138. CPPUNIT_ASSERT_EQUAL((unsigned int)213, _ftp->receiveMdtmResponse(t));
  139. CPPUNIT_ASSERT(t.bad());
  140. }
  141. {
  142. Time t;
  143. _serverSocket->writeData("550 File Not Found\r\n");
  144. CPPUNIT_ASSERT_EQUAL((unsigned int)550, _ftp->receiveMdtmResponse(t));
  145. }
  146. }
  147. void FtpConnectionTest::testReceiveResponse_overflow()
  148. {
  149. char data[1024];
  150. memset(data, 0, sizeof(data));
  151. memcpy(data, "213 ", 4);
  152. for(int i = 0; i < 4; ++i) {
  153. _serverSocket->writeData(data, sizeof(data));
  154. CPPUNIT_ASSERT_EQUAL((unsigned int)0, _ftp->receiveResponse());
  155. }
  156. _serverSocket->writeData(data, sizeof(data));
  157. try {
  158. _ftp->receiveResponse();
  159. CPPUNIT_FAIL("exception must be thrown.");
  160. } catch(DlRetryEx& e) {
  161. // success
  162. }
  163. }
  164. void FtpConnectionTest::testSendPwd()
  165. {
  166. _ftp->sendPwd();
  167. char data[32];
  168. size_t len = sizeof(data);
  169. _serverSocket->readData(data, len);
  170. CPPUNIT_ASSERT_EQUAL((size_t)5, len);
  171. data[len] = '\0';
  172. CPPUNIT_ASSERT_EQUAL(std::string("PWD\r\n"), std::string(data));
  173. }
  174. void FtpConnectionTest::testReceivePwdResponse()
  175. {
  176. std::string pwd;
  177. _serverSocket->writeData("257 ");
  178. CPPUNIT_ASSERT_EQUAL((unsigned int)0, _ftp->receivePwdResponse(pwd));
  179. CPPUNIT_ASSERT(pwd.empty());
  180. _serverSocket->writeData("\"/dir/to\" is your directory.\r\n");
  181. CPPUNIT_ASSERT_EQUAL((unsigned int)257, _ftp->receivePwdResponse(pwd));
  182. CPPUNIT_ASSERT_EQUAL(std::string("/dir/to"), pwd);
  183. }
  184. void FtpConnectionTest::testReceivePwdResponse_unquotedResponse()
  185. {
  186. std::string pwd;
  187. _serverSocket->writeData("257 /dir/to\r\n");
  188. try {
  189. _ftp->receivePwdResponse(pwd);
  190. CPPUNIT_FAIL("exception must be thrown.");
  191. } catch(DlAbortEx& e) {
  192. // success
  193. }
  194. }
  195. void FtpConnectionTest::testReceivePwdResponse_badStatus()
  196. {
  197. std::string pwd;
  198. _serverSocket->writeData("500 failed\r\n");
  199. CPPUNIT_ASSERT_EQUAL((unsigned int)500, _ftp->receivePwdResponse(pwd));
  200. CPPUNIT_ASSERT(pwd.empty());
  201. }
  202. void FtpConnectionTest::testSendCwd()
  203. {
  204. _ftp->sendCwd();
  205. char data[32];
  206. size_t len = sizeof(data);
  207. _serverSocket->readData(data, len);
  208. CPPUNIT_ASSERT_EQUAL((size_t)10, len);
  209. data[len] = '\0';
  210. CPPUNIT_ASSERT_EQUAL(std::string("CWD /dir\r\n"), std::string(data));
  211. }
  212. void FtpConnectionTest::testSendCwd_baseWorkingDir()
  213. {
  214. _ftp->setBaseWorkingDir("/base");
  215. _ftp->sendCwd();
  216. char data[32];
  217. size_t len = sizeof(data);
  218. _serverSocket->readData(data, len);
  219. CPPUNIT_ASSERT_EQUAL((size_t)15, len);
  220. data[len] = '\0';
  221. CPPUNIT_ASSERT_EQUAL(std::string("CWD /base/dir\r\n"), std::string(data));
  222. }
  223. } // namespace aria2