Solved 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.htmlAnd 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
-
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?
-
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