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
const_iterator constEnd() const const
QString & prepend(QChar ch)
QVariant fromValue(T &&value)
Response * res() const noexcept
bool isEmpty() const const
qsizetype size() const const
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, ParsingMode mode)
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.
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
void setLocale(const QLocale &locale)
Application * app() const noexcept
QString fromLatin1(QByteArrayView str)
QStack< Component * > stack() const noexcept
QVariant stashTake(const QString &key)
void append(QList< T > &&value)
Engine * engine() const noexcept
Abstract View component for Cutelyst.
View * view(QStringView name={}) const
Controller * controller() const noexcept
void setQuery(const QString &query, 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