18 #include "response_p.h"
20 #include "context_p.h"
25 #include <QtCore/QJsonDocument>
27 #include <QCryptographicHash>
33 : d_ptr(new ResponsePrivate(defaultHeaders, engineRequest))
54 if (!(d->engineRequest->status & EngineRequest::FinalizedHeaders)) {
55 if (d->headers.header(QStringLiteral(
"TRANSFER_ENCODING")) ==
QLatin1String(
"chunked")) {
56 d->engineRequest->status |= EngineRequest::IOWrite | EngineRequest::Chunked;
60 d->headers.setHeader(QStringLiteral(
"CONNECTION"), QStringLiteral(
"close"));
61 d->engineRequest->status |= EngineRequest::IOWrite;
63 delete d->bodyIODevice;
64 d->bodyIODevice =
nullptr;
67 d->engineRequest->finalizeHeaders();
70 return d->engineRequest->write(data, len);
75 delete d_ptr->bodyIODevice;
94 return !d->bodyData.isEmpty() || d->bodyIODevice || d->engineRequest->status & EngineRequest::IOWrite;
100 if (d->bodyIODevice) {
101 delete d->bodyIODevice;
102 d->bodyIODevice =
nullptr;
111 return d->bodyIODevice;
119 if (!(d->engineRequest->status & EngineRequest::IOWrite)) {
121 if (d->bodyIODevice) {
122 delete d->bodyIODevice;
124 d->bodyIODevice =
body;
131 d->setBodyData(
body);
138 d->setBodyData(
body);
139 d->headers.setContentType(QStringLiteral(
"application/json"));
145 d->setBodyData(json.
toUtf8());
146 d->headers.setContentType(QStringLiteral(
"application/json"));
152 d->setBodyData(json);
153 d->headers.setContentType(QStringLiteral(
"application/json"));
160 d->setBodyData(
body);
161 d->headers.setContentType(QStringLiteral(
"application/json"));
168 d->setBodyData(
body);
169 d->headers.setContentType(QStringLiteral(
"application/json"));
175 return d->headers.contentEncoding();
181 Q_ASSERT_X(!(d->engineRequest->status & EngineRequest::FinalizedHeaders),
182 "setContentEncoding",
183 "setting a header value after finalize_headers and the response callback has been called. Not what you want.");
185 d->headers.setContentEncoding(encoding);
191 return d->headers.contentLength();
197 Q_ASSERT_X(!(d->engineRequest->status & EngineRequest::FinalizedHeaders),
199 "setting a header value after finalize_headers and the response callback has been called. Not what you want.");
201 d->headers.setContentLength(length);
207 return d->headers.contentType();
213 return d->headers.contentTypeCharset();
225 return d->cookies.values();
245 return d->cookies.remove(name);
256 qCDebug(CUTELYST_RESPONSE) <<
"Redirecting to" <<
location <<
status;
258 d->headers.setHeader(QStringLiteral(
"LOCATION"),
location);
259 d->headers.setContentType(QStringLiteral(
"text/html; charset=utf-8"));
262 <html xmlns="http://www.w3.org/1999/xhtml">
273 d->headers.removeHeader(QStringLiteral(
"LOCATION"));
274 qCDebug(CUTELYST_ENGINE) <<
"Invalid redirect removing header" << url <<
status;
302 return d->headers.header(field);
308 Q_ASSERT_X(!(d->engineRequest->status & EngineRequest::FinalizedHeaders),
310 "setting a header value after finalize_headers and the response callback has been called. Not what you want.");
312 d->headers.setHeader(field, value);
324 return d->engineRequest->status & EngineRequest::FinalizedHeaders;
335 if (d->engineRequest->status & EngineRequest::IOWrite) {
337 }
else if (d->bodyIODevice) {
338 return d->bodyIODevice->size();
340 return d->bodyData.size();
347 return d->engineRequest->webSocketHandshake(key, origin, protocol);
353 return d->engineRequest->webSocketSendTextMessage(message);
359 return d->engineRequest->webSocketSendBinaryMessage(message);
365 return d->engineRequest->webSocketSendPing(payload);
371 return d->engineRequest->webSocketClose(code, reason);
374 void ResponsePrivate::setBodyData(
const QByteArray &body)
376 if (!(engineRequest->status & EngineRequest::IOWrite)) {
379 bodyIODevice =
nullptr;
382 headers.setContentLength(body.
size());
386 #include "moc_response.cpp"
void redirect(const QUrl &url, quint16 status=Found)
QVariant cookie(const QByteArray &name) const
qint64 contentLength() const
QString header(const QString &field) const
bool webSocketTextMessage(const QString &message)
Sends a WebSocket text message.
bool webSocketPing(const QByteArray &payload={})
Sends a WebSocket ping with an optional payload limited to 125 bytes, which will be truncated if larg...
Response(const Headers &defaultHeaders, EngineRequest *conn=nullptr)
void setBody(QIODevice *body)
QIODevice * bodyDevice() const
QString contentEncoding() const
virtual qint64 size() const override
void setJsonArrayBody(const QJsonArray &array)
void redirectSafe(const QUrl &url, const QUrl &fallback)
void setCookies(const QList< QNetworkCookie > &cookies)
virtual qint64 writeData(const char *data, qint64 len) override
QList< QNetworkCookie > cookies() const
bool webSocketBinaryMessage(const QByteArray &message)
Sends a WebSocket binary message.
virtual bool isSequential() const 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.
QString contentType() const
QString contentTypeCharset() const
void setContentLength(qint64 length)
int removeCookies(const QByteArray &name)
void setContentEncoding(const QString &encoding)
void setJsonObjectBody(const QJsonObject &object)
void setHeader(const QString &field, const QString &value)
virtual qint64 readData(char *data, qint64 maxlen) override
bool isFinalizedHeaders() const
void setJsonBody(const QJsonDocument &documment)
void setStatus(quint16 status)
Q_REQUIRED_RESULT QByteArray & body()
bool webSocketClose(quint16 code=Response::CloseCodeNormal, const QString &reason={})
Sends a WebSocket close frame, with both optional close code and a string reason.
void setCookie(const QNetworkCookie &cookie)
The Cutelyst namespace holds all public Cutelyst API.
virtual bool open(QIODevice::OpenMode mode)
QByteArray toJson() const const
QString fromLatin1(const char *str, int size)
QByteArray toLatin1() const const
QByteArray toUtf8() const const
bool isValid() const const
bool matches(const QUrl &url, QUrl::FormattingOptions options) const const
QByteArray toEncoded(QUrl::FormattingOptions options) const const
QVariant fromValue(const T &value)