9 #include <Cutelyst/response_p.h>
10 #include <Cutelyst/Context>
12 #include <QLoggingCategory>
13 Q_LOGGING_CATEGORY(CUTELYST_ENGINEREQUEST,
"cutelyst.engine_request", QtWarningMsg)
17 EngineRequest::EngineRequest()
22 EngineRequest::~EngineRequest()
29 if (!(
status & EngineRequest::Chunked)) {
34 if (!
body->isSequential()) {
38 char block[64 * 1024];
39 while (!
body->atEnd()) {
40 qint64 in =
body->read(block,
sizeof(block));
45 if (
write(block, in) != in) {
46 qCWarning(CUTELYST_ENGINEREQUEST) <<
"Failed to write body";
51 const QByteArray bodyByteArray = response->
body();
52 write(bodyByteArray.constData(), bodyByteArray.size());
54 }
else if (!(
status & EngineRequest::ChunkedDone)) {
77 res->
setStatus(Response::InternalServerError);
90 status |= EngineRequest::Finalized;
98 const auto cookies = res->
cookies();
99 for (
const QNetworkCookie &cookie : cookies) {
100 headers.
pushHeader(QStringLiteral(
"SET_COOKIE"), QString::fromLatin1(cookie.toRawForm()));
111 qint64 size = response->
size();
120 status |= EngineRequest::FinalizedHeaders;
126 if (!(
status & EngineRequest::Chunked)) {
128 }
else if (!(
status & EngineRequest::ChunkedDone)) {
129 const QByteArray chunkSize = QByteArray::number(len, 16).toUpper();
131 chunk.reserve(
int(len + chunkSize.size() + 4));
132 chunk.append(chunkSize).append(
"\r\n", 2)
133 .append(data,
int(len)).append(
"\r\n", 2);
135 qint64 retWrite =
doWrite(chunk.data(), chunk.size());
139 status |= EngineRequest::ChunkedDone;
142 return retWrite == chunk.size() ? len : -1;
147 bool EngineRequest::webSocketHandshake(
const QString &key,
const QString &origin,
const QString &protocol)
149 if (
status & EngineRequest::FinalizedHeaders) {
153 if (webSocketHandshakeDo(key, origin,
protocol)) {
154 status |= EngineRequest::FinalizedHeaders | EngineRequest::Async | EngineRequest::IOWrite;
164 bool EngineRequest::webSocketSendTextMessage(
const QString &message)
170 bool EngineRequest::webSocketSendBinaryMessage(
const QByteArray &message)
176 bool EngineRequest::webSocketSendPing(
const QByteArray &payload)
182 bool EngineRequest::webSocketClose(quint16 code,
const QString &reason)
193 bool EngineRequest::webSocketHandshakeDo(
const QString &key,
const QString &origin,
const QString &protocol)
208 char *data = rawPath;
209 const char *inputPtr = data;
211 bool skipUtf8 =
true;
213 for (
int i = 0; i < len; ++i, ++outlen) {
214 const char c = inputPtr[i];
215 if (c ==
'%' && i + 2 < len) {
216 int a = inputPtr[++i];
217 int b = inputPtr[++i];
219 if (a >=
'0' && a <=
'9') a -=
'0';
220 else if (a >=
'a' && a <=
'f') a = a -
'a' + 10;
221 else if (a >=
'A' && a <=
'F') a = a -
'A' + 10;
223 if (b >=
'0' && b <=
'9') b -=
'0';
224 else if (b >=
'a' && b <=
'f') b = b -
'a' + 10;
225 else if (b >=
'A' && b <=
'F') b = b -
'A' + 10;
227 *data++ = char((a << 4) | b);
229 }
else if (c ==
'+') {
237 path = QString::fromLatin1(rawPath, outlen);
239 path = QString::fromUtf8(rawPath, outlen);
243 #include "moc_enginerequest.cpp"
QStringList errors() const noexcept
Returns a list of errors that were defined.
void finalize()
finalize the request right away this is automatically called at the end of the actions chain
bool error() const noexcept
Returns true if an error was set.
Response * response() const noexcept
virtual qint64 doWrite(const char *data, qint64 len)=0
Reimplement this to do the RAW writing to the client.
Context * context
The Cutelyst::Context of this request.
virtual void finalizeBody()
Engines must reimplement this to write the response body back to the caller.
virtual void finalizeError()
Engines should overwrite this if they want to to make custom error messages.
QString path
Call setPath() instead.
Status status
Connection status.
void finalize()
Called by Application to deal with finalizing cookies, headers and body.
qint64 write(const char *data, qint64 len)
Called by Response to manually write data.
void setPath(char *rawPath, const int len)
This method sets the path and already does the decoding so that it is done a single time.
Headers headers
The request headers.
virtual bool writeHeaders(quint16 status, const Headers &headers)=0
Reimplement this to write the headers back to the client.
virtual bool finalizeHeaders()
Finalize the headers, and call doWriteHeader(), reimplemententions must call this first.
virtual void finalizeCookies()
Reimplement if you need a custom way to Set-Cookie, the default implementation writes them to c->res(...
QIODevice * body
The QIODevice containing the body (if any) of the request.
QString protocol
The protocol requested by the user agent 'HTTP1/1'.
virtual void processingFinished()
This is called when the Application chain is finished processing this request, here the request can s...
void setStatus(quint16 status) noexcept
Headers & headers() noexcept
void setBody(QIODevice *body)
QIODevice * bodyDevice() const
QList< QNetworkCookie > cookies() const
virtual qint64 size() const noexcept override
Q_REQUIRED_RESULT QByteArray & body()
quint16 status() const noexcept
void setContentType(const QString &type)
The Cutelyst namespace holds all public Cutelyst API.