From dc59e6a2bb1272206dfd4cf21557c0e4e70fe74d Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sat, 28 Jun 2008 08:54:54 +0000 Subject: [PATCH] 2008-06-28 Tatsuhiro Tsujikawa Disabled getting size from the response of RETR. If SIZE command failed, then disable resuming and segmented downloading. * src/FtpConnection.cc * src/FtpConnection.h * src/FtpNegotiationCommand.cc * src/FtpNegotiationCommand.h --- ChangeLog | 9 +++++ src/FtpConnection.cc | 30 ----------------- src/FtpConnection.h | 1 - src/FtpNegotiationCommand.cc | 64 ++++++++---------------------------- src/FtpNegotiationCommand.h | 2 -- 5 files changed, 23 insertions(+), 83 deletions(-) diff --git a/ChangeLog b/ChangeLog index c390d742..15c97696 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-06-28 Tatsuhiro Tsujikawa + + Disabled getting size from the response of RETR. + If SIZE command failed, then disable resuming and segmented downloading. + * src/FtpConnection.cc + * src/FtpConnection.h + * src/FtpNegotiationCommand.cc + * src/FtpNegotiationCommand.h + 2008-06-26 Tatsuhiro Tsujikawa Use digits to find first byte of file size, which makes the intention diff --git a/src/FtpConnection.cc b/src/FtpConnection.cc index f8598882..8a9062b3 100644 --- a/src/FtpConnection.cc +++ b/src/FtpConnection.cc @@ -283,34 +283,4 @@ unsigned int FtpConnection::receivePasvResponse(std::pair } } -unsigned int FtpConnection::receiveRetrResponse(uint64_t& size) -{ - static const char* DIGITS = "0123456789"; - std::pair response; - if(bulkReceiveResponse(response)) { - if(response.first == 150 || response.first == 125) { - // Attempting to get file size from the response. - // We assume the response is like: - // 150 Opening BINARY mode data connection for aria2.tar.bz2 (12345 bytes) - // If the attempt is failed, size is unchanged. - std::string& res = response.second; - std::string::size_type start; - if((start = res.find_first_of("(")) != std::string::npos && - (start = res.find_first_of(DIGITS, start)) != std::string::npos) { - - // now start points to the first digit of the size string. - std::string::size_type end = - res.find_first_not_of(DIGITS, start); - - if(end != std::string::npos) { - size = Util::parseULLInt(res.substr(start, end-start)); - } - } - } - return response.first; - } else { - return 0; - } -} - } // namespace aria2 diff --git a/src/FtpConnection.h b/src/FtpConnection.h index 875894d5..51fe4039 100644 --- a/src/FtpConnection.h +++ b/src/FtpConnection.h @@ -83,7 +83,6 @@ public: unsigned int receiveResponse(); unsigned int receiveSizeResponse(uint64_t& size); unsigned int receivePasvResponse(std::pair& dest); - unsigned int receiveRetrResponse(uint64_t& size); }; } // namespace aria2 diff --git a/src/FtpNegotiationCommand.cc b/src/FtpNegotiationCommand.cc index c819433c..52b2e155 100644 --- a/src/FtpNegotiationCommand.cc +++ b/src/FtpNegotiationCommand.cc @@ -81,12 +81,7 @@ bool FtpNegotiationCommand::executeInternal() { while(processSequence(_segments.front())); if(sequence == SEQ_RETRY) { return prepareForRetry(0); - } else if(sequence == SEQ_EXIT) { - return true; } else if(sequence == SEQ_NEGOTIATION_COMPLETED) { - - afterFileAllocation(); - FtpDownloadCommand* command = new FtpDownloadCommand(cuid, req, _requestGroup, ftp, e, dataSocket, socket); command->setMaxDownloadSpeedLimit(e->option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT)); @@ -106,13 +101,6 @@ bool FtpNegotiationCommand::executeInternal() { sequence = SEQ_SEND_PORT; } return false; - } else if(sequence == SEQ_FILE_PREPARATION_ON_RETR) { - if(e->option->getAsBool(PREF_FTP_PASV)) { - sequence = SEQ_NEGOTIATION_COMPLETED; - } else { - sequence = SEQ_WAIT_CONNECTION; - } - return false; } else { e->commands.push_back(this); return false; @@ -257,26 +245,8 @@ bool FtpNegotiationCommand::onFileSizeDetermined(uint64_t totalLength) } _requestGroup->loadAndOpenFile(infoFile); - if(sequence == SEQ_FILE_PREPARATION_ON_RETR) { - // See the transfer is starting from 0 byte. - SharedHandle segment = - _requestGroup->getSegmentMan()->getSegment(cuid, 0); - if(!segment.isNull() && segment->getPositionToWrite() == 0) { - prepareForNextAction(this); - } else { - // If not, drop connection and connect the server and send REST - // with appropriate starting position. - logger->debug("Request range is not valid. Re-sending RETR is necessary."); - sequence = SEQ_EXIT; - prepareForNextAction(0); - } - } else { - // At the time of this writing, when this clause is executed, - // sequence should be SEQ_FILE_PREPARATION. - // At this point, REST is not sent yet, so checking the starting byte - // is not necessary. - prepareForNextAction(this); - } + prepareForNextAction(this); + disableReadCheckSocket(); } return false; @@ -307,6 +277,17 @@ bool FtpNegotiationCommand::recvSize() { logger->info("CUID#%d - The remote FTP Server doesn't recognize SIZE command. Continue.", cuid); + // Even if one of the other servers waiting in the queue supports SIZE + // command, resuming and segmented downloading are disabled when the first + // contacted FTP server doesn't support it. + if(_requestGroup->getPieceStorage().isNull()) { + + sequence = SEQ_FILE_PREPARATION; + return onFileSizeDetermined(0); + + } + // TODO Skipping RequestGroup::validateTotalLength(0) here will allow + // wrong file to be downloaded if user-specified URL is wrong. } if(e->option->getAsBool(PREF_FTP_PASV)) { sequence = SEQ_SEND_PASV; @@ -406,28 +387,13 @@ bool FtpNegotiationCommand::sendRetr() { } bool FtpNegotiationCommand::recvRetr() { - uint64_t size = 0; - unsigned int status = ftp->receiveRetrResponse(size); + unsigned int status = ftp->receiveResponse(); if(status == 0) { return false; } if(status != 150 && status != 125) { throw DlAbortEx(StringFormat(EX_BAD_STATUS, status).str()); } - - if(_requestGroup->getPieceStorage().isNull()) { - - sequence = SEQ_FILE_PREPARATION_ON_RETR; - return onFileSizeDetermined(size); - - } else { - // size == 0 means file size could not be retrieved from the response of - // RETR raw command. - if(size > 0) { - _requestGroup->validateTotalLength(size); - } - } - if(e->option->getAsBool(PREF_FTP_PASV)) { sequence = SEQ_NEGOTIATION_COMPLETED; return false; @@ -494,8 +460,6 @@ bool FtpNegotiationCommand::processSequence(const SegmentHandle& segment) { return recvRetr(); case SEQ_WAIT_CONNECTION: return waitConnection(); - case SEQ_NEGOTIATION_COMPLETED: - return false; default: abort(); } diff --git a/src/FtpNegotiationCommand.h b/src/FtpNegotiationCommand.h index 084439c6..8666f16f 100644 --- a/src/FtpNegotiationCommand.h +++ b/src/FtpNegotiationCommand.h @@ -71,8 +71,6 @@ public: SEQ_HEAD_OK, SEQ_DOWNLOAD_ALREADY_COMPLETED, SEQ_FILE_PREPARATION, // File allocation after SIZE command - SEQ_FILE_PREPARATION_ON_RETR, // File allocation after RETR command - SEQ_EXIT, // Make executeInternal() return true. }; private: bool recvGreeting();