mirror of https://github.com/aria2/aria2
2008-06-28 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
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.hpull/1/head
parent
c42c8b7f9c
commit
dc59e6a2bb
|
@ -1,3 +1,12 @@
|
||||||
|
2008-06-28 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
|
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 <tujikawa at rednoah dot com>
|
2008-06-26 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
Use digits to find first byte of file size, which makes the intention
|
Use digits to find first byte of file size, which makes the intention
|
||||||
|
|
|
@ -283,34 +283,4 @@ unsigned int FtpConnection::receivePasvResponse(std::pair<std::string, uint16_t>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int FtpConnection::receiveRetrResponse(uint64_t& size)
|
|
||||||
{
|
|
||||||
static const char* DIGITS = "0123456789";
|
|
||||||
std::pair<unsigned int, std::string> 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
|
} // namespace aria2
|
||||||
|
|
|
@ -83,7 +83,6 @@ public:
|
||||||
unsigned int receiveResponse();
|
unsigned int receiveResponse();
|
||||||
unsigned int receiveSizeResponse(uint64_t& size);
|
unsigned int receiveSizeResponse(uint64_t& size);
|
||||||
unsigned int receivePasvResponse(std::pair<std::string, uint16_t>& dest);
|
unsigned int receivePasvResponse(std::pair<std::string, uint16_t>& dest);
|
||||||
unsigned int receiveRetrResponse(uint64_t& size);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -81,12 +81,7 @@ bool FtpNegotiationCommand::executeInternal() {
|
||||||
while(processSequence(_segments.front()));
|
while(processSequence(_segments.front()));
|
||||||
if(sequence == SEQ_RETRY) {
|
if(sequence == SEQ_RETRY) {
|
||||||
return prepareForRetry(0);
|
return prepareForRetry(0);
|
||||||
} else if(sequence == SEQ_EXIT) {
|
|
||||||
return true;
|
|
||||||
} else if(sequence == SEQ_NEGOTIATION_COMPLETED) {
|
} else if(sequence == SEQ_NEGOTIATION_COMPLETED) {
|
||||||
|
|
||||||
afterFileAllocation();
|
|
||||||
|
|
||||||
FtpDownloadCommand* command =
|
FtpDownloadCommand* command =
|
||||||
new FtpDownloadCommand(cuid, req, _requestGroup, ftp, e, dataSocket, socket);
|
new FtpDownloadCommand(cuid, req, _requestGroup, ftp, e, dataSocket, socket);
|
||||||
command->setMaxDownloadSpeedLimit(e->option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT));
|
command->setMaxDownloadSpeedLimit(e->option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT));
|
||||||
|
@ -106,13 +101,6 @@ bool FtpNegotiationCommand::executeInternal() {
|
||||||
sequence = SEQ_SEND_PORT;
|
sequence = SEQ_SEND_PORT;
|
||||||
}
|
}
|
||||||
return false;
|
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 {
|
} else {
|
||||||
e->commands.push_back(this);
|
e->commands.push_back(this);
|
||||||
return false;
|
return false;
|
||||||
|
@ -257,26 +245,8 @@ bool FtpNegotiationCommand::onFileSizeDetermined(uint64_t totalLength)
|
||||||
}
|
}
|
||||||
_requestGroup->loadAndOpenFile(infoFile);
|
_requestGroup->loadAndOpenFile(infoFile);
|
||||||
|
|
||||||
if(sequence == SEQ_FILE_PREPARATION_ON_RETR) {
|
prepareForNextAction(this);
|
||||||
// See the transfer is starting from 0 byte.
|
|
||||||
SharedHandle<Segment> 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);
|
|
||||||
}
|
|
||||||
disableReadCheckSocket();
|
disableReadCheckSocket();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -307,6 +277,17 @@ bool FtpNegotiationCommand::recvSize() {
|
||||||
|
|
||||||
logger->info("CUID#%d - The remote FTP Server doesn't recognize SIZE command. Continue.", cuid);
|
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)) {
|
if(e->option->getAsBool(PREF_FTP_PASV)) {
|
||||||
sequence = SEQ_SEND_PASV;
|
sequence = SEQ_SEND_PASV;
|
||||||
|
@ -406,28 +387,13 @@ bool FtpNegotiationCommand::sendRetr() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FtpNegotiationCommand::recvRetr() {
|
bool FtpNegotiationCommand::recvRetr() {
|
||||||
uint64_t size = 0;
|
unsigned int status = ftp->receiveResponse();
|
||||||
unsigned int status = ftp->receiveRetrResponse(size);
|
|
||||||
if(status == 0) {
|
if(status == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(status != 150 && status != 125) {
|
if(status != 150 && status != 125) {
|
||||||
throw DlAbortEx(StringFormat(EX_BAD_STATUS, status).str());
|
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)) {
|
if(e->option->getAsBool(PREF_FTP_PASV)) {
|
||||||
sequence = SEQ_NEGOTIATION_COMPLETED;
|
sequence = SEQ_NEGOTIATION_COMPLETED;
|
||||||
return false;
|
return false;
|
||||||
|
@ -494,8 +460,6 @@ bool FtpNegotiationCommand::processSequence(const SegmentHandle& segment) {
|
||||||
return recvRetr();
|
return recvRetr();
|
||||||
case SEQ_WAIT_CONNECTION:
|
case SEQ_WAIT_CONNECTION:
|
||||||
return waitConnection();
|
return waitConnection();
|
||||||
case SEQ_NEGOTIATION_COMPLETED:
|
|
||||||
return false;
|
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,8 +71,6 @@ public:
|
||||||
SEQ_HEAD_OK,
|
SEQ_HEAD_OK,
|
||||||
SEQ_DOWNLOAD_ALREADY_COMPLETED,
|
SEQ_DOWNLOAD_ALREADY_COMPLETED,
|
||||||
SEQ_FILE_PREPARATION, // File allocation after SIZE command
|
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:
|
private:
|
||||||
bool recvGreeting();
|
bool recvGreeting();
|
||||||
|
|
Loading…
Reference in New Issue