Skip to content

Commit c2ad13a

Browse files
committed
Fixed bugs in ssh connection
1 parent 65fd819 commit c2ad13a

File tree

6 files changed

+100
-36
lines changed

6 files changed

+100
-36
lines changed

redis-desktop-manager/include/redis/RedisConnection.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ class RedisConnection : public RedisConnectionAbstract
3232
void init();
3333

3434
private:
35-
QTcpSocket * socket;
36-
QByteArray readingBuffer;
35+
QTcpSocket * socket;
3736

3837
private slots:
3938
void readyRead();

redis-desktop-manager/include/redis/RedisConnectionAbstract.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public slots:
6464
bool connected;
6565
QTimer * executionTimer;
6666
Response resp;
67+
QByteArray readingBuffer;
6768
bool commandRunning;
6869
Command runningCommand;
6970
QQueue<Command> commands;

redis-desktop-manager/include/redis/RedisConnectionOverSsh.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,16 @@ class RedisConnectionOverSsh : public RedisConnectionAbstract
2828
return connected && socketConnected;
2929
}
3030

31+
protected:
32+
33+
void init();
34+
3135
private:
3236
QxtSshTcpSocket * socket;
33-
QxtSshClient sshClient;
37+
QxtSshClient * sshClient;
3438
bool isHostKeyAlreadyAdded;
35-
QEventLoop syncLoop;
36-
QTimer syncTimer;
39+
QEventLoop * syncLoop;
40+
QTimer * syncTimer;
3741
bool socketConnected;
3842

3943
bool waitForData(int ms);

redis-desktop-manager/source/demo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ void MainWin::OnTreeViewContextMenu(const QPoint &point)
228228
QMenu *menu = new QMenu();
229229
menu->addAction(QIcon(":/images/terminal.png"), "Console", this, SLOT(OnConsoleOpen()));
230230
menu->addSeparator();
231-
menu->addAction(QIcon(":/images/serverinfo.png"), "Server info", this, SLOT(OnServerInfoOpen()));
231+
//menu->addAction(QIcon(":/images/serverinfo.png"), "Server info", this, SLOT(OnServerInfoOpen()));
232232
menu->addAction(QIcon(":/images/refreshdb.png"), "Reload", this, SLOT(OnReloadServerInTree()));
233233
menu->addAction(QIcon(":/images/redisIcon_offline.png"), "Disconnect", this, SLOT(OnDisconnectFromServer()));
234234
menu->addSeparator();

redis-desktop-manager/source/redis/RedisConnection.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ RedisConnection::RedisConnection(const RedisConnectionConfig & c)
77
{
88
}
99

10-
1110
void RedisConnection::init()
1211
{
1312
if (socket != nullptr) {

redis-desktop-manager/source/redis/RedisConnectionOverSsh.cpp

Lines changed: 90 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,33 @@
22
#include "Command.h"
33
#include "Response.h"
44

5-
#define MAX_BUFFER_SIZE 536870999 //redis response limit
5+
#define MAX_BUFFER_SIZE 536800 //response part limit
66

77
RedisConnectionOverSsh::RedisConnectionOverSsh(const RedisConnectionConfig &c)
8-
: RedisConnectionAbstract(c), socket(nullptr), isHostKeyAlreadyAdded(false), socketConnected(false)
8+
: RedisConnectionAbstract(c), socket(nullptr), sshClient(nullptr), isHostKeyAlreadyAdded(false), socketConnected(false)
99
{
10-
syncTimer.setSingleShot(true);
1110

12-
QObject::connect(&syncTimer, SIGNAL(timeout()), &syncLoop, SLOT(quit()));
13-
QObject::connect(&sshClient, SIGNAL(connected()), this, SLOT(OnSshConnected()));
11+
}
12+
13+
void RedisConnectionOverSsh::init()
14+
{
15+
if (sshClient != nullptr) {
16+
return;
17+
}
18+
19+
RedisConnectionAbstract::init();
20+
21+
sshClient = new QxtSshClient;
22+
syncLoop = new QEventLoop;
23+
syncTimer = new QTimer;
24+
25+
syncTimer->setSingleShot(true);
26+
27+
QObject::connect(syncTimer, SIGNAL(timeout()), syncLoop, SLOT(quit()));
28+
QObject::connect(sshClient, SIGNAL(connected()), this, SLOT(OnSshConnected()));
1429

1530
QObject::connect(
16-
&sshClient, SIGNAL(error(QxtSshClient::Error)),
31+
sshClient, SIGNAL(error(QxtSshClient::Error)),
1732
this, SLOT(OnSshConnectionError(QxtSshClient::Error))
1833
);
1934
}
@@ -22,26 +37,31 @@ RedisConnectionOverSsh::~RedisConnectionOverSsh(void)
2237
{
2338
if (socket != nullptr) {
2439
delete socket;
40+
delete syncLoop;
41+
delete syncTimer;
42+
delete sshClient;
2543
}
2644
}
2745

2846
bool RedisConnectionOverSsh::connect()
2947
{
48+
init();
49+
3050
//set password
31-
sshClient.setPassphrase(config.sshPassword);
51+
sshClient->setPassphrase(config.sshPassword);
3252

3353
//connect to ssh server
34-
syncTimer.start(config.connectionTimeout);
35-
sshClient.connectToHost(config.sshUser, config.sshHost, config.sshPort);
36-
syncLoop.exec();
54+
syncTimer->start(config.connectionTimeout);
55+
sshClient->connectToHost(config.sshUser, config.sshHost, config.sshPort);
56+
syncLoop->exec();
3757

38-
if (!connected && !syncTimer.isActive()) {
58+
if (!connected && !syncTimer->isActive()) {
3959
connected = false;
4060
return connected;
4161
}
4262

4363
//connect to redis
44-
socket = sshClient.openTcpSocket(config.host, config.port);
64+
socket = sshClient->openTcpSocket(config.host, config.port);
4565

4666
if (socket == NULL) {
4767
socketConnected = false;
@@ -50,10 +70,10 @@ bool RedisConnectionOverSsh::connect()
5070

5171
QObject::connect(socket, SIGNAL(readyRead()), this, SLOT(OnSocketReadyRead()));
5272

53-
syncTimer.start(config.connectionTimeout);
54-
syncLoop.exec();
73+
syncTimer->start(config.connectionTimeout);
74+
syncLoop->exec();
5575

56-
if (!socketConnected && !syncTimer.isActive()) {
76+
if (!socketConnected && !syncTimer->isActive()) {
5777
socketConnected = false;
5878
return socketConnected;
5979
}
@@ -68,20 +88,20 @@ bool RedisConnectionOverSsh::connect()
6888
void RedisConnectionOverSsh::OnSshConnectionError(QxtSshClient::Error error)
6989
{
7090
if (QxtSshClient::HostKeyUnknownError == error) {
71-
QxtSshKey hostKey = sshClient.hostKey();
91+
QxtSshKey hostKey = sshClient->hostKey();
7292

73-
sshClient.addKnownHost(config.sshHost, hostKey);
93+
sshClient->addKnownHost(config.sshHost, hostKey);
7494

75-
sshClient.resetState();
95+
sshClient->resetState();
7696

77-
sshClient.connectToHost(config.sshUser, config.sshHost, config.sshPort);
97+
sshClient->connectToHost(config.sshUser, config.sshHost, config.sshPort);
7898

7999
isHostKeyAlreadyAdded = true;
80100
return;
81101
}
82102

83-
if (syncLoop.isRunning()) {
84-
syncLoop.exit();
103+
if (syncLoop->isRunning()) {
104+
syncLoop->exit();
85105
}
86106

87107
}
@@ -90,8 +110,8 @@ void RedisConnectionOverSsh::OnSshConnected()
90110
{
91111
connected = true;
92112

93-
if (syncLoop.isRunning()) {
94-
syncLoop.exit();
113+
if (syncLoop->isRunning()) {
114+
syncLoop->exit();
95115
}
96116
}
97117

@@ -102,10 +122,29 @@ void RedisConnectionOverSsh::OnSocketReadyRead()
102122
socketConnected = true;
103123
}
104124

105-
if (syncLoop.isRunning()) {
106-
syncLoop.exit();
125+
if (syncLoop->isRunning()) {
126+
syncLoop->exit();
127+
}
128+
129+
// ignore signals if running blocking version
130+
if (!commandRunning) {
131+
return;
132+
}
133+
134+
readingBuffer = socket->read(MAX_BUFFER_SIZE);
135+
136+
if (readingBuffer.size() == 0) {
137+
return;
107138
}
108139

140+
executionTimer->stop();
141+
resp.appendToSource(readingBuffer);
142+
143+
if (resp.isValid()) {
144+
return sendResponse();
145+
} else {
146+
executionTimer->start(config.executeTimeout); //restart execution timer
147+
}
109148
}
110149

111150

@@ -136,10 +175,10 @@ QVariant RedisConnectionOverSsh::execute(QString command)
136175
socket->write(cString, byteArray.size());
137176

138177
//wait for ready read
139-
syncTimer.start(config.executeTimeout);
140-
syncLoop.exec();
178+
syncTimer->start(config.executeTimeout);
179+
syncLoop->exec();
141180

142-
if (!syncTimer.isActive()) {
181+
if (!syncTimer->isActive()) {
143182
return QVariant();
144183
}
145184

@@ -189,9 +228,31 @@ QVariant RedisConnectionOverSsh::execute(QString command)
189228
return response.getValue();
190229
}
191230

192-
void RedisConnectionOverSsh::runCommand(const Command &cmd)
231+
void RedisConnectionOverSsh::runCommand(const Command &command)
193232
{
194233
//todo: implement this
234+
if (command.hasDbIndex()) {
235+
selectDb(command.getDbIndex());
236+
}
237+
238+
resp.clear();
239+
commandRunning = true;
240+
runningCommand = command;
241+
executionTimer->start(config.executeTimeout);
242+
243+
if (command.isEmpty()) {
244+
return sendResponse();
245+
}
246+
247+
QString formattedCommand = command.getFormattedString();
248+
249+
/*
250+
* Send command
251+
*/
252+
QByteArray byteArray = formattedCommand.toUtf8();
253+
const char* cString = byteArray.constData();
254+
255+
socket->write(cString, byteArray.size());
195256
}
196257

197258
bool RedisConnectionOverSsh::waitForData(int ms)

0 commit comments

Comments
 (0)