QSslSocket::supportsSsl() returns false



  • I am now making Mastodon client application and writing a program to communicate with the server.
    However, the following error occurs.

    Also, I downloaded and installed Win32 OpenSSL v1.1.0e from the following site.
    http://slproweb.com/products/Win32OpenSSL.html

    And my kit is Desktop Qt 5.9.0 MinGW 32bit.

    Help me.

    Output
    The first false is the return value of QSslSocket::supportsSsl()

    false
    qt.network.ssl: QSslSocket: cannot call unresolved function SSLv23_client_method
    qt.network.ssl: QSslSocket: cannot call unresolved function SSL_CTX_new
    qt.network.ssl: QSslSocket: cannot call unresolved function SSL_library_init
    qt.network.ssl: QSslSocket: cannot call unresolved function ERR_get_error
    qt.network.ssl: QSslSocket: cannot call unresolved function ERR_get_error
    MainWindow::replyFinished() called.
    url QUrl("https://mstdn.jp/api/v1/timelines/public?local=%22true%22")
    "Error creating SSL context ()"
    

    Source(mainwindow.cpp)

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include <QLabel>
    #include <QFrame>
    
    #include <QNetworkAccessManager>
    #include <QNetworkReply>
    
    #include <QJsonObject>
    #include <QJsonDocument>
    #include <QJsonParseError>
    #include <QJsonArray>
    
    #include <vector>
    
    #include "IconWidget.h"
    #include <QHBoxLayout>
    
    #include "defineconstants.h"
    
    #include <QUrlQuery>
    #include <QSystemTrayIcon>
    
    #include <QTextCodec>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        manager = new QNetworkAccessManager(this);
        connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
    
        ui->menuStartLocalTimeline->setEnabled(false);
        ui->menuStopLocalTimeline->setEnabled(true);
        mLocalTimelineTimer = startTimer(LOCAL_TIMELINE_UPDATE_INTERVAL);
    
        connect(ui->menuStartLocalTimeline, SIGNAL(triggered(bool)), this, SLOT(startLocalTimelineTimer()));
        connect(ui->menuStopLocalTimeline, SIGNAL(triggered(bool)), this, SLOT(stopLocalTimelineTimer()));
    
        manager->get(QNetworkRequest(QUrl("https://mstdn.jp/api/v1/timelines/public?local=\"true\"")));
    
        trayIcon = new QSystemTrayIcon(this);
    
        qDebug() << QSslSocket::supportsSsl();
    }
    
    void MainWindow::timerEvent(QTimerEvent *e)
    {
        if (e->timerId() == mLocalTimelineTimer) {
            manager->get(QNetworkRequest(QUrl("https://mstdn.jp/api/v1/timelines/public?local=\"true\"")));
        }
    }
    
    void MainWindow::startLocalTimelineTimer()
    {
        mLocalTimelineTimer = startTimer(LOCAL_TIMELINE_UPDATE_INTERVAL);
        ui->menuStartLocalTimeline->setEnabled(false);
        ui->menuStopLocalTimeline->setEnabled(true);
    }
    
    void MainWindow::stopLocalTimelineTimer()
    {
        killTimer(mLocalTimelineTimer);
        ui->menuStartLocalTimeline->setEnabled(true);
        ui->menuStopLocalTimeline->setEnabled(false);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::on_pushButton_2_clicked()
    {
        manager->get(QNetworkRequest(QUrl("https://mstdn.jp/api/v1/timelines/public?local=\"true\"")));
    }
    
    void MainWindow::replyFinished(QNetworkReply *reply)
    {
        if (DEBUG_MODE) {
            qDebug() << "MainWindow::replyFinished() called.";
            qDebug() << "url" << reply->url();
            qDebug() << reply->errorString();
        }
    
        if (reply->url().toString() == "https://mstdn.jp/api/v1/statuses") {
            return;
        }
    
        if (reply->error() == QNetworkReply::NoError) {
            QByteArray byteArray = reply->readAll();
            //ui->textEdit->setPlainText(byteArray);
    
            QJsonParseError error;
            QJsonDocument jsonDocument = QJsonDocument::fromJson(byteArray, &error);
            qDebug() << error.errorString();
    
            /*
            qDebug() << "Is Object? " << jsonDocument.isObject();
            qDebug() << "Is Array? " << jsonDocument.isArray();
            */
    
            QJsonArray jsonArray = jsonDocument.array();
            //qDebug() << jsonArray.size();
            QStringList keys = jsonArray[0].toObject().keys();
            qDebug() << keys;
            foreach (QString key, keys) {
                qDebug() << "key =" << key;
                QString value = jsonArray[0].toObject().value(key).toString();
                qDebug() << "value =" << value;
            }
    
            //std::vector<QHBoxLayout*> tootLayouts;
            static QVBoxLayout *timelineLayout = new QVBoxLayout();
            //for (int i=0; i<jsonArray.size(); i++) {
            for (int i=jsonArray.size()-1; i>=0; i--) {
                if (i == 0) {
                    QString *title = new QString("タイトルは長いんだよー");
                    trayIcon->show();
                    trayIcon->showMessage(*title, jsonArray[i].toObject().value("content").toString());
                }
    
                QFrame *tootFrame = new QFrame();
                tootFrame->setObjectName("tootFrame");
                tootFrame->setStyleSheet("#tootFrame { border: 1px solid; background-color: white; }");
                //tootFrame->maximumWidth = ui->scrollAreaWidgetContents->width();
                //tootFrame->setMaximumWidth(ui->scrollAreaWidgetContents->width());
                QHBoxLayout *tootLayout = new QHBoxLayout();
    
                QVBoxLayout *tootContentsLayout = new QVBoxLayout();
                QLabel *name = new QLabel(jsonArray[i].toObject().value("account").toObject().value("display_name").toString(), this);
    
                QString tootHtml = jsonArray[i].toObject().value("content").toString();
                QRegExp br("<br />");
                tootHtml.replace(br, "\n");
                //QRegExp tag("<[^>]*>");
                //tootHtml.remove(tag);
                QLabel *toot = new QLabel(tootHtml);
                toot->setWordWrap(true);
                toot->setTextFormat(Qt::PlainText);
    
                QUrl *iconUrl = new QUrl(jsonArray[i].toObject().value("account").toObject().value("avatar").toString());
                //QUrl *iconUrl = new QUrl("https://media.mstdn.jp/images/accounts/avatars/000/006/953/original/b0a6986188b3fdf7.png");
                IconWidget *iconWidget = new IconWidget(iconUrl, nullptr);
                tootLayout->addWidget(iconWidget);
    
                tootContentsLayout->addWidget(name);
                tootContentsLayout->addWidget(toot);
                tootLayout->addLayout(tootContentsLayout);
                tootFrame->setLayout(tootLayout);
    
                //timelineLayout->addLayout(tootLayout);
                //timelineLayout->addWidget(tootFrame);
                timelineLayout->insertWidget(0, tootFrame);
            }
            //ui->tootList->setLayout(timelineLayout);
            //ui->scrollAreaWidgetContents->setLayout(timelineLayout);
            ui->localTimelineContents->setLayout(timelineLayout);
        }
    }
    
    void MainWindow::on_tootButton_clicked()
    {
        QUrlQuery params;
        QNetworkRequest req(QUrl("https://mstdn.jp/api/v1/statuses"));
    
        QFile file("your_usercred.txt");
        if (!file.open(QIODevice::ReadOnly)) {
            if (DEBUG_MODE) {
                qDebug() << "file could not open.";
            }
        }
        QTextStream in(&file);
        QString usercred = in.readLine();
    
        QString header_text = "Bearer " + usercred;
        req.setRawHeader("Authorization", header_text.toUtf8());
        params.addQueryItem("visibility", "");
        params.addQueryItem("status", ui->tootText->toPlainText());
    
        manager->post(req, params.toString(QUrl::FullyEncoded).toUtf8());
    }
    
    

    Source(mastodon-client.pro)

    #-------------------------------------------------
    #
    # Project created by QtCreator 2017-05-01T17:33:54
    #
    #-------------------------------------------------
    
    QT       += core gui network
    
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET = mastodon-client
    TEMPLATE = app
    
    # The following define makes your compiler emit warnings if you use
    # any feature of Qt which as been marked as deprecated (the exact warnings
    # depend on your compiler). Please consult the documentation of the
    # deprecated API in order to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS
    
    # You can also make your code fail to compile if you use deprecated APIs.
    # In order to do so, uncomment the following line.
    # You can also select to disable deprecated APIs only up to a certain version of Qt.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    
    SOURCES += main.cpp\
            mainwindow.cpp \
        IconWidget.cpp
    
    HEADERS  += mainwindow.h \
        defineconstants.h \
        IconWidget.h
    
    FORMS    += mainwindow.ui
    
    #LIBS += -LC:/OpenSSL-Win32/lib -lubsec
    #LIBS += -LC:/OpenSSL-Win32/lib -llibssl -llibcrypto
    LIBS += -LC:/OpenSSL-Win32/lib/MinGW -llibssl-1_1
    LIBS += -LC:/OpenSSL-Win32/lib/MinGW -llibcrypto-1_1
    
    INCLUDEPATH += C:/OpenSSL-Win32/include
    
    
    

  • Lifetime Qt Champion

    Hi,

    OpenSSL 1.1 broke API compatibility. AFAIK, there's currently a patch in progress to implement a backend that support it in Qt.

    In between, you should use the latest pre-1.1 version of OpenSSL.



  • I downloaded and installed Win32 OpenSSL v1.0.2k from that site.
    Then it was done.
    Thank you for answering.



  • Just a side note, the official OpenSSL source download is this link: https://www.openssl.org/source/



  • How does Qt find SSL libraries that it needs? I've seen OpenSSL dlls with different names and they are sometimes 1 or 2 in number. What is the library's import logic here?


  • Lifetime Qt Champion

    By default Qt dlopen the dlls and uses a set of common known folders and library names.

    If you want all the gory details: qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.