1

.pro

LIBS += -LC:\Qt\Tools\OpenSSL\Win_x86\lib -llibssl
LIBS += -LC:\Qt\Tools\OpenSSL\Win_x86\lib -llibcrypto
INCLUDEPATH += C:\Qt\Tools\OpenSSL\Win_x86\include

main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.0

Window {
    visible: true
    width: 640
    height: 480

    Component.onCompleted: getPage(logResults)

    function logResults(results) {
        console.log("RESULTS: " + results)
    }

    function getPage(callback) {
        var xhttp = new XMLHttpRequest();
        var url = "https://www.google.com/"

        xhttp.onreadystatechange = function() {
            if (xhttp.readyState === 4 && xhttp.status === 200) {
                console.log("calling callback")
                callback(xhttp.responseText)
            }
        };
        xhttp.open("GET", url);
        xhttp.send();
    }
}

expected output

qml: calling callback
qml: RESULTS: <html>

actual output

qt.network.ssl: QSslSocket: cannot resolve SSL_CTX_set_ciphersuites
qt.network.ssl: QSslSocket: cannot resolve SSL_set_psk_use_session_callback
qt.network.ssl: QSslSocket: cannot call unresolved function SSL_set_psk_use_session_callback
qml: calling callback

Windows 10 64-bit OS, running MSVC2017 QML project

I ran C:\Qt\MaintenanceTool.exe to install Developer and Designer Tools > OpenSSL 1.1.1d Toolkit

I've tried following a previous tutorial and another one for MSVC2017 but no luck in resolving the errors or getting xhttp.responseText. Found out the code works in ubuntu 19.4 so it just has to be that I'm running it on my windows machine that something funky is happening with the OpenSSL. I couldn't find any resolution by googling the outputted error messages. I've read that accidentally installing openSSL to "the windows directory" can cause errors, but I've not been able to actually locate "the windows directory" in question to check if I did.

edit

From C:\Qt\Tools\OpenSSL\Win_x64\bin I copied libcrypto-1_1-x64.dll and libssl-1_1-x64.dll to my project's \debug and \release folders. This removed the qt.network.ssl errors, however I am still not getting the expected output of qml: RESULTS: <html>

Tyler M
  • 352
  • 4
  • 21
  • OpenSSL is loaded at runtime, try adding the DLLs (ssl and crypto) to the PATH or put them next to the .exe – Frank Osterfeld Dec 28 '19 at 13:24
  • I've added `libcrypto-1_1-x64.dll` and `libssl-1_1-x64.dll` to the `\debug` folder, and that removed the errors. However, the output is still not there. I'd expect `qml: calling callback` and `qml: RESULTS: `, but I only get the former – Tyler M Dec 28 '19 at 16:43
  • Maybe your get an unexpected status or readyState? – Frank Osterfeld Dec 28 '19 at 19:02
  • See, I would expect the same thing, except it's definitely getting readyState 4 and status 200 because of this line: `if (xhttp.readyState === 4 && xhttp.status === 200) {` which definitely results in this occuring: `console.log("calling callback")`, so I know it's hitting the `callback(xhttp.responseText)`, and it works in Ubuntu 18.4 and 19.4, just not in my windows 10 environment **edit** sorry, I should clarify that i did try `console.log()` on readyState and status, and both did output `4` and `200` as expected – Tyler M Dec 28 '19 at 20:51
  • I just verified in cmd that `curl https://www.google.com` returns the expected html – Tyler M Dec 28 '19 at 21:05
  • If anyone can do a fresh install of OpenSSL on windows 10, and get the above code to function properly (return ), please do provide instructions or post a link to the instructions you followed. – Tyler M Jan 07 '20 at 20:19
  • If I understood your question correctly, this is the same of https://stackoverflow.com/questions/59482223/why-does-xmlhttprequest-responsetext-not-exist with the addition in the title the installing part? – Former contributor Jan 08 '20 at 10:13
  • @Pedro Correct, that question you linked was the original question in which eyllanesc pointed out that it functioned in an ubuntu environment. I created this new question, now knowing that I was looking in the wrong direction given the new information. The previous question did help diagnose the issue, but did not resolve the symptoms – Tyler M Jan 08 '20 at 17:45

1 Answers1

1

You ran C:\Qt\MaintenanceTool.exe to install Developer and Designer Tools > OpenSSL 1.1.1d Toolkit

That is also my recommendation. The alternative is to compile OpenSSL yourself, or download a binary package from a third party provider. I have one of those packages installed at "C:\Program Files\OpenSSL-Win64\bin", and programs using Qt+=network are able to locate and load the libraries when their path is included in the PATH environment variable. The problem is that you will need to take care of the updates yourself, but the Qt packages are automatically updated with the MaintenanceTool along with Qt and Qt Creator. So pick your choice.

Anyway, even if you have another set of OpenSSL DLLs in your path, if you copy the libraries to the output directory of your executable, these libraries will be loaded instead. Two questions need to be answered here: 1) how do you copy the DLLs automatically each time they are needed?, and 2) how do you verify which DLLs are loaded when you run your program?

1) You may add the following to your project .pro:

win32 {
    CONFIG += file_copies
    CONFIG(debug, debug|release) {
        openssllibs.path = $$OUT_PWD/debug
    } else {
        openssllibs.path = $$OUT_PWD/release
    }
    contains(QMAKE_TARGET.arch, x86_64) {
        openssllibs.files = C:/Qt/Tools/OpenSSL/Win_x64/bin/libcrypto-1_1-x64.dll \
                            C:/Qt/Tools/OpenSSL/Win_x64/bin/libssl-1_1-x64.dll
    } else {
        openssllibs.files = C:/Qt/Tools/OpenSSL/Win_x86/bin/libcrypto-1_1.dll \
                            C:/Qt/Tools/OpenSSL/Win_x86/bin/libssl-1_1.dll
    }
    COPIES += openssllibs
}

That is it. Now your program will always have the latest libraries from Qt/Tools copied to the output directory of your project, without worrying if you compile in debug or release mode, or 32/64 bits, or another Qt Kit.

2) Run your program while inspecting the loaded DLLs with Process Explorer, by Mark Russinovich. To do so, in Process Explorer->View->Show lower pane, and select your running program in the upper pane. The lower pane lists all your loaded DLLs and origins. There are other similar utilities out there, like the open source Process Hacker.

Even understanding all of the above, and following exactly the recipe, your program still does not print the desired output. Please change the function logResults() in your qml like this:

function logResults(results) {
    console.log("RESULTS Length=", results.length);
    console.log("results.substr=", results.substr(0, 20)); 
}

You will get the following output:

qml: calling callback
qml: RESULTS Length= 47932
qml: results.substr= <!doctype html><html

Explanation: looks like console.log() has a limitation of about 32K in Windows (it doesn't on Linux). The document retrieved from the remote host is much larger, and this breaks the logging function. This is probably a bug in Qt (it should not fail silently like that).

Another advice for anybody coming here in the future: It is not strictly needed, but you may want to verify in your main() function that SSL is available, with something like this code:

#include <QDebug>
#include <QSslSocket>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    if (!QSslSocket::supportsSsl()) {
       qDebug() << "Sorry, OpenSSL is not supported";
       return -1;
    }
    qDebug() << "build-time OpenSSL version:" << QSslSocket::sslLibraryBuildVersionString();
    qDebug() << "run-time OpenSSL version:" << QSslSocket::sslLibraryVersionString();
    [...]
}
Former contributor
  • 2,466
  • 2
  • 10
  • 15