1 /*
2 SPDX-FileCopyrightText: 2015-2019 Krzysztof Nowicki <krissn@op.pl>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7 #include "fakeewsserver.h"
8
9 #include "fakeewsconnection.h"
10 #include "fakeewsserver_debug.h"
11 #include <QRandomGenerator>
12 #include <QThread>
13
14 const FakeEwsServer::DialogEntry::HttpResponse FakeEwsServer::EmptyResponse = {QString(), 0};
15
FakeEwsServer(QObject * parent)16 FakeEwsServer::FakeEwsServer(QObject *parent)
17 : QTcpServer(parent)
18 , mPortNumber(0)
19 {
20 }
21
~FakeEwsServer()22 FakeEwsServer::~FakeEwsServer()
23 {
24 qCInfoNC(EWSFAKE_LOG) << QStringLiteral("Stopping fake EWS server.");
25 }
26
start()27 bool FakeEwsServer::start()
28 {
29 QMutexLocker lock(&mMutex);
30
31 int retries = 3;
32 bool ok;
33 auto generator = QRandomGenerator::global();
34 do {
35 mPortNumber = (generator->bounded(10000)) + 10000;
36 qCInfoNC(EWSFAKE_LOG) << QStringLiteral("Starting fake EWS server at 127.0.0.1:%1").arg(mPortNumber);
37 ok = listen(QHostAddress::LocalHost, mPortNumber);
38 if (!ok) {
39 qCWarningNC(EWSFAKE_LOG) << QStringLiteral("Failed to start server");
40 }
41 } while (!ok && --retries);
42
43 if (ok) {
44 connect(this, &QTcpServer::newConnection, this, &FakeEwsServer::newConnectionReceived);
45 }
46
47 return ok;
48 }
49
setDialog(const DialogEntry::List & dialog)50 void FakeEwsServer::setDialog(const DialogEntry::List &dialog)
51 {
52 QMutexLocker lock(&mMutex);
53
54 mDialog = dialog;
55 }
56
setDefaultReplyCallback(const DialogEntry::ReplyCallback & defaultReplyCallback)57 void FakeEwsServer::setDefaultReplyCallback(const DialogEntry::ReplyCallback &defaultReplyCallback)
58 {
59 QMutexLocker lock(&mMutex);
60
61 mDefaultReplyCallback = defaultReplyCallback;
62 }
63
setOverrideReplyCallback(const DialogEntry::ReplyCallback & overrideReplyCallback)64 void FakeEwsServer::setOverrideReplyCallback(const DialogEntry::ReplyCallback &overrideReplyCallback)
65 {
66 QMutexLocker lock(&mMutex);
67
68 mOverrideReplyCallback = overrideReplyCallback;
69 }
70
queueEventsXml(const QStringList & events)71 void FakeEwsServer::queueEventsXml(const QStringList &events)
72 {
73 if (QThread::currentThread() != thread()) {
74 qCWarningNC(EWSFAKE_LOG) << QStringLiteral(
75 "queueEventsXml called from wrong thread "
76 "(called from ") << QThread::currentThread()
77 << QStringLiteral(", should be ") << thread() << QStringLiteral(")");
78 return;
79 }
80 mEventQueue += events;
81
82 if (mStreamingEventsConnection) {
83 mStreamingEventsConnection->sendEvents(mEventQueue);
84 mEventQueue.clear();
85 }
86 }
87
retrieveEventsXml()88 QStringList FakeEwsServer::retrieveEventsXml()
89 {
90 QStringList events = mEventQueue;
91 mEventQueue.clear();
92 return events;
93 }
94
newConnectionReceived()95 void FakeEwsServer::newConnectionReceived()
96 {
97 QTcpSocket *sock = nextPendingConnection();
98
99 auto conn = new FakeEwsConnection(sock, this);
100 connect(conn, &FakeEwsConnection::streamingRequestStarted, this, &FakeEwsServer::streamingConnectionStarted);
101 }
102
dialog() const103 const FakeEwsServer::DialogEntry::List FakeEwsServer::dialog() const
104 {
105 QMutexLocker lock(&mMutex);
106
107 return mDialog;
108 }
109
defaultReplyCallback() const110 const FakeEwsServer::DialogEntry::ReplyCallback FakeEwsServer::defaultReplyCallback() const
111 {
112 QMutexLocker lock(&mMutex);
113
114 return mDefaultReplyCallback;
115 }
116
overrideReplyCallback() const117 const FakeEwsServer::DialogEntry::ReplyCallback FakeEwsServer::overrideReplyCallback() const
118 {
119 QMutexLocker lock(&mMutex);
120
121 return mOverrideReplyCallback;
122 }
123
streamingConnectionStarted(FakeEwsConnection * conn)124 void FakeEwsServer::streamingConnectionStarted(FakeEwsConnection *conn)
125 {
126 if (mStreamingEventsConnection) {
127 qCWarningNC(EWSFAKE_LOG) << QStringLiteral("Got new streaming connection while existing one is active - terminating existing one");
128 mStreamingEventsConnection->deleteLater();
129 }
130
131 mStreamingEventsConnection = conn;
132 }
133
portNumber() const134 ushort FakeEwsServer::portNumber() const
135 {
136 QMutexLocker lock(&mMutex);
137
138 return mPortNumber;
139 }
140