18 #include "enginerequest.h" 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);
110 const auto cookies = res->
cookies();
111 for (
const QNetworkCookie &cookie : cookies) {
112 headers.
pushHeader(QStringLiteral(
"SET_COOKIE"), QString::fromLatin1(cookie.toRawForm()));
123 qint64 size = response->
size();
132 status |= EngineRequest::FinalizedHeaders;
138 if (!(
status & EngineRequest::Chunked)) {
140 }
else if (!(
status & EngineRequest::ChunkedDone)) {
141 const QByteArray chunkSize = QByteArray::number(len, 16).toUpper();
143 chunk.reserve(
int(len + chunkSize.size() + 4));
144 chunk.append(chunkSize).append(
"\r\n", 2)
145 .append(data,
int(len)).append(
"\r\n", 2);
147 qint64 retWrite =
doWrite(chunk.data(), chunk.size());
151 status |= EngineRequest::ChunkedDone;
154 return retWrite == chunk.size() ? len : -1;
159 bool EngineRequest::webSocketHandshake(
const QString &key,
const QString &origin,
const QString &protocol)
161 if (
status & EngineRequest::FinalizedHeaders) {
165 if (webSocketHandshakeDo(key, origin,
protocol)) {
166 status |= EngineRequest::FinalizedHeaders | EngineRequest::Async | EngineRequest::IOWrite;
173 bool EngineRequest::webSocketSendTextMessage(
const QString &message)
179 bool EngineRequest::webSocketSendBinaryMessage(
const QByteArray &message)
185 bool EngineRequest::webSocketSendPing(
const QByteArray &payload)
191 bool EngineRequest::webSocketClose(quint16 code,
const QString &reason)
202 bool EngineRequest::webSocketHandshakeDo(
const QString &key,
const QString &origin,
const QString &protocol)
217 char *data = rawPath;
218 const char *inputPtr = data;
220 bool skipUtf8 =
true;
222 for (
int i = 0; i < len; ++i, ++outlen) {
223 const char c = inputPtr[i];
224 if (c ==
'%' && i + 2 < len) {
225 int a = inputPtr[++i];
226 int b = inputPtr[++i];
228 if (a >=
'0' && a <=
'9') a -=
'0';
229 else if (a >=
'a' && a <=
'f') a = a -
'a' + 10;
230 else if (a >=
'A' && a <=
'F') a = a -
'A' + 10;
232 if (b >=
'0' && b <=
'9') b -=
'0';
233 else if (b >=
'a' && b <=
'f') b = b -
'a' + 10;
234 else if (b >=
'A' && b <=
'F') b = b -
'A' + 10;
236 *data++ = char((a << 4) | b);
238 }
else if (c ==
'+') {
246 path = QString::fromLatin1(rawPath, outlen);
248 path = QString::fromUtf8(rawPath, outlen);
252 #include "moc_enginerequest.cpp"
QString path
Call setPath() instead.
void setContentType(const QString &type)
QString protocol
The protocol requested by the user agent 'HTTP1/1'.
QIODevice * body
The QIODevice containing the body (if any) of the request.
qint64 write(const char *data, qint64 len)
Called by Response to manually write data.
virtual qint64 size() const override
QString join(const QString &sep) const const
void setStatus(quint16 status)
virtual void finalizeError()
Engines should overwrite this if they want to to make custom error messages.
virtual qint64 doWrite(const char *data, qint64 len)=0
Reimplement this to do the RAW writing to the client.
QList< QNetworkCookie > cookies() const
QStringList errors() const
Returns a list of errors that were defined.
Context * context
The Cutelyst::Context of this request.
Response * response() const
Headers headers
The request headers.
The Cutelyst namespace holds all public Cutelyst API.
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.
virtual bool finalizeHeaders()
Finalize the headers, and call doWriteHeader(), reimplemententions must call this first.
Q_REQUIRED_RESULT QByteArray & body()
Status status
Connection status.
void setBody(QIODevice *body)
virtual void finalizeBody()
Engines must reimplement this to write the response body back to the caller.
virtual bool writeHeaders(quint16 status, const Headers &headers)=0
Reimplement this to write the headers back to the client.
virtual void finalizeCookies()
Reimplement if you need a custom way to Set-Cookie, the default implementation writes them to c->res(...
void finalize()
Called by Application to deal with finalizing cookies, headers and body.
virtual void processingFinished()
This is called when the Application chain is finished processing this request, here the request can s...
bool error() const
Returns true if an error was set.
QIODevice * bodyDevice() const