summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/Config.cpp6
-rw-r--r--client/DownloadClient.cpp35
-rw-r--r--client/DownloadClient.h15
-rw-r--r--client/FileOpThread.cpp22
-rw-r--r--client/FileOpThread.h9
-rw-r--r--client/ProxyClientApp.cpp17
-rw-r--r--client/ProxyClientApp.h3
-rw-r--r--client/SslClient.cpp17
-rw-r--r--client/SslClient.h5
-rw-r--r--client/UpdatedConfig.cpp6
-rw-r--r--client/UpdatedConfig.h25
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