Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Cannot get data from HTTP request



  • Hello,

    this is my code:

    QSslConfiguration config = QSslConfiguration::defaultConfiguration();
    config.setProtocol(QSsl::TlsV1_2);
    QNetworkAccessManager *manager = new QNetworkAccessManager();
    QNetworkRequest request;
    QNetworkReply *reply = NULL;
        
    request.setHeader(QNetworkRequest::ServerHeader, "application/json");
    request.setSslConfiguration(config);
    request.setUrl(QUrl("https://www.archlinux.org/packages/search/json/?q=dolphin"));
    
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
    

    And this is callback function for reply:

    void Manager::replyFinished(QNetworkReply *reply)
    {
        qDebug() << reply->readAll();
    
        QString test = reply->readAll();
    }
    

    Problem is that, if I debug it I don't jump into replyFinished function, it looks like connect doesn't call that function, can you help me, where is problem?

    Thank you


  • Lifetime Qt Champion

    Hi,

    You're not connecting any of the error related signals. You should add that to your code.



  • @t0msk hi
    are you posting the request?


  • Lifetime Qt Champion

    Hi
    I dont see any
    manager->get(request);
    or similar to actually run the Request.

    Also, you are using HTTPS so did you install the
    OpenSSL 1.0.2 and put it in a PATH that your app can find?
    (or next to the app in the build folder)

    Note:
    5.12.4 Released with support for OpenSSL 1.1.1
    https://www.qt.io/blog/2019/06/17/qt-5-12-4-released-support-openssl-1-1-1

    Try to add
    qDebug() << QSslSocket::supportsSsl();
    qDebug() << QSslSocket::sslLibraryBuildVersionString();

    and see if it say TRUE or FALSE
    and it will also list the openSSL Lib it supports.
    like
    "OpenSSL 1.1.1b 26 Feb 2019"



  • I changed code like this:

        QSslConfiguration config = QSslConfiguration::defaultConfiguration();
        config.setProtocol(QSsl::TlsV1_2);
        QNetworkAccessManager *manager = new QNetworkAccessManager();
        QNetworkRequest request;
        QNetworkReply *reply = NULL;
    
        request.setHeader(QNetworkRequest::ServerHeader, "application/json");
        request.setSslConfiguration(config);
        request.setUrl(QUrl("https://www.archlinux.org/packages/search/json/?q=dolphin"));
    
        manager->get(request);
    
        connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
    
        connect(manager, SIGNAL(error(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
    
        connect(manager, SIGNAL(sslErrors(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
    

    And still during debugging I dont stop in replyFinsihed function.


  • Lifetime Qt Champion

    You should move the Qt 5 new syntax. It would have show you that error is not part of QNetworkAccessManager and that the signature of ssErrors is wrong.



  • @SGaist said in Cannot get data from HTTP request:

    You should move the Qt 5 new syntax. It would have show you that error is not part of QNetworkAccessManager and that the signature of ssErrors is wrong.

    Which syntax? I use Qt5.

    I tried even:

        QNetworkReply *reply = manager->get(request);
    
        connect(reply, SIGNAL(finished(reply)), this, SLOT(replyFinished(reply)));
    
        connect(reply, SIGNAL(error(reply)), this, SLOT(replyFinished(reply)));
    
        connect(reply, SIGNAL(sslErrors(reply)), this, SLOT(replyFinished(reply)));
    

  • Lifetime Qt Champion

    @t0msk
    Hi
    The SIGNAL and SLOT macros is the "old way"
    its explained here
    https://wiki.qt.io/New_Signal_Slot_Syntax

    The main benefit is that it gives errors at compile time if its not correct.
    The SIGNAL and SLOT will eat most things and not complain but simply
    fail to work at runtime.



  • So I tried this:

    connect(
            reply, &reply::finished,
            this, &Manager::replyFinished
        );
    

    And I get:

    error: 'reply' is not a class, namespace, or enumeration
    

    I quite don't understand what to put into &reply yet :)


  • Lifetime Qt Champion

    The name of the class containing the signal, same goes for the last parameter, it's the name of the class containing the slot.



  • @SGaist

    Changed it to this:

    connect(
            reply, &QNetworkReply::finished,
            this, &Manager::replyFinished
        );
    

    And I get:

    /usr/include/qt/QtCore/qobject.h:243: error: static assertion failed: The slot requires more arguments than the signal provides.
      243 |         Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
          |         ^~~~~~~~~~~~~~~~~
    

  • Lifetime Qt Champion

    @t0msk said in Cannot get data from HTTP request:

    QNetworkReply::finished,

    Well you are mixing the classes/signals.
    The reply's signals is
    https://doc.qt.io/qt-5/qnetworkreply.html#finished
    and have no QNetworkReply* parameter.

    so i think you mean

    connect(
            Manager, &QNetworkAccessManager::finished,
            this, &Manager::replyFinished
        );
    


  • @mrjj said in Cannot get data from HTTP request:

    @t0msk said in Cannot get data from HTTP request:

    QNetworkReply::finished,

    Well you are mixing the classes.
    The reply signals is
    https://doc.qt.io/qt-5/qnetworkreply.html#finished
    and have no QNetworkReply* parameter.

    so i think you mean

    connect(
            Manager, &QNetworkAccessManager::finished,
            this, &Manager::replyFinished
        );
    

    Thank you,
    so now I have:

        QSslConfiguration config = QSslConfiguration::defaultConfiguration();
        config.setProtocol(QSsl::TlsV1_2);
        QNetworkAccessManager *manager = new QNetworkAccessManager();
        QNetworkRequest request;
    
    
        request.setHeader(QNetworkRequest::ServerHeader, "application/json");
        request.setSslConfiguration(config);
        request.setUrl(QUrl("https://www.archlinux.org/packages/search/json/?q=dolphin"));
    
        QNetworkReply *reply = manager->get(request);
    
        connect(
            manager, &QNetworkAccessManager::finished,
            this, &Manager::replyFinished
        );
    
        connect(
            manager, &QNetworkAccessManager::sslErrors,
            this, &Manager::replyFinished
        );
    
    void Manager::replyFinished(QNetworkReply *reply)
    {
        qDebug() << reply->readAll();
    
        QString ha = reply->readAll();
    
        QString he;
    }
    

    Still no output and no error :/


  • Lifetime Qt Champion

    Hi
    Its a bit odd to connect all to the same slot but lets leave it for now.

    now its time to
    check your openSSL support !

    what does
    qDebug() << "i can use HTTPS:" << QSslSocket::supportsSsl();
    qDebug() << "version" << QSslSocket::sslLibraryBuildVersionString();

    say ?



  • @mrjj
    It says:

    i can use HTTPS: true
    version "OpenSSL 1.1.1c  28 May 2019"
    

  • Lifetime Qt Champion

    What version of Qt are you using ?

    One more thing: do these connections prior to calling get.



  • @SGaist Qt version is 5.13.1



  • So where can be problem? :/


  • Lifetime Qt Champion

    Did you move the connection statements as I suggested ?



  • @SGaist I dont know what do you mean



  • @t0msk

    @SGaist wrote

    Did you move the connection statements as I suggested ?

    In your code you show:

        QNetworkReply *reply = manager->get(request);
    
        connect(
            manager, &QNetworkAccessManager::finished,
            this, &Manager::replyFinished
        );
    
        connect(
            manager, &QNetworkAccessManager::sslErrors,
            this, &Manager::replyFinished
        );
    

    You are calling the manager->get(request) before you have connected the signals/slots on manager, which may/will be too late. He is asking you to change over anything like that to

        connect(
            manager, &QNetworkAccessManager::finished,
            this, &Manager::replyFinished
        );
    
        connect(
            manager, &QNetworkAccessManager::sslErrors,
            this, &Manager::replyFinished
        );
    
        QNetworkReply *reply = manager->get(request);
    

    so you move the connection statements to before the get(request). So we get to see finished or quite possibly errors from the request. In general, you need to set up signals/slots as soon as you create an object (manager here), before you call anything which could raise a signal.



  • Changed it like:

        connect(
            manager, &QNetworkAccessManager::finished,
            this, &Manager::replyFinished
        );
    
        connect(
            manager, &QNetworkAccessManager::sslErrors,
            this, &Manager::replyFinished
        );
    
        QNetworkReply *reply = manager->get(request);
    

    and still doesn't work, no error, no reply.


Log in to reply