【问题标题】:TLS initialization failed and SSL handshake failed QtNetworkTLS 初始化失败和 SSL 握手失败 QtNetwork
【发布时间】:2020-09-14 02:29:48
【问题描述】:

我正在使用QtNetwork, QNetworkAccessManager, QNetworkRequest, QNetworkReply 设置模式对话框以下载 URL 路径中提供的任何文件。

当我开始下载时,我收到一条错误消息:Download failed: TLS initialization 或“下载失败:SSL 握手失败”,具体取决于我测试的不同机器。

这似乎是一个 OpenSSL 问题。有没有办法在不要求用户机器安装 OpenSSL 的情况下修复错误?

这是我的下载类

fAppDownloadDialog::fAppDownloadDialog()
{
  // set up UI modal dialog
  // ...
  // ...

  connect(cancelButton, SIGNAL(clicked()), this, SLOT(CancelButtonPressed()));
  connect(confirmButton, SIGNAL(clicked()), this, SLOT(ConfirmButtonPressed()));
}

void fAppDownloadDialog::CancelButtonPressed()
{
    this->close();
}

void fAppDownloadDialog::ConfirmButtonPressed()
{
    manager = new QNetworkAccessManager(this);

    QFileInfo fileInfo(url.path()); // QUrl url defined in .h
    QString fileName = fileInfo.fileName(); 

    fullPath = downloadPath + fileName; // QString fullPath, downloadPath in .h

    if (QFile::exists(fullPath)) {
        if (QMessageBox::question(this, tr("HTTP"),
                tr("There already exists a file %1. Overwrite?").arg(fileName),
                QMessageBox::Yes|QMessageBox::No, QMessageBox::No)
                == QMessageBox::No)
                return;
        QFile::remove(fullPath);
    }

    file = new QFile(fullPath); // QFile file in .h
    if (!file->open(QIODevice::WriteOnly)) {
        QMessageBox::information(this, tr("HTTP"),
                    tr("Unable to save the file %1: %2")
                    .arg(fileName).arg(file->errorString()));
        delete file;
        file = 0;
        return;
    }

    // used for progressDialog
    // This will be set true when canceled from progress dialog
    httpRequestAborted = false;

    startRequest(url);

    this->close();
}

// This will be called when download button is clicked
void fAppDownloadDialog::startRequest(QUrl url)
{
    // get() method posts a request
    // to obtain the contents of the target request
    // and returns a new QNetworkReply object
    // opened for reading which emits
    // the readyRead() signal whenever new data arrives.
    reply = manager->get(QNetworkRequest(url));

    // Whenever more data is received from the network,
    // this readyRead() signal is emitted
    connect(reply, SIGNAL(readyRead()),
            this, SLOT(httpReadyRead()));

    // This signal is emitted when the reply has finished processing.
    // After this signal is emitted,
    // there will be no more updates to the reply's data or metadata.
    connect(reply, SIGNAL(finished()),
            this, SLOT(httpDownloadFinished()));
}


void fAppDownloadDialog::httpReadyRead()
{
    // this slot gets called every time the QNetworkReply has new data.
    // We read all of its new data and write it into the file.
    // That way we use less RAM than when reading it at the finished()
    // signal of the QNetworkReply
    if (file)
        file->write(reply->readAll());
}

// When download finished or canceled, this will be called
void fAppDownloadDialog::httpDownloadFinished()
{
  // when canceled
    if (httpRequestAborted) {
        if (file) {
            file->close();
            file->remove();
            delete file;
            file = 0;
        }
        reply->deleteLater();

        return;
    }

    // download finished normally
    file->flush();
    file->close();

    // get redirection url
    QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
    if (reply->error()) {
        file->remove();
        QMessageBox::information(this, tr("HTTP"),
                                tr("Download failed: %1.")
                                .arg(reply->errorString()));
    } else if (!redirectionTarget.isNull()) {
        QUrl newUrl = url.resolved(redirectionTarget.toUrl());
        if (QMessageBox::question(this, tr("HTTP"),
                                tr("Redirect to %1 ?").arg(newUrl.toString()),
                                QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
            url = newUrl;
            reply->deleteLater();
            file->open(QIODevice::WriteOnly);
            file->resize(0);
            startRequest(url);
            return;
        }
    } else {
        QString fileName = QFileInfo(QUrl(qInputLink).path()).fileName();

    }

    reply->deleteLater();
    reply = 0;
    delete file;
    file = 0;
    manager = 0;
}

// During the download progress, it can be canceled
void fAppDownloadDialog::cancelDownload()
{
    httpRequestAborted = true;
    reply->abort();

    this->close();
}

【问题讨论】:

    标签: c++ qt ssl openssl qtnetwork


    【解决方案1】:

    您需要为您的应用程序提供 libssl 和 libcrypto 库。

    如果您在 Windows 上使用 Qt Installer 安装了 Qt,请运行 Qt 的维护者工具并安装 OpenSSL Toolkit:

    然后将 ssl 和 crypto dll 的权限复制到您的应用程序 .exe 文件所在的位置。 Dll 可以在 QTSDK 根子文件夹 Tools\OpenSSL\Win_x64\bin 中找到

    在 linux 上只需安装/编译 OpenSSL 并将 .so 链接到正确的位置

    Adding OpenSSL Support

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-28
      • 1970-01-01
      • 2021-02-02
      • 1970-01-01
      • 2019-12-16
      相关资源
      最近更新 更多