Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for WebAssembly
  4. Receiving QNetworkReply::ProtocolFailure to GET request
QtWS25 Last Chance

Receiving QNetworkReply::ProtocolFailure to GET request

Scheduled Pinned Locked Moved Solved Qt for WebAssembly
2 Posts 1 Posters 187 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    leonidh
    wrote on last edited by leonidh
    #1

    Hello Everyone.
    I apologize for the lengthy post. I am attempting to create a remote program that will communicate with a main program running on SBC. The remote needs to run on a browser. The remote has a UI to send control information as well as to request updates from the main application (same as operating an oscilloscope through a Web interface).

    When the remote is compiled as a desktop application, I can receive the data from the main application properly. However, when I compile the remote application using Webassembly, I get QNetworkReply::ProtocolFailure every time I receive a reply from my main app.
    Monitoring the HTTP communication, using Wireshark, I see that the GET request and reply are sent properly.

    I create two small server-client applications that can easily reproduce the problem. The client had QTextEdit Widget to output debug information.
    My test server:
    main.cpp:

    #include "mainwindow.h"
    #include <QApplication>
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        return a.exec();
    }
    

    mainwindow.h

    ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QTcpServer>
    #include <QHttpServer>
    
    QT_BEGIN_NAMESPACE
    namespace Ui {
    class MainWindow;
    }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
    
        int const NETWORK_PORT_SERVER   {12345};
        int const NETWORK_PORT_CLIENT   {23456};
    
        QTcpServer *tcpServer;
        QHttpServer hServer;
    };
    #endif // MAINWINDOW_H
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        tcpServer = new QTcpServer(this);
        tcpServer->listen(QHostAddress("192.168.86.48"), NETWORK_PORT_SERVER);
        hServer.bind(tcpServer);
    
        hServer.route("/", QHttpServerRequest::Method::Options, []()
        {
            QHttpServerResponse res(QHttpServerResponse::StatusCode::NoContent);
            res.addHeader("Allow", "*");
            res.addHeader("Access-Control-Allow-Origin", "*");
            res.addHeader("Access-Control-Allow-Language", "*");
            res.addHeader("Access-Control-Allow-Encoding", "*");
            res.addHeader("Access-Control-Allow-Method", "*");
            res.addHeader("Access-Control-Allow-Headers", "*");
            return res;
        });
    
        hServer.route("/", QHttpServerRequest::Method::Get, []()
        {
            QString testAnswer = "TEST REPLY";
            QHttpServerResponse res(testAnswer, QHttpServerResponse::StatusCode::Ok);
            return res;
        });
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    

    My test client:
    main.cpp:

    #include "mainwindow.h"
    #include <QApplication>
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        return a.exec();
    }
    

    mainwindow.h:

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QNetworkAccessManager>
    #include <QNetworkReply>
    #include <QtHttpServer>
    
    QT_BEGIN_NAMESPACE
    namespace Ui {
    class MainWindow;
    }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
    
        int const NETWORK_PORT_SERVER   {12345};
        int const NETWORK_PORT_CLIENT   {23456};
    
        QNetworkAccessManager * manager;
        QNetworkRequest req;
    
    private slots:
        void serverDataReceived(QNetworkReply *);
    };
    #endif // MAINWINDOW_H
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        ui->debugInfo->append("Program Started");
    
        manager = new QNetworkAccessManager(this);
        connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(serverDataReceived(QNetworkReply*)));
        QUrl contAdress(QString("http://192.168.0.84:%1").arg(NETWORK_PORT_SERVER));
        req.setUrl(contAdress);
        manager->get(req, "Test");
    }
    
    void MainWindow::serverDataReceived(QNetworkReply * rep)
    {
        ui->debugInfo->append("Reply Received");
        QVariant status = rep->attribute(QNetworkRequest::HttpStatusCodeAttribute);
        ui->debugInfo->append(status.toString());
        ui->debugInfo->append(QString("Network Error: %1").arg(static_cast<int>(rep->error())));
        ui->debugInfo->append(rep->readAll());
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    

    Does anyone know why this happens and how to resolve this?

    1 Reply Last reply
    0
    • L Offline
      L Offline
      leonidh
      wrote on last edited by
      #2

      The solution to the problem is to add the header res.addHeader("Access-Control-Allow-Origin", "*"); to the HTTP server;

      hServer.route("/", QHttpServerRequest::Method::Get, []()
          {
              QString testAnswer = "TEST REPLY";
              res.addHeader("Access-Control-Allow-Origin", "*");  // Added line
              QHttpServerResponse res(testAnswer, QHttpServerResponse::StatusCode::Ok);
              return res;
          });
      

      After adding this line, the browser forwarded the reply to my application.

      1 Reply Last reply
      0
      • L leonidh has marked this topic as solved on

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved