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