QtHttps.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. #include "QtHttps.h"
  2. #include "LightLog.h"
  3. #include <QEventLoop>
  4. // #include "spdlog/spdlog.h"
  5. QtHttps::QtHttps(QObject *parent) :
  6. QObject(parent)
  7. {
  8. /* 初始化函数 */
  9. m_manager = new QNetworkAccessManager(this);
  10. /* 设置定时器精度 */
  11. m_timer.setTimerType(Qt::PreciseTimer);
  12. m_timer.setSingleShot(true);
  13. /* 检查是否支持OpenSSL */
  14. bool isSupport = QSslSocket::supportsSsl();
  15. QString opensslVersion = QSslSocket::sslLibraryVersionString();
  16. QString openSSLBuildVersion = QSslSocket::sslLibraryBuildVersionString();
  17. QLOG_INFO("OpenSSL is support : " + QString::number(isSupport));
  18. // QLOG_INFO("OpenSSL version : " + opensslVersion);
  19. // QLOG_INFO("OpenSSL build version : " + openSSLBuildVersion);
  20. /* 查看支持的协议 */
  21. auto list = m_manager->supportedSchemes();
  22. QString str;
  23. for(auto &item : list)
  24. {
  25. str = str + item + " ";
  26. }
  27. QLOG_INFO("supportedSchemes : " + str);
  28. /* 连接信号和槽 */
  29. connect(&m_timer, &QTimer::timeout, this, &QtHttps::do_timeout);
  30. }
  31. QtHttps::~QtHttps()
  32. {
  33. delete m_manager;
  34. if(m_file != nullptr)
  35. {
  36. if(m_file->isOpen())
  37. {
  38. m_file->close();
  39. }
  40. delete m_file;
  41. m_file = nullptr;
  42. }
  43. if(m_reply != nullptr)
  44. {
  45. m_reply->deleteLater();
  46. m_reply = nullptr;
  47. }
  48. }
  49. bool QtHttps::Get(const QString &url)
  50. {
  51. if(m_manager == nullptr)
  52. {
  53. QLOG_WARN("m_manager is nullptr");
  54. return false;
  55. }
  56. QNetworkRequest request;
  57. request.setUrl(QUrl(url));
  58. /* 等待返回 */
  59. m_reply = m_manager->get(request);
  60. connect(m_reply, &QNetworkReply::finished, this, &QtHttps::do_replyFinished);
  61. connect(m_reply, &QNetworkReply::readyRead, this, &QtHttps::do_replyReadyRead);
  62. connect(m_reply, &QNetworkReply::downloadProgress, this, &QtHttps::do_downloadProgress);
  63. #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
  64. connect(m_reply, &QNetworkReply::errorOccurred, this, &QtHttps::do_error);
  65. #endif
  66. /* 转发信号 */
  67. connect(m_reply, &QNetworkReply::downloadProgress, this, &QtHttps::signal_downloadProgress);
  68. connect(m_reply, &QNetworkReply::finished, this, &QtHttps::signal_replyFinished);
  69. m_isFinished = false;
  70. return true;
  71. }
  72. /* 获取请求头信息 */
  73. bool QtHttps::GetHead(const QString &url)
  74. {
  75. if(m_manager == nullptr)
  76. {
  77. QLOG_WARN("m_manager is nullptr");
  78. return false;
  79. }
  80. QNetworkRequest request;
  81. // QSslConfiguration conf = request.sslConfiguration();
  82. // conf.setPeerVerifyMode(QSslSocket::VerifyNone);
  83. // conf.setProtocol(QSsl::TlsV1SslV3);
  84. // request.setSslConfiguration(conf);
  85. request.setUrl(url);
  86. m_reply = m_manager->head(request);
  87. connect(m_reply, &QNetworkReply::finished, this, &QtHttps::do_replyFinished);
  88. connect(m_reply, &QNetworkReply::readyRead, this, &QtHttps::do_replyReadyRead);
  89. #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
  90. connect(m_reply, &QNetworkReply::errorOccurred, this, &QtHttps::do_error);
  91. #endif
  92. /* 转发信号 */
  93. connect(m_reply, &QNetworkReply::downloadProgress, this, &QtHttps::signal_downloadProgress);
  94. connect(m_reply, &QNetworkReply::finished, this, &QtHttps::signal_replyFinished);
  95. m_isFinished = false;
  96. return true;
  97. }
  98. void QtHttps::Post(const QString &url, const QByteArray &data)
  99. {
  100. }
  101. /* 下载文件 */
  102. void QtHttps::downloadFile(const QString &url, const QString &filePath)
  103. {
  104. if(m_manager == nullptr)
  105. {
  106. QLOG_WARN("m_manager is nullptr");
  107. return;
  108. }
  109. /* 检查文件有效性 */
  110. m_file = new QFile(this);
  111. m_file->setFileName(filePath);
  112. if(!m_file->open(QIODevice::WriteOnly | QIODevice::Truncate))
  113. {
  114. QLOG_WARN("open file failed , file path : " + filePath);
  115. m_file->close();
  116. delete m_file;
  117. m_file = nullptr;
  118. return;
  119. }
  120. /* 发送请求 */
  121. QNetworkRequest request;
  122. request.setUrl(QUrl(url));
  123. m_reply = m_manager->get(request);
  124. /* 链接信号和槽 */
  125. connect(m_reply, &QNetworkReply::finished, this, &QtHttps::do_replyFinished);
  126. connect(m_reply, &QNetworkReply::readyRead, this, &QtHttps::do_replyReadyRead);
  127. connect(m_reply, &QNetworkReply::downloadProgress, this, &QtHttps::do_downloadProgress);
  128. #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
  129. connect(m_reply, &QNetworkReply::errorOccurred, this, &QtHttps::do_error);
  130. #endif
  131. /* 转发信号 */
  132. connect(m_reply, &QNetworkReply::downloadProgress, this, &QtHttps::signal_downloadProgress);
  133. connect(m_reply, &QNetworkReply::finished, this, &QtHttps::signal_replyFinished);
  134. m_isFinished = false;
  135. }
  136. /**
  137. * @brief 等待完成,同时设置超时时间,超时后,断开reply的信号和槽的连接
  138. * 参数设置为0表示查询是否完成,设置为-1表示一直等待
  139. *
  140. * @param msecs 超时时间
  141. * @arg -1 一直等待,将会阻塞在这里
  142. * @arg 0 查询是否完成
  143. * @arg 正整数,等待完成的时间,设置完成之后再次设置,会覆盖之前的设置
  144. * @return true
  145. * @return false
  146. */
  147. bool QtHttps::waitFinished(int msecs)
  148. {
  149. if(msecs == 0)
  150. {
  151. return m_isFinished;
  152. }
  153. else if(msecs == -1)
  154. {
  155. QEventLoop loop;
  156. connect(this, &QtHttps::signal_replyFinished, &loop, &QEventLoop::quit);
  157. loop.exec();
  158. return true;
  159. }
  160. else if (msecs > 0)
  161. {
  162. m_timer.start(msecs);
  163. return m_isFinished;
  164. }
  165. return m_isFinished;
  166. }
  167. /* 请求完成的槽函数 */
  168. void QtHttps::do_replyFinished()
  169. {
  170. QLOG_DEBUG("do_replyFinished");
  171. /* 停止定时器 */
  172. if(m_timer.isActive())
  173. {
  174. m_timer.stop();
  175. }
  176. /* 获取状态码 */
  177. auto retCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
  178. if(m_reply->error() == QNetworkReply::NoError)
  179. {
  180. QLOG_DEBUG("reply : " + QString::number(retCode));
  181. auto list = m_reply->rawHeaderList();
  182. for(auto &item : list)
  183. {
  184. // SPDQLOG_INFO("{} : {}", item.toStdString(), m_reply->rawHeader(item).toStdString());
  185. QLOG_DEBUG(item + " : " + m_reply->rawHeader(item));
  186. }
  187. /* 检查文件是否打开 */
  188. if(m_file != nullptr)
  189. {
  190. if(m_file->isOpen())
  191. {
  192. m_file->close();
  193. }
  194. delete m_file;
  195. m_file = nullptr;
  196. }
  197. }
  198. else
  199. {
  200. QLOG_WARN("reply error : " + QString::number(retCode) + " " + m_reply->errorString());
  201. }
  202. /* 检查文件是否打开 */
  203. if(m_file != nullptr)
  204. {
  205. if(m_file->isOpen())
  206. {
  207. m_file->close();
  208. }
  209. delete m_file;
  210. m_file = nullptr;
  211. }
  212. /* 记得设置这个,需要手动释放 */
  213. m_reply->deleteLater();
  214. m_reply = nullptr;
  215. /* 设置完成标志 */
  216. m_isFinished = true;
  217. }
  218. /* 读取数据 */
  219. void QtHttps::do_replyReadyRead()
  220. {
  221. // QLOG_DEBUG("do_replyReadyRead");
  222. if(m_file != nullptr)
  223. {
  224. m_file->write(m_reply->readAll());
  225. }
  226. }
  227. /* 下载进度 */
  228. void QtHttps::do_downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
  229. {
  230. // QLOG_DEBUG("do_downloadProgress");
  231. QLOG_DEBUG("bytesReceived / bytesTotal : " + QString::number(bytesReceived) + " / " + QString::number(bytesTotal));
  232. }
  233. #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
  234. void QtHttps::do_error(QNetworkReply::NetworkError code)
  235. {
  236. QLOG_WARN("error : " + QString::number(code));
  237. }
  238. #endif
  239. /* 超时,断开reply连接,删除reply */
  240. void QtHttps::do_timeout()
  241. {
  242. QLOG_WARN("Http timeout");
  243. if(m_reply != nullptr)
  244. {
  245. m_reply->disconnect();
  246. m_reply->abort();
  247. m_reply->deleteLater();
  248. m_reply = nullptr;
  249. }
  250. m_isFinished = true;
  251. }