cutelyst 4.3.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;
8
9TestEngine::TestEngine(Application *app, const QVariantMap &opts)
10 : Engine{app, 0, opts}
11{
12}
13
14int TestEngine::workerId() const
15{
16 return 0;
17}
18
19TestEngine::TestResponse TestEngine::createRequest(const QByteArray &method,
20 const QByteArray &path,
21 const QByteArray &query,
22 const Headers &headers,
23 QByteArray *body)
24{
25 QIODevice *bodyDevice = nullptr;
26 if (headers.header("Sequential"_qba).isEmpty()) {
27 bodyDevice = new QBuffer(body);
28 } else {
29 bodyDevice = new SequentialBuffer(body);
30 }
31 bodyDevice->open(QIODevice::ReadOnly);
32
33 Headers headersCL = headers;
34 if (bodyDevice->size()) {
35 headersCL.setContentLength(bodyDevice->size());
36 }
37
38 TestEngineConnection req;
39 req.method = method;
40 QByteArray _path = path;
41 req.setPath(_path);
42 req.query = query;
43 req.protocol = "HTTP/1.1"_qba;
44 req.isSecure = false;
45 req.serverAddress = "127.0.0.1"_qba;
46 req.remoteAddress = QHostAddress(u"127.0.0.1"_qs);
47 req.remotePort = 3000;
48 req.remoteUser = QString{};
49 req.headers = headersCL;
50 req.startOfRequest = std::chrono::steady_clock::now();
51 req.body = bodyDevice;
52
53 Q_EMIT processRequestAsync(&req);
54
55 // Due async requests we create a local event loop
56 req.m_eventLoop.exec();
57
58 TestResponse ret;
59 ret.body = req.m_responseData;
60 ret.statusCode = req.m_statusCode;
61 ret.headers = req.m_headers;
62
63 return ret;
64}
65
66TestEngine::TestResponse TestEngine::createRequest(const QByteArray &method,
67 const QString &path,
68 const QByteArray &query,
69 const Headers &headers,
70 QByteArray *body)
71{
72 return createRequest(method, path.toLatin1(), query, headers, body);
73}
74
75bool TestEngine::init()
76{
77 return initApplication() && postForkApplication();
78}
79
80QByteArray TestEngine::httpStatus(quint16 status)
81{
82 int len;
83 const auto *statusChar = httpStatusMessage(status, &len);
84 return QByteArray(statusChar + 9, len - 9);
85}
86
87SequentialBuffer::SequentialBuffer(QByteArray *buffer)
88 : buf(buffer)
89{
90}
91
92bool SequentialBuffer::isSequential() const
93{
94 return true;
95}
96
97qint64 SequentialBuffer::bytesAvailable() const
98{
99 return buf->size() + QIODevice::bytesAvailable();
100}
101
102qint64 SequentialBuffer::readData(char *data, qint64 maxlen)
103{
104 QByteArray mid = buf->mid(pos(), maxlen);
105 memcpy(data, mid.data(), mid.size());
106 // Sequential devices consume the body
107 buf->remove(0, mid.size());
108 return mid.size();
109}
110
111qint64 SequentialBuffer::writeData(const char *data, qint64 len)
112{
113 Q_UNUSED(data);
114 Q_UNUSED(len);
115 return -1;
116}
117
118qint64 TestEngineConnection::doWrite(const char *data, qint64 len)
119{
120 m_responseData.append(data, len);
121 return len;
122}
123
124bool TestEngineConnection::writeHeaders(quint16 status, const Headers &headers)
125{
126 m_statusCode = status;
127 m_headers = headers;
128
129 return true;
130}
131
132void TestEngineConnection::processingFinished()
133{
134 m_eventLoop.quit();
135}
136
137#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:172
QByteArray header(QByteArrayView key) const noexcept
Definition headers.cpp:392
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