18 #include "response_p.h"
20 #include "context_p.h"
22 #include "enginerequest.h"
25 #include <QtCore/QJsonDocument>
27 #include <QCryptographicHash>
33 : d_ptr(new ResponsePrivate(defaultHeaders, engineRequest))
35 open(QIODevice::WriteOnly);
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;
65 d->bodyData = QByteArray();
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)) {
120 d->bodyData = QByteArray();
121 if (d->bodyIODevice) {
122 delete d->bodyIODevice;
124 d->bodyIODevice =
body;
131 d->setBodyData(
body);
137 const QByteArray
body = documment.toJson(QJsonDocument::Compact);
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"));
159 const QByteArray
body = QJsonDocument(
object).toJson(QJsonDocument::Compact);
160 d->setBodyData(
body);
161 d->headers.setContentType(QStringLiteral(
"application/json"));
167 const QByteArray
body = QJsonDocument(array).toJson(QJsonDocument::Compact);
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();
219 return QVariant::fromValue(d->cookies.value(name));
225 return d->cookies.values();
245 return d->cookies.remove(name);
255 const QString
location = QString::fromLatin1(url.toEncoded(QUrl::FullyEncoded));
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"));
261 const QString buf = QStringLiteral(
263 "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
265 " <title>Moved</title>\n"
268 " <p>This item has moved <a href=\"") +
location +
269 QStringLiteral(
"\">here</a>.</p>\n"
274 d->headers.removeHeader(QStringLiteral(
"LOCATION"));
275 qCDebug(CUTELYST_ENGINE) <<
"Invalid redirect removing header" << url <<
status;
287 if (url.matches(d->engineRequest->context->req()->uri(), QUrl::RemovePath | QUrl::RemoveQuery)) {
303 return d->headers.header(field);
309 Q_ASSERT_X(!(d->engineRequest->status & EngineRequest::FinalizedHeaders),
311 "setting a header value after finalize_headers and the response callback has been called. Not what you want.");
313 d->headers.setHeader(field, value);
325 return d->engineRequest->status & EngineRequest::FinalizedHeaders;
336 if (d->engineRequest->status & EngineRequest::IOWrite) {
338 }
else if (d->bodyIODevice) {
339 return d->bodyIODevice->size();
341 return d->bodyData.size();
348 return d->engineRequest->webSocketHandshake(key, origin, protocol);
354 return d->engineRequest->webSocketSendTextMessage(message);
360 return d->engineRequest->webSocketSendBinaryMessage(message);
366 return d->engineRequest->webSocketSendPing(payload);
372 return d->engineRequest->webSocketClose(code, reason);
375 void ResponsePrivate::setBodyData(
const QByteArray &body)
377 if (!(engineRequest->status & EngineRequest::IOWrite)) {
380 bodyIODevice =
nullptr;
383 headers.setContentLength(body.size());
387 #include "moc_response.cpp"