6 #include "application.h" 10 #include "controller.h" 11 #include "dispatcher.h" 18 #include <QCoreApplication> 31 : d_ptr(new ContextPrivate(app, app->engine(), app->dispatcher(), app->plugins()))
33 auto req =
new DummyRequest(
this);
40 d_ptr->request->d_ptr->engine = d_ptr->engine;
46 delete d_ptr->request;
47 delete d_ptr->response;
54 return !d->error.isEmpty();
60 if (
error.isEmpty()) {
64 qCCritical(CUTELYST_CORE) <<
error;
119 return d->action->name();
125 return d->action->ns();
143 return d->dispatcher;
149 return d->action->className();
155 return d->action->controller();
161 return d->dispatcher->controller(name);
173 return d->app->view(name);
179 d->view = d->app->view(name);
192 return d->stash.value(key);
198 return d->stash.value(key, defaultValue);
204 return d->stash.take(key);
210 return d->stash.remove(key);
216 d->stash.insert(key, value);
237 QUrl uri = d->request->uri();
242 const QString controllerNS = d->action->controller()->ns();
251 if (_path.
compare(u
"/") == 0) {
252 _path += args.
join(u
'/');
254 _path = _path + u
'/' + args.
join(u
'/');
266 if (queryValues.
size()) {
294 Action *expandedAction = d->dispatcher->expandAction(
this,
action);
301 localCapturesAux.
append(localArgs);
302 localArgs = localCapturesAux;
306 const QString path = d->dispatcher->uriForAction(
action, localCaptures);
308 qCWarning(CUTELYST_CORE) <<
"Can not find action for" <<
action << localCaptures;
312 uri =
uriFor(path, localArgs, queryValues);
326 qCWarning(CUTELYST_CORE) <<
"Can not find action for" << path;
344 d->dispatcher->forward(
this,
action);
365 if (--d->actionRefCount || !d->stack.isEmpty()) {
369 if (Q_UNLIKELY(d->engineRequest->status & EngineRequest::Finalized)) {
370 qCWarning(CUTELYST_ASYNC) <<
"Trying to async attach to a finalized request! Skipping...";
374 if (d->engineRequest->status & EngineRequest::Async) {
375 while (!d->pendingAsync.isEmpty()) {
379 if (d->actionRefCount) {
388 Q_EMIT d->app->afterDispatch(
this);
397 return d->dispatcher->forward(
this,
action);
403 return d->dispatcher->forward(
this,
action);
409 return d->dispatcher->getAction(
action,
ns);
415 return d->dispatcher->getActions(
action,
ns);
427 Q_ASSERT_X(code,
"Context::execute",
"trying to execute a null Cutelyst::Component");
429 static int recursion =
430 qEnvironmentVariableIsSet(
"RECURSION") ? qEnvironmentVariableIntValue(
"RECURSION") : 1000;
431 if (d->stack.size() >= recursion) {
432 QString msg = QStringLiteral(
"Deep recursion detected (stack size %1) calling %2, %3")
443 const QString statsInfo = d->statsStartExecute(code);
449 if (d->stats && !statsInfo.
isEmpty()) {
450 d->statsFinishExecute(statsInfo);
476 return d->app->config(key, defaultValue);
482 return d->app->config();
486 const char *sourceText,
487 const char *disambiguation,
491 return d->app->translate(d->locale, context, sourceText, disambiguation, n);
498 if (Q_UNLIKELY(d->engineRequest->status & EngineRequest::Finalized)) {
499 qCWarning(CUTELYST_CORE) <<
"Trying to finalize a finalized request! Skipping...";
504 qCDebug(CUTELYST_STATS,
505 "Response Code: %d; Content-Type: %s; Content-Length: %s",
506 d->response->status(),
507 d->response->headers().header(
"Content-Type"_ba,
"unknown"_ba).constData(),
508 d->response->headers()
512 const std::chrono::duration<double> duration =
513 std::chrono::steady_clock::now() - d->engineRequest->startOfRequest;
516 if (duration.count() == 0.0) {
517 average = QStringLiteral(
"??");
522 qCInfo(CUTELYST_STATS) << qPrintable(QStringLiteral(
"Request took: %1s (%2/s)\n%3")
530 d->engineRequest->finalize();
543 if (qobject_cast<Action *>(code)) {
547 if (stack.size() > 2) {
548 actionName = u
"-> " + actionName;
553 stats->profileStart(actionName);
558 void ContextPrivate::statsFinishExecute(
const QString &statsInfo)
560 stats->profileEnd(statsInfo);
566 auto it = unite.constBegin();
567 while (it != unite.constEnd()) {
568 d->stash.insert(it.key(), it.value());
573 #include "moc_context.cpp" 574 #include "moc_context_p.cpp" Context(Application *app)
void truncate(qsizetype position)
bool state() const noexcept
QString controllerName() const noexcept
bool error() const noexcept
virtual qint8 numberOfCaptures() const
QMultiMap::const_iterator constEnd() const const
QString & prepend(QChar ch)
Response * res() const noexcept
bool isEmpty() const const
qsizetype size() const const
QMultiMap::size_type size() const const
Action * getAction(QStringView action, QStringView ns={}) const
void setStash(const QString &key, const QVariant &value)
QString ns() const noexcept
void detach(Action *action=nullptr)
QUrl uriFor(const QString &path={}, const QStringList &args={}, const ParamsMultiMap &queryValues={}) const
QString join(QChar separator) const const
Request * req() const noexcept
virtual bool open(QIODeviceBase::OpenMode mode)
QString reverse() const noexcept
QIODevice * body() const noexcept
void appendError(const QString &error)
The Cutelyst Component base class.
QString actionName() const noexcept
qsizetype size() const const
This class represents a Cutelyst Action.
Headers & defaultHeaders() noexcept
void setPath(const QString &path, QUrl::ParsingMode mode)
QMultiMap::const_iterator constBegin() const const
void addQueryItem(const QString &key, const QString &value)
bool forward(Component *component)
QString number(double n, char format, int precision)
Cutelyst Controller base class.
void append(QList::parameter_type value)
QByteArray number(double n, char format, int precision)
QLocale defaultLocale() const noexcept
QString rightJustified(qsizetype width, QChar fill, bool truncate) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
Action * action() const noexcept
bool detached() const noexcept
bool isEmpty() const const
bool isEmpty() const const
Request * request() const noexcept
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
QVariantMap config() const noexcept
QString name() const noexcept
The Cutelyst namespace holds all public Cutelyst API.
void detachAsync() noexcept
QLocale locale() const noexcept
bool execute(Component *code)
QUrl uriForAction(QStringView path, const QStringList &captures={}, const QStringList &args={}, const ParamsMultiMap &queryValues={}) const
QVector< Plugin * > plugins() const
QVector< Action * > getActions(QStringView action, QStringView ns={}) const
QVariant fromValue(const T &value)
void setLocale(const QLocale &locale)
Application * app() const noexcept
QString fromLatin1(QByteArrayView str)
QStack< Component * > stack() const noexcept
QVariant stashTake(const QString &key)
QList::value_type takeFirst()
Engine * engine() const noexcept
Abstract View component for Cutelyst.
View * view(QStringView name={}) const
Controller * controller() const noexcept
void setQuery(const QString &query, QUrl::ParsingMode mode)
bool setCustomView(QStringView name)
The Cutelyst application.
bool stashRemove(const QString &key)
void setState(bool state) noexcept
Response * response() const noexcept
int compare(QLatin1StringView s1, const QString &s2, Qt::CaseSensitivity cs)
QString arg(Args &&... args) const const
View * customView() const noexcept
QStringList errors() const noexcept
Dispatcher * dispatcher() const noexcept