#include "QtHttps.h" #include "LightLog.h" #include // #include "spdlog/spdlog.h" QtHttps::QtHttps(QObject *parent) : QObject(parent) { /* 初始化函数 */ m_manager = new QNetworkAccessManager(this); /* 设置定时器精度 */ m_timer.setTimerType(Qt::PreciseTimer); m_timer.setSingleShot(true); /* 检查是否支持OpenSSL */ bool isSupport = QSslSocket::supportsSsl(); QString opensslVersion = QSslSocket::sslLibraryVersionString(); QString openSSLBuildVersion = QSslSocket::sslLibraryBuildVersionString(); QLOG_INFO("OpenSSL is support : " + QString::number(isSupport)); // QLOG_INFO("OpenSSL version : " + opensslVersion); // QLOG_INFO("OpenSSL build version : " + openSSLBuildVersion); /* 查看支持的协议 */ auto list = m_manager->supportedSchemes(); QString str; for(auto &item : list) { str = str + item + " "; } QLOG_INFO("supportedSchemes : " + str); /* 连接信号和槽 */ connect(&m_timer, &QTimer::timeout, this, &QtHttps::do_timeout); } QtHttps::~QtHttps() { delete m_manager; if(m_file != nullptr) { if(m_file->isOpen()) { m_file->close(); } delete m_file; m_file = nullptr; } if(m_reply != nullptr) { m_reply->deleteLater(); m_reply = nullptr; } } bool QtHttps::Get(const QString &url) { if(m_manager == nullptr) { QLOG_WARN("m_manager is nullptr"); return false; } QNetworkRequest request; request.setUrl(QUrl(url)); /* 等待返回 */ m_reply = m_manager->get(request); connect(m_reply, &QNetworkReply::finished, this, &QtHttps::do_replyFinished); connect(m_reply, &QNetworkReply::readyRead, this, &QtHttps::do_replyReadyRead); connect(m_reply, &QNetworkReply::downloadProgress, this, &QtHttps::do_downloadProgress); #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) connect(m_reply, &QNetworkReply::errorOccurred, this, &QtHttps::do_error); #endif /* 转发信号 */ connect(m_reply, &QNetworkReply::downloadProgress, this, &QtHttps::signal_downloadProgress); connect(m_reply, &QNetworkReply::finished, this, &QtHttps::signal_replyFinished); m_isFinished = false; return true; } /* 获取请求头信息 */ bool QtHttps::GetHead(const QString &url) { if(m_manager == nullptr) { QLOG_WARN("m_manager is nullptr"); return false; } QNetworkRequest request; // QSslConfiguration conf = request.sslConfiguration(); // conf.setPeerVerifyMode(QSslSocket::VerifyNone); // conf.setProtocol(QSsl::TlsV1SslV3); // request.setSslConfiguration(conf); request.setUrl(url); m_reply = m_manager->head(request); connect(m_reply, &QNetworkReply::finished, this, &QtHttps::do_replyFinished); connect(m_reply, &QNetworkReply::readyRead, this, &QtHttps::do_replyReadyRead); #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) connect(m_reply, &QNetworkReply::errorOccurred, this, &QtHttps::do_error); #endif /* 转发信号 */ connect(m_reply, &QNetworkReply::downloadProgress, this, &QtHttps::signal_downloadProgress); connect(m_reply, &QNetworkReply::finished, this, &QtHttps::signal_replyFinished); m_isFinished = false; return true; } void QtHttps::Post(const QString &url, const QByteArray &data) { } /* 下载文件 */ void QtHttps::downloadFile(const QString &url, const QString &filePath) { if(m_manager == nullptr) { QLOG_WARN("m_manager is nullptr"); return; } /* 检查文件有效性 */ m_file = new QFile(this); m_file->setFileName(filePath); if(!m_file->open(QIODevice::WriteOnly | QIODevice::Truncate)) { QLOG_WARN("open file failed , file path : " + filePath); m_file->close(); delete m_file; m_file = nullptr; return; } /* 发送请求 */ QNetworkRequest request; request.setUrl(QUrl(url)); m_reply = m_manager->get(request); /* 链接信号和槽 */ connect(m_reply, &QNetworkReply::finished, this, &QtHttps::do_replyFinished); connect(m_reply, &QNetworkReply::readyRead, this, &QtHttps::do_replyReadyRead); connect(m_reply, &QNetworkReply::downloadProgress, this, &QtHttps::do_downloadProgress); #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) connect(m_reply, &QNetworkReply::errorOccurred, this, &QtHttps::do_error); #endif /* 转发信号 */ connect(m_reply, &QNetworkReply::downloadProgress, this, &QtHttps::signal_downloadProgress); connect(m_reply, &QNetworkReply::finished, this, &QtHttps::signal_replyFinished); m_isFinished = false; } /** * @brief 等待完成,同时设置超时时间,超时后,断开reply的信号和槽的连接 * 参数设置为0表示查询是否完成,设置为-1表示一直等待 * * @param msecs 超时时间 * @arg -1 一直等待,将会阻塞在这里 * @arg 0 查询是否完成 * @arg 正整数,等待完成的时间,设置完成之后再次设置,会覆盖之前的设置 * @return true * @return false */ bool QtHttps::waitFinished(int msecs) { if(msecs == 0) { return m_isFinished; } else if(msecs == -1) { QEventLoop loop; connect(this, &QtHttps::signal_replyFinished, &loop, &QEventLoop::quit); loop.exec(); return true; } else if (msecs > 0) { m_timer.start(msecs); return m_isFinished; } return m_isFinished; } /* 请求完成的槽函数 */ void QtHttps::do_replyFinished() { QLOG_DEBUG("do_replyFinished"); /* 停止定时器 */ if(m_timer.isActive()) { m_timer.stop(); } /* 获取状态码 */ auto retCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if(m_reply->error() == QNetworkReply::NoError) { QLOG_DEBUG("reply : " + QString::number(retCode)); auto list = m_reply->rawHeaderList(); for(auto &item : list) { // SPDQLOG_INFO("{} : {}", item.toStdString(), m_reply->rawHeader(item).toStdString()); QLOG_DEBUG(item + " : " + m_reply->rawHeader(item)); } /* 检查文件是否打开 */ if(m_file != nullptr) { if(m_file->isOpen()) { m_file->close(); } delete m_file; m_file = nullptr; } } else { QLOG_WARN("reply error : " + QString::number(retCode) + " " + m_reply->errorString()); } /* 检查文件是否打开 */ if(m_file != nullptr) { if(m_file->isOpen()) { m_file->close(); } delete m_file; m_file = nullptr; } /* 记得设置这个,需要手动释放 */ m_reply->deleteLater(); m_reply = nullptr; /* 设置完成标志 */ m_isFinished = true; } /* 读取数据 */ void QtHttps::do_replyReadyRead() { // QLOG_DEBUG("do_replyReadyRead"); if(m_file != nullptr) { m_file->write(m_reply->readAll()); } } /* 下载进度 */ void QtHttps::do_downloadProgress(qint64 bytesReceived, qint64 bytesTotal) { // QLOG_DEBUG("do_downloadProgress"); QLOG_DEBUG("bytesReceived / bytesTotal : " + QString::number(bytesReceived) + " / " + QString::number(bytesTotal)); } #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) void QtHttps::do_error(QNetworkReply::NetworkError code) { QLOG_WARN("error : " + QString::number(code)); } #endif /* 超时,断开reply连接,删除reply */ void QtHttps::do_timeout() { QLOG_WARN("Http timeout"); if(m_reply != nullptr) { m_reply->disconnect(); m_reply->abort(); m_reply->deleteLater(); m_reply = nullptr; } m_isFinished = true; }