summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-07-09 11:48:59 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-07-09 11:48:59 +0000
commitf285f66ac8a95f175aaedf16783bb62f9821a8fc (patch)
tree89e4a07ba7107bcc453c4e0bdbd1de1b50b6b102 /src
parentbe423e2c77bba5a88013e285925034a08d31bfc7 (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.cc15
-rw-r--r--src/FtpConnection.h2
-rw-r--r--src/FtpInitiateConnectionCommand.cc4
-rw-r--r--src/FtpNegotiationCommand.cc32
-rw-r--r--src/FtpNegotiationCommand.h4
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: