1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#ifndef QHTTPSERVERROUTERRULE_H
5#define QHTTPSERVERROUTERRULE_H
6
7#include <QtHttpServer/qhttpserverrequest.h>
8#include <QtHttpServer/qhttpserverresponder.h>
9#include <QtHttpServer/qhttpserverrouterviewtraits.h>
10
11#include <QtCore/qcontainerfwd.h>
12#include <QtCore/qregularexpression.h>
13
14#include <initializer_list>
15#include <memory>
16
17QT_BEGIN_NAMESPACE
18
19class QString;
20class QHttpServerRequest;
21class QHttpServerResponder;
22class QRegularExpressionMatch;
23class QHttpServerRouter;
24
25class QHttpServerRouterRulePrivate;
26class Q_HTTPSERVER_EXPORT QHttpServerRouterRule
27{
28 Q_DECLARE_PRIVATE(QHttpServerRouterRule)
29 Q_DISABLE_COPY_MOVE(QHttpServerRouterRule)
30
31private:
32 using RouterHandlerPrototype = void (*)(const QRegularExpressionMatch &,
33 const QHttpServerRequest &, QHttpServerResponder &);
34
35 template <typename T>
36 using if_routerhandler_prototype_compatible = typename std::enable_if<
37 QtPrivate::AreFunctionsCompatible<RouterHandlerPrototype, T>::value, bool>::type;
38
39 QHttpServerRouterRule(const QString &pathPattern, const QHttpServerRequest::Methods methods,
40 const QObject *context, QtPrivate::QSlotObjectBase *slotObjRaw);
41
42public:
43#ifdef Q_QDOC
44 template <typename Functor>
45 QHttpServerRouterRule(
46 const QString &pathPattern, const QHttpServerRequest::Methods methods,
47 const QObject *receiver,
48 Functor &&slot);
49
50 template <typename Functor>
51 QHttpServerRouterRule(
52 const QString &pathPattern,
53 const QObject *receiver,
54 Functor &&slot);
55#else
56 template <typename Handler, if_routerhandler_prototype_compatible<Handler> = true>
57 QHttpServerRouterRule(
58 const QString &pathPattern,
59 const typename QtPrivate::ContextTypeForFunctor<Handler>::ContextType *context,
60 Handler &&func)
61 : QHttpServerRouterRule(
62 pathPattern, QHttpServerRequest::Method::AnyKnown, context,
63 QtPrivate::makeCallableObject<RouterHandlerPrototype>(std::forward<Handler>(func)))
64 {
65 }
66
67 template <typename Handler, if_routerhandler_prototype_compatible<Handler> = true>
68 QHttpServerRouterRule(
69 const QString &pathPattern, const QHttpServerRequest::Methods methods,
70 const typename QtPrivate::ContextTypeForFunctor<Handler>::ContextType *context,
71 Handler &&func)
72 : QHttpServerRouterRule(
73 pathPattern, methods, context,
74 QtPrivate::makeCallableObject<RouterHandlerPrototype>(std::forward<Handler>(func)))
75 {
76 }
77#endif
78
79#ifdef Q_QDOC
80 template <typename Functor, typename ViewTraits = QHttpServerRouterViewTraits<Functor>>
81 static typename ViewTraits::BindableType bindCaptured(
82 QObject *receiver,
83 Functor &&slot,
84 const QRegularExpressionMatch &match) const;
85# else
86 template<typename ViewHandler, typename ViewTraits = QHttpServerRouterViewTraits<ViewHandler>>
87 static typename ViewTraits::BindableType bindCaptured(
88 const typename QtPrivate::ContextTypeForFunctor<ViewHandler>::ContextType *context,
89 ViewHandler &&handler,
90 const QRegularExpressionMatch &match)
91 {
92 return bindCapturedImpl<ViewHandler, ViewTraits>(
93 context, std::forward<ViewHandler>(handler), match,
94 typename ViewTraits::Arguments::CapturableIndexes{});
95 }
96#endif
97
98 const QObject *contextObject() const;
99
100 virtual ~QHttpServerRouterRule();
101
102protected:
103 bool exec(const QHttpServerRequest &request, QHttpServerResponder &responder) const;
104
105 bool hasValidMethods() const;
106
107 bool createPathRegexp(std::initializer_list<QMetaType> metaTypes,
108 const QHash<QMetaType, QString> &converters);
109
110 virtual bool matches(const QHttpServerRequest &request,
111 QRegularExpressionMatch *match) const;
112
113 QHttpServerRouterRule(QHttpServerRouterRulePrivate *d);
114
115 // Implementation of C++20 std::bind_front() in C++17
116 template<typename F, typename... Args>
117 static auto bind_front(F &&f, Args &&...args)
118 {
119 return [f = std::forward<F>(f),
120 args = std::make_tuple(std::forward<Args>(args)...)](auto &&...callArgs) {
121 return std::apply(f,
122 std::tuple_cat(args,
123 std::forward_as_tuple(std::forward<decltype(callArgs)>(
124 callArgs)...)));
125 };
126 }
127
128 template<typename ViewHandler, typename ViewTraits, int... Cx>
129 static typename ViewTraits::BindableType bindCapturedImpl(
130 const typename QtPrivate::ContextTypeForFunctor<ViewHandler>::ContextType *context,
131 ViewHandler &&handler,
132 const QRegularExpressionMatch &match,
133 QtPrivate::IndexesList<Cx...>)
134 {
135 if constexpr (std::is_member_function_pointer_v<ViewHandler>) {
136 return bind_front(
137 handler, const_cast<typename QtPrivate::ContextTypeForFunctor<ViewHandler>::ContextType*>(context),
138 QVariant(match.captured(nth: Cx + 1))
139 .value<typename ViewTraits::Arguments::template Arg<Cx>::CleanType>()...);
140 } else {
141 Q_UNUSED(context);
142 return bind_front(
143 handler,
144 QVariant(match.captured(nth: Cx + 1))
145 .value<typename ViewTraits::Arguments::template Arg<Cx>::CleanType>()...);
146 }
147 }
148
149private:
150 std::unique_ptr<QHttpServerRouterRulePrivate> d_ptr;
151
152 friend class QHttpServerRouter;
153};
154
155QT_END_NAMESPACE
156
157#endif // QHTTPSERVERROUTERRULE_H
158

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

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