mirror of
https://gitee.com/zyjblog/oatpp.git
synced 2024-12-22 22:16:37 +08:00
Merge pull request #46 from oatpp/merge_server_side_query_params_mapping
Merge server side query params mapping
This commit is contained in:
commit
6f7b2dcbc1
@ -21,7 +21,6 @@
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "oatpp/core/macro/basic.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
|
||||
@ -42,6 +41,12 @@ OATPP_MACRO_API_CONTROLLER_PARAM(OATPP_MACRO_API_CONTROLLER_HEADER, OATPP_MACRO_
|
||||
#define PATH(TYPE, NAME, ...) \
|
||||
OATPP_MACRO_API_CONTROLLER_PARAM(OATPP_MACRO_API_CONTROLLER_PATH, OATPP_MACRO_API_CONTROLLER_PATH_INFO, TYPE, NAME, (__VA_ARGS__))
|
||||
|
||||
#define QUERIES(TYPE, NAME) \
|
||||
OATPP_MACRO_API_CONTROLLER_PARAM(OATPP_MACRO_API_CONTROLLER_QUERIES, OATPP_MACRO_API_CONTROLLER_QUERIES_INFO, TYPE, NAME, ())
|
||||
|
||||
#define QUERY(TYPE, NAME, ...) \
|
||||
OATPP_MACRO_API_CONTROLLER_PARAM(OATPP_MACRO_API_CONTROLLER_QUERY, OATPP_MACRO_API_CONTROLLER_QUERY_INFO, TYPE, NAME, (__VA_ARGS__))
|
||||
|
||||
#define BODY_STRING(TYPE, NAME) \
|
||||
OATPP_MACRO_API_CONTROLLER_PARAM(OATPP_MACRO_API_CONTROLLER_BODY_STRING, OATPP_MACRO_API_CONTROLLER_BODY_STRING_INFO, TYPE, NAME, ())
|
||||
|
||||
@ -56,6 +61,7 @@ TYPE NAME = __request;
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_REQUEST_INFO(TYPE, NAME, PARAM_LIST)
|
||||
|
||||
|
||||
// HEADER MACRO // ------------------------------------------------------
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_HEADER_0(TYPE, NAME, PARAM_LIST) \
|
||||
@ -164,6 +170,67 @@ OATPP_MACRO_API_CONTROLLER_PATH_INFO_CHOOSER (TYPE, NAME, PARAM_LIST, HAS_ARGS)
|
||||
#define OATPP_MACRO_API_CONTROLLER_PATH_INFO(TYPE, NAME, PARAM_LIST) \
|
||||
OATPP_MACRO_API_CONTROLLER_PATH_INFO_CHOOSER_EXP(TYPE, NAME, PARAM_LIST, OATPP_MACRO_HAS_ARGS PARAM_LIST);
|
||||
|
||||
// QUERIES MACRO // ------------------------------------------------------
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_QUERIES(TYPE, NAME, PARAM_LIST) \
|
||||
TYPE NAME = __request->getQueryParameters();
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_QUERIES_INFO(TYPE, NAME, PARAM_LIST)
|
||||
|
||||
// QUERY MACRO // ------------------------------------------------------
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_QUERY_0(TYPE, NAME, PARAM_LIST) \
|
||||
auto __param_str_val_##NAME = __request->getQueryParameter(#NAME); \
|
||||
if(!__param_str_val_##NAME){ \
|
||||
return ApiController::handleError(Status::CODE_400, "Missing QUERY parameter '" #NAME "'"); \
|
||||
} \
|
||||
bool __param_validation_check_##NAME; \
|
||||
TYPE NAME = TYPE::Class::parseFromString(__param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||
if(!__param_validation_check_##NAME){ \
|
||||
return ApiController::handleError(Status::CODE_400, "Invalid QUERY parameter '" #NAME "'. Expected type is '" #TYPE "'"); \
|
||||
}
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_QUERY_1(TYPE, NAME, PARAM_LIST) \
|
||||
auto __param_str_val_##NAME = __request->getQueryParameter(OATPP_MACRO_FIRSTARG PARAM_LIST); \
|
||||
if(!__param_str_val_##NAME){ \
|
||||
return ApiController::handleError(Status::CODE_400, \
|
||||
oatpp::String("Missing QUERY parameter '") + OATPP_MACRO_FIRSTARG PARAM_LIST + "'"); \
|
||||
} \
|
||||
bool __param_validation_check_##NAME; \
|
||||
TYPE NAME = TYPE::Class::parseFromString(__param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||
if(!__param_validation_check_##NAME){ \
|
||||
return ApiController::handleError(Status::CODE_400, \
|
||||
oatpp::String("Invalid QUERY parameter '") + \
|
||||
OATPP_MACRO_FIRSTARG PARAM_LIST + \
|
||||
"'. Expected type is '" #TYPE "'"); \
|
||||
}
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_QUERY_CHOOSER(TYPE, NAME, PARAM_LIST, HAS_ARGS) \
|
||||
OATPP_MACRO_API_CONTROLLER_QUERY_##HAS_ARGS (TYPE, NAME, PARAM_LIST)
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_QUERY_CHOOSER_EXP(TYPE, NAME, PARAM_LIST, HAS_ARGS) \
|
||||
OATPP_MACRO_API_CONTROLLER_QUERY_CHOOSER (TYPE, NAME, PARAM_LIST, HAS_ARGS)
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_QUERY(TYPE, NAME, PARAM_LIST) \
|
||||
OATPP_MACRO_API_CONTROLLER_QUERY_CHOOSER_EXP(TYPE, NAME, PARAM_LIST, OATPP_MACRO_HAS_ARGS PARAM_LIST);
|
||||
|
||||
// __INFO
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_QUERY_INFO_0(TYPE, NAME, PARAM_LIST) \
|
||||
info->queryParams.add(#NAME, TYPE::Class::getType());
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_QUERY_INFO_1(TYPE, NAME, PARAM_LIST) \
|
||||
info->queryParams.add(OATPP_MACRO_FIRSTARG PARAM_LIST, TYPE::Class::getType());
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_QUERY_INFO_CHOOSER(TYPE, NAME, PARAM_LIST, HAS_ARGS) \
|
||||
OATPP_MACRO_API_CONTROLLER_QUERY_INFO_##HAS_ARGS (TYPE, NAME, PARAM_LIST)
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_QUERY_INFO_CHOOSER_EXP(TYPE, NAME, PARAM_LIST, HAS_ARGS) \
|
||||
OATPP_MACRO_API_CONTROLLER_QUERY_INFO_CHOOSER (TYPE, NAME, PARAM_LIST, HAS_ARGS)
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_QUERY_INFO(TYPE, NAME, PARAM_LIST) \
|
||||
OATPP_MACRO_API_CONTROLLER_QUERY_INFO_CHOOSER_EXP(TYPE, NAME, PARAM_LIST, OATPP_MACRO_HAS_ARGS PARAM_LIST);
|
||||
|
||||
// BODY_STRING MACRO // ------------------------------------------------------
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_BODY_STRING(TYPE, NAME, PARAM_LIST) \
|
||||
|
@ -33,6 +33,8 @@
|
||||
#undef REQUEST
|
||||
#undef HEADER
|
||||
#undef PATH
|
||||
#undef QUERIES
|
||||
#undef QUERY
|
||||
#undef BODY_STRING
|
||||
#undef BODY_DTO
|
||||
|
||||
@ -77,6 +79,27 @@
|
||||
#undef OATPP_MACRO_API_CONTROLLER_PATH_INFO_CHOOSER_EXP
|
||||
#undef OATPP_MACRO_API_CONTROLLER_PATH_INFO
|
||||
|
||||
// QUERIES MACRO // ------------------------------------------------------
|
||||
|
||||
#undef OATPP_MACRO_API_CONTROLLER_QUERIES
|
||||
#undef OATPP_MACRO_API_CONTROLLER_QUERIES_INFO
|
||||
|
||||
// QUERY MACRO // ------------------------------------------------------
|
||||
|
||||
#undef OATPP_MACRO_API_CONTROLLER_QUERY_0
|
||||
#undef OATPP_MACRO_API_CONTROLLER_QUERY_1
|
||||
#undef OATPP_MACRO_API_CONTROLLER_QUERY_CHOOSER
|
||||
#undef OATPP_MACRO_API_CONTROLLER_QUERY_CHOOSER_EXP
|
||||
#undef OATPP_MACRO_API_CONTROLLER_QUERY
|
||||
|
||||
// __INFO
|
||||
|
||||
#undef OATPP_MACRO_API_CONTROLLER_QUERY_INFO_0
|
||||
#undef OATPP_MACRO_API_CONTROLLER_QUERY_INFO_1
|
||||
#undef OATPP_MACRO_API_CONTROLLER_QUERY_INFO_CHOOSER
|
||||
#undef OATPP_MACRO_API_CONTROLLER_QUERY_INFO_CHOOSER_EXP
|
||||
#undef OATPP_MACRO_API_CONTROLLER_QUERY_INFO
|
||||
|
||||
// BODY_STRING MACRO // ------------------------------------------------------
|
||||
|
||||
#undef OATPP_MACRO_API_CONTROLLER_BODY_STRING
|
||||
|
@ -33,7 +33,9 @@
|
||||
#include <unordered_map>
|
||||
|
||||
namespace oatpp { namespace network {
|
||||
|
||||
|
||||
|
||||
// TODO - refactor to use oatpp::data::share::MemoryLabel
|
||||
class Url : public oatpp::base::Controllable {
|
||||
public:
|
||||
typedef oatpp::data::share::StringKeyLabel StringKeyLabel;
|
||||
|
@ -263,6 +263,7 @@ struct ResponseStartingLine {
|
||||
class Protocol {
|
||||
public:
|
||||
typedef std::unordered_map<oatpp::data::share::StringKeyLabelCI_FAST, oatpp::data::share::StringKeyLabel> Headers;
|
||||
typedef std::unordered_map<oatpp::data::share::StringKeyLabel, oatpp::data::share::StringKeyLabel> QueryParams;
|
||||
private:
|
||||
static oatpp::data::share::StringKeyLabelCI_FAST parseHeaderNameLabel(const std::shared_ptr<oatpp::base::StrBuffer>& headersText,
|
||||
oatpp::parser::Caret& caret);
|
||||
|
@ -36,6 +36,7 @@ Request::Request(const http::RequestStartingLine& startingLine,
|
||||
, m_headers(headers)
|
||||
, m_bodyStream(bodyStream)
|
||||
, m_bodyDecoder(bodyDecoder)
|
||||
, m_queryParamsParsed(false)
|
||||
{}
|
||||
|
||||
std::shared_ptr<Request> Request::createShared(const http::RequestStartingLine& startingLine,
|
||||
@ -58,6 +59,28 @@ const http::Protocol::Headers& Request::getHeaders() const {
|
||||
return m_headers;
|
||||
}
|
||||
|
||||
const http::Protocol::QueryParams& Request::getQueryParameters() const {
|
||||
if(!m_queryParamsParsed) {
|
||||
m_queryParams = oatpp::network::Url::Parser::labelQueryParams(m_pathVariables.getTail());
|
||||
m_queryParamsParsed = true;
|
||||
}
|
||||
return m_queryParams;
|
||||
}
|
||||
|
||||
oatpp::String Request::getQueryParameter(const oatpp::data::share::StringKeyLabel& name) const {
|
||||
auto iter = getQueryParameters().find(name);
|
||||
if (iter == getQueryParameters().end()) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return iter->second.toString();
|
||||
}
|
||||
}
|
||||
|
||||
oatpp::String Request::getQueryParameter(const oatpp::data::share::StringKeyLabel& name, const oatpp::String& defaultValue) const {
|
||||
auto value = getQueryParameter(name);
|
||||
return value ? value : defaultValue;
|
||||
}
|
||||
|
||||
std::shared_ptr<oatpp::data::stream::InputStream> Request::getBodyStream() const {
|
||||
return m_bodyStream;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "oatpp/web/protocol/http/Http.hpp"
|
||||
#include "oatpp/web/protocol/http/incoming/BodyDecoder.hpp"
|
||||
#include "oatpp/web/url/mapping/Pattern.hpp"
|
||||
#include "oatpp/network/Url.hpp"
|
||||
|
||||
namespace oatpp { namespace web { namespace protocol { namespace http { namespace incoming {
|
||||
|
||||
@ -39,6 +40,7 @@ public:
|
||||
OBJECT_POOL(Incoming_Request_Pool, Request, 32)
|
||||
SHARED_OBJECT_POOL(Shared_Incoming_Request_Pool, Request, 32)
|
||||
private:
|
||||
|
||||
http::RequestStartingLine m_startingLine;
|
||||
url::mapping::Pattern::MatchMap m_pathVariables;
|
||||
http::Protocol::Headers m_headers;
|
||||
@ -49,6 +51,10 @@ private:
|
||||
* Custom BodyDecoder can be set on demand
|
||||
*/
|
||||
std::shared_ptr<const http::incoming::BodyDecoder> m_bodyDecoder;
|
||||
|
||||
mutable bool m_queryParamsParsed; // used for lazy parsing of QueryParams
|
||||
mutable http::Protocol::QueryParams m_queryParams;
|
||||
|
||||
public:
|
||||
|
||||
Request(const http::RequestStartingLine& startingLine,
|
||||
@ -64,6 +70,29 @@ public:
|
||||
const std::shared_ptr<oatpp::data::stream::InputStream>& bodyStream,
|
||||
const std::shared_ptr<const http::incoming::BodyDecoder>& bodyDecoder);
|
||||
|
||||
/**
|
||||
* Get map of url query parameters.
|
||||
* Query parameters will be lazy parsed from url "tail"
|
||||
* Please note: lazy parsing of query parameters is not thread-safe!
|
||||
* @return map<key, value> for "&key=value"
|
||||
*/
|
||||
const http::Protocol::QueryParams& getQueryParameters() const;
|
||||
|
||||
/**
|
||||
* Get query parameter value by name
|
||||
* @param name
|
||||
* @return query parameter value
|
||||
*/
|
||||
oatpp::String getQueryParameter(const oatpp::data::share::StringKeyLabel& name) const;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param name
|
||||
* @param defaultValue
|
||||
* @return query parameter value or defaultValue if no such parameter found
|
||||
*/
|
||||
oatpp::String getQueryParameter(const oatpp::data::share::StringKeyLabel& name, const oatpp::String& defaultValue) const;
|
||||
|
||||
/**
|
||||
* Get request starting line. (method, path, protocol)
|
||||
* @return starting line structure
|
||||
|
@ -52,6 +52,7 @@ public:
|
||||
typedef oatpp::web::protocol::http::outgoing::Response OutgoingResponse;
|
||||
typedef oatpp::web::protocol::http::Status Status;
|
||||
typedef oatpp::web::protocol::http::Header Header;
|
||||
typedef oatpp::web::protocol::http::Protocol::QueryParams QueryParams;
|
||||
typedef oatpp::web::server::api::Endpoint Endpoint;
|
||||
typedef oatpp::collection::LinkedList<std::shared_ptr<Endpoint>> Endpoints;
|
||||
|
||||
|
@ -89,6 +89,17 @@ public:
|
||||
*/
|
||||
Param& add(const oatpp::String& name, oatpp::data::mapping::type::Type* type);
|
||||
|
||||
/**
|
||||
* Add parameter name to list order
|
||||
* @tparam T
|
||||
* @param name
|
||||
* @return new or existing parameter
|
||||
*/
|
||||
template<class T>
|
||||
Param& add(const oatpp::String& name) {
|
||||
return add(name, T::Class::getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or add param by name
|
||||
* @param name
|
||||
|
@ -131,6 +131,26 @@ void FullTest::onRun() {
|
||||
OATPP_ASSERT(dto->testValue == "my_test_param");
|
||||
}
|
||||
|
||||
{ // test GET with query parameters
|
||||
auto response = client->getWithQueries("oatpp", 1, connection);
|
||||
OATPP_ASSERT(response->getStatusCode() == 200);
|
||||
auto dto = response->readBodyToDto<app::TestDto>(objectMapper);
|
||||
OATPP_ASSERT(dto);
|
||||
OATPP_ASSERT(dto->testValue == "name=oatpp&age=1");
|
||||
}
|
||||
|
||||
{ // test GET with query parameters
|
||||
auto response = client->getWithQueriesMap("value1", 32, 0.32, connection);
|
||||
OATPP_ASSERT(response->getStatusCode() == 200);
|
||||
auto dto = response->readBodyToDto<app::TestDto>(objectMapper);
|
||||
OATPP_ASSERT(dto);
|
||||
OATPP_ASSERT(dto->testMap);
|
||||
OATPP_ASSERT(dto->testMap->count() == 3);
|
||||
OATPP_ASSERT(dto->testMap->get("key1", "") == "value1");
|
||||
OATPP_ASSERT(dto->testMap->get("key2", "") == "32");
|
||||
OATPP_ASSERT(dto->testMap->get("key3", "") == oatpp::utils::conversion::float32ToStr(0.32));
|
||||
}
|
||||
|
||||
{ // test GET with header parameter
|
||||
auto response = client->getWithHeaders("my_test_header", connection);
|
||||
OATPP_ASSERT(response->getStatusCode() == 200);
|
||||
|
@ -37,6 +37,8 @@ class Client : public oatpp::web::client::ApiClient {
|
||||
|
||||
API_CALL("GET", "/", getRoot)
|
||||
API_CALL("GET", "params/{param}", getWithParams, PATH(String, param))
|
||||
API_CALL("GET", "queries", getWithQueries, QUERY(String, name), QUERY(Int32, age))
|
||||
API_CALL("GET", "queries/map", getWithQueriesMap, QUERY(String, key1), QUERY(Int32, key2), QUERY(Float32, key3))
|
||||
API_CALL("GET", "headers", getWithHeaders, HEADER(String, param, "X-TEST-HEADER"))
|
||||
API_CALL("POST", "body", postBody, BODY_STRING(String, body))
|
||||
API_CALL("POST", "echo", echoBody, BODY_STRING(String, body))
|
||||
|
@ -28,9 +28,12 @@
|
||||
#include "./DTOs.hpp"
|
||||
#include "oatpp/web/server/api/ApiController.hpp"
|
||||
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
|
||||
#include "oatpp/core/utils/ConversionUtils.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/macro/component.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace oatpp { namespace test { namespace web { namespace app {
|
||||
|
||||
class Controller : public oatpp::web::server::api::ApiController {
|
||||
@ -61,6 +64,23 @@ public:
|
||||
return createDtoResponse(Status::CODE_200, dto);
|
||||
}
|
||||
|
||||
ENDPOINT("GET", "queries", getWithQueries,
|
||||
QUERY(String, name), QUERY(Int32, age)) {
|
||||
auto dto = TestDto::createShared();
|
||||
dto->testValue = "name=" + name + "&age=" + oatpp::utils::conversion::int32ToStr(age->getValue());
|
||||
return createDtoResponse(Status::CODE_200, dto);
|
||||
}
|
||||
|
||||
ENDPOINT("GET", "queries/map", getWithQueriesMap,
|
||||
QUERIES(QueryParams, queries)) {
|
||||
auto dto = TestDto::createShared();
|
||||
dto->testMap = dto->testMap->createShared();
|
||||
for(auto& it : queries) {
|
||||
dto->testMap->put(it.first.toString(), it.second.toString());
|
||||
}
|
||||
return createDtoResponse(Status::CODE_200, dto);
|
||||
}
|
||||
|
||||
ENDPOINT("GET", "headers", getWithHeaders,
|
||||
HEADER(String, param, "X-TEST-HEADER")) {
|
||||
//OATPP_LOGD(TAG, "GET headers {X-TEST-HEADER: %s}", param->c_str());
|
||||
|
@ -37,6 +37,7 @@ class TestDto : public oatpp::data::mapping::type::Object {
|
||||
DTO_INIT(TestDto, Object)
|
||||
|
||||
DTO_FIELD(String, testValue);
|
||||
DTO_FIELD(Fields<String>::ObjectWrapper, testMap);
|
||||
|
||||
};
|
||||
|
||||
|
@ -56,8 +56,8 @@ public:
|
||||
|
||||
ENDPOINT_INFO(pathParams) {
|
||||
info->pathParams["param1"].description = "this is param1";
|
||||
info->queryParams.add("q1", String::Class::getType()).description = "query param";
|
||||
info->headers.add("X-TEST-HEADER", String::Class::getType()).description = "TEST-HEADER-PARAM";
|
||||
info->queryParams.add<String>("q1").description = "query param";
|
||||
info->headers.add<String>("X-TEST-HEADER").description = "TEST-HEADER-PARAM";
|
||||
}
|
||||
ENDPOINT("GET", "path/{param1}/{param2}", pathParams,
|
||||
PATH(String, param1),
|
||||
@ -65,6 +65,15 @@ public:
|
||||
return createResponse(Status::CODE_200, "test2");
|
||||
}
|
||||
|
||||
ENDPOINT_INFO(queryParams) {
|
||||
info->queryParams["param1"].description = "this is param1";
|
||||
}
|
||||
ENDPOINT("GET", "query", queryParams,
|
||||
QUERY(String, param1),
|
||||
QUERY(String, param2)) {
|
||||
return createResponse(Status::CODE_200, "test3");
|
||||
}
|
||||
|
||||
#include OATPP_CODEGEN_END(ApiController)
|
||||
|
||||
};
|
||||
@ -99,7 +108,7 @@ void ApiControllerTest::onRun() {
|
||||
auto stream = oatpp::data::stream::ChunkedBuffer::createShared();
|
||||
response->send(stream);
|
||||
|
||||
OATPP_LOGD(TAG, "response=\n---\n%s\n---\n", stream->toString()->c_str());
|
||||
OATPP_LOGD(TAG, "response:\n---\n%s\n---\n", stream->toString()->c_str());
|
||||
|
||||
}
|
||||
|
||||
@ -126,7 +135,28 @@ void ApiControllerTest::onRun() {
|
||||
auto stream = oatpp::data::stream::ChunkedBuffer::createShared();
|
||||
response->send(stream);
|
||||
|
||||
OATPP_LOGD(TAG, "response=\n---\n%s\n---\n", stream->toString()->c_str());
|
||||
OATPP_LOGD(TAG, "response:\n---\n%s\n---\n", stream->toString()->c_str());
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
auto endpoint = controller.Z__ENDPOINT_queryParams;
|
||||
OATPP_ASSERT(endpoint);
|
||||
OATPP_ASSERT(!endpoint->info->summary);
|
||||
|
||||
OATPP_ASSERT(endpoint->info->queryParams["param1"].name == "param1");
|
||||
OATPP_ASSERT(endpoint->info->queryParams["param1"].description == "this is param1");
|
||||
|
||||
OATPP_ASSERT(endpoint->info->queryParams["param2"].name == "param2");
|
||||
OATPP_ASSERT(!endpoint->info->queryParams["param2"].description);
|
||||
|
||||
auto response = controller.queryParams("p1", "p2");
|
||||
OATPP_ASSERT(response->getStatus().code == 200);
|
||||
|
||||
auto stream = oatpp::data::stream::ChunkedBuffer::createShared();
|
||||
response->send(stream);
|
||||
|
||||
OATPP_LOGD(TAG, "response:\n---\n%s\n---\n", stream->toString()->c_str());
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user