Cutelyst
2.14.2
Cutelyst
Actions
REST
actionrest.cpp
1
/*
2
* Copyright (C) 2013-2018 Daniel Nicoletti <dantti12@gmail.com>
3
*
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2.1 of the License, or (at your option) any later version.
8
*
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
13
*
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with this library; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
*/
18
#include "actionrest_p.h"
19
#include "context.h"
20
#include "controller.h"
21
#include "dispatcher.h"
22
23
#include <QUrl>
24
#include <QDebug>
25
26
using namespace
Cutelyst
;
27
62
ActionREST::ActionREST
(
QObject
*parent) :
Action
(new ActionRESTPrivate(this), parent)
63
{
64
}
65
66
bool
ActionREST::doExecute
(
Context
*c)
67
{
68
Q_D(
const
ActionREST
);
69
70
if
(!
Action::doExecute
(c)) {
71
return
false
;
72
}
73
74
return
d->dispatchRestMethod(c, c->request()->method());
75
}
76
77
ActionRESTPrivate::ActionRESTPrivate(
ActionREST
* q) : q_ptr(q)
78
{
79
}
80
81
bool
ActionRESTPrivate::dispatchRestMethod(
Context
*c,
const
QString
&httpMethod)
const
82
{
83
Q_Q(
const
ActionREST
);
84
const
QString
restMethod = q->name() +
QLatin1Char
(
'_'
) + httpMethod;
85
86
Controller
*controller = q->controller();
87
Action
*action = controller->
actionFor
(restMethod);
88
if
(!action) {
89
// Look for non registered actions in this controller
90
const
ActionList
actions = controller->
actions
();
91
for
(
Action
*controllerAction : actions) {
92
if
(controllerAction->name() == restMethod) {
93
action = controllerAction;
94
break
;
95
}
96
}
97
}
98
99
if
(action) {
100
return
c->
execute
(action);
101
}
102
103
bool
ret =
false
;
104
if
(httpMethod ==
QLatin1String
(
"OPTIONS"
)) {
105
ret = returnOptions(c, q->name());
106
}
else
if
(httpMethod ==
QLatin1String
(
"HEAD"
)) {
107
// redispatch to GET
108
ret = dispatchRestMethod(c, QStringLiteral(
"GET"
));
109
}
else
if
(httpMethod !=
QLatin1String
(
"not_implemented"
)) {
110
// try dispatching to foo_not_implemented
111
ret = dispatchRestMethod(c, QStringLiteral(
"not_implemented"
));
112
}
else
{
113
// not_implemented
114
ret = returnNotImplemented(c, q->name());
115
}
116
117
return
ret;
118
}
119
120
bool
ActionRESTPrivate::returnOptions(
Context
*c,
const
QString
&methodName)
const
121
{
122
Response
*response = c->
response
();
123
response->
setContentType
(QStringLiteral(
"text/plain"
));
124
response->
setStatus
(Response::OK);
// 200
125
response->
setHeader
(QStringLiteral(
"ALLOW"
),
126
getAllowedMethods(c->controller(), methodName));
127
response->
body
().
clear
();
128
return
true
;
129
}
130
131
bool
ActionRESTPrivate::returnNotImplemented(
Context
*c,
const
QString
&methodName)
const
132
{
133
Response
*response = c->
response
();
134
response->
setStatus
(Response::MethodNotAllowed);
// 405
135
response->
setHeader
(QStringLiteral(
"ALLOW"
),
136
getAllowedMethods(c->controller(), methodName));
137
const
QString
body =
QLatin1String
(
"Method "
) + c->req()->method()
138
+
QLatin1String
(
" not implemented for "
) + c->
uriFor
(methodName).
toString
();
139
response->
setBody
(body);
140
return
true
;
141
}
142
143
QString
Cutelyst::ActionRESTPrivate::getAllowedMethods(
Controller
*controller,
const
QString
&methodName)
const
144
{
145
QStringList
methods;
146
const
QString
name = methodName +
QLatin1Char
(
'_'
);
147
const
ActionList
actions = controller->
actions
();
148
for
(
Action
*action : actions) {
149
const
QString
method = action->
name
();
150
if
(method.
startsWith
(name)) {
151
methods.
append
(method.
mid
(name.
size
()));
152
}
153
}
154
155
if
(methods.
contains
(QStringLiteral(
"GET"
))) {
156
methods.
append
(QStringLiteral(
"HEAD"
));
157
}
158
159
methods.
removeAll
(QStringLiteral(
"not_implemented"
));
160
methods.
sort
();
161
methods.
removeDuplicates
();
162
163
return
methods.
join
(QStringLiteral(
", "
));
164
}
165
166
#include "moc_actionrest.cpp"
QList::append
void append(const T &value)
Cutelyst::Controller
Cutelyst Controller base class
Definition:
controller.h:103
Cutelyst::Controller::actions
ActionList actions() const
Definition:
controller.cpp:60
QString::size
int size() const const
Cutelyst::Response::setStatus
void setStatus(quint16 status)
Definition:
response.cpp:85
QList::removeAll
int removeAll(const T &value)
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
Cutelyst::Context
The Cutelyst Context.
Definition:
context.h:52
Cutelyst::Context::response
Response * response() const
Definition:
context.cpp:110
QByteArray::clear
void clear()
Cutelyst::ActionREST::doExecute
bool doExecute(Context *c) override
Definition:
actionrest.cpp:66
Cutelyst::Response::setContentType
void setContentType(const QString &type)
Definition:
response.h:218
Cutelyst::Context::execute
bool execute(Component *code)
Definition:
context.cpp:421
QUrl::toString
QString toString(QUrl::FormattingOptions options) const const
Cutelyst::Controller::actionFor
Action * actionFor(const QString &name) const
Definition:
controller.cpp:50
QObject
QString
Cutelyst::Response::setBody
void setBody(QIODevice *body)
Definition:
response.cpp:114
Cutelyst::Response::setHeader
void setHeader(const QString &field, const QString &value)
Definition:
response.cpp:306
QStringList::join
QString join(const QString &separator) const const
QLatin1String
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
QStringList::removeDuplicates
int removeDuplicates()
Cutelyst::Context::uriFor
QUrl uriFor(const QString &path=QString(), const QStringList &args=QStringList(), const ParamsMultiMap &queryValues=ParamsMultiMap()) const
Definition:
context.cpp:243
Cutelyst
The Cutelyst namespace holds all public Cutelyst API.
Definition:
Mainpage.dox:8
Cutelyst::Component::name
QString name() const
Definition:
component.cpp:44
Cutelyst::ActionREST::ActionREST
ActionREST(QObject *parent=nullptr)
Definition:
actionrest.cpp:62
QLatin1Char
Cutelyst::ActionREST
Automated REST Method Dispatching.
Definition:
actionrest.h:29
Cutelyst::Action::doExecute
virtual bool doExecute(Context *c) override
Definition:
action.cpp:147
Cutelyst::Action
This class represents a Cutelyst Action.
Definition:
action.h:48
QVector
QString::mid
QString mid(int position, int n) const const
Cutelyst::Response::body
Q_REQUIRED_RESULT QByteArray & body()
Definition:
response.cpp:97
QStringList
QStringList::sort
void sort(Qt::CaseSensitivity cs)
Cutelyst::Response
Definition:
response.h:35
Generated by
1.8.20