2008-09-10 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

Fixed the bug that bulkReceiveResponse() reads all received data 
as a
	response even if more than one response is in it.
	* src/FtpConnection.cc
	* src/FtpConnection.h
	* test/FtpConnectionTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2008-09-09 15:22:32 +00:00
parent b23c3facc9
commit 1b2a76706f
4 changed files with 74 additions and 15 deletions

View File

@ -1,3 +1,11 @@
2008-09-10 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Fixed the bug that bulkReceiveResponse() reads all received data as a
response even if more than one response is in it.
* src/FtpConnection.cc
* src/FtpConnection.h
* test/FtpConnectionTest.cc
2008-09-09 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com> 2008-09-09 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Merged from stable-0.15 Merged from stable-0.15

View File

@ -176,24 +176,38 @@ unsigned int FtpConnection::getStatus(const std::string& response) const
} }
} }
bool FtpConnection::isEndOfResponse(unsigned int status, const std::string& response) const // Returns the length of the reponse if the whole response has been received.
// The length includes \r\n.
// If the whole response has not been recieved, then returns std::string::npos.
std::string::size_type
FtpConnection::findEndOfResponse(unsigned int status,
const std::string& buf) const
{ {
if(response.size() <= 4) { if(buf.size() <= 4) {
return false; return std::string::npos;
} }
// if 4th character of buf is '-', then multi line response is expected. // if 4th character of buf is '-', then multi line response is expected.
if(response.at(3) == '-') { if(buf.at(3) == '-') {
// multi line response // multi line response
std::string::size_type p; std::string::size_type p;
p = response.find("\r\n"+Util::uitos(status)+" "); p = buf.find(A2STR::CRLF+Util::uitos(status)+" ");
if(p == std::string::npos) { if(p == std::string::npos) {
return false; return std::string::npos;
}
p = buf.find(A2STR::CRLF, p+6);
if(p == std::string::npos) {
return std::string::npos;
} else {
return p+2;
} }
}
if(Util::endsWith(response, A2STR::CRLF)) {
return true;
} else { } else {
return false; // single line response
std::string::size_type p = buf.find(A2STR::CRLF);
if(p == std::string::npos) {
return std::string::npos;
} else {
return p+2;
}
} }
} }
@ -218,11 +232,12 @@ bool FtpConnection::bulkReceiveResponse(std::pair<unsigned int, std::string>& re
} else { } else {
return false; return false;
} }
if(isEndOfResponse(status, strbuf)) { std::string::size_type length;
logger->info(MSG_RECEIVE_RESPONSE, cuid, strbuf.c_str()); if((length = findEndOfResponse(status, strbuf)) != std::string::npos) {
response.first = status; response.first = status;
response.second = strbuf; response.second = strbuf.substr(0, length);
strbuf.erase(); logger->info(MSG_RECEIVE_RESPONSE, cuid, response.second.c_str());
strbuf.erase(0, length);
return true; return true;
} else { } else {
// didn't receive response fully. // didn't receive response fully.

View File

@ -60,7 +60,8 @@ private:
std::string strbuf; std::string strbuf;
unsigned int getStatus(const std::string& response) const; unsigned int getStatus(const std::string& response) const;
bool isEndOfResponse(unsigned int status, const std::string& response) const; std::string::size_type findEndOfResponse(unsigned int status,
const std::string& buf) const;
bool bulkReceiveResponse(std::pair<unsigned int, std::string>& response); bool bulkReceiveResponse(std::pair<unsigned int, std::string>& response);
static const std::string A; static const std::string A;

View File

@ -12,6 +12,7 @@ namespace aria2 {
class FtpConnectionTest:public CppUnit::TestFixture { class FtpConnectionTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(FtpConnectionTest); CPPUNIT_TEST_SUITE(FtpConnectionTest);
CPPUNIT_TEST(testReceiveResponse);
CPPUNIT_TEST(testSendMdtm); CPPUNIT_TEST(testSendMdtm);
CPPUNIT_TEST(testReceiveMdtmResponse); CPPUNIT_TEST(testReceiveMdtmResponse);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
@ -48,11 +49,45 @@ public:
void testSendMdtm(); void testSendMdtm();
void testReceiveMdtmResponse(); void testReceiveMdtmResponse();
void testReceiveResponse();
}; };
CPPUNIT_TEST_SUITE_REGISTRATION(FtpConnectionTest); CPPUNIT_TEST_SUITE_REGISTRATION(FtpConnectionTest);
void FtpConnectionTest::testReceiveResponse()
{
_serverSocket->writeData("100");
CPPUNIT_ASSERT_EQUAL((unsigned int)0, _ftp->receiveResponse());
_serverSocket->writeData(" single line response");
CPPUNIT_ASSERT_EQUAL((unsigned int)0, _ftp->receiveResponse());
_serverSocket->writeData("\r\n");
CPPUNIT_ASSERT_EQUAL((unsigned int)100, _ftp->receiveResponse());
// 2 responses in the buffer
_serverSocket->writeData("101 single1\r\n"
"102 single2\r\n");
CPPUNIT_ASSERT_EQUAL((unsigned int)101, _ftp->receiveResponse());
CPPUNIT_ASSERT_EQUAL((unsigned int)102, _ftp->receiveResponse());
_serverSocket->writeData("103-multi line response\r\n");
CPPUNIT_ASSERT_EQUAL((unsigned int)0, _ftp->receiveResponse());
_serverSocket->writeData("103-line2\r\n");
CPPUNIT_ASSERT_EQUAL((unsigned int)0, _ftp->receiveResponse());
_serverSocket->writeData("103");
CPPUNIT_ASSERT_EQUAL((unsigned int)0, _ftp->receiveResponse());
_serverSocket->writeData(" ");
CPPUNIT_ASSERT_EQUAL((unsigned int)0, _ftp->receiveResponse());
_serverSocket->writeData("last\r\n");
CPPUNIT_ASSERT_EQUAL((unsigned int)103, _ftp->receiveResponse());
_serverSocket->writeData("104-multi\r\n"
"104 \r\n"
"105-multi\r\n"
"105 \r\n");
CPPUNIT_ASSERT_EQUAL((unsigned int)104, _ftp->receiveResponse());
CPPUNIT_ASSERT_EQUAL((unsigned int)105, _ftp->receiveResponse());
}
void FtpConnectionTest::testSendMdtm() void FtpConnectionTest::testSendMdtm()
{ {
_ftp->sendMdtm(); _ftp->sendMdtm();