2022-02-04 20:40:43 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								///////////////////////////////////////////////////////////////////////////////////
							 | 
						
					
						
							
								
									
										
										
										
											2023-11-18 13:12:18 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// Copyright (C) 2022-2023 Jon Beniston, M7RCE <jon@beniston.com>                //
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//                                                                               //
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// This program is free software; you can redistribute it and/or modify          //
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// it under the terms of the GNU General Public License as published by          //
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// the Free Software Foundation as version 3 of the License, or                  //
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// (at your option) any later version.                                           //
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//                                                                               //
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// This program is distributed in the hope that it will be useful,               //
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// but WITHOUT ANY WARRANTY; without even the implied warranty of                //
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// GNU General Public License V3 for more details.                               //
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//                                                                               //
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// You should have received a copy of the GNU General Public License             //
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// along with this program. If not, see <http://www.gnu.org/licenses/>.          //
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								///////////////////////////////////////////////////////////////////////////////////
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												Fix memleaks found with AddressSanitizer/LeakSanitizer
Fixes:
Direct leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x7efeb72f46b8 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x7efe834b65a2 in WebServer::WebServer(unsigned short&, QObject*) sdrangel/plugins/feature/map/webserver.cpp:34
    #2 0x7efe834bc342 in MapGUI::MapGUI(PluginAPI*, FeatureUISet*, Feature*, QWidget*) sdrangel/plugins/feature/map/mapgui.cpp:265
    #3 0x7efe835372f4 in MapGUI::create(PluginAPI*, FeatureUISet*, Feature*) sdrangel/plugins/feature/map/mapgui.cpp:66
    #4 0x7efe834b5471 in MapPlugin::createFeatureGUI(FeatureUISet*, Feature*) const sdrangel/plugins/feature/map/mapplugin.cpp:72
    #5 0x7efeb6b416c2 in FeatureUISet::loadFeatureSetSettings(FeatureSetPreset const*, PluginAPI*, WebAPIAdapterInterface*, QList<Workspace*>*, Workspace*) sdrangel/sdrgui/feature/featureuiset.cpp:185
    #6 0x7efeb67e9b41 in MainWindow::loadConfiguration(Configuration const*, bool) sdrangel/sdrgui/mainwindow.cpp:1503
    #7 0x7efeb6730e3e in MainWindow::MainWindow(qtwebapp::LoggerWithFile*, MainParser const&, QWidget*) sdrangel/sdrgui/mainwindow.cpp:257
    #8 0x557281218bad in runQtApplication sdrangel/app/main.cpp:196
    #9 0x5572812194a3 in main sdrangel/app/main.cpp:248
    #10 0x7efeb10456c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
and others
											
										 
										
											2024-05-01 15:22:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <QtAlgorithms>
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <QResource>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <QFile>
							 | 
						
					
						
							
								
									
										
										
										
											2023-08-06 09:08:53 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <QRegularExpression>
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <QDebug>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include "webserver.h"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// port - port to listen on / is listening on. Use 0 for any free port.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								WebServer::WebServer(quint16 &port, QObject* parent) :
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    QTcpServer(parent),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    m_defaultMimeType("application/octet-stream")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    listen(QHostAddress::Any, port);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    port = serverPort();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    qDebug() << "WebServer on port " << port;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    m_mimeTypes.insert(".html", new MimeType("text/html; charset=\"utf-8\"", false));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    m_mimeTypes.insert(".png", new MimeType("image/png"));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    m_mimeTypes.insert(".glb", new MimeType("model/gltf-binary"));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    m_mimeTypes.insert(".glbe", new MimeType("model/gltf-binary"));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    m_mimeTypes.insert(".js", new MimeType("text/javascript"));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    m_mimeTypes.insert(".css", new MimeType("text/css"));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    m_mimeTypes.insert(".json", new MimeType("application/json"));
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-20 17:41:11 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    m_mimeTypes.insert(".geojson", new MimeType("application/geo+json"));
							 | 
						
					
						
							
								
									
										
										
										
											2025-06-09 10:38:53 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    m_mimeTypes.insert(".wasm", new MimeType("application/wasm"));
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												Fix memleaks found with AddressSanitizer/LeakSanitizer
Fixes:
Direct leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x7efeb72f46b8 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x7efe834b65a2 in WebServer::WebServer(unsigned short&, QObject*) sdrangel/plugins/feature/map/webserver.cpp:34
    #2 0x7efe834bc342 in MapGUI::MapGUI(PluginAPI*, FeatureUISet*, Feature*, QWidget*) sdrangel/plugins/feature/map/mapgui.cpp:265
    #3 0x7efe835372f4 in MapGUI::create(PluginAPI*, FeatureUISet*, Feature*) sdrangel/plugins/feature/map/mapgui.cpp:66
    #4 0x7efe834b5471 in MapPlugin::createFeatureGUI(FeatureUISet*, Feature*) const sdrangel/plugins/feature/map/mapplugin.cpp:72
    #5 0x7efeb6b416c2 in FeatureUISet::loadFeatureSetSettings(FeatureSetPreset const*, PluginAPI*, WebAPIAdapterInterface*, QList<Workspace*>*, Workspace*) sdrangel/sdrgui/feature/featureuiset.cpp:185
    #6 0x7efeb67e9b41 in MainWindow::loadConfiguration(Configuration const*, bool) sdrangel/sdrgui/mainwindow.cpp:1503
    #7 0x7efeb6730e3e in MainWindow::MainWindow(qtwebapp::LoggerWithFile*, MainParser const&, QWidget*) sdrangel/sdrgui/mainwindow.cpp:257
    #8 0x557281218bad in runQtApplication sdrangel/app/main.cpp:196
    #9 0x5572812194a3 in main sdrangel/app/main.cpp:248
    #10 0x7efeb10456c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
and others
											
										 
										
											2024-05-01 15:22:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								WebServer::~WebServer()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												Fix memleaks found with AddressSanitizer/LeakSanitizer
Found with:
ASAN_OPTIONS="detect_odr_violation=1,strip_path_prefix=$(pwd)/" build/sdrangel
Fixes:
Direct leak of 8 byte(s) in 1 object(s) allocated from:
    #0 0x7efeb72f46b8 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x7efe83515718 in WebServer::addSubstitution(QString, QString, QString) sdrangel/plugins/feature/map/webserver.cpp:84
    #2 0x7efe83559c9e in MapGUI::applyMap3DSettings(bool) sdrangel/plugins/feature/map/mapgui.cpp:1789
    #3 0x7efe8355e483 in MapGUI::displaySettings() sdrangel/plugins/feature/map/mapgui.cpp:1964
    #4 0x7efe834be0f6 in MapGUI::MapGUI(PluginAPI*, FeatureUISet*, Feature*, QWidget*) sdrangel/plugins/feature/map/mapgui.cpp:376
    #5 0x7efe835372f4 in MapGUI::create(PluginAPI*, FeatureUISet*, Feature*) sdrangel/plugins/feature/map/mapgui.cpp:66
    #6 0x7efe834b5471 in MapPlugin::createFeatureGUI(FeatureUISet*, Feature*) const sdrangel/plugins/feature/map/mapplugin.cpp:72
    #7 0x7efeb6b416c2 in FeatureUISet::loadFeatureSetSettings(FeatureSetPreset const*, PluginAPI*, WebAPIAdapterInterface*, QList<Workspace*>*, Workspace*) sdrangel/sdrgui/feature/featureuiset.cpp:185
    #8 0x7efeb67e9b41 in MainWindow::loadConfiguration(Configuration const*, bool) sdrangel/sdrgui/mainwindow.cpp:1503
    #9 0x7efeb6730e3e in MainWindow::MainWindow(qtwebapp::LoggerWithFile*, MainParser const&, QWidget*) sdrangel/sdrgui/mainwindow.cpp:257
    #10 0x557281218bad in runQtApplication sdrangel/app/main.cpp:196
    #11 0x5572812194a3 in main sdrangel/app/main.cpp:248
    #12 0x7efeb10456c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
											
										 
										
											2024-05-01 15:40:01 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    qDeleteAll(m_substitutions);
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												Fix memleaks found with AddressSanitizer/LeakSanitizer
Fixes:
Direct leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x7efeb72f46b8 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x7efe834b65a2 in WebServer::WebServer(unsigned short&, QObject*) sdrangel/plugins/feature/map/webserver.cpp:34
    #2 0x7efe834bc342 in MapGUI::MapGUI(PluginAPI*, FeatureUISet*, Feature*, QWidget*) sdrangel/plugins/feature/map/mapgui.cpp:265
    #3 0x7efe835372f4 in MapGUI::create(PluginAPI*, FeatureUISet*, Feature*) sdrangel/plugins/feature/map/mapgui.cpp:66
    #4 0x7efe834b5471 in MapPlugin::createFeatureGUI(FeatureUISet*, Feature*) const sdrangel/plugins/feature/map/mapplugin.cpp:72
    #5 0x7efeb6b416c2 in FeatureUISet::loadFeatureSetSettings(FeatureSetPreset const*, PluginAPI*, WebAPIAdapterInterface*, QList<Workspace*>*, Workspace*) sdrangel/sdrgui/feature/featureuiset.cpp:185
    #6 0x7efeb67e9b41 in MainWindow::loadConfiguration(Configuration const*, bool) sdrangel/sdrgui/mainwindow.cpp:1503
    #7 0x7efeb6730e3e in MainWindow::MainWindow(qtwebapp::LoggerWithFile*, MainParser const&, QWidget*) sdrangel/sdrgui/mainwindow.cpp:257
    #8 0x557281218bad in runQtApplication sdrangel/app/main.cpp:196
    #9 0x5572812194a3 in main sdrangel/app/main.cpp:248
    #10 0x7efeb10456c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
and others
											
										 
										
											2024-05-01 15:22:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    qDeleteAll(m_mimeTypes);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void WebServer::incomingConnection(qintptr socket)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    QTcpSocket* s = new QTcpSocket(this);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    connect(s, SIGNAL(readyRead()), this, SLOT(readClient()));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    connect(s, SIGNAL(disconnected()), this, SLOT(discardClient()));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    s->setSocketDescriptor(socket);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    //addPendingConnection(socket);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Don't include leading or trailing / in from
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void WebServer::addPathSubstitution(const QString &from, const QString &to)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2024-04-05 10:41:24 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    //qDebug() << "Mapping " << from << " to " << to;
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    m_pathSubstitutions.insert(from, to);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void WebServer::addSubstitution(QString path, QString from, QString to)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    Substitution *s = new Substitution(from, to);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (m_substitutions.contains(path))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        QList<Substitution *> *list = m_substitutions.value(path);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        QMutableListIterator<Substitution *> i(*list);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        while (i.hasNext()) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            Substitution *sub = i.next();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if (sub->m_from == from) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                i.remove();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                delete sub;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        list->append(s);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        QList<Substitution *> *list = new QList<Substitution *>();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        list->append(s);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        m_substitutions.insert(path, list);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								QString WebServer::substitute(QString path, QString html)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    QList<Substitution *> *list = m_substitutions.value(path);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    for (const auto s : *list) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        html = html.replace(s->m_from, s->m_to);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return html;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-20 17:41:11 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void WebServer::addFile(const QString &path, const QByteArray &data)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    m_files.insert(path, data);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void WebServer::sendFile(QTcpSocket* socket, const QByteArray &data, MimeType *mimeType, const QString &path)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2024-02-27 15:40:06 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    QString header = QString("HTTP/1.0 200 Ok\r\nContent-Type: %1\r\nAccess-Control-Allow-Headers: *\r\nAccess-Control-Allow-Methods: *\r\nAccess-Control-Allow-Origin: *\r\n\r\n").arg(mimeType->m_type);
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (mimeType->m_binary)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        // Send file as binary
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        QByteArray headerUtf8 = header.toUtf8();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        socket->write(headerUtf8);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        socket->write(data);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        // Send file as text
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        QString html = QString(data);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        // Make any substitutions in the content of the file
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if (m_substitutions.contains(path)) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            html = substitute(path, html);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        QTextStream os(socket);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        os.setAutoDetectUnicode(true);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        os << header << html;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void WebServer::readClient()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    QTcpSocket* socket = (QTcpSocket*)sender();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (socket->canReadLine())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        QString line = socket->readLine();
							 | 
						
					
						
							
								
									
										
										
										
											2024-04-05 10:41:24 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        //qDebug() << "WebServer HTTP Request: " << line;
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2023-08-06 09:08:53 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        QStringList tokens = QString(line).split(QRegularExpression("[ \r\n][ \r\n]*"));
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if (tokens[0] == "GET")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // Get file type from extension
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            QString path = tokens[1];
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            MimeType *mimeType = &m_defaultMimeType;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            int extensionIdx = path.lastIndexOf(".");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if (extensionIdx != -1) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                QString extension = path.mid(extensionIdx);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if (m_mimeTypes.contains(extension)) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                     mimeType = m_mimeTypes[extension];
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // Try mapping path
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            QStringList dirs = path.split('/');
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if ((dirs.length() >= 2) && m_pathSubstitutions.contains(dirs[1]))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                dirs[1] = m_pathSubstitutions.value(dirs[1]);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                dirs.removeFirst();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                QString newPath = dirs.join('/');
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                //qDebug() << "Mapping " << path << " to " << newPath;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                path = newPath;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // See if we can find the file in our resources
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            QResource res(path);
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-04 21:33:04 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if (res.isValid() && (res.uncompressedSize() > 0))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                QByteArray data = res.uncompressedData();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                sendFile(socket, data, mimeType, path);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-04 21:33:04 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if (res.isValid() && (res.size() > 0))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                QByteArray data = QByteArray::fromRawData((const char *)res.data(), res.size());
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-09 16:41:40 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if (res.isCompressed()) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    data = qUncompress(data);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-04 21:33:04 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                sendFile(socket, data, mimeType, path);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-20 17:41:11 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            else if (m_files.contains(path))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                // Path is a file held in memory
							 | 
						
					
						
							
								
									
										
										
										
											2025-06-09 10:38:53 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                sendFile(socket, m_files.value(path), mimeType, path);
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-20 17:41:11 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-20 17:41:11 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                // See if we can find a file on disk
							 | 
						
					
						
							
								
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                QFile file(path);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if (file.open(QIODevice::ReadOnly))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    QByteArray data = file.readAll();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    if (path.endsWith(".glbe")) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        for (int i = 0; i < data.size(); i++) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            data[i] = data[i] ^ 0x55;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    sendFile(socket, data, mimeType, path);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    qDebug() << "WebServer " << path << " not found";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    // File not found
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    QTextStream os(socket);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    os.setAutoDetectUnicode(true);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    os << "HTTP/1.0 404 Not Found\r\n"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        "Content-Type: text/html; charset=\"utf-8\"\r\n"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        "\r\n"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        "<html>\n"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        "<body>\n"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        "<h1>404 Not Found</h1>\n"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        "</body>\n"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        "</html>\n";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            socket->close();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if (socket->state() == QTcpSocket::UnconnectedState) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                delete socket;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void WebServer::discardClient()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    QTcpSocket* socket = (QTcpSocket*)sender();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    socket->deleteLater();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 |