diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2010-07-09 11:48:59 +0000 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2010-07-09 11:48:59 +0000 |
| commit | f285f66ac8a95f175aaedf16783bb62f9821a8fc (patch) | |
| tree | 89e4a07ba7107bcc453c4e0bdbd1de1b50b6b102 /src | |
| parent | be423e2c77bba5a88013e285925034a08d31bfc7 (diff) | |
2010-07-09 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Send each CWD component of FTP URI in separate CWD command as
described in RFC1738.
* src/FtpConnection.cc
* src/FtpConnection.h
* src/FtpInitiateConnectionCommand.cc
* src/FtpNegotiationCommand.cc
* src/FtpNegotiationCommand.h
* test/FtpConnectionTest.cc
Diffstat (limited to 'src')
| -rw-r--r-- | src/FtpConnection.cc | 15 | ||||
| -rw-r--r-- | src/FtpConnection.h | 2 | ||||
| -rw-r--r-- | src/FtpInitiateConnectionCommand.cc | 4 | ||||
| -rw-r--r-- | src/FtpNegotiationCommand.cc | 32 | ||||
| -rw-r--r-- | src/FtpNegotiationCommand.h | 4 |
5 files changed, 34 insertions, 23 deletions
diff --git a/src/FtpConnection.cc b/src/FtpConnection.cc index 0aaa9a4a..8a54f935 100644 --- a/src/FtpConnection.cc +++ b/src/FtpConnection.cc @@ -142,22 +142,11 @@ bool FtpConnection::sendPwd() return socketBuffer_.sendBufferIsEmpty(); } -bool FtpConnection::sendCwd() +bool FtpConnection::sendCwd(const std::string& dir) { if(socketBuffer_.sendBufferIsEmpty()) { - if(logger_->info()) { - logger_->info("CUID#%s - Using base working directory '%s'", - util::itos(cuid_).c_str(), baseWorkingDir_.c_str()); - } std::string request = "CWD "; - if(util::startsWith(util::toUpper(req_->getDir()), "/%2F")) { - request += util::percentDecode(req_->getDir().substr(1)); - } else { - if(baseWorkingDir_ != "/") { - request += baseWorkingDir_; - } - request += util::percentDecode(req_->getDir()); - } + request += util::percentDecode(dir); request += "\r\n"; if(logger_->info()) { logger_->info(MSG_SENDING_REQUEST, diff --git a/src/FtpConnection.h b/src/FtpConnection.h index b973c597..891b6feb 100644 --- a/src/FtpConnection.h +++ b/src/FtpConnection.h @@ -92,7 +92,7 @@ public: bool sendPass(); bool sendType(); bool sendPwd(); - bool sendCwd(); + bool sendCwd(const std::string& dir); bool sendMdtm(); bool sendSize(); bool sendPasv(); diff --git a/src/FtpInitiateConnectionCommand.cc b/src/FtpInitiateConnectionCommand.cc index 8a1d5b44..9833a5f8 100644 --- a/src/FtpInitiateConnectionCommand.cc +++ b/src/FtpInitiateConnectionCommand.cc @@ -130,7 +130,7 @@ Command* FtpInitiateConnectionCommand::createNextCommand new FtpNegotiationCommand(getCuid(), getRequest(), getFileEntry(), getRequestGroup(), getDownloadEngine(), pooledSocket, - FtpNegotiationCommand::SEQ_SEND_CWD, + FtpNegotiationCommand::SEQ_SEND_CWD_PREP, options["baseWorkingDir"]); } else if(proxyMethod == V_GET) { // Use GET for FTP via HTTP proxy. @@ -175,7 +175,7 @@ Command* FtpInitiateConnectionCommand::createNextCommand new FtpNegotiationCommand(getCuid(), getRequest(), getFileEntry(), getRequestGroup(), getDownloadEngine(), pooledSocket, - FtpNegotiationCommand::SEQ_SEND_CWD, + FtpNegotiationCommand::SEQ_SEND_CWD_PREP, options["baseWorkingDir"]); } } diff --git a/src/FtpNegotiationCommand.cc b/src/FtpNegotiationCommand.cc index 1617ef36..558d4944 100644 --- a/src/FtpNegotiationCommand.cc +++ b/src/FtpNegotiationCommand.cc @@ -259,14 +259,24 @@ bool FtpNegotiationCommand::recvPwd() getLogger()->info("CUID#%s - base working directory is '%s'", util::itos(getCuid()).c_str(), pwd.c_str()); } - sequence_ = SEQ_SEND_CWD; + sequence_ = SEQ_SEND_CWD_PREP; return true; } -bool FtpNegotiationCommand::sendCwd() { +bool FtpNegotiationCommand::sendCwdPrep() +{ // Calling setReadCheckSocket() is needed when the socket is reused, setReadCheckSocket(getSocket()); - if(ftp_->sendCwd()) { + util::split(getRequest()->getDir(), std::back_inserter(cwdDirs_), + A2STR::SLASH_C); + cwdDirs_.push_front(ftp_->getBaseWorkingDir()); + sequence_ = SEQ_SEND_CWD; + return true; +} + +bool FtpNegotiationCommand::sendCwd() +{ + if(ftp_->sendCwd(cwdDirs_.front())) { disableWriteCheckSocket(); sequence_ = SEQ_RECV_CWD; } else { @@ -275,7 +285,8 @@ bool FtpNegotiationCommand::sendCwd() { return false; } -bool FtpNegotiationCommand::recvCwd() { +bool FtpNegotiationCommand::recvCwd() +{ unsigned int status = ftp_->receiveResponse(); if(status == 0) { return false; @@ -289,10 +300,15 @@ bool FtpNegotiationCommand::recvCwd() { else throw DL_ABORT_EX(StringFormat(EX_BAD_STATUS, status).str()); } - if(getOption()->getAsBool(PREF_REMOTE_TIME)) { - sequence_ = SEQ_SEND_MDTM; + cwdDirs_.pop_front(); + if(cwdDirs_.empty()) { + if(getOption()->getAsBool(PREF_REMOTE_TIME)) { + sequence_ = SEQ_SEND_MDTM; + } else { + sequence_ = SEQ_SEND_SIZE; + } } else { - sequence_ = SEQ_SEND_SIZE; + sequence_ = SEQ_SEND_CWD; } return true; } @@ -773,6 +789,8 @@ bool FtpNegotiationCommand::processSequence return sendPwd(); case SEQ_RECV_PWD: return recvPwd(); + case SEQ_SEND_CWD_PREP: + return sendCwdPrep(); case SEQ_SEND_CWD: return sendCwd(); case SEQ_RECV_CWD: diff --git a/src/FtpNegotiationCommand.h b/src/FtpNegotiationCommand.h index afbbd061..badd14a3 100644 --- a/src/FtpNegotiationCommand.h +++ b/src/FtpNegotiationCommand.h @@ -55,6 +55,7 @@ public: SEQ_RECV_TYPE, SEQ_SEND_PWD, SEQ_RECV_PWD, + SEQ_SEND_CWD_PREP, SEQ_SEND_CWD, SEQ_RECV_CWD, SEQ_SEND_MDTM, @@ -92,6 +93,7 @@ private: bool recvType(); bool sendPwd(); bool recvPwd(); + bool sendCwdPrep(); bool sendCwd(); bool recvCwd(); bool sendMdtm(); @@ -136,6 +138,8 @@ private: std::string connectedHostname_; std::string connectedAddr_; uint16_t connectedPort_; + + std::deque<std::string> cwdDirs_; protected: virtual bool executeInternal(); public: |
