1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#ifndef QHTTPSERVERROUTER_H
5#define QHTTPSERVERROUTER_H
6
7#include <QtHttpServer/qthttpserverglobal.h>
8#include <QtHttpServer/qhttpserverrouterviewtraits.h>
9
10#include <QtCore/qscopedpointer.h>
11#include <QtCore/qmetatype.h>
12#include <QtCore/qregularexpression.h>
13
14#include <functional>
15#include <initializer_list>
16#include <memory>
17
18QT_BEGIN_NAMESPACE
19
20class QHttpServerResponder;
21class QHttpServerRequest;
22class QHttpServerRouterRule;
23
24class QHttpServerRouterPrivate;
25class Q_HTTPSERVER_EXPORT QHttpServerRouter
26{
27 Q_DECLARE_PRIVATE(QHttpServerRouter)
28 Q_DISABLE_COPY_MOVE(QHttpServerRouter)
29
30public:
31 QHttpServerRouter();
32 ~QHttpServerRouter();
33
34 template<typename Type>
35 bool addConverter(QAnyStringView regexp) {
36 if (!QMetaType::registerConverter<QString, Type>())
37 return false;
38
39 addConverter(QMetaType::fromType<Type>(), regexp);
40 return true;
41 }
42
43 void addConverter(QMetaType metaType, QAnyStringView regexp);
44 void removeConverter(QMetaType metaType);
45 void clearConverters();
46 const QHash<QMetaType, QString> &converters() const;
47
48 template<typename ViewHandler, typename ViewTraits = QHttpServerRouterViewTraits<ViewHandler>>
49 bool addRule(std::unique_ptr<QHttpServerRouterRule> rule)
50 {
51 return addRuleHelper<ViewTraits>(
52 std::move(rule),
53 typename ViewTraits::Arguments::Indexes{});
54 }
55
56 template<typename ViewHandler, typename ViewTraits = QHttpServerRouterViewTraits<ViewHandler>>
57 typename ViewTraits::BindableType bindCaptured(ViewHandler &&handler,
58 const QRegularExpressionMatch &match) const
59 {
60 return bindCapturedImpl<ViewHandler, ViewTraits>(
61 std::forward<ViewHandler>(handler), match,
62 typename ViewTraits::Arguments::CapturableIndexes{});
63 }
64
65 bool handleRequest(const QHttpServerRequest &request, QHttpServerResponder &responder) const;
66
67private:
68 template<typename ViewTraits, int ... Idx>
69 bool addRuleHelper(std::unique_ptr<QHttpServerRouterRule> rule,
70 QtPrivate::IndexesList<Idx...>)
71 {
72 return addRuleImpl(rule: std::move(rule), metaTypes: {ViewTraits::Arguments::template metaType<Idx>()...});
73 }
74
75 bool addRuleImpl(std::unique_ptr<QHttpServerRouterRule> rule,
76 std::initializer_list<QMetaType> metaTypes);
77
78 // Implementation of C++20 std::bind_front() in C++17
79 template<typename F, typename... Args>
80 auto bind_front(F &&f, Args &&...args) const
81 {
82 return [f = std::forward<F>(f),
83 args = std::make_tuple(std::forward<Args>(args)...)](auto &&...callArgs) {
84 return std::apply(f,
85 std::tuple_cat(args,
86 std::forward_as_tuple(std::forward<decltype(callArgs)>(
87 callArgs)...)));
88 };
89 }
90
91 template<typename ViewHandler, typename ViewTraits, int... Cx>
92 typename ViewTraits::BindableType bindCapturedImpl(ViewHandler &&handler,
93 const QRegularExpressionMatch &match,
94 QtPrivate::IndexesList<Cx...>) const
95 {
96 return bind_front(
97 std::forward<ViewHandler>(handler),
98 QVariant(match.captured(nth: Cx + 1))
99 .value<typename ViewTraits::Arguments::template Arg<Cx>::CleanType>()...);
100 }
101
102 std::unique_ptr<QHttpServerRouterPrivate> d_ptr;
103};
104
105QT_END_NAMESPACE
106
107#endif // QHTTPSERVERROUTER_H
108

source code of qthttpserver/src/httpserver/qhttpserverrouter.h