mirror of
https://github.com/YACReader/yacreader
synced 2025-05-28 03:10:27 -04:00
Update QtWebApp to 1.8.3
nullptr redefinition for old __cplusplus versions has been removed, the rest is vanilla
This commit is contained in:
parent
baccb1a21b
commit
986450eb20
21
third_party/QtWebApp/CHANGELOG.txt
vendored
21
third_party/QtWebApp/CHANGELOG.txt
vendored
@ -1,6 +1,27 @@
|
||||
Dont forget to update the release number also in
|
||||
QtWebApp.pro and httpserver/httpglobal.cpp.
|
||||
|
||||
1.8.3
|
||||
21.03.2021
|
||||
The minLevel for logging can now be configured as string:
|
||||
DEBUG/ALL=0, INFO=4, WARNING=1, ERROR/CRITICAL=2, FATAL=3
|
||||
Info messages are now positioned between DEBUG and WARNING.
|
||||
I also added an example for HTTP Basic authorization.
|
||||
|
||||
1.8.2
|
||||
08.03.2021
|
||||
Fix threadId not printed in log file.
|
||||
|
||||
1.8.1
|
||||
07.02.2021
|
||||
Add Cookie attribute "SameSite".
|
||||
SessionStore does now emit a signal when a session expires.
|
||||
|
||||
1.8.0
|
||||
06.02.2021
|
||||
Fix compatibility issues to Qt 4.7 and 6.0.
|
||||
Removed qtservice, use the Non-Sucking Service Manager (https://nssm.cc/) instead.
|
||||
|
||||
1.7.11
|
||||
28.12.2019
|
||||
Fix Http Headers are not properly received if the two characters of
|
||||
|
15
third_party/QtWebApp/README.txt
vendored
15
third_party/QtWebApp/README.txt
vendored
@ -1,25 +1,22 @@
|
||||
QtWebAppLib is a library to develop server-side web applications in C++.
|
||||
It requires the Qt SDK version 4.7.0 or newer.
|
||||
Works with Qt SDK version 4.7 until at least 6.0
|
||||
|
||||
License: LGPL v3.
|
||||
|
||||
Project homepage: http://stefanfrings.de/qtwebapp/index.html
|
||||
Project homepage: http://stefanfrings.de/qtwebapp/index-en.html
|
||||
Tutorial: http://stefanfrings.de/qtwebapp/tutorial/index.html
|
||||
API doc: http://stefanfrings.de/qtwebapp/api/index.html
|
||||
|
||||
There are three demo applications that demonstrate how to use the library.
|
||||
In Qt 6.0 or newer, you must install the optional "core5compat" component.
|
||||
This package contains the QTextCodec class which is needed to decode template files.
|
||||
It supports a lot more encodings, for example ISO-8859-15 with the EUR symbol.
|
||||
|
||||
Demo1 shows how to use the library by including the source code into your
|
||||
project. This does not depend on the shared library.
|
||||
project, the preferred method.
|
||||
|
||||
Demo2 shows how to link against the shared library.
|
||||
Build the project QtWebApp to generate the shared library.
|
||||
|
||||
Demo3 shows how to use the qtservice component to start the application
|
||||
as a Windows Service or Unix daemon. Start it with option -h to get help.
|
||||
|
||||
I recommend to include the library by source as shown in Demo1 and 3.
|
||||
|
||||
Stefan Frings
|
||||
http://stefanfrings.de
|
||||
|
||||
|
@ -28,16 +28,16 @@ HttpConnectionHandler::HttpConnectionHandler(const QSettings *settings, HttpRequ
|
||||
readTimer.setSingleShot(true);
|
||||
|
||||
// Create TCP or SSL socket
|
||||
createSocket();
|
||||
createSocket();
|
||||
socket->moveToThread(thread);
|
||||
|
||||
// Connect signals
|
||||
connect(socket, &QIODevice::readyRead, this, &HttpConnectionHandler::read);
|
||||
connect(socket, &QAbstractSocket::disconnected, this, &HttpConnectionHandler::disconnected);
|
||||
connect(&readTimer, &QTimer::timeout, this, &HttpConnectionHandler::readTimeout);
|
||||
connect(thread, &QThread::finished, this, &HttpConnectionHandler::thread_done);
|
||||
connect(socket, SIGNAL(readyRead()), SLOT(read()));
|
||||
connect(socket, SIGNAL(disconnected()), SLOT(disconnected()));
|
||||
connect(&readTimer, SIGNAL(timeout()), SLOT(readTimeout()));
|
||||
connect(thread, SIGNAL(finished()), this, SLOT(thread_done()));
|
||||
|
||||
qDebug("HttpConnectionHandler (%p): constructed", static_cast<void*>(this));
|
||||
qDebug("HttpConnectionHandler (%p): constructed", static_cast<void*>(this));
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
namespace stefanfrings {
|
||||
|
||||
/** Alias type definition, for compatibility to different Qt versions */
|
||||
#if QT_VERSION >= 0x050000
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
typedef qintptr tSocketDescriptor;
|
||||
#else
|
||||
typedef int tSocketDescriptor;
|
||||
|
@ -18,7 +18,7 @@ HttpConnectionHandlerPool::HttpConnectionHandlerPool(const QSettings *settings,
|
||||
this->sslConfiguration=NULL;
|
||||
loadSslConfig();
|
||||
cleanupTimer.start(settings->value("cleanupInterval",1000).toInt());
|
||||
connect(&cleanupTimer, &QTimer::timeout, this, &HttpConnectionHandlerPool::cleanup);
|
||||
connect(&cleanupTimer, SIGNAL(timeout()), SLOT(cleanup()));
|
||||
}
|
||||
|
||||
|
||||
@ -77,7 +77,8 @@ void HttpConnectionHandlerPool::cleanup()
|
||||
{
|
||||
delete handler;
|
||||
pool.removeOne(handler);
|
||||
qDebug("HttpConnectionHandlerPool: Removed connection handler (%p), pool size is now %i",handler,pool.size());
|
||||
long int poolSize=(long int)pool.size();
|
||||
qDebug("HttpConnectionHandlerPool: Removed connection handler (%p), pool size is now %li",handler,poolSize);
|
||||
break; // remove only one handler in each interval
|
||||
}
|
||||
}
|
||||
@ -140,7 +141,7 @@ void HttpConnectionHandlerPool::loadSslConfig()
|
||||
sslConfiguration->setLocalCertificate(certificate);
|
||||
sslConfiguration->setPrivateKey(sslKey);
|
||||
sslConfiguration->setPeerVerifyMode(QSslSocket::VerifyNone);
|
||||
sslConfiguration->setProtocol(QSsl::TlsV1SslV3);
|
||||
sslConfiguration->setProtocol(QSsl::AnyProtocol);
|
||||
|
||||
qDebug("HttpConnectionHandlerPool: SSL settings loaded");
|
||||
#endif
|
||||
|
24
third_party/QtWebApp/httpserver/httpcookie.cpp
vendored
24
third_party/QtWebApp/httpserver/httpcookie.cpp
vendored
@ -14,7 +14,9 @@ HttpCookie::HttpCookie()
|
||||
secure=false;
|
||||
}
|
||||
|
||||
HttpCookie::HttpCookie(const QByteArray name, const QByteArray value, const int maxAge, const QByteArray path, const QByteArray comment, const QByteArray domain, const bool secure, const bool httpOnly)
|
||||
HttpCookie::HttpCookie(const QByteArray name, const QByteArray value, const int maxAge, const QByteArray path,
|
||||
const QByteArray comment, const QByteArray domain, const bool secure, const bool httpOnly,
|
||||
const QByteArray sameSite)
|
||||
{
|
||||
this->name=name;
|
||||
this->value=value;
|
||||
@ -24,6 +26,7 @@ HttpCookie::HttpCookie(const QByteArray name, const QByteArray value, const int
|
||||
this->domain=domain;
|
||||
this->secure=secure;
|
||||
this->httpOnly=httpOnly;
|
||||
this->sameSite=sameSite;
|
||||
this->version=1;
|
||||
}
|
||||
|
||||
@ -32,6 +35,7 @@ HttpCookie::HttpCookie(const QByteArray source)
|
||||
version=1;
|
||||
maxAge=0;
|
||||
secure=false;
|
||||
httpOnly=false;
|
||||
QList<QByteArray> list=splitCSV(source);
|
||||
foreach(QByteArray part, list)
|
||||
{
|
||||
@ -76,6 +80,10 @@ HttpCookie::HttpCookie(const QByteArray source)
|
||||
{
|
||||
httpOnly=true;
|
||||
}
|
||||
else if (name=="SameSite")
|
||||
{
|
||||
sameSite=value;
|
||||
}
|
||||
else if (name=="Version")
|
||||
{
|
||||
version=value.toInt();
|
||||
@ -125,6 +133,10 @@ QByteArray HttpCookie::toByteArray() const
|
||||
if (httpOnly) {
|
||||
buffer.append("; HttpOnly");
|
||||
}
|
||||
if (!sameSite.isEmpty()) {
|
||||
buffer.append("; SameSite=");
|
||||
buffer.append(sameSite);
|
||||
}
|
||||
buffer.append("; Version=");
|
||||
buffer.append(QByteArray::number(version));
|
||||
return buffer;
|
||||
@ -170,6 +182,11 @@ void HttpCookie::setHttpOnly(const bool httpOnly)
|
||||
this->httpOnly=httpOnly;
|
||||
}
|
||||
|
||||
void HttpCookie::setSameSite(const QByteArray sameSite)
|
||||
{
|
||||
this->sameSite=sameSite;
|
||||
}
|
||||
|
||||
QByteArray HttpCookie::getName() const
|
||||
{
|
||||
return name;
|
||||
@ -210,6 +227,11 @@ bool HttpCookie::getHttpOnly() const
|
||||
return httpOnly;
|
||||
}
|
||||
|
||||
QByteArray HttpCookie::getSameSite() const
|
||||
{
|
||||
return sameSite;
|
||||
}
|
||||
|
||||
int HttpCookie::getVersion() const
|
||||
{
|
||||
return version;
|
||||
|
21
third_party/QtWebApp/httpserver/httpcookie.h
vendored
21
third_party/QtWebApp/httpserver/httpcookie.h
vendored
@ -13,9 +13,8 @@
|
||||
namespace stefanfrings {
|
||||
|
||||
/**
|
||||
HTTP cookie as defined in RFC 2109. This class can also parse
|
||||
RFC 2965 cookies, but skips fields that are not defined in RFC
|
||||
2109.
|
||||
HTTP cookie as defined in RFC 2109.
|
||||
Supports some additional attributes of RFC6265bis.
|
||||
*/
|
||||
|
||||
class DECLSPEC HttpCookie
|
||||
@ -35,11 +34,13 @@ public:
|
||||
@param domain Optional domain for that the cookie will be sent. Defaults to the current domain
|
||||
@param secure If true, the cookie will be sent by the browser to the server only on secure connections
|
||||
@param httpOnly If true, the browser does not allow client-side scripts to access the cookie
|
||||
@param sameSite Declare if the cookie can only be read by the same site, which is a stronger
|
||||
restriction than the domain. Allowed values: "Lax" and "Strict".
|
||||
*/
|
||||
HttpCookie(const QByteArray name, const QByteArray value, const int maxAge,
|
||||
const QByteArray path="/", const QByteArray comment=QByteArray(),
|
||||
const QByteArray domain=QByteArray(), const bool secure=false,
|
||||
const bool httpOnly=false);
|
||||
const bool httpOnly=false, const QByteArray sameSite=QByteArray());
|
||||
|
||||
/**
|
||||
Create a cookie from a string.
|
||||
@ -77,9 +78,15 @@ public:
|
||||
/** Set secure mode, so that the cookie will be sent by the browser to the server only on secure connections */
|
||||
void setSecure(const bool secure);
|
||||
|
||||
/** Set HTTP-only mode, so that he browser does not allow client-side scripts to access the cookie */
|
||||
/** Set HTTP-only mode, so that the browser does not allow client-side scripts to access the cookie */
|
||||
void setHttpOnly(const bool httpOnly);
|
||||
|
||||
/**
|
||||
* Set same-site mode, so that the browser does not allow other web sites to access the cookie.
|
||||
* Allowed values: "Lax" and "Strict".
|
||||
*/
|
||||
void setSameSite(const QByteArray sameSite);
|
||||
|
||||
/** Get the name of this cookie */
|
||||
QByteArray getName() const;
|
||||
|
||||
@ -104,6 +111,9 @@ public:
|
||||
/** Get the HTTP-only flag of this cookie */
|
||||
bool getHttpOnly() const;
|
||||
|
||||
/** Get the same-site flag of this cookie */
|
||||
QByteArray getSameSite() const;
|
||||
|
||||
/** Returns always 1 */
|
||||
int getVersion() const;
|
||||
|
||||
@ -117,6 +127,7 @@ private:
|
||||
QByteArray path;
|
||||
bool secure;
|
||||
bool httpOnly;
|
||||
QByteArray sameSite;
|
||||
int version;
|
||||
|
||||
};
|
||||
|
@ -2,6 +2,6 @@
|
||||
|
||||
const char* getQtWebAppLibVersion()
|
||||
{
|
||||
return "1.7.11";
|
||||
return "1.8.3";
|
||||
}
|
||||
|
||||
|
1
third_party/QtWebApp/httpserver/httpglobal.h
vendored
1
third_party/QtWebApp/httpserver/httpglobal.h
vendored
@ -23,6 +23,5 @@
|
||||
/** Get the library version number */
|
||||
DECLSPEC const char* getQtWebAppLibVersion();
|
||||
|
||||
|
||||
#endif // HTTPGLOBAL_H
|
||||
|
||||
|
@ -83,7 +83,7 @@ void HttpListener::incomingConnection(tSocketDescriptor socketDescriptor) {
|
||||
qDebug("HttpListener: Too many incoming connections");
|
||||
QTcpSocket* socket=new QTcpSocket(this);
|
||||
socket->setSocketDescriptor(socketDescriptor);
|
||||
connect(socket, &QAbstractSocket::disconnected, socket, &QObject::deleteLater);
|
||||
connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
|
||||
socket->write("HTTP/1.1 503 too many connections\r\nConnection: close\r\n\r\nToo many connections\r\n");
|
||||
socket->disconnectFromHost();
|
||||
}
|
||||
|
@ -482,7 +482,8 @@ void HttpRequest::parseMultiPartFile()
|
||||
parameters.insert(fieldName,fileName);
|
||||
qDebug("HttpRequest: set parameter %s=%s",fieldName.data(),fileName.data());
|
||||
uploadedFiles.insert(fieldName,uploadedFile);
|
||||
qDebug("HttpRequest: uploaded file size is %lli",uploadedFile->size());
|
||||
long int fileSize=(long int) uploadedFile->size();
|
||||
qDebug("HttpRequest: uploaded file size is %li",fileSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -43,7 +43,6 @@ public:
|
||||
*/
|
||||
HttpSession& operator= (const HttpSession& other);
|
||||
|
||||
|
||||
/**
|
||||
Destructor. Detaches from the shared data.
|
||||
*/
|
||||
@ -54,7 +53,7 @@ public:
|
||||
|
||||
/**
|
||||
Null sessions cannot store data. All calls to set() and remove()
|
||||
do not have any effect.This method is thread safe.
|
||||
do not have any effect. This method is thread safe.
|
||||
*/
|
||||
bool isNull() const;
|
||||
|
||||
|
@ -13,7 +13,7 @@ HttpSessionStore::HttpSessionStore(const QSettings *settings, QObject* parent)
|
||||
:QObject(parent)
|
||||
{
|
||||
this->settings=settings;
|
||||
connect(&cleanupTimer,&QTimer::timeout,this,&HttpSessionStore::sessionTimerEvent);
|
||||
connect(&cleanupTimer,SIGNAL(timeout()),this,SLOT(sessionTimerEvent()));
|
||||
cleanupTimer.start(60000);
|
||||
cookieName=settings->value("cookieName","sessionid").toByteArray();
|
||||
expirationTime=settings->value("expirationTime",3600000).toInt();
|
||||
@ -64,7 +64,8 @@ HttpSession HttpSessionStore::getSession(HttpRequest& request, HttpResponse& res
|
||||
QByteArray cookiePath=settings->value("cookiePath").toByteArray();
|
||||
QByteArray cookieComment=settings->value("cookieComment").toByteArray();
|
||||
QByteArray cookieDomain=settings->value("cookieDomain").toByteArray();
|
||||
response.setCookie(HttpCookie(cookieName,session.getId(),expirationTime/1000,cookiePath,cookieComment,cookieDomain));
|
||||
response.setCookie(HttpCookie(cookieName,session.getId(),expirationTime/1000,
|
||||
cookiePath,cookieComment,cookieDomain,false,false,"Lax"));
|
||||
session.setLastAccess();
|
||||
return session;
|
||||
}
|
||||
@ -79,7 +80,8 @@ HttpSession HttpSessionStore::getSession(HttpRequest& request, HttpResponse& res
|
||||
HttpSession session(true);
|
||||
qDebug("HttpSessionStore: create new session with ID %s",session.getId().data());
|
||||
sessions.insert(session.getId(),session);
|
||||
response.setCookie(HttpCookie(cookieName,session.getId(),expirationTime/1000,cookiePath,cookieComment,cookieDomain));
|
||||
response.setCookie(HttpCookie(cookieName,session.getId(),expirationTime/1000,
|
||||
cookiePath,cookieComment,cookieDomain,false,false,"Lax"));
|
||||
mutex.unlock();
|
||||
return session;
|
||||
}
|
||||
@ -111,6 +113,7 @@ void HttpSessionStore::sessionTimerEvent()
|
||||
if (now-lastAccess>expirationTime)
|
||||
{
|
||||
qDebug("HttpSessionStore: session %s expired",session.getId().data());
|
||||
emit sessionDeleted(session.getId());
|
||||
sessions.erase(prev);
|
||||
}
|
||||
}
|
||||
@ -122,6 +125,7 @@ void HttpSessionStore::sessionTimerEvent()
|
||||
void HttpSessionStore::removeSession(HttpSession session)
|
||||
{
|
||||
mutex.lock();
|
||||
emit sessionDeleted(session.getId());
|
||||
sessions.remove(session.getId());
|
||||
mutex.unlock();
|
||||
}
|
||||
|
@ -112,6 +112,14 @@ private slots:
|
||||
|
||||
/** Called every minute to cleanup expired sessions. */
|
||||
void sessionTimerEvent();
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
Emitted when the session is deleted.
|
||||
@param sessionId The ID number of the session.
|
||||
*/
|
||||
void sessionDeleted(const QByteArray& sessionId);
|
||||
};
|
||||
|
||||
} // end of namespace
|
||||
|
@ -33,7 +33,8 @@ StaticFileController::StaticFileController(const QSettings *settings, QObject* p
|
||||
maxCachedFileSize=settings->value("maxCachedFileSize","65536").toInt();
|
||||
cache.setMaxCost(settings->value("cacheSize","1000000").toInt());
|
||||
cacheTimeout=settings->value("cacheTime","60000").toInt();
|
||||
qDebug("StaticFileController: cache timeout=%i, size=%i",cacheTimeout,cache.maxCost());
|
||||
long int cacheMaxCost=(long int)cache.maxCost();
|
||||
qDebug("StaticFileController: cache timeout=%i, size=%li",cacheTimeout,cacheMaxCost);
|
||||
}
|
||||
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
#define TEMPLATE_H
|
||||
|
||||
#include <QString>
|
||||
#include <QRegExp>
|
||||
#include <QIODevice>
|
||||
#include <QTextCodec>
|
||||
#include <QFile>
|
||||
|
@ -10,7 +10,8 @@ TemplateCache::TemplateCache(const QSettings* settings, QObject* parent)
|
||||
{
|
||||
cache.setMaxCost(settings->value("cacheSize","1000000").toInt());
|
||||
cacheTimeout=settings->value("cacheTime","60000").toInt();
|
||||
qDebug("TemplateCache: timeout=%i, size=%i",cacheTimeout,cache.maxCost());
|
||||
long int cacheMaxCost=(long int)cache.maxCost();
|
||||
qDebug("TemplateCache: timeout=%i, size=%li",cacheTimeout,cacheMaxCost);
|
||||
}
|
||||
|
||||
QString TemplateCache::tryFile(const QString localizedName)
|
||||
|
@ -1,6 +1,10 @@
|
||||
INCLUDEPATH += $$PWD
|
||||
DEPENDPATH += $$PWD
|
||||
|
||||
greaterThan(QT_VERSION,6) {
|
||||
QT += core5compat
|
||||
}
|
||||
|
||||
HEADERS += $$PWD/templateglobal.h
|
||||
HEADERS += $$PWD/template.h
|
||||
HEADERS += $$PWD/templateloader.h
|
||||
|
@ -9,6 +9,12 @@
|
||||
#include <QStringList>
|
||||
#include <QDir>
|
||||
#include <QSet>
|
||||
#include <QTextStream>
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
#include <QRegularExpression>
|
||||
#else
|
||||
#include <QRegExp>
|
||||
#endif
|
||||
|
||||
using namespace stefanfrings;
|
||||
|
||||
@ -35,8 +41,8 @@ TemplateLoader::TemplateLoader(const QSettings *settings, QObject *parent)
|
||||
else
|
||||
{
|
||||
textCodec=QTextCodec::codecForName(encoding.toLocal8Bit());
|
||||
}
|
||||
qDebug("TemplateLoader: path=%s, codec=%s",qPrintable(templatePath),textCodec->name().data());
|
||||
}
|
||||
qDebug("TemplateLoader: path=%s, codec=%s",qPrintable(templatePath),qPrintable(encoding));
|
||||
}
|
||||
|
||||
TemplateLoader::~TemplateLoader()
|
||||
@ -67,13 +73,23 @@ QString TemplateLoader::tryFile(QString localizedName)
|
||||
Template TemplateLoader::getTemplate(QString templateName, QString locales)
|
||||
{
|
||||
QSet<QString> tried; // used to suppress duplicate attempts
|
||||
QStringList locs=locales.split(',',QString::SkipEmptyParts);
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
QStringList locs=locales.split(',',Qt::SkipEmptyParts);
|
||||
#else
|
||||
QStringList locs=locales.split(',',QString::SkipEmptyParts);
|
||||
#endif
|
||||
|
||||
// Search for exact match
|
||||
foreach (QString loc,locs)
|
||||
{
|
||||
loc.replace(QRegExp(";.*"),"");
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
loc.replace(QRegularExpression(";.*"),"");
|
||||
#else
|
||||
loc.replace(QRegExp(";.*"),"");
|
||||
#endif
|
||||
loc.replace('-','_');
|
||||
|
||||
QString localizedName=templateName+"-"+loc.trimmed();
|
||||
if (!tried.contains(localizedName))
|
||||
{
|
||||
@ -88,7 +104,11 @@ Template TemplateLoader::getTemplate(QString templateName, QString locales)
|
||||
// Search for correct language but any country
|
||||
foreach (QString loc,locs)
|
||||
{
|
||||
loc.replace(QRegExp("[;_-].*"),"");
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
loc.replace(QRegularExpression("[;_-].*"),"");
|
||||
#else
|
||||
loc.replace(QRegExp("[;_-].*"),"");
|
||||
#endif
|
||||
QString localizedName=templateName+"-"+loc.trimmed();
|
||||
if (!tried.contains(localizedName))
|
||||
{
|
||||
|
@ -8,8 +8,8 @@
|
||||
|
||||
#include <QString>
|
||||
#include <QSettings>
|
||||
#include <QTextCodec>
|
||||
#include <QMutex>
|
||||
#include <QTextCodec>
|
||||
#include "templateglobal.h"
|
||||
#include "template.h"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user