cutelyst 5.0.0
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
testengine.cpp
1#include "testengine.hpp"
2
3#include "testengine_p.h"
4
5#include <QBuffer>
6
7using namespace Cutelyst;
8using namespace Qt::Literals::StringLiterals;
9
10TestEngine::TestEngine(Application *app, const QVariantMap &opts)
11 : Engine{app, 0, opts}
12{
13}
14
15int TestEngine::workerId() const
16{
17 return 0;
18}
19
20TestEngine::TestResponse TestEngine::createRequest(const QByteArray &method,
21 const QByteArray &path,
22 const QByteArray &query,
23 const Headers &headers,
24 QByteArray *body)
25{
26 QIODevice *bodyDevice = nullptr;
27 if (headers.header("Sequential").isEmpty()) {
28 bodyDevice = new QBuffer(body);
29 } else {
30 bodyDevice = new SequentialBuffer(body);
31 }
32 bodyDevice->open(QIODevice::ReadOnly);
33
34 Headers headersCL = headers;
35 if (bodyDevice->size()) {
36 headersCL.setContentLength(bodyDevice->size());
37 }
38
39 TestEngineConnection req;
40 req.method = method;
41 QByteArray _path = path;
42 req.setPath(_path);
43 req.query = query;
44 req.protocol = "HTTP/1.1"_ba;
45 req.isSecure = false;
46 req.serverAddress = "127.0.0.1"_ba;
47 req.remoteAddress = QHostAddress(u"127.0.0.1"_s);
48 req.remotePort = 3000;
49 req.remoteUser = QString{};
50 req.headers = headersCL;
51 req.startOfRequest = std::chrono::steady_clock::now();
52 req.body = bodyDevice;
53
54 Q_EMIT processRequestAsync(&req);
55
56 // Due async requests we create a local event loop
57 req.m_eventLoop.exec();
58
59 TestResponse ret;
60 ret.body = req.m_responseData;
61 ret.statusCode = req.m_statusCode;
62 ret.headers = req.m_headers;
63
64 return ret;
65}
66
67TestEngine::TestResponse TestEngine::createRequest(const QByteArray &method,
68 const QString &path,
69 const QByteArray &query,
70 const Headers &headers,
71 QByteArray *body)
72{
73 return createRequest(method, path.toLatin1(), query, headers, body);
74}
75
76bool TestEngine::init()
77{
78 return initApplication() && postForkApplication();
79}
80
81SequentialBuffer::SequentialBuffer(QByteArray *buffer)
82 : buf(buffer)
83{
84}
85
86bool SequentialBuffer::isSequential() const
87{
88 return true;
89}
90
91qint64 SequentialBuffer::bytesAvailable() const
92{
93 return buf->size() + QIODevice::bytesAvailable();
94}
95
96qint64 SequentialBuffer::readData(char *data, qint64 maxlen)
97{
98 QByteArray mid = buf->mid(pos(), maxlen);
99 memcpy(data, mid.data(), mid.size());
100 // Sequential devices consume the body
101 buf->remove(0, mid.size());
102 return mid.size();
103}
104
105qint64 SequentialBuffer::writeData(const char *data, qint64 len)
106{
107 Q_UNUSED(data);
108 Q_UNUSED(len);
109 return -1;
110}
111
112qint64 TestEngineConnection::doWrite(const char *data, qint64 len)
113{
114 m_responseData.append(data, len);
115 return len;
116}
117
118bool TestEngineConnection::writeHeaders(quint16 status, const Headers &headers)
119{
120 m_statusCode = status;
121 m_headers = headers;
122
123 return true;
124}
125
126void TestEngineConnection::processingFinished()
127{
128 m_eventLoop.quit();
129}
130
131#include "moc_testengine.cpp"
The Cutelyst application.
Definition application.h:66
The Cutelyst Engine.
Definition engine.h:20
Container for HTTP headers.
Definition headers.h:24
void setContentLength(qint64 value)
Definition headers.cpp:173
QByteArray header(QAnyStringView key) const noexcept
Definition headers.cpp:393
The Cutelyst namespace holds all public Cutelyst API.
char * data()
bool isEmpty() const const
QByteArray mid(qsizetype pos, qsizetype len) const const
qsizetype size() const const
virtual qint64 bytesAvailable() const const
virtual bool open(QIODeviceBase::OpenMode mode)
virtual qint64 size() const const
QByteArray toLatin1() const const