22 #include <Cutelyst/response_p.h>
23 #include <Cutelyst/Context>
25 #include <QLoggingCategory>
26 Q_LOGGING_CATEGORY(CUTELYST_ENGINEREQUEST,
"cutelyst.engine_request", QtWarningMsg)
30 EngineRequest::EngineRequest()
35 EngineRequest::~EngineRequest()
42 if (!(
status & EngineRequest::Chunked)) {
47 if (!
body->isSequential()) {
51 char block[64 * 1024];
52 while (!
body->atEnd()) {
53 qint64 in =
body->read(block,
sizeof(block));
58 if (
write(block, in) != in) {
59 qCWarning(CUTELYST_ENGINEREQUEST) <<
"Failed to write body";
64 const QByteArray bodyByteArray = response->
body();
65 write(bodyByteArray.constData(), bodyByteArray.size());
67 }
else if (!(
status & EngineRequest::ChunkedDone)) {
90 res->
setStatus(Response::InternalServerError);
103 status |= EngineRequest::Finalized;
111 const auto cookies = res->
cookies();
112 for (
const QNetworkCookie &cookie : cookies) {
113 headers.
pushHeader(QStringLiteral(
"SET_COOKIE"), QString::fromLatin1(cookie.toRawForm()));
124 qint64 size = response->
size();
133 status |= EngineRequest::FinalizedHeaders;
139 if (!(
status & EngineRequest::Chunked)) {
141 }
else if (!(
status & EngineRequest::ChunkedDone)) {
142 const QByteArray chunkSize = QByteArray::number(len, 16).toUpper();
144 chunk.reserve(
int(len + chunkSize.size() + 4));
145 chunk.append(chunkSize).append(
"\r\n", 2)
146 .append(data,
int(len)).append(
"\r\n", 2);
148 qint64 retWrite =
doWrite(chunk.data(), chunk.size());
152 status |= EngineRequest::ChunkedDone;
155 return retWrite == chunk.size() ? len : -1;
160 bool EngineRequest::webSocketHandshake(
const QString &key,
const QString &origin,
const QString &protocol)
162 if (
status & EngineRequest::FinalizedHeaders) {
166 if (webSocketHandshakeDo(key, origin,
protocol)) {
167 status |= EngineRequest::FinalizedHeaders | EngineRequest::Async | EngineRequest::IOWrite;
177 bool EngineRequest::webSocketSendTextMessage(
const QString &message)
183 bool EngineRequest::webSocketSendBinaryMessage(
const QByteArray &message)
189 bool EngineRequest::webSocketSendPing(
const QByteArray &payload)
195 bool EngineRequest::webSocketClose(quint16 code,
const QString &reason)
206 bool EngineRequest::webSocketHandshakeDo(
const QString &key,
const QString &origin,
const QString &protocol)
221 char *data = rawPath;
222 const char *inputPtr = data;
224 bool skipUtf8 =
true;
226 for (
int i = 0; i < len; ++i, ++outlen) {
227 const char c = inputPtr[i];
228 if (c ==
'%' && i + 2 < len) {
229 int a = inputPtr[++i];
230 int b = inputPtr[++i];
232 if (a >=
'0' && a <=
'9') a -=
'0';
233 else if (a >=
'a' && a <=
'f') a = a -
'a' + 10;
234 else if (a >=
'A' && a <=
'F') a = a -
'A' + 10;
236 if (b >=
'0' && b <=
'9') b -=
'0';
237 else if (b >=
'a' && b <=
'f') b = b -
'a' + 10;
238 else if (b >=
'A' && b <=
'F') b = b -
'A' + 10;
240 *data++ = char((a << 4) | b);
242 }
else if (c ==
'+') {
250 path = QString::fromLatin1(rawPath, outlen);
252 path = QString::fromUtf8(rawPath, outlen);
256 #include "moc_enginerequest.cpp"