11#include <QCryptographicHash>
13#include <QtCore/QJsonDocument>
18 : d_ptr(new ResponsePrivate(defaultHeaders, engineRequest))
39 if (!(d->engineRequest->status & EngineRequest::FinalizedHeaders)) {
40 if (d->headers.header(QStringLiteral(
"TRANSFER_ENCODING")).compare(u
"chunked") == 0) {
41 d->engineRequest->status |= EngineRequest::IOWrite | EngineRequest::Chunked;
45 d->headers.setHeader(QStringLiteral(
"CONNECTION"), QStringLiteral(
"close"));
46 d->engineRequest->status |= EngineRequest::IOWrite;
48 delete d->bodyIODevice;
49 d->bodyIODevice =
nullptr;
52 d->engineRequest->finalizeHeaders();
55 return d->engineRequest->write(data, len);
60 delete d_ptr->bodyIODevice;
79 return !d->bodyData.isEmpty() || d->bodyIODevice ||
80 d->engineRequest->status & EngineRequest::IOWrite;
86 if (d->bodyIODevice) {
87 delete d->bodyIODevice;
88 d->bodyIODevice =
nullptr;
97 return d->bodyIODevice;
105 if (!(d->engineRequest->status & EngineRequest::IOWrite)) {
107 if (d->bodyIODevice) {
108 delete d->bodyIODevice;
110 d->bodyIODevice =
body;
117 d->setBodyData(
body);
124 d->setBodyData(
body);
125 d->headers.setContentType(QStringLiteral(
"application/json"));
131 d->setBodyData(json.
toUtf8());
132 d->headers.setContentType(QStringLiteral(
"application/json"));
138 d->setBodyData(json);
139 d->headers.setContentType(QStringLiteral(
"application/json"));
146 d->setBodyData(
body);
147 d->headers.setContentType(QStringLiteral(
"application/json"));
154 d->setBodyData(
body);
155 d->headers.setContentType(QStringLiteral(
"application/json"));
161 return d->headers.contentEncoding();
167 Q_ASSERT_X(!(d->engineRequest->status & EngineRequest::FinalizedHeaders),
168 "setContentEncoding",
169 "setting a header value after finalize_headers and the response callback has been "
170 "called. Not what you want.");
172 d->headers.setContentEncoding(encoding);
178 return d->headers.contentLength();
184 Q_ASSERT_X(!(d->engineRequest->status & EngineRequest::FinalizedHeaders),
186 "setting a header value after finalize_headers and the response callback has been "
187 "called. Not what you want.");
189 d->headers.setContentLength(length);
195 return d->headers.contentType();
201 return d->headers.contentTypeCharset();
210#if (QT_VERSION < QT_VERSION_CHECK(6, 1, 0))
221 return d->cookies.values();
224#if (QT_VERSION < QT_VERSION_CHECK(6, 1, 0))
228 return d->cuteCookies.values();
238#if (QT_VERSION < QT_VERSION_CHECK(6, 1, 0))
239void Response::setCuteCookie(
const Cookie &cookie)
254#if (QT_VERSION < QT_VERSION_CHECK(6, 1, 0))
267 return d->cookies.remove(name);
270#if (QT_VERSION < QT_VERSION_CHECK(6, 1, 0))
271int Response::removeCuteCookies(
const QByteArray &name)
274 return d->cuteCookies.remove(name);
286 qCDebug(CUTELYST_RESPONSE) <<
"Redirecting to" <<
location <<
status;
288 d->headers.setHeader(QStringLiteral(
"LOCATION"),
location);
289 d->headers.setContentType(QStringLiteral(
"text/html; charset=utf-8"));
292<html xmlns="http://www.w3.org/1999/xhtml">
297 <p>This item has moved <a href=")V0G0N") +
304 d->headers.removeHeader(QStringLiteral(
"LOCATION"));
305 qCDebug(CUTELYST_ENGINE) <<
"Invalid redirect removing header" << url <<
status;
317 if (url.
matches(d->engineRequest->context->req()->uri(),
334 return d->headers.header(field);
340 Q_ASSERT_X(!(d->engineRequest->status & EngineRequest::FinalizedHeaders),
342 "setting a header value after finalize_headers and the response callback has been "
343 "called. Not what you want.");
345 d->headers.setHeader(field, value);
357 return d->engineRequest->status & EngineRequest::FinalizedHeaders;
368 if (d->engineRequest->status & EngineRequest::IOWrite) {
370 }
else if (d->bodyIODevice) {
371 return d->bodyIODevice->size();
373 return d->bodyData.size();
382 return d->engineRequest->webSocketHandshake(key, origin, protocol);
388 return d->engineRequest->webSocketSendTextMessage(message);
394 return d->engineRequest->webSocketSendBinaryMessage(message);
400 return d->engineRequest->webSocketSendPing(payload);
406 return d->engineRequest->webSocketClose(code, reason);
409void ResponsePrivate::setBodyData(
const QByteArray &body)
411 if (!(engineRequest->status & EngineRequest::IOWrite)) {
414 bodyIODevice =
nullptr;
417 headers.setContentLength(body.
size());
421#include "moc_response.cpp"
void redirect(const QUrl &url, quint16 status=Found)
Headers & headers() noexcept
QVariant cookie(const QByteArray &name) const
QUrl location() const noexcept
qint64 contentLength() const
bool hasBody() const noexcept
void setStatus(quint16 status) noexcept
Response(const Headers &defaultHeaders, EngineRequest *conn=nullptr)
void redirectSafe(const QUrl &url, const QUrl &fallback)
void setBody(QIODevice *body)
QIODevice * bodyDevice() const
QString contentEncoding() const
void setJsonArrayBody(const QJsonArray &array)
void setCookies(const QList< QNetworkCookie > &cookies)
virtual qint64 writeData(const char *data, qint64 len) override
bool webSocketHandshake(const QString &key={}, const QString &origin={}, const QString &protocol={})
Sends the websocket handshake, if no parameters are defined it will use header data.
virtual bool isSequential() const noexcept override
bool webSocketClose(quint16 code=Response::CloseCodeNormal, const QString &reason={})
Sends a WebSocket close frame, with both optional close code and a string reason.
QList< QNetworkCookie > cookies() const
QString header(const QString &field) const
QString contentType() const
bool webSocketPing(const QByteArray &payload={})
Sends a WebSocket ping with an optional payload limited to 125 bytes, which will be truncated if larg...
QString contentTypeCharset() const
void setContentLength(qint64 length)
int removeCookies(const QByteArray &name)
void setContentEncoding(const QString &encoding)
void setJsonObjectBody(const QJsonObject &object)
bool webSocketBinaryMessage(const QByteArray &message)
Sends a WebSocket binary message.
virtual qint64 readData(char *data, qint64 maxlen) override
void setJsonBody(const QJsonDocument &documment)
Q_REQUIRED_RESULT QByteArray & body()
virtual qint64 size() const noexcept override
bool webSocketTextMessage(const QString &message)
Sends a WebSocket text message.
void setHeader(const QString &field, const QString &value)
quint16 status() const noexcept
void setCookie(const QNetworkCookie &cookie)
bool isFinalizedHeaders() const noexcept
The Cutelyst namespace holds all public Cutelyst API.
bool isOpen() const const
bool isReadable() const const
virtual bool open(OpenMode mode)
QByteArray toJson() const const
QByteArray name() const const
QString fromLatin1(const char *str, int size)
QByteArray toUtf8() const const
bool isValid() const const
bool matches(const QUrl &url, FormattingOptions options) const const
QByteArray toEncoded(FormattingOptions options) const const
QVariant fromValue(const T &value)