diff --git a/src/httpdata.cpp b/src/httpdata.cpp index 5d07626a..5b4b02ef 100644 --- a/src/httpdata.cpp +++ b/src/httpdata.cpp @@ -38,7 +38,7 @@ HttpResponse& HttpData::getResponse() return m_HttpResponse; } -void HttpData::setResponse(const QJsonObject& json) +void HttpData::setResponse(const QJsonDocument& json) { getResponse().setJson(json); } @@ -51,7 +51,7 @@ void HttpData::setErrorResponse(const QString& msg) void HttpData::setErrorResponse(const QString &msg, HttpError code) { getResponse().setStatus(static_cast(code)); - getResponse().getJson()["error"] = msg; + getResponse().getJson().setObject({{"error", msg}}); } void HttpData::setErrorResponse(const QJsonObject& json) @@ -62,7 +62,7 @@ void HttpData::setErrorResponse(const QJsonObject& json) void HttpData::setErrorResponse(const QJsonObject &json, HttpError code) { getResponse().setStatus(static_cast(code)); - getResponse().setJson(json); + getResponse().setJson(QJsonDocument(json)); } const QUuid& HttpData::getUid() const diff --git a/src/httpdata.h b/src/httpdata.h index d1110d97..d397e093 100644 --- a/src/httpdata.h +++ b/src/httpdata.h @@ -46,7 +46,7 @@ class QTTPSHARED_EXPORT HttpData * * This is the same as getResponse().setJson(); */ - void setResponse(const QJsonObject& json); + void setResponse(const QJsonDocument &json); //! Quick and easy way to set error messages. void setErrorResponse(const QString& msg); diff --git a/src/httprequest.cpp b/src/httprequest.cpp index 0d895529..05e414ba 100644 --- a/src/httprequest.cpp +++ b/src/httprequest.cpp @@ -59,7 +59,7 @@ HttpMethod HttpRequest::getMethod(bool strictComparison) const return m_MethodEnum; } -const QJsonObject& HttpRequest::getJson() const +const QJsonDocument& HttpRequest::getJson() const { if(!m_Json.isEmpty()) { @@ -86,7 +86,9 @@ const QJsonObject& HttpRequest::getJson() const QList > list = getQuery().queryItems(); for(auto i = list.begin(); i != list.end(); ++i) { - m_Json.insert(i->first, i->second); + QJsonObject old = m_Json.object(); + old.insert(i->first, i->second); + m_Json.setObject(old); } return m_Json; diff --git a/src/httprequest.h b/src/httprequest.h index ffca1142..8ec965e8 100644 --- a/src/httprequest.h +++ b/src/httprequest.h @@ -54,7 +54,7 @@ class QTTPSHARED_EXPORT HttpRequest * should be called before dispatching to multiple threads (if there's some * reason for multiple threads). */ - const QJsonObject& getJson() const; + const QJsonDocument& getJson() const; const QByteArray& getBody() const; @@ -84,7 +84,7 @@ class QTTPSHARED_EXPORT HttpRequest native::http::QttpRequest * m_Request; HttpUrl m_HttpUrl; mutable HttpMethod m_MethodEnum; - mutable QJsonObject m_Json; + mutable QJsonDocument m_Json; QUrlQuery m_Query; }; diff --git a/src/httpresponse.cpp b/src/httpresponse.cpp index 81e65a0c..ecf762f2 100644 --- a/src/httpresponse.cpp +++ b/src/httpresponse.cpp @@ -46,17 +46,17 @@ HttpStatus HttpResponse::getStatus() const return m_Status; } -QJsonObject& HttpResponse::getJson() +QJsonDocument& HttpResponse::getJson() { return m_Json; } -const QJsonObject& HttpResponse::getJson() const +const QJsonDocument& HttpResponse::getJson() const { return m_Json; } -void HttpResponse::setJson(const QJsonObject& json) +void HttpResponse::setJson(const QJsonDocument& json) { m_Json = json; } @@ -80,16 +80,15 @@ bool HttpResponse::finish(const string& body) return m_Response->close(); } -bool HttpResponse::finish(const QJsonObject& json) +bool HttpResponse::finish(const QJsonDocument& json) { LOG_TRACE; setHeader("Content-Type", "application/json"); - QJsonDocument doc(json); #ifdef QTTP_FORMAT_JSON_RESPONSE - return finish(doc.toJson(QJsonDocument::Indented)); + return finish(json.toJson(QJsonDocument::Indented)); #else - return finish(doc.toJson(QJsonDocument::Compact)); + return finish(json.toJson(QJsonDocument::Compact)); #endif } diff --git a/src/httpresponse.h b/src/httpresponse.h index d37e4c3a..e32dc586 100644 --- a/src/httpresponse.h +++ b/src/httpresponse.h @@ -44,9 +44,9 @@ class QTTPSHARED_EXPORT HttpResponse * As an alternative, the caller may optionally complete the transaction * with finishResponse(). */ - QJsonObject& getJson(); - const QJsonObject& getJson() const; - void setJson(const QJsonObject& json); + QJsonDocument &getJson(); + const QJsonDocument& getJson() const; + void setJson(const QJsonDocument &json); /** * @brief Preferred method when working with the json object. Populate @@ -63,7 +63,7 @@ class QTTPSHARED_EXPORT HttpResponse */ bool finish(const std::string& body); bool finish(const QByteArray& bytes); - bool finish(const QJsonObject& json); + bool finish(const QJsonDocument &json); /** * @return Boolean indicating if finishResponse() has been called. @@ -113,7 +113,7 @@ class QTTPSHARED_EXPORT HttpResponse native::http::QttpResponse * m_Response; HttpStatus m_Status; - QJsonObject m_Json; + QJsonDocument m_Json; quint32 m_ControlFlag; }; diff --git a/src/httpserver.cpp b/src/httpserver.cpp index a7a9e139..206bf718 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -587,8 +587,8 @@ function HttpServer::defaultEventCallback() const default: STATS_INC("http:method:unknown"); response.setStatus(HttpStatus::BAD_REQUEST); - QJsonObject& json = data.getResponse().getJson(); - json["error"] = QSTR("Invalid HTTP method"); + QJsonDocument& json = data.getResponse().getJson(); + json.setObject({{"error", QSTR("Invalid HTTP method")}}); return; } @@ -597,8 +597,8 @@ function HttpServer::defaultEventCallback() const { LOG_ERROR("Invalid route"); response.setStatus(HttpStatus::INTERNAL_SERVER_ERROR); - QJsonObject& json = data.getResponse().getJson(); - json["error"] = QSTR("Internal error"); + QJsonDocument& json = data.getResponse().getJson(); + json.setObject({{"error", QSTR("Internal error")}}); return; } @@ -682,8 +682,8 @@ function HttpServer::defaultEventCallback() const if(!searchAndServeFile(data)) { response.setStatus(HttpStatus::BAD_REQUEST); - QJsonObject& json = data.getResponse().getJson(); - json["error"] = QSTR("Invalid request"); + QJsonDocument& json = data.getResponse().getJson(); + json.setObject({{"error", QSTR("Invalid request")}}); performPostprocessing(data); } } @@ -694,20 +694,20 @@ function HttpServer::defaultEventCallback() const { LOG_ERROR("Exception caught" << e.what()); response.setStatus(HttpStatus::INTERNAL_SERVER_ERROR); - QJsonObject& json = data.getResponse().getJson(); - json["error"] = e.what(); + QJsonDocument& json = data.getResponse().getJson(); + json.setObject({{"error", e.what()}}); } catch(const QJsonObject& e) { LOG_ERROR("JSON caught" << e); response.setStatus(HttpStatus::INTERNAL_SERVER_ERROR); - data.getResponse().getJson() = e; + data.getResponse().getJson().setObject(e); } catch(...) { response.setStatus(HttpStatus::INTERNAL_SERVER_ERROR); - QJsonObject& json = data.getResponse().getJson(); - json["error"] = QSTR("Internal server error"); + QJsonDocument& json = data.getResponse().getJson(); + json.setObject({{"error", QSTR("Internal server error")}}); } if(!response.isFinished()) @@ -734,8 +734,8 @@ function HttpServer::defaultEventCallback() const obj["timeElapsedMs"] = (qreal)(uv_hrtime() - request.getTimestamp()) / (qreal)1000000.00; - QJsonObject& json = data.getResponse().getJson(); - json["requestMetadata"] = obj; + QJsonDocument& json = data.getResponse().getJson(); + json.setObject({{"requestMetadata", obj}}); } if( !response.finish()) diff --git a/src/swagger.cpp b/src/swagger.cpp index f409577f..92f8a5c2 100644 --- a/src/swagger.cpp +++ b/src/swagger.cpp @@ -235,7 +235,7 @@ void Swagger::onGet(HttpData& data) { if(m_IsEnabled) { - data.getResponse().setJson(m_Response); + data.getResponse().setJson(QJsonDocument(m_Response)); } else { diff --git a/src/utils.h b/src/utils.h index 138f58d2..bea87575 100644 --- a/src/utils.h +++ b/src/utils.h @@ -292,34 +292,19 @@ class QTTPSHARED_EXPORT Utils return Utils::toByteArray(buffer.str()); } - static inline QJsonObject toJson(const std::stringstream& buffer, QJsonParseError* error = 0) + static inline QJsonDocument toJson(const std::stringstream& buffer, QJsonParseError* error = 0) { - return QJsonDocument::fromJson(toByteArray(buffer), error).object(); + return QJsonDocument::fromJson(toByteArray(buffer), error); } - static inline QJsonObject toJson(const std::string& str, QJsonParseError* error = 0) + static inline QJsonDocument toJson(const std::string& str, QJsonParseError* error = 0) { - return QJsonDocument::fromJson(toByteArray(str), error).object(); + return QJsonDocument::fromJson(toByteArray(str), error); } - static inline QJsonObject toJson(QByteArray bytes, QJsonParseError* error = 0) + static inline QJsonDocument toJson(QByteArray bytes, QJsonParseError* error = 0) { - return QJsonDocument::fromJson(bytes, error).object(); - } - - static inline QJsonArray toArray(const std::stringstream& buffer, QJsonParseError* error = 0) - { - return QJsonDocument::fromJson(toByteArray(buffer), error).array(); - } - - static inline QJsonArray toArray(const std::string& str, QJsonParseError* error = 0) - { - return QJsonDocument::fromJson(toByteArray(str), error).array(); - } - - static inline QJsonArray toArray(QByteArray bytes, QJsonParseError* error = 0) - { - return QJsonDocument::fromJson(bytes, error).array(); + return QJsonDocument::fromJson(bytes, error); } }; diff --git a/test/qttptest/qttptest.cpp b/test/qttptest/qttptest.cpp index 34db4c71..ab3f3b9c 100644 --- a/test/qttptest/qttptest.cpp +++ b/test/qttptest/qttptest.cpp @@ -198,16 +198,18 @@ void QttpTest::initTestCase() QVERIFY(httpSvr->initialize() == true); auto action = httpSvr->createAction("", [](HttpData& data) { - QJsonObject& json = data.getResponse().getJson(); + QJsonObject json = data.getResponse().getJson().object(); json["response"] = "C++ FTW"; + data.getResponse().getJson().setObject(json); }); httpSvr->addProcessor(); action = httpSvr->createAction("echo", [](HttpData& data) { - QJsonObject& json = data.getResponse().getJson(); + QJsonObject json = data.getResponse().getJson().object(); auto& query = data.getRequest().getQuery(); json["response"] = "C++ FTW " + query.queryItemValue("id"); + data.getResponse().getJson().setObject(json); }); auto result = httpSvr->registerRoute("get", "", "/echo/:id"); @@ -217,8 +219,9 @@ void QttpTest::initTestCase() QVERIFY(result == true); action = httpSvr->createAction("echobody", [](HttpData& data) { - QJsonObject& json = data.getResponse().getJson(); - json["response"] = data.getRequest().getJson(); + QJsonObject json = data.getResponse().getJson().object(); + json["response"] = data.getRequest().getJson().object(); + data.getResponse().getJson().setObject(json); }); result = httpSvr->registerRoute("post", "echobody", "/echobody"); @@ -257,8 +260,9 @@ void QttpTest::initTestCase() // Uses a raw std::function based callback. action = httpSvr->createAction("test", [](HttpData& data) { - QJsonObject& json = data.getResponse().getJson(); + QJsonObject json = data.getResponse().getJson().object(); json["response"] = "Test C++ FTW"; + data.getResponse().getJson().setObject(json); // NOTE: This terminates early so we should not expect any post-processing. data.getResponse().finish(); @@ -272,8 +276,9 @@ void QttpTest::initTestCase() QVERIFY(result == true); action = httpSvr->createAction("terminates", [](HttpData& data) { - QJsonObject& json = data.getResponse().getJson(); + QJsonObject json = data.getResponse().getJson().object(); json["response"] = "Test C++ FTW"; + data.getResponse().getJson().setObject(json); // NOTE: This terminates early so we should not expect any post-processing. data.getResponse().terminate(); }); @@ -283,9 +288,10 @@ void QttpTest::initTestCase() QVERIFY(result == true); action = httpSvr->createAction("regex", [](HttpData& data) { - QJsonObject& json = data.getResponse().getJson(); - QString name = data.getRequest().getJson()["name"].toString(); + QJsonObject json = data.getResponse().getJson().object(); + QString name = data.getRequest().getJson().object()["name"].toString(); json["response"] = name; + data.getResponse().getJson().setObject(json); }); result = httpSvr->registerRoute(qttp::GET, "regex", "/regex/:name([A-Za-z]+)"); diff --git a/test/qttptest/qttptest.h b/test/qttptest/qttptest.h index 0dc5f4fa..75e0a6df 100644 --- a/test/qttptest/qttptest.h +++ b/test/qttptest/qttptest.h @@ -20,8 +20,9 @@ class SampleAction : public Action void onAction(HttpData& data) { TEST_TRACE; - QJsonObject& json = data.getResponse().getJson(); + QJsonObject json = data.getResponse().getJson().object(); json["response"] = "Sample C++ FTW"; + data.getResponse().getJson().setObject(json); } const char* getName() const @@ -36,29 +37,33 @@ class SampleActionWithHttpMethods : public Action void onGet(HttpData& data) { TEST_TRACE; - QJsonObject& json = data.getResponse().getJson(); + QJsonObject json = data.getResponse().getJson().object(); json["response"] = "Sample C++ FTW Get"; + data.getResponse().getJson().setObject(json); } void onPost(HttpData& data) { TEST_TRACE; - QJsonObject& json = data.getResponse().getJson(); + QJsonObject json = data.getResponse().getJson().object(); json["response"] = "Sample C++ FTW Post"; + data.getResponse().getJson().setObject(json); } void onPut(HttpData& data) { TEST_TRACE; - QJsonObject& json = data.getResponse().getJson(); + QJsonObject json = data.getResponse().getJson().object(); json["response"] = "Sample C++ FTW Put"; + data.getResponse().getJson().setObject(json); } void onDelete(HttpData& data) { TEST_TRACE; - QJsonObject& json = data.getResponse().getJson(); + QJsonObject json = data.getResponse().getJson().object(); json["response"] = "Sample C++ FTW Delete"; + data.getResponse().getJson().setObject(json); } const char* getName() const @@ -77,8 +82,9 @@ class ActionWithParameter : public Action void onAction(HttpData& data) { TEST_TRACE; - QJsonObject& json = data.getResponse().getJson(); + QJsonObject json = data.getResponse().getJson().object(); json["response"] = "Sample C++ FTW With Parameter " + m_Param; + data.getResponse().getJson().setObject(json); } const char* getName() const @@ -100,13 +106,17 @@ class SampleProcessor : public Processor void preprocess(HttpData& data) { TEST_TRACE; - data.getResponse().getJson()["preprocess"] = true; + QJsonObject obj = data.getResponse().getJson().object(); + obj["preprocess"] = true; + data.getResponse().getJson().setObject(obj); } void postprocess(HttpData& data) { TEST_TRACE; - data.getResponse().getJson()["postprocess"] = true; + QJsonObject obj = data.getResponse().getJson().object(); + obj["postprocess"] = true; + data.getResponse().getJson().setObject(obj); } };