Сбой инициализации TLS и сбой подтверждения SSL QtNetwork - PullRequest
0 голосов
/ 27 мая 2020

Я использую 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();
}

1 Ответ

1 голос
/ 27 мая 2020

Вам необходимо предоставить библиотеки libssl и libcrypto для вашего приложения.

Если вы установили Qt с Qt Installer на Windows, запустите Qt's Maintainer Tools и установите OpenSSL Toolkit:

enter image description here

затем скопируйте права ssl и crypto dll в то место, где размещен файл вашего приложения .exe. Dll можно найти в QTSDK root подпапке Tools \ OpenSSL \ Win_x64 \ bin

enter image description here

На linux просто установите / скомпилируйте OpenSSL и сделайте ссылку. так что в нужное место

Добавление поддержки OpenSSL

...