JQHttpServer.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*
  2. This file is part of JQLibrary
  3. Copyright: Jason
  4. Contact email: 188080501@qq.com
  5. GNU Lesser General Public License Usage
  6. Alternatively, this file may be used under the terms of the GNU Lesser
  7. General Public License version 2.1 or version 3 as published by the Free
  8. Software Foundation and appearing in the file LICENSE.LGPLv21 and
  9. LICENSE.LGPLv3 included in the packaging of this file. Please review the
  10. following information to ensure the GNU Lesser General Public License
  11. requirements will be met: https://www.gnu.org/licenses/lgpl.html and
  12. http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  13. */
  14. #ifndef JQHTTPSERVER_H_
  15. #define JQHTTPSERVER_H_
  16. #ifndef QT_NETWORK_LIB
  17. #error("Please add network in pro file")
  18. #endif
  19. #ifndef QT_CONCURRENT_LIB
  20. #error("Please add concurrent in pro file")
  21. #endif
  22. // C++ lib import
  23. #include <functional>
  24. // Qt lib import
  25. #include <QHostAddress>
  26. #include <QMap>
  27. #include <QMutex>
  28. #include <QObject>
  29. #include <QPointer>
  30. #include <QSet>
  31. #include <QSharedPointer>
  32. #include <QUrl>
  33. #include <QVector>
  34. class QIODevice;
  35. class QThreadPool;
  36. class QHostAddress;
  37. class QTimer;
  38. class QImage;
  39. class QTcpServer;
  40. class QLocalServer;
  41. class QSslCertificate;
  42. class QSslKey;
  43. class QSslConfiguration;
  44. namespace JQHttpServer {
  45. class Session : public QObject {
  46. Q_OBJECT
  47. Q_DISABLE_COPY(Session)
  48. public:
  49. Session(const QPointer<QIODevice>& tcpSocket);
  50. ~Session();
  51. inline void setHandleAcceptedCallback(const std::function<void(const QPointer<Session>&)>& callback) { handleAcceptedCallback_ = callback; }
  52. inline QString requestMethod() const { return requestMethod_; }
  53. inline QString requestUrl() const { return requestUrl_; }
  54. inline QString requestCrlf() const { return requestCrlf_; }
  55. inline QMap<QString, QString> requestHeader() const { return requestHeader_; }
  56. inline QByteArray requestBody() const { return requestBody_; }
  57. QString requestUrlPath() const;
  58. QStringList requestUrlPathSplitToList() const;
  59. QMap<QString, QString> requestUrlQuery() const;
  60. public slots:
  61. void replyText(const QString& replyData, const int& httpStatusCode = 200);
  62. void replyRedirects(const QUrl& targetUrl, const int& httpStatusCode = 200);
  63. void replyJsonObject(const QJsonObject& jsonObject, const int& httpStatusCode = 200);
  64. void replyJsonArray(const QJsonArray& jsonArray, const int& httpStatusCode = 200);
  65. void replyFile(const QString& filePath, const int& httpStatusCode = 200);
  66. void replyImage(const QImage& image, const int& httpStatusCode = 200);
  67. void replyImage(const QString& imageFilePath, const int& httpStatusCode = 200);
  68. void replyBytes(const QByteArray& bytes, const int& httpStatusCode = 200);
  69. void replyOptions();
  70. private:
  71. void inspectionBufferSetup1();
  72. void inspectionBufferSetup2();
  73. private:
  74. QPointer<QIODevice> ioDevice_;
  75. std::function<void(const QPointer<Session>&)> handleAcceptedCallback_;
  76. QSharedPointer<QTimer> timerForClose_;
  77. QByteArray buffer_;
  78. QString requestMethod_;
  79. QString requestUrl_;
  80. QString requestCrlf_;
  81. QMap<QString, QString> requestHeader_;
  82. bool headerAcceptedFinish_ = false;
  83. qint64 contentLength_ = -1;
  84. bool alreadyReply_ = false;
  85. QByteArray requestBody_;
  86. qint64 waitWrittenByteCount_ = 0;
  87. QSharedPointer<QIODevice> ioDeviceForReply_;
  88. };
  89. class AbstractManage : public QObject {
  90. Q_OBJECT
  91. Q_DISABLE_COPY(AbstractManage)
  92. public:
  93. AbstractManage(const int& handleMaxThreadCount);
  94. virtual ~AbstractManage();
  95. inline void setHttpAcceptedCallback(const std::function<void(const QPointer<Session>& session)>& httpAcceptedCallback) { httpAcceptedCallback_ = httpAcceptedCallback; }
  96. inline QSharedPointer<QThreadPool> handleThreadPool() { return handleThreadPool_; }
  97. inline QSharedPointer<QThreadPool> serverThreadPool() { return serverThreadPool_; }
  98. virtual bool isRunning() = 0;
  99. protected Q_SLOTS:
  100. bool begin();
  101. void close();
  102. protected:
  103. virtual bool onStart() = 0;
  104. virtual void onFinish() = 0;
  105. bool startServerThread();
  106. void stopHandleThread();
  107. void stopServerThread();
  108. void newSession(const QPointer<Session>& session);
  109. void handleAccepted(const QPointer<Session>& session);
  110. signals:
  111. void readyToClose();
  112. protected:
  113. QSharedPointer<QThreadPool> serverThreadPool_;
  114. QSharedPointer<QThreadPool> handleThreadPool_;
  115. QMutex mutex_;
  116. std::function<void(const QPointer<Session>& session)> httpAcceptedCallback_;
  117. QSet<Session*> availableSessions_;
  118. };
  119. class TcpServerManage : public AbstractManage {
  120. Q_OBJECT
  121. Q_DISABLE_COPY(TcpServerManage)
  122. public:
  123. TcpServerManage(const int& handleMaxThreadCount = 2);
  124. ~TcpServerManage();
  125. bool listen(const QHostAddress& address, const quint16& port);
  126. signals:
  127. void doProcess(int code);
  128. private:
  129. bool isRunning();
  130. bool onStart();
  131. void onFinish();
  132. private:
  133. QPointer<QTcpServer> tcpServer_;
  134. QHostAddress listenAddress_ = QHostAddress::Any;
  135. quint16 listenPort_ = 0;
  136. };
  137. #ifndef QT_NO_SSL
  138. class SslServerHelper;
  139. class SslServerManage : public AbstractManage {
  140. Q_OBJECT
  141. Q_DISABLE_COPY(SslServerManage)
  142. public:
  143. SslServerManage(const int& handleMaxThreadCount = 2);
  144. ~SslServerManage();
  145. bool listen(
  146. const QHostAddress& address,
  147. const quint16& port,
  148. const QString& crtFilePath,
  149. const QString& keyFilePath,
  150. const QList<QPair<QString, bool>>& caFileList = {} // [ { filePath, isPem } ]
  151. );
  152. private:
  153. bool isRunning();
  154. bool onStart();
  155. void onFinish();
  156. private:
  157. QPointer<SslServerHelper> tcpServer_;
  158. QHostAddress listenAddress_ = QHostAddress::Any;
  159. quint16 listenPort_ = 0;
  160. QSharedPointer<QSslConfiguration> sslConfiguration_;
  161. };
  162. #endif
  163. class LocalServerManage : public AbstractManage {
  164. Q_OBJECT
  165. Q_DISABLE_COPY(LocalServerManage)
  166. public:
  167. LocalServerManage(const int& handleMaxThreadCount);
  168. ~LocalServerManage();
  169. bool listen(const QString& name);
  170. private:
  171. bool isRunning();
  172. bool onStart();
  173. void onFinish();
  174. private:
  175. QPointer<QLocalServer> localServer_;
  176. QString listenName_;
  177. };
  178. }
  179. #endif //JQHTTPSERVER_H_