From 523493c3dd28cef4273a9a075a7f4863c568eb68 Mon Sep 17 00:00:00 2001 From: Marco De Marco <demarco@oats.inaf.it> Date: Thu, 19 Dec 2013 11:06:10 +0100 Subject: [PATCH] File transfer draft implemented --- src/PlainSession.cpp | 55 +++++++++++++++++++++++++++++++++++++++++ src/ProtocolManager.cpp | 38 ++++++++++++++++++++++++++++ src/ProtocolManager.h | 15 +++++++++++ src/SSLSession.cpp | 55 +++++++++++++++++++++++++++++++++++++++++ src/Session.cpp | 48 +++++++++++++++++++++++++++++++++-- src/Session.h | 6 +++++ 6 files changed, 215 insertions(+), 2 deletions(-) diff --git a/src/PlainSession.cpp b/src/PlainSession.cpp index 79994d4..b2062a5 100644 --- a/src/PlainSession.cpp +++ b/src/PlainSession.cpp @@ -164,6 +164,61 @@ void PlainSession::startWriteResponse() void PlainSession::startWriteData() { DEBUG_STREAM << "PlainSession::startWriteData()" << endl; + + try + { + if(!m_inputStream.bad()) + { + if(m_inputStream.tellg()<m_inputStreamSize) + { + int leftToRead = m_inputStreamSize - m_inputStream.tellg(); + + DEBUG_STREAM << "PlainSession::startWriteData() left to read " << leftToRead << endl; + + int bufferSize = 0; + + if(leftToRead < BUFFER_SIZE) + bufferSize = leftToRead; + else + bufferSize = BUFFER_SIZE; + + DEBUG_STREAM << "PlainSession::startWriteData() buffer size " << bufferSize << endl; + + std::vector<char> writeBuff; + writeBuff.resize(bufferSize); + + m_inputStream.read(&writeBuff[0], bufferSize); + + boost::asio::async_write(m_plainSocket, boost::asio::buffer(writeBuff), + m_strand.wrap(boost::bind(&PlainSession::handleWriteData, + shared_from_this(), boost::asio::placeholders::error))); + } + else + { + INFO_STREAM << "SSLSession::startWriteData() " + << " transfer completed " << endl; + + m_inputStream.close(); + + startReadRequestHeader(); + } + } + else + { + ERROR_STREAM << "SSLSession::startWriteData() error on file I/O " + << "from " << m_remoteEndpoint << endl; + } + } + catch(std::exception& ec) + { + ERROR_STREAM << "PlainSession::startWriteData() " + << ec.what() << " from " << m_remoteEndpoint << endl; + } + catch(...) + { + ERROR_STREAM << "PlainSession::startWriteData() unknown error from " + << m_remoteEndpoint << endl; + } } } //namespace \ No newline at end of file diff --git a/src/ProtocolManager.cpp b/src/ProtocolManager.cpp index 07a4c67..41925ea 100644 --- a/src/ProtocolManager.cpp +++ b/src/ProtocolManager.cpp @@ -17,6 +17,8 @@ ProtocolManager::ProtocolManager(Tango::DeviceImpl* deviceImpl_p, DEBUG_STREAM << "ProtocolManager::ProtocolManager()" << endl; m_isAuthorised = false; + m_isValidated = false; + m_isTransferRequest = false; } //============================================================================== @@ -94,6 +96,36 @@ ResponseSP ProtocolManager::prepareResponse(RequestSP request_sp) return response_sp; } +//============================================================================== +// ProtocolManager::isTransferRequest() +//============================================================================== +bool ProtocolManager::isTransferRequest() +{ + DEBUG_STREAM << "ProtocolManager::isTransferRequest()" << endl; + + return m_isTransferRequest; +} + +//============================================================================== +// ProtocolManager::getFilePath() +//============================================================================== +std::string ProtocolManager::getFilePath() +{ + DEBUG_STREAM << "ProtocolManager::getFilePath()" << endl; + + return m_filePath; +} + +//============================================================================== +// ProtocolManager::getFileSize() +//============================================================================== +int ProtocolManager::getFileSize() +{ + DEBUG_STREAM << "ProtocolManager::getFileSize()" << endl; + + return m_fileSize; +} + //============================================================================== // ProtocolManager::prepareAuthroisation() //============================================================================== @@ -233,6 +265,8 @@ ResponseSP ProtocolManager::prepareTransfer(RequestSP request_sp) try { + m_isTransferRequest = false; + DBManager::FileTuple fileTuple = m_dBManager_sp->retrieveFileInfo(m_validatedSchema, m_validatedTable, fileVersion, fileName); @@ -276,6 +310,10 @@ ResponseSP ProtocolManager::prepareTransfer(RequestSP request_sp) transferRes->set_state(Response::Transfer::ACCEPTED); transferRes->set_status("File found"); + + m_isTransferRequest = true; + m_filePath = absPath.string(); + m_fileSize = boost::filesystem::file_size(absPath); } catch(std::exception& ex) { diff --git a/src/ProtocolManager.h b/src/ProtocolManager.h index 815c662..9b38336 100644 --- a/src/ProtocolManager.h +++ b/src/ProtocolManager.h @@ -59,6 +59,15 @@ public: virtual ResponseSP prepareResponse(RequestSP) throw(std::runtime_error); +//------------------------------------------------------------------------------ +// [Public] File transfer methods +//------------------------------------------------------------------------------ + virtual bool isTransferRequest(); + + virtual std::string getFilePath(); + + virtual int getFileSize(); + protected: //------------------------------------------------------------------------------ // [Protected] Request specific methods @@ -94,6 +103,12 @@ protected: //Address and port of remote endpoint std::string m_remoteEndpoint; + + bool m_isTransferRequest; + + std::string m_filePath; + + int m_fileSize; }; } //End of namespace diff --git a/src/SSLSession.cpp b/src/SSLSession.cpp index 8f2a896..9ebcd94 100644 --- a/src/SSLSession.cpp +++ b/src/SSLSession.cpp @@ -199,6 +199,61 @@ void SSLSession::startWriteResponse() void SSLSession::startWriteData() { DEBUG_STREAM << "SSLSession::startWriteData()" << endl; + + try + { + if(!m_inputStream.bad()) + { + if(m_inputStream.tellg()<m_inputStreamSize) + { + int leftToRead = m_inputStreamSize - m_inputStream.tellg(); + + DEBUG_STREAM << "SSLSession::startWriteData() left to read " << leftToRead << endl; + + int bufferSize = 0; + + if(leftToRead < BUFFER_SIZE) + bufferSize = leftToRead; + else + bufferSize = BUFFER_SIZE; + + DEBUG_STREAM << "SSLSession::startWriteData() buffer size " << bufferSize << endl; + + std::vector<char> writeBuff; + writeBuff.resize(bufferSize); + + m_inputStream.read(&writeBuff[0], bufferSize); + + boost::asio::async_write(m_sslSocket, boost::asio::buffer(writeBuff), + m_strand.wrap(boost::bind(&SSLSession::handleWriteData, + shared_from_this(), boost::asio::placeholders::error))); + } + else + { + INFO_STREAM << "SSLSession::startWriteData() " + << " transfer completed " << endl; + + m_inputStream.close(); + + startReadRequestHeader(); + } + } + else + { + ERROR_STREAM << "SSLSession::startWriteData() error on file I/O " + << "from " << m_remoteEndpoint << endl; + } + } + catch(std::exception& ec) + { + ERROR_STREAM << "SSLSession::startWriteData() " + << ec.what() << " from " << m_remoteEndpoint << endl; + } + catch(...) + { + ERROR_STREAM << "SSLSession::startWriteData() unknown error from " + << m_remoteEndpoint << endl; + } } } //namespace diff --git a/src/Session.cpp b/src/Session.cpp index 481de1e..15366ee 100644 --- a/src/Session.cpp +++ b/src/Session.cpp @@ -82,7 +82,36 @@ void Session::handleWriteResponse(const boost::system::error_code& errorCode) if(!errorCode) { - startReadRequestHeader(); + if(m_protocolManager_sp->isTransferRequest()) + { + std::string filePath = m_protocolManager_sp->getFilePath(); + int fileSize = m_protocolManager_sp->getFileSize(); + + INFO_STREAM << "Session::handleWriteResponse() transfer request " + << filePath << " size " << fileSize << " from " + << m_remoteEndpoint << endl; + + m_inputStreamSize = fileSize; + + if(m_inputStream.is_open()) + m_inputStream.close(); + + m_inputStream.open(filePath.c_str(), std::ios::binary); + + if(m_inputStream) + { + startWriteData(); + } + else + { + ERROR_STREAM << "Session::handleWriteResponse() Cannot open " + << filePath << endl; + } + } + else + { + startReadRequestHeader(); + } } else if(errorCode == boost::asio::error::eof) { @@ -99,9 +128,24 @@ void Session::handleWriteResponse(const boost::system::error_code& errorCode) //============================================================================== // Session::handleWriteData() //============================================================================== -void Session::handleWriteData(const boost::system::error_code&) +void Session::handleWriteData(const boost::system::error_code& errorCode) { DEBUG_STREAM << "Session::handleWriteData()" << endl; + + if(!errorCode) + { + startWriteData(); + } + else if(errorCode == boost::asio::error::eof) + { + DEBUG_STREAM << "Session::handleWriteResponse() end of file from " + << m_remoteEndpoint << endl; + } + else + { + ERROR_STREAM << "Session::handleWriteResponse() " + << errorCode.message() << " from " << m_remoteEndpoint << endl; + } } //============================================================================== diff --git a/src/Session.h b/src/Session.h index ed022a6..5f7b2cc 100644 --- a/src/Session.h +++ b/src/Session.h @@ -97,6 +97,12 @@ protected: //Address and port of remote endpoint std::string m_remoteEndpoint; + + const int BUFFER_SIZE = 1024; + + std::ifstream m_inputStream; + + int m_inputStreamSize; }; } //End of namespace -- GitLab