cutelyst  4.9.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 using namespace Qt::Literals::StringLiterals;
9 
10 TestEngine::TestEngine(Application *app, const QVariantMap &opts)
11  : Engine{app, 0, opts}
12 {
13 }
14 
15 int TestEngine::workerId() const
16 {
17  return 0;
18 }
19 
20 TestEngine::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"_ba).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 
67 TestEngine::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 
76 bool TestEngine::init()
77 {
78  return initApplication() && postForkApplication();
79 }
80 
81 SequentialBuffer::SequentialBuffer(QByteArray *buffer)
82  : buf(buffer)
83 {
84 }
85 
86 bool SequentialBuffer::isSequential() const
87 {
88  return true;
89 }
90 
91 qint64 SequentialBuffer::bytesAvailable() const
92 {
93  return buf->size() + QIODevice::bytesAvailable();
94 }
95 
96 qint64 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 
105 qint64 SequentialBuffer::writeData(const char *data, qint64 len)
106 {
107  Q_UNUSED(data);
108  Q_UNUSED(len);
109  return -1;
110 }
111 
112 qint64 TestEngineConnection::doWrite(const char *data, qint64 len)
113 {
114  m_responseData.append(data, len);
115  return len;
116 }
117 
118 bool TestEngineConnection::writeHeaders(quint16 status, const Headers &headers)
119 {
120  m_statusCode = status;
121  m_headers = headers;
122 
123  return true;
124 }
125 
126 void TestEngineConnection::processingFinished()
127 {
128  m_eventLoop.quit();
129 }
130 
131 #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:393
QByteArray toLatin1() const const
char * data()
The Cutelyst application.
Definition: application.h:72
void setContentLength(qint64 value)
Definition: headers.cpp:173
qsizetype size() const const
The Cutelyst Engine.
Definition: engine.h:19
QByteArray & remove(qsizetype pos, qsizetype len)