2019-06-04 16:25:26 +02:00
|
|
|
/* This file is part of Flowee
|
|
|
|
|
*
|
|
|
|
|
* Copyright (C) 2017 Nathan Osman
|
|
|
|
|
*
|
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This library 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
|
|
|
|
|
* Library General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* For the full copy of the License see <http://www.gnu.org/licenses/>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "handler.h"
|
|
|
|
|
#include "middleware.h"
|
|
|
|
|
#include "socket.h"
|
|
|
|
|
|
|
|
|
|
#include "handler_p.h"
|
|
|
|
|
|
|
|
|
|
using namespace HttpEngine;
|
|
|
|
|
|
|
|
|
|
HandlerPrivate::HandlerPrivate(Handler *handler)
|
|
|
|
|
: QObject(handler),
|
|
|
|
|
q(handler)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Handler::Handler(QObject *parent)
|
|
|
|
|
: QObject(parent),
|
|
|
|
|
d(new HandlerPrivate(this))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Handler::addMiddleware(Middleware *middleware)
|
|
|
|
|
{
|
|
|
|
|
d->middleware.append(middleware);
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-10 00:35:59 +02:00
|
|
|
void Handler::addRedirect(const QRegularExpression &pattern, const QString &path)
|
2019-06-04 16:25:26 +02:00
|
|
|
{
|
|
|
|
|
d->redirects.append(Redirect(pattern, path));
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-10 00:35:59 +02:00
|
|
|
void Handler::addSubHandler(const QRegularExpression &pattern, Handler *handler)
|
2019-06-04 16:25:26 +02:00
|
|
|
{
|
|
|
|
|
d->subHandlers.append(SubHandler(pattern, handler));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Handler::route(Socket *socket, const QString &path)
|
|
|
|
|
{
|
|
|
|
|
// Run through each of the middleware
|
|
|
|
|
foreach (Middleware *middleware, d->middleware) {
|
|
|
|
|
if (!middleware->process(socket)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check each of the redirects for a match
|
|
|
|
|
foreach (Redirect redirect, d->redirects) {
|
2022-09-10 00:35:59 +02:00
|
|
|
auto match = redirect.first.match(path);
|
|
|
|
|
if (match.hasMatch()) {
|
2019-06-04 16:25:26 +02:00
|
|
|
QString newPath = redirect.second;
|
2022-09-10 00:35:59 +02:00
|
|
|
foreach (QString replacement, match.capturedTexts().mid(1)) {
|
2019-06-04 16:25:26 +02:00
|
|
|
newPath = newPath.arg(replacement);
|
|
|
|
|
}
|
|
|
|
|
socket->writeRedirect(newPath.toUtf8());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check each of the sub-handlers for a match
|
|
|
|
|
foreach (SubHandler subHandler, d->subHandlers) {
|
2022-09-10 00:35:59 +02:00
|
|
|
auto match = subHandler.first.match(path);
|
|
|
|
|
if (match.hasMatch()) {
|
|
|
|
|
subHandler.second->route(socket, path.mid(match.captured().length()));
|
2019-06-04 16:25:26 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If no match, invoke the process() method
|
|
|
|
|
process(socket, path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Handler::process(Socket *socket, const QString &)
|
|
|
|
|
{
|
|
|
|
|
// The default response is simply a 404 error
|
|
|
|
|
socket->writeError(Socket::NotFound);
|
|
|
|
|
}
|