cutelyst  4.6.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 
7 using namespace Cutelyst;
8 
9 TestEngine::TestEngine(Application *app, const QVariantMap &opts)
10  : Engine{app, 0, opts}
11 {
12 }
13 
14 int TestEngine::workerId() const
15 {
16  return 0;
17 }
18 
19 TestEngine::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 
66 TestEngine::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 
75 bool TestEngine::init()
76 {
77  return initApplication() && postForkApplication();
78 }
79 
80 SequentialBuffer::SequentialBuffer(QByteArray *buffer)
81  : buf(buffer)
82 {
83 }
84 
85 bool SequentialBuffer::isSequential() const
86 {
87  return true;
88 }
89 
90 qint64 SequentialBuffer::bytesAvailable() const
91 {
92  return buf->size() + QIODevice::bytesAvailable();
93 }
94 
95 qint64 SequentialBuffer::readData(char *data, qint64 maxlen)
96 {
97  QByteArray mid = buf->mid(pos(), maxlen);
98  memcpy(data, mid.data(), mid.size());
99  // Sequential devices consume the body
100  buf->remove(0, mid.size());
101  return mid.size();
102 }
103 
104 qint64 SequentialBuffer::writeData(const char *data, qint64 len)
105 {
106  Q_UNUSED(data);
107  Q_UNUSED(len);
108  return -1;
109 }
110 
111 qint64 TestEngineConnection::doWrite(const char *data, qint64 len)
112 {
113  m_responseData.append(data, len);
114  return len;
115 }
116 
117 bool TestEngineConnection::writeHeaders(quint16 status, const Headers &headers)
118 {
119  m_statusCode = status;
120  m_headers = headers;
121 
122  return true;
123 }
124 
125 void TestEngineConnection::processingFinished()
126 {
127  m_eventLoop.quit();
128 }
129 
130 #include "moc_testengine.cpp"
bool isEmpty() const const
Container for HTTP headers.
Definition: headers.h:23
virtual bool open(QIODeviceBase::OpenMode mode)
virtual qint64 size() const const
The Cutelyst namespace holds all public Cutelyst API.
QByteArray mid(qsizetype pos, qsizetype len) const const
virtual qint64 bytesAvailable() const const
QByteArray header(QByteArrayView key) const noexcept
Definition: headers.cpp:392
QByteArray toLatin1() const const
char * data()
The Cutelyst application.
Definition: application.h:72
void setContentLength(qint64 value)
Definition: headers.cpp:172
qsizetype size() const const
The Cutelyst Engine.
Definition: engine.h:19
QByteArray & remove(qsizetype pos, qsizetype len)