1 /** HTTP server class.
2  * https://github.com/azadkuh/qhttp
3  *
4  * @author amir zamani
5  * @version 2.0.0
6  * @date 2014-07-11
7   */
8 
9 #ifndef QHTTPSERVER_HPP
10 #define QHTTPSERVER_HPP
11 
12 ///////////////////////////////////////////////////////////////////////////////
13 #include "qhttpfwd.hpp"
14 
15 #include <QObject>
16 #include <QHostAddress>
17 ///////////////////////////////////////////////////////////////////////////////
18 namespace qhttp {
19 namespace server {
20 ///////////////////////////////////////////////////////////////////////////////
21 
22 /** The QHttpServer class is a fast, async (non-blocking) HTTP server. */
23 class QHTTP_API QHttpServer : public QObject
24 {
25     Q_OBJECT
26 
27     Q_PROPERTY(quint32 timeOut READ timeOut WRITE setTimeOut)
28 
29 public:
30     /** construct a new HTTP Server. */
31     explicit    QHttpServer(QObject *parent = nullptr);
32 
33     virtual    ~QHttpServer();
34 
35     /** starts a TCP or Local (unix domain socket) server.
36      * if you provide a server handler, the newRequest() signal won't be emitted.
37      *
38      * @param socketOrPort could be a tcp port number as "8080" or a unix socket name as
39      *  "/tmp/sample.socket" or "sample.socket".
40      * @param handler optional server handler (a lambda, std::function, ...)
41      * @return false if listening fails.
42      */
43     bool        listen(const QString& socketOrPort,
44                        const TServerHandler& handler = nullptr);
45 
46     /** starts a TCP server on specified address and port.
47      * if you provide a server handler, the newRequest() signal won't be emitted.
48      *
49      * @param address listening address as QHostAddress::Any.
50      * @param port listening port.
51      * @param handler optional server handler (a lambda, std::function, ...)
52      * @return false if listening fails.
53      */
54     bool        listen(const QHostAddress& address, quint16 port,
55                        const TServerHandler& handler = nullptr);
56 
57     /** @overload listen() */
listen(quint16 port)58     bool        listen(quint16 port) {
59         return listen(QHostAddress::Any, port);
60     }
61 
62     /** returns true if server successfully listens. @sa listen() */
63     bool        isListening() const;
64 
65     /** closes the server and stops from listening. */
66     void        stopListening();
67 
68     /** returns timeout value [mSec] for open connections (sockets).
69      *  @sa setTimeOut(). */
70     quint32     timeOut()const;
71 
72     /** set time-out for new open connections in miliseconds [mSec].
73      * new incoming connections will be forcefully closed after this time out.
74      *  a zero (0) value disables timer for new connections. */
75     void        setTimeOut(quint32);
76 
77     /** returns the QHttpServer's backend type. */
78     TBackend    backendType() const;
79 
80 signals:
81     /** emitted when a client makes a new request to the server if you do not override
82      *  incomingConnection(QHttpConnection *connection);
83      * @sa incommingConnection(). */
84     void        newRequest(QHttpRequest *request, QHttpResponse *response);
85 
86     /** emitted when a new connection comes to the server if you do not override
87      *  incomingConnection(QHttpConnection *connection);
88      * @sa incomingConnection(); */
89     void        newConnection(QHttpConnection* connection);
90 
91 protected:
92     /** returns the tcp server instance if the backend() == ETcpSocket. */
93     QTcpServer* tcpServer() const;
94 
95     /** returns the local server instance if the backend() == ELocalSocket. */
96     QLocalServer* localServer() const;
97 
98 
99     /** is called when server accepts a new connection.
100      * you can override this function for using a thread-pool or ... some other reasons.
101      *
102      *  the default implementation just connects QHttpConnection::newRequest signal.
103      * @note if you override this method, the signal won't be emitted by QHttpServer.
104      * (perhaps, you do not need it anymore).
105      *
106      * @param connection New incoming connection. */
107     virtual void incomingConnection(QHttpConnection* connection);
108 
109     /** overrides QTcpServer::incomingConnection() to make a new QHttpConnection.
110      * override this function if you like to create your derived QHttpConnection instances.
111      *
112      * @note if you override this method, incomingConnection(QHttpConnection*) or
113      *  newRequest(QHttpRequest *, QHttpResponse *) signal won't be called.
114      *
115      * @see example/benchmark/server.cpp to see how to override.
116      */
117     virtual void incomingConnection(qintptr handle);
118 
119 private:
120     explicit    QHttpServer(QHttpServerPrivate&, QObject *parent);
121 
122     Q_DECLARE_PRIVATE(QHttpServer)
123     Q_DISABLE_COPY(QHttpServer)
124     QScopedPointer<QHttpServerPrivate>  d_ptr;
125 };
126 
127 ///////////////////////////////////////////////////////////////////////////////
128 } // namespace server
129 } // namespace qhttp
130 ///////////////////////////////////////////////////////////////////////////////
131 #endif // define QHTTPSERVER_HPP
132