mirror of https://github.com/aria2/aria2
sftp: Seek to the correct position to resume, fix slow start of transfer
parent
89c1916fa5
commit
5723f4211a
|
@ -91,8 +91,10 @@ bool InitiateConnectionCommand::executeInternal() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
getDownloadEngine()->addCommand(createNextCommand(hostname, ipaddr, port,
|
auto c = createNextCommand(hostname, ipaddr, port, addrs, proxyRequest);
|
||||||
addrs, proxyRequest));
|
c->setStatus(Command::STATUS_ONESHOT_REALTIME);
|
||||||
|
getDownloadEngine()->setNoWait(true);
|
||||||
|
getDownloadEngine()->addCommand(std::move(c));
|
||||||
return true;
|
return true;
|
||||||
} catch(RecoverableException& ex) {
|
} catch(RecoverableException& ex) {
|
||||||
// Catch exception and retry another address.
|
// Catch exception and retry another address.
|
||||||
|
|
|
@ -227,6 +227,11 @@ int SSHSession::sftpStat(int64_t& totalLength, time_t& mtime)
|
||||||
return SSH_ERR_OK;
|
return SSH_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SSHSession::sftpSeek(int64_t pos)
|
||||||
|
{
|
||||||
|
libssh2_sftp_seek64(sftph_, pos);
|
||||||
|
}
|
||||||
|
|
||||||
std::string SSHSession::getLastErrorString()
|
std::string SSHSession::getLastErrorString()
|
||||||
{
|
{
|
||||||
if (!ssh2_) {
|
if (!ssh2_) {
|
||||||
|
|
|
@ -122,6 +122,9 @@ public:
|
||||||
// blocks, or SSH_ERR_ERROR.
|
// blocks, or SSH_ERR_ERROR.
|
||||||
int sftpStat(int64_t& totalLength, time_t& mtime);
|
int sftpStat(int64_t& totalLength, time_t& mtime);
|
||||||
|
|
||||||
|
// Moves file postion to |pos|.
|
||||||
|
void sftpSeek(int64_t pos);
|
||||||
|
|
||||||
// Returns last error string
|
// Returns last error string
|
||||||
std::string getLastErrorString();
|
std::string getLastErrorString();
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,14 @@ bool SftpDownloadCommand::prepareForNextSegment()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DownloadCommand::prepareForNextSegment();
|
auto rv = DownloadCommand::prepareForNextSegment();
|
||||||
|
if (rv) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// sftp may not get incoming data. Enable write check to make this
|
||||||
|
// command invoke.
|
||||||
|
setWriteCheckSocket(getSocket());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t SftpDownloadCommand::getRequestEndOffset() const
|
int64_t SftpDownloadCommand::getRequestEndOffset() const
|
||||||
|
|
|
@ -81,7 +81,6 @@ SftpNegotiationCommand::SftpNegotiationCommand
|
||||||
|
|
||||||
{
|
{
|
||||||
path_ = getPath();
|
path_ = getPath();
|
||||||
disableReadCheckSocket();
|
|
||||||
setWriteCheckSocket(getSocket());
|
setWriteCheckSocket(getSocket());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +107,7 @@ bool SftpNegotiationCommand::executeInternal() {
|
||||||
getCuid()));
|
getCuid()));
|
||||||
sequence_ = SEQ_SFTP_OPEN;
|
sequence_ = SEQ_SFTP_OPEN;
|
||||||
break;
|
break;
|
||||||
case SEQ_SFTP_OPEN: {
|
case SEQ_SFTP_OPEN:
|
||||||
if (!getSocket()->sshSFTPOpen(path_)) {
|
if (!getSocket()->sshSFTPOpen(path_)) {
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
@ -116,7 +115,6 @@ bool SftpNegotiationCommand::executeInternal() {
|
||||||
path_.c_str()));
|
path_.c_str()));
|
||||||
sequence_ = SEQ_SFTP_STAT;
|
sequence_ = SEQ_SFTP_STAT;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case SEQ_SFTP_STAT: {
|
case SEQ_SFTP_STAT: {
|
||||||
int64_t totalLength;
|
int64_t totalLength;
|
||||||
time_t mtime;
|
time_t mtime;
|
||||||
|
@ -134,12 +132,26 @@ bool SftpNegotiationCommand::executeInternal() {
|
||||||
} else {
|
} else {
|
||||||
getRequestGroup()->validateTotalLength(getFileEntry()->getLength(),
|
getRequestGroup()->validateTotalLength(getFileEntry()->getLength(),
|
||||||
totalLength);
|
totalLength);
|
||||||
sequence_ = SEQ_NEGOTIATION_COMPLETED;
|
sequence_ = SEQ_SFTP_SEEK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SEQ_FILE_PREPARATION:
|
case SEQ_SFTP_SEEK: {
|
||||||
sequence_ = SEQ_NEGOTIATION_COMPLETED;
|
sequence_ = SEQ_NEGOTIATION_COMPLETED;
|
||||||
|
if (getSegments().empty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& segment = getSegments().front();
|
||||||
|
|
||||||
|
A2_LOG_INFO(fmt("CUID#%" PRId64 " - SFTP seek to %" PRId64,
|
||||||
|
getCuid(), segment->getPositionToWrite()));
|
||||||
|
getSocket()->sshSFTPSeek(segment->getPositionToWrite());
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEQ_FILE_PREPARATION:
|
||||||
|
sequence_ = SEQ_SFTP_SEEK;
|
||||||
disableReadCheckSocket();
|
disableReadCheckSocket();
|
||||||
disableWriteCheckSocket();
|
disableWriteCheckSocket();
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -49,6 +49,7 @@ public:
|
||||||
SEQ_AUTH_PASSWORD,
|
SEQ_AUTH_PASSWORD,
|
||||||
SEQ_SFTP_OPEN,
|
SEQ_SFTP_OPEN,
|
||||||
SEQ_SFTP_STAT,
|
SEQ_SFTP_STAT,
|
||||||
|
SEQ_SFTP_SEEK,
|
||||||
SEQ_NEGOTIATION_COMPLETED,
|
SEQ_NEGOTIATION_COMPLETED,
|
||||||
SEQ_DOWNLOAD_ALREADY_COMPLETED,
|
SEQ_DOWNLOAD_ALREADY_COMPLETED,
|
||||||
SEQ_HEAD_OK,
|
SEQ_HEAD_OK,
|
||||||
|
|
|
@ -1090,6 +1090,13 @@ bool SocketCore::sshSFTPStat(int64_t& totalLength, time_t& mtime,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SocketCore::sshSFTPSeek(int64_t pos)
|
||||||
|
{
|
||||||
|
assert(sshSession_);
|
||||||
|
|
||||||
|
sshSession_->sftpSeek(pos);
|
||||||
|
}
|
||||||
|
|
||||||
bool SocketCore::sshGracefulShutdown()
|
bool SocketCore::sshGracefulShutdown()
|
||||||
{
|
{
|
||||||
assert(sshSession_);
|
assert(sshSession_);
|
||||||
|
|
|
@ -313,6 +313,8 @@ public:
|
||||||
// opened. |path| is used for logging.
|
// opened. |path| is used for logging.
|
||||||
bool sshSFTPStat(int64_t& totalLength, time_t& mtime,
|
bool sshSFTPStat(int64_t& totalLength, time_t& mtime,
|
||||||
const std::string& path);
|
const std::string& path);
|
||||||
|
// Seeks file position to |pos|.
|
||||||
|
void sshSFTPSeek(int64_t pos);
|
||||||
bool sshGracefulShutdown();
|
bool sshGracefulShutdown();
|
||||||
#endif // HAVE_LIBSSH2
|
#endif // HAVE_LIBSSH2
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue