1 /*
2    Drawpile - a collaborative drawing program.
3 
4    Copyright (C) 2019 Calle Laakkonen
5 
6    Drawpile is free software: you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation, either version 3 of the License, or
9    (at your option) any later version.
10 
11    Drawpile is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with Drawpile.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #ifndef DP_ThickServer_H
21 #define DP_ThickServer_H
22 
23 #include "../libserver/sessions.h"
24 
25 #include <QObject>
26 #include <QHostAddress>
27 #include <QDateTime>
28 
29 class QTcpServer;
30 
31 namespace protocol {
32 	class ProtocolVersion;
33 }
34 
35 namespace sessionlisting {
36 	class Announcements;
37 }
38 
39 namespace server {
40 
41 class ThickSession;
42 class Session;
43 class ThickServerClient;
44 class ServerConfig;
45 class ServerLog;
46 
47 /**
48  * The drawpile server.
49  */
50 class ThickServer : public QObject, public Sessions {
51 	Q_OBJECT
52 public:
53 	explicit ThickServer(ServerConfig *config, QObject *parent=nullptr);
54 
setSslCertFile(const QString & certfile,const QString & keyfile)55 	void setSslCertFile(const QString &certfile, const QString &keyfile) { m_sslCertFile = certfile; m_sslKeyFile = keyfile; }
56 	void setAutoStop(bool autostop);
57 	void setRecordingPath(const QString &path);
58 
59 	/**
60 	 * @brief Get the port the server is running from
61 	 * @return port number or zero if server is not running
62 	 */
port()63 	int port() const { return m_port; }
64 
isRunning()65 	bool isRunning() const { return m_state != State::Stopped; }
66 
67 	//! Start the server with the given socket descriptor
68 	bool startFd(int fd);
69 
session()70 	ThickSession *session() { return m_session; }
71 
config()72 	ServerConfig *config() { return m_config; }
73 
74 	QJsonArray sessionDescriptions() const override;
75 
76 	Session *getSessionById(const QString &id, bool loadTemplate) override;
77 
78 	std::tuple<Session*, QString> createSession(const QString &id, const QString &idAlias, const protocol::ProtocolVersion &protocolVersion, const QString &founder) override;
79 
80 public slots:
81 	//! Start the server on the given port and listening address
82 	bool start(quint16 port, const QHostAddress& address = QHostAddress::Any);
83 
84 	 //! Stop the server. All clients are disconnected.
85 	void stop();
86 
87 private slots:
88 	void newClient();
89 	void removeClient(QObject *clientObj);
90 	void sessionEnded();
91 
92 signals:
93 	void serverStartError(const QString &message);
94 	void serverStarted();
95 	void serverStopped();
96 
97 private:
98 	enum class State {Running, Stopping, Stopped};
99 
100 	bool createServer();
101 
102 	ServerConfig *m_config = nullptr;
103 	QTcpServer *m_server = nullptr;
104 	sessionlisting::Announcements *m_announcements;
105 
106 	QList<ThickServerClient*> m_clients;
107 	ThickSession *m_session = nullptr;
108 
109 	State m_state = State::Stopped;
110 
111 	bool m_autoStop = false;
112 	int m_port = 0;
113 
114 	QString m_sslCertFile;
115 	QString m_sslKeyFile;
116 	QString m_recordingPath;
117 
118 	QDateTime m_started;
119 };
120 
121 }
122 
123 #endif
124 
125