diff options
-rw-r--r-- | client/Config.cpp | 6 | ||||
-rw-r--r-- | client/DownloadClient.cpp | 35 | ||||
-rw-r--r-- | client/DownloadClient.h | 15 | ||||
-rw-r--r-- | client/FileOpThread.cpp | 22 | ||||
-rw-r--r-- | client/FileOpThread.h | 9 | ||||
-rw-r--r-- | client/ProxyClientApp.cpp | 17 | ||||
-rw-r--r-- | client/ProxyClientApp.h | 3 | ||||
-rw-r--r-- | client/SslClient.cpp | 17 | ||||
-rw-r--r-- | client/SslClient.h | 5 | ||||
-rw-r--r-- | client/UpdatedConfig.cpp | 6 | ||||
-rw-r--r-- | client/UpdatedConfig.h | 25 |
11 files changed, 92 insertions, 68 deletions
diff --git a/client/Config.cpp b/client/Config.cpp index 21b2c44..ef6a37b 100644 --- a/client/Config.cpp +++ b/client/Config.cpp @@ -430,7 +430,11 @@ void Config::ParseDownloadList(string data) while (! files.eof()) { files.getline(str, str_size, ';'); - //there is no \n or \r\n + // there is no \n or \r\n + // so string processing is quite different + if (files.eof()) + break; + string entry = str; FileEntry file; file.Parse(entry, FileEntry::DownloadAction); diff --git a/client/DownloadClient.cpp b/client/DownloadClient.cpp index b834622..3fe7b59 100644 --- a/client/DownloadClient.cpp +++ b/client/DownloadClient.cpp @@ -5,8 +5,6 @@ DownloadClient::DownloadClient(): isDownloading(false), current(NULL), currentId(-1) { - connect(this, SIGNAL(ReplyRecieved(SslClient::RequestType&, QByteArray&)), - this, SLOT(FileDataRecieved(SslClient::RequestType&, QByteArray&))); } DownloadClient::DownloadClient(QString addr): SslClient(addr), isDownloading(false), current(NULL), currentId(-1) @@ -41,28 +39,32 @@ void DownloadClient::Download(const vector<pair<string, string> > &fileList) Logger::Error("Previous downloading process wasn't finished! Aborting.\n"); return; } + + connect(this, SIGNAL(ReplyRecieved(SslClient::RequestType&, QByteArray&)), + this, SLOT(FileDataRecieved(SslClient::RequestType&, QByteArray&))); isDownloading = true; files = fileList; DoDownload(); } void DownloadClient::DoDownload() -{ +{ + currentId++; + if (currentId < (int)files.size()) { - currentId++; pair<string, string> file = files[currentId]; QString filename = QString::fromLocal8Bit(file.first.c_str()); string md5 = file.second; current = new QFile(filename); - current->open(QIODevice::ReadWrite); + current->open(QIODevice::WriteOnly | QIODevice::Unbuffered); - Logger::Info("Downloading file %s\n", file.first.c_str()); + Logger::Info("Downloading file (%d of %u): %s\n", currentId + 1, files.size(), file.first.c_str()); SendFileRequest(file.first); } else { - Logger::Info("All files have been downloaded."); + Logger::Info("All files have been downloaded.\n"); isDownloading = false; emit downloadFinished(); } @@ -70,33 +72,29 @@ void DownloadClient::DoDownload() void DownloadClient::FileDataRecieved(SslClient::RequestType &type, QByteArray &data) { + Logger::Trace("Recieved file data: %u bytes\n", data.size()); + if (type != RegularFile) { Logger::Error("Invalid reply recieved: %x\n", type); return; } - - if ((current != NULL) && (current->isOpen())) + if ((current == NULL) || (! current->isOpen())) { - Logger::Error("File is not open or invalid state\n"); + Logger::Error("File isn't open or in invalid state.\n"); return; } pair<string, string> file = files[currentId]; string filename = file.first; - if (data.size() == FRAGMENT_SIZE) + if (data.size() != 0) { - Logger::Debug("data:\n %s", data.constData()); current->write(data); - SendFileRequest(filename); + current->waitForBytesWritten(-1); } else { - if (data.size() != 0) - { - Logger::Debug("data:\n %s", data.constData()); - current->write(data); - } + Logger::Trace("Last (empty) packet recieved\n"); current->close(); delete current; current = NULL; @@ -105,6 +103,7 @@ void DownloadClient::FileDataRecieved(SslClient::RequestType &type, QByteArray & * @todo md5 hash check */ + // proceed to the next file DoDownload(); } } diff --git a/client/DownloadClient.h b/client/DownloadClient.h index 5b75c2c..0e6c510 100644 --- a/client/DownloadClient.h +++ b/client/DownloadClient.h @@ -14,7 +14,7 @@ using std::vector; class QFile; -class DownloadClient: public SslClient +class DownloadClient: public SslClient { Q_OBJECT @@ -50,23 +50,15 @@ public: * it's quite unsuitable to iterate through( */ void Download(const vector<pair<string, string> > &files); - + signals: /** * @brief This signal is emitted when all files have been downloaded */ void downloadFinished(); -private slots: - void FileDataRecieved(SslClient::RequestType &type, QByteArray &confdata); - private: /** - * @brief size of file data fragment - */ - static const int FRAGMENT_SIZE = 4096; - - /** * @brief indicates that program is downloading file(s) right now */ bool isDownloading; @@ -90,6 +82,9 @@ private: * @brief start file-by-file downloading process */ void DoDownload(); + +private slots: + void FileDataRecieved(SslClient::RequestType &type, QByteArray &confdata); }; #endif diff --git a/client/FileOpThread.cpp b/client/FileOpThread.cpp index 42cb51b..3340db2 100644 --- a/client/FileOpThread.cpp +++ b/client/FileOpThread.cpp @@ -4,6 +4,13 @@ #include "FileOpThread.h" #include "UpdatedConfig.h" + +FileOpThread::~FileOpThread() +{ + if (downloadClient != NULL) + delete downloadClient; +} + void FileOpThread::run() { UpdatedConfig *cfg = UpdatedConfig::CurrentConfig(); @@ -51,13 +58,20 @@ void FileOpThread::run() if (files.size() != 0) { Logger::Debug("Setting server address to %s\n", cfg->GetServerAddr().c_str()); - QString addr = QString::fromLocal8Bit(cfg->GetServerAddr().c_str()); - DownloadClient downloadClient(addr); - downloadClient.Download(files); + downloadClient = new DownloadClient(addr); + + // start downloading files and + // wait for files to be downloaded + QEventLoop loop; + connect(downloadClient, SIGNAL(downloadFinished()), &loop, SLOT(quit())); + downloadClient->Download(files); + loop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers); } else { Logger::Trace("No files to download from server.\n"); } -}
\ No newline at end of file + + Logger::Trace("Terminating Download Helper thread\n"); +} diff --git a/client/FileOpThread.h b/client/FileOpThread.h index 29731c9..83a8dd0 100644 --- a/client/FileOpThread.h +++ b/client/FileOpThread.h @@ -5,6 +5,8 @@ #include <QThread> +class DownloadClient; + /** * @brief Special thread to process all file operations */ @@ -14,12 +16,17 @@ public: /** * @brief Initialize new FIleOpThread instance */ - FileOpThread() {} + FileOpThread(): downloadClient(NULL) {} + + ~FileOpThread(); /** * @brief Thread main loop */ void run(); + +private: + DownloadClient *downloadClient; }; #endif
\ No newline at end of file diff --git a/client/ProxyClientApp.cpp b/client/ProxyClientApp.cpp index 6dcfed2..e2968b0 100644 --- a/client/ProxyClientApp.cpp +++ b/client/ProxyClientApp.cpp @@ -5,8 +5,6 @@ #include "client.h" #include "Dialog.h" -#include "DownloadClient.h" -#include "FileOpThread.h" #include "ProxyClientApp.h" #include "UpdatedConfig.h" @@ -15,7 +13,6 @@ using namespace std; ProxyClientApp::ProxyClientApp(int &argc, char *argv[]): QApplication(argc, argv) { /* initiates UpdatedConfig singleton that start sending configuration requests */ - /* UpdatedConfig *cfg = UpdatedConfig::CurrentConfig(); connect(cfg, SIGNAL(updated()), this, SLOT(configUpdated())); @@ -62,6 +59,10 @@ ProxyClientApp::ProxyClientApp(int &argc, char *argv[]): QApplication(argc, argv Logger::Info("CSS stylesheet file 'style.qss' wasn't found.\n"); } + /** + * @todo FIX: trying to access cfg while it is being updated + * (note that initial config is still read from config.cfg) + */ QString msg = QString::fromLocal8Bit(cfg->WelcomeMsg.c_str()); QMessageBox welcomeMsg; welcomeMsg.setText(msg); @@ -69,18 +70,17 @@ ProxyClientApp::ProxyClientApp(int &argc, char *argv[]): QApplication(argc, argv welcomeMsg.setStandardButtons(QMessageBox::Ok); welcomeMsg.setIcon(QMessageBox::Information); welcomeMsg.exec(); - */ + /* vector<pair<string, string> > files; pair<string, string> file; - file = make_pair("server.workspace.session", "70ba1d68907cc9d3"); - files.push_back(file); - file = make_pair("tz/TZ_v.1.2.pdf", "80e28032841aca45"); + file = make_pair("../main.cpp", "70ba1d68907cc9d3"); files.push_back(file); //QString addr = QString::fromLocal8Bit(); DownloadClient downloadClient("127.0.0.1"); downloadClient.Download(files); + */ } void ProxyClientApp::trayActivated(QSystemTrayIcon::ActivationReason reason) @@ -100,7 +100,8 @@ void ProxyClientApp::showProxyDialog() void ProxyClientApp::configUpdated() { - FileOpThread fileOpThread; + // start downloading files in seperate thread + // (all necessary check are done by the thread) fileOpThread.start(QThread::NormalPriority); UpdatedConfig *cfg = UpdatedConfig::CurrentConfig(); diff --git a/client/ProxyClientApp.h b/client/ProxyClientApp.h index 5dd0a69..b015344 100644 --- a/client/ProxyClientApp.h +++ b/client/ProxyClientApp.h @@ -5,6 +5,8 @@ #include <QSystemTrayIcon> #include <QApplication> +#include "FileOpThread.h" + //class ProxyClientApp: public QtSingleApplication //this will be paid later ))) class ProxyClientApp: public QApplication @@ -22,6 +24,7 @@ private slots: private: QSystemTrayIcon *trayIcon; + FileOpThread fileOpThread; }; diff --git a/client/SslClient.cpp b/client/SslClient.cpp index 885b228..2a599c8 100644 --- a/client/SslClient.cpp +++ b/client/SslClient.cpp @@ -4,7 +4,6 @@ #include <QtNetwork> #include "SslClient.h" -QSslSocket SslClient::sslSocket; SslClient::SslClient(): port(13666) { @@ -37,6 +36,7 @@ SslClient::SslClient(QString addr): port(13666) cert_file.close(); /* create ssl socket */ + sslSocket.setReadBufferSize(8096); sslSocket.setLocalCertificate(cert); sslSocket.setPrivateKey(key); sslSocket.setCaCertificates(ca_certs); @@ -75,10 +75,7 @@ void SslClient::SendRequest(RequestType type) { Logger::Trace("Connecting to server %s:%u\n", server.toLocal8Bit().data(), port); sslSocket.connectToHostEncrypted(server, port); - while (! sslSocket.waitForConnected(5000)) - { - Logger::Trace("Waiting for connection to be established...\n"); - } + sslSocket.waitForEncrypted(-1); } else { @@ -113,10 +110,7 @@ void SslClient::SendFileRequest(string filename) { Logger::Trace("Connecting to server %s:%u\n", server.toLocal8Bit().data(), port); sslSocket.connectToHostEncrypted(server, port); - while (! sslSocket.waitForConnected(5000)) - { - Logger::Trace("Waiting for connection to be established...\n"); - } + sslSocket.waitForEncrypted(-1); } else { @@ -132,7 +126,6 @@ void SslClient::SendFileRequest(string filename) data[2] = rcode; strncpy(data + 3, file, path_len); data[pkt_size - 1] = data[pkt_size - 2] = 0x14; - QByteArray pkt(data); sslSocket.write(pkt); } @@ -167,7 +160,6 @@ void SslClient::DataRecieved() char t1 = data[length-3]; char t2 = data[length-2]; char t3 = data[length-1]; - if ((h1 != 0x13) || (h2 != 0x13) || (t1 != 0x14) || (t2 != 0x14) || (t3 != 0x00)) { @@ -185,6 +177,7 @@ void SslClient::DataRecieved() case FirewallList: case DownloadList: case DeleteList: + case RegularFile: type = (RequestType)rcode; break; default: @@ -193,8 +186,8 @@ void SslClient::DataRecieved() } /* remove header and tail */ + data.remove(data.size()-3, 3); data.remove(0, 3); - data.remove(length-1, 3); emit ReplyRecieved(type, data); } diff --git a/client/SslClient.h b/client/SslClient.h index 3c4976c..41f0952 100644 --- a/client/SslClient.h +++ b/client/SslClient.h @@ -82,7 +82,8 @@ public: /** * @brief Request file upload (the list of this files is obtained via RequestType::UploadList) * @note Request should contain file path as specified in RequestType::UploadList<br/> - * Reply data is split into 4k parts and sent one by one + * Reply data is split into 4k packets and sent one by one<br/> + * (4k packet is a Qt limitation; see qabstractsocket.cpp QAbstractSocketPrivate::readFromSocket()) */ RegularFile = 0x12 }; @@ -148,7 +149,7 @@ protected: QString server; private: - static QSslSocket sslSocket; + QSslSocket sslSocket; unsigned short port; }; diff --git a/client/UpdatedConfig.cpp b/client/UpdatedConfig.cpp index a59bc67..99a89db 100644 --- a/client/UpdatedConfig.cpp +++ b/client/UpdatedConfig.cpp @@ -65,10 +65,12 @@ void UpdatedConfig::update() retryFailed = false; } + /* if (! (updateStatus & (1 << SslClient::Config))) { client->SendRequest(SslClient::Config); } + */ if (! (updateStatus & (1 << SslClient::GenericProxyList))) { client->SendRequest(SslClient::GenericProxyList); @@ -113,7 +115,7 @@ void UpdatedConfig::gotServerReply(SslClient::RequestType &type, QByteArray &con Logger::Trace("Got server reply w type: %x\n", type); if (confdata.size() == 0) { - Logger::Warn("Empty server reply recieved"); + Logger::Warn("Empty server reply recieved\n"); goto end; } @@ -149,7 +151,7 @@ void UpdatedConfig::gotServerReply(SslClient::RequestType &type, QByteArray &con updateStatus |= (1 << type); end: - if (updateStatus != 0x7E) + if (updateStatus != UPDATED_STATE_FULL) { Logger::Trace("Still need to update other config parts. Update status: %x\n", updateStatus); update(); diff --git a/client/UpdatedConfig.h b/client/UpdatedConfig.h index 2e4deac..a9def0b 100644 --- a/client/UpdatedConfig.h +++ b/client/UpdatedConfig.h @@ -18,8 +18,8 @@ class QTimer; class UpdatedConfig: public QObject, public Config { Q_OBJECT + public: - /** * @brief Retrieve application-wide instance of Config class * @return Pointer to singleton instance of Config class @@ -31,17 +31,20 @@ public: * @return address of server to communicate with ot empty string */ string GetServerAddr(); + signals: /** * @brief Signal is emitted when client configuration is updated */ void updated(); + +private slots: + void update(); + void connectionError(); + void gotServerReply(SslClient::RequestType &type, QByteArray &confdata); + private: - /** - * @brief creates an instance and tries to connect to servers from config.cfg<br/> - * one by one until working server is found or no other ServerEntry records left - */ - UpdatedConfig(); + static const int UPDATED_STATE_FULL = 0x7C; /** * @brief Pointer to the singleton Config instance @@ -85,10 +88,12 @@ private: * value and any of SslClient::RequestType values */ unsigned char updateStatus; -private slots: - void update(); - void connectionError(); - void gotServerReply(SslClient::RequestType &type, QByteArray &confdata); + + /** + * @brief creates an instance and tries to connect to servers from config.cfg<br/> + * one by one until working server is found or no other ServerEntry records left + */ + UpdatedConfig(); }; #endif
\ No newline at end of file |