mirror of
https://gitee.com/zyjblog/oatpp.git
synced 2024-12-22 22:16:37 +08:00
web::mime::ContentMappers: implement selectMapper() method
This commit is contained in:
parent
9ec854ebbb
commit
c8dcb2238e
@ -34,6 +34,10 @@ v_int32 Conversion::strToInt32(const char* str){
|
|||||||
}
|
}
|
||||||
|
|
||||||
v_int32 Conversion::strToInt32(const oatpp::String& str, bool& success){
|
v_int32 Conversion::strToInt32(const oatpp::String& str, bool& success){
|
||||||
|
if(str == nullptr || str->empty()) {
|
||||||
|
success = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
char* end;
|
char* end;
|
||||||
v_int32 result = static_cast<v_int32>(std::strtol(str->data(), &end, 10));
|
v_int32 result = static_cast<v_int32>(std::strtol(str->data(), &end, 10));
|
||||||
success = ((reinterpret_cast<v_buff_size>(end) - reinterpret_cast<v_buff_size>(str->data())) == static_cast<v_buff_size>(str->size()));
|
success = ((reinterpret_cast<v_buff_size>(end) - reinterpret_cast<v_buff_size>(str->data())) == static_cast<v_buff_size>(str->size()));
|
||||||
@ -46,6 +50,10 @@ v_uint32 Conversion::strToUInt32(const char* str){
|
|||||||
}
|
}
|
||||||
|
|
||||||
v_uint32 Conversion::strToUInt32(const oatpp::String& str, bool& success){
|
v_uint32 Conversion::strToUInt32(const oatpp::String& str, bool& success){
|
||||||
|
if(str == nullptr || str->empty()) {
|
||||||
|
success = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
char* end;
|
char* end;
|
||||||
v_uint32 result = static_cast<v_uint32>(std::strtoul(str->data(), &end, 10));
|
v_uint32 result = static_cast<v_uint32>(std::strtoul(str->data(), &end, 10));
|
||||||
success = ((reinterpret_cast<v_buff_size>(end) - reinterpret_cast<v_buff_size>(str->data())) == static_cast<v_buff_size>(str->size()));
|
success = ((reinterpret_cast<v_buff_size>(end) - reinterpret_cast<v_buff_size>(str->data())) == static_cast<v_buff_size>(str->size()));
|
||||||
@ -58,6 +66,10 @@ v_int64 Conversion::strToInt64(const char* str){
|
|||||||
}
|
}
|
||||||
|
|
||||||
v_int64 Conversion::strToInt64(const oatpp::String& str, bool& success){
|
v_int64 Conversion::strToInt64(const oatpp::String& str, bool& success){
|
||||||
|
if(str == nullptr || str->empty()) {
|
||||||
|
success = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
char* end;
|
char* end;
|
||||||
v_int64 result = std::strtoll(str->data(), &end, 10);
|
v_int64 result = std::strtoll(str->data(), &end, 10);
|
||||||
success = ((reinterpret_cast<v_buff_size>(end) - reinterpret_cast<v_buff_size>(str->data())) == static_cast<v_buff_size>(str->size()));
|
success = ((reinterpret_cast<v_buff_size>(end) - reinterpret_cast<v_buff_size>(str->data())) == static_cast<v_buff_size>(str->size()));
|
||||||
@ -70,6 +82,10 @@ v_uint64 Conversion::strToUInt64(const char* str){
|
|||||||
}
|
}
|
||||||
|
|
||||||
v_uint64 Conversion::strToUInt64(const oatpp::String& str, bool& success){
|
v_uint64 Conversion::strToUInt64(const oatpp::String& str, bool& success){
|
||||||
|
if(str == nullptr || str->empty()) {
|
||||||
|
success = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
char* end;
|
char* end;
|
||||||
v_uint64 result = std::strtoull(str->data(), &end, 10);
|
v_uint64 result = std::strtoull(str->data(), &end, 10);
|
||||||
success = ((reinterpret_cast<v_buff_size>(end) - reinterpret_cast<v_buff_size>(str->data())) == static_cast<v_buff_size>(str->size()));
|
success = ((reinterpret_cast<v_buff_size>(end) - reinterpret_cast<v_buff_size>(str->data())) == static_cast<v_buff_size>(str->size()));
|
||||||
@ -170,6 +186,10 @@ v_float32 Conversion::strToFloat32(const char* str){
|
|||||||
}
|
}
|
||||||
|
|
||||||
v_float32 Conversion::strToFloat32(const oatpp::String& str, bool& success) {
|
v_float32 Conversion::strToFloat32(const oatpp::String& str, bool& success) {
|
||||||
|
if(str == nullptr || str->empty()) {
|
||||||
|
success = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
char* end;
|
char* end;
|
||||||
v_float32 result = std::strtof(str->data(), &end);
|
v_float32 result = std::strtof(str->data(), &end);
|
||||||
success = ((reinterpret_cast<v_buff_size>(end) - reinterpret_cast<v_buff_size>(str->data())) == static_cast<v_buff_size>(str->size()));
|
success = ((reinterpret_cast<v_buff_size>(end) - reinterpret_cast<v_buff_size>(str->data())) == static_cast<v_buff_size>(str->size()));
|
||||||
@ -182,6 +202,10 @@ v_float64 Conversion::strToFloat64(const char* str){
|
|||||||
}
|
}
|
||||||
|
|
||||||
v_float64 Conversion::strToFloat64(const oatpp::String& str, bool& success) {
|
v_float64 Conversion::strToFloat64(const oatpp::String& str, bool& success) {
|
||||||
|
if(str == nullptr || str->empty()) {
|
||||||
|
success = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
char* end;
|
char* end;
|
||||||
v_float64 result = std::strtod(str->data(), &end);
|
v_float64 result = std::strtod(str->data(), &end);
|
||||||
success = ((reinterpret_cast<v_buff_size>(end) - reinterpret_cast<v_buff_size>(str->data())) == static_cast<v_buff_size>(str->size()));
|
success = ((reinterpret_cast<v_buff_size>(end) - reinterpret_cast<v_buff_size>(str->data())) == static_cast<v_buff_size>(str->size()));
|
||||||
|
@ -24,28 +24,54 @@
|
|||||||
|
|
||||||
#include "ContentMappers.hpp"
|
#include "ContentMappers.hpp"
|
||||||
|
|
||||||
namespace oatpp { namespace web { namespace mime {
|
#include "oatpp/utils/parser/Caret.hpp"
|
||||||
|
#include "oatpp/utils/Conversion.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace oatpp::web::mime {
|
||||||
|
|
||||||
|
std::pair<oatpp::String, oatpp::String> ContentMappers::typeAndSubtype(const data::share::StringKeyLabelCI& contentType) const {
|
||||||
|
|
||||||
|
if(contentType == nullptr || contentType.getSize() == 0) return {};
|
||||||
|
|
||||||
|
utils::parser::Caret caret(reinterpret_cast<const char*>(contentType.getData()), contentType.getSize());
|
||||||
|
auto typeL = caret.putLabel();
|
||||||
|
|
||||||
|
if(!caret.findChar('/')) return {};
|
||||||
|
|
||||||
|
typeL.end();
|
||||||
|
|
||||||
|
caret.canContinueAtChar('/', 1);
|
||||||
|
|
||||||
|
auto stypeL = caret.putLabel();
|
||||||
|
|
||||||
|
caret.findCharFromSet(";, \r\n\t");
|
||||||
|
|
||||||
|
return {typeL.toString(), stypeL.toString()};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void ContentMappers::putMapper(const std::shared_ptr<data::mapping::ObjectMapper>& mapper) {
|
void ContentMappers::putMapper(const std::shared_ptr<data::mapping::ObjectMapper>& mapper) {
|
||||||
std::unique_lock lock(m_mutex);
|
std::unique_lock lock(m_mutex);
|
||||||
if(m_defaultMapper == nullptr) {
|
if(m_defaultMapper == nullptr) {
|
||||||
m_defaultMapper = mapper;
|
m_defaultMapper = mapper;
|
||||||
}
|
}
|
||||||
|
m_index[mapper->getInfo().mimeType][mapper->getInfo().mimeSubtype] = mapper;
|
||||||
m_mappers[mapper->getInfo().httpContentType] = mapper;
|
m_mappers[mapper->getInfo().httpContentType] = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentMappers::setDefaultMapper(const oatpp::String& contentType) {
|
void ContentMappers::setDefaultMapper(const oatpp::String& contentType) {
|
||||||
std::unique_lock lock(m_mutex);
|
std::unique_lock lock(m_mutex);
|
||||||
if(m_defaultMapper == nullptr) {
|
m_defaultMapper = m_mappers.at(contentType);
|
||||||
m_defaultMapper = m_mappers.at(contentType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentMappers::setDefaultMapper(const std::shared_ptr<data::mapping::ObjectMapper>& mapper) {
|
void ContentMappers::setDefaultMapper(const std::shared_ptr<data::mapping::ObjectMapper>& mapper) {
|
||||||
std::unique_lock lock(m_mutex);
|
std::unique_lock lock(m_mutex);
|
||||||
m_defaultMapper = mapper;
|
m_defaultMapper = mapper;
|
||||||
if(m_defaultMapper) {
|
if(m_defaultMapper) {
|
||||||
m_mappers[m_defaultMapper->getInfo().httpContentType] = m_defaultMapper;
|
m_index[m_defaultMapper->getInfo().mimeType][m_defaultMapper->getInfo().mimeSubtype] = m_defaultMapper;
|
||||||
|
m_mappers[mapper->getInfo().httpContentType] = m_defaultMapper;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,20 +90,86 @@ std::shared_ptr<data::mapping::ObjectMapper> ContentMappers::getDefaultMapper()
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<data::mapping::ObjectMapper> ContentMappers::selectMapper(const protocol::http::HeaderValueData& values) const {
|
std::shared_ptr<data::mapping::ObjectMapper> ContentMappers::selectMapper(const protocol::http::HeaderValueData& values) const {
|
||||||
// TODO select
|
|
||||||
return m_defaultMapper;
|
for(auto& t : values.tokens) {
|
||||||
|
|
||||||
|
if(t == "*/*") return m_defaultMapper;
|
||||||
|
|
||||||
|
auto tst = typeAndSubtype(t);
|
||||||
|
if(!tst.first || !tst.second) continue;
|
||||||
|
|
||||||
|
auto it = m_index.find(tst.first);
|
||||||
|
|
||||||
|
if(it == m_index.end()) continue;
|
||||||
|
|
||||||
|
auto ist = it->second.find(tst.second);
|
||||||
|
|
||||||
|
if(ist != it->second.end()) {
|
||||||
|
return ist->second; // return immediately - quality = 1
|
||||||
|
} else if(tst.second == "*" && !it->second.empty()) {
|
||||||
|
if(m_defaultMapper && tst.first == m_defaultMapper->getInfo().mimeType) {
|
||||||
|
return m_defaultMapper;
|
||||||
|
}
|
||||||
|
return it->second.begin()->second; // return immediately - quality = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<MatchedMapper> matches;
|
||||||
|
|
||||||
|
for(auto& tp : values.titleParams) {
|
||||||
|
|
||||||
|
auto tst = typeAndSubtype(tp.first);
|
||||||
|
if(!tst.first || !tst.second) continue;
|
||||||
|
|
||||||
|
bool success;
|
||||||
|
auto q = utils::Conversion::strToFloat64(tp.second.toString(), success);
|
||||||
|
if(!success) continue;
|
||||||
|
|
||||||
|
if(tst.first == "*" && tst.second == "*") {
|
||||||
|
matches.push_back({m_defaultMapper, q});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = m_index.find(tst.first);
|
||||||
|
|
||||||
|
if(it == m_index.end()) continue;
|
||||||
|
|
||||||
|
auto ist = it->second.find(tst.second);
|
||||||
|
|
||||||
|
if(ist != it->second.end()) {
|
||||||
|
matches.push_back({ist->second, q});
|
||||||
|
continue;
|
||||||
|
} else if(tst.second == "*" && !it->second.empty()) {
|
||||||
|
if(m_defaultMapper && tst.first == m_defaultMapper->getInfo().mimeType) {
|
||||||
|
matches.push_back({m_defaultMapper, q});
|
||||||
|
} else {
|
||||||
|
matches.push_back({it->second.begin()->second, q});
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(matches.empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(matches.begin(), matches.end());
|
||||||
|
return matches.at(0).mapper;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<data::mapping::ObjectMapper> ContentMappers::selectMapper(const oatpp::String& contentType) const {
|
std::shared_ptr<data::mapping::ObjectMapper> ContentMappers::selectMapper(const oatpp::String& acceptHeader) const {
|
||||||
|
|
||||||
std::shared_lock lock(m_mutex);
|
std::shared_lock lock(m_mutex);
|
||||||
|
|
||||||
if(!contentType || contentType->empty()) {
|
if(!acceptHeader || acceptHeader->empty()) {
|
||||||
return m_defaultMapper;
|
return m_defaultMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol::http::HeaderValueData values;
|
protocol::http::HeaderValueData values;
|
||||||
protocol::http::Parser::parseHeaderValueData(values, contentType, ',');
|
protocol::http::Parser::parseHeaderValueData(values, acceptHeader, ',');
|
||||||
|
|
||||||
return selectMapper(values);
|
return selectMapper(values);
|
||||||
|
|
||||||
@ -93,6 +185,7 @@ std::shared_ptr<data::mapping::ObjectMapper> ContentMappers::selectMapper(const
|
|||||||
|
|
||||||
protocol::http::HeaderValueData values;
|
protocol::http::HeaderValueData values;
|
||||||
for(auto& ct : acceptableContentTypes) {
|
for(auto& ct : acceptableContentTypes) {
|
||||||
|
if(ct == nullptr || ct->empty()) continue;
|
||||||
protocol::http::Parser::parseHeaderValueData(values, ct, ',');
|
protocol::http::Parser::parseHeaderValueData(values, ct, ',');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,4 +199,4 @@ void ContentMappers::clear() {
|
|||||||
m_mappers.clear();
|
m_mappers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
}}}
|
}
|
||||||
|
@ -34,9 +34,26 @@ namespace oatpp::web::mime {
|
|||||||
|
|
||||||
class ContentMappers {
|
class ContentMappers {
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
struct MatchedMapper {
|
||||||
|
|
||||||
|
std::shared_ptr<data::mapping::ObjectMapper> mapper;
|
||||||
|
v_float64 quality;
|
||||||
|
|
||||||
|
bool operator < (const MatchedMapper& other) const {
|
||||||
|
return quality > other.quality;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::unordered_map<data::share::StringKeyLabelCI, std::shared_ptr<data::mapping::ObjectMapper>> MappersBySubtypes;
|
||||||
|
private:
|
||||||
|
std::pair<oatpp::String, oatpp::String> typeAndSubtype(const data::share::StringKeyLabelCI& contentType) const;
|
||||||
std::shared_ptr<data::mapping::ObjectMapper> selectMapper(const protocol::http::HeaderValueData& values) const;
|
std::shared_ptr<data::mapping::ObjectMapper> selectMapper(const protocol::http::HeaderValueData& values) const;
|
||||||
private:
|
private:
|
||||||
std::unordered_map<oatpp::String, std::shared_ptr<data::mapping::ObjectMapper>> m_mappers;
|
std::unordered_map<data::share::StringKeyLabelCI, MappersBySubtypes> m_index;
|
||||||
|
std::unordered_map<data::share::StringKeyLabelCI, std::shared_ptr<data::mapping::ObjectMapper>> m_mappers;
|
||||||
std::shared_ptr<data::mapping::ObjectMapper> m_defaultMapper;
|
std::shared_ptr<data::mapping::ObjectMapper> m_defaultMapper;
|
||||||
mutable std::shared_mutex m_mutex;
|
mutable std::shared_mutex m_mutex;
|
||||||
public:
|
public:
|
||||||
@ -52,7 +69,7 @@ public:
|
|||||||
std::shared_ptr<data::mapping::ObjectMapper> getMapper(const oatpp::String& contentType) const;
|
std::shared_ptr<data::mapping::ObjectMapper> getMapper(const oatpp::String& contentType) const;
|
||||||
std::shared_ptr<data::mapping::ObjectMapper> getDefaultMapper() const;
|
std::shared_ptr<data::mapping::ObjectMapper> getDefaultMapper() const;
|
||||||
|
|
||||||
std::shared_ptr<data::mapping::ObjectMapper> selectMapper(const oatpp::String& contentType) const;
|
std::shared_ptr<data::mapping::ObjectMapper> selectMapper(const oatpp::String& acceptHeader) const;
|
||||||
std::shared_ptr<data::mapping::ObjectMapper> selectMapper(const std::vector<oatpp::String>& acceptableContentTypes) const;
|
std::shared_ptr<data::mapping::ObjectMapper> selectMapper(const std::vector<oatpp::String>& acceptableContentTypes) const;
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -31,37 +31,161 @@
|
|||||||
|
|
||||||
namespace oatpp::web::mime {
|
namespace oatpp::web::mime {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class FakeMapper : public data::mapping::ObjectMapper {
|
||||||
|
public:
|
||||||
|
|
||||||
|
FakeMapper(const oatpp::String& mimeType, const oatpp::String& mimeSubtype)
|
||||||
|
: ObjectMapper(Info(mimeType, mimeSubtype))
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
void write(data::stream::ConsistentOutputStream* stream, const oatpp::Void& variant, data::mapping::ErrorStack& errorStack) const override {
|
||||||
|
// DO NOTHING
|
||||||
|
}
|
||||||
|
|
||||||
|
oatpp::Void read(oatpp::utils::parser::Caret& caret, const oatpp::Type* type, data::mapping::ErrorStack& errorStack) const override {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void ContentMappersTest::onRun() {
|
void ContentMappersTest::onRun() {
|
||||||
|
|
||||||
protocol::http::incoming::Request request(nullptr, {}, {}, nullptr, nullptr);
|
{
|
||||||
|
OATPP_LOGD(TAG, "case 1 - default mapper")
|
||||||
request.putHeader("Content-Type", "application/json");
|
ContentMappers mappers;
|
||||||
request.putHeader("Content-Length", "1000");
|
mappers.putMapper(std::make_shared<FakeMapper>("application", "json"));
|
||||||
|
auto m = mappers.getMapper("APPLICATION/JSON");
|
||||||
request.putHeader("Accept", "application/*");
|
OATPP_ASSERT(m != nullptr)
|
||||||
request.putHeader("Accept", "application/json");
|
OATPP_ASSERT(m->getInfo().httpContentType == "application/json")
|
||||||
request.putHeader("Accept", "text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, */*;q=0.8");
|
OATPP_ASSERT(mappers.getDefaultMapper().get() == m.get())
|
||||||
|
|
||||||
auto values = request.getHeaderValues("Accept");
|
|
||||||
|
|
||||||
protocol::http::HeaderValueData data;
|
|
||||||
|
|
||||||
for(auto& v : values) {
|
|
||||||
protocol::http::Parser::parseHeaderValueData(data, v, ',');
|
|
||||||
OATPP_LOGD(TAG, "value='%s'", v->c_str())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OATPP_LOGD(TAG, "")
|
{
|
||||||
|
OATPP_LOGD(TAG, "case 2 - default mapper")
|
||||||
|
ContentMappers mappers;
|
||||||
|
mappers.putMapper(std::make_shared<FakeMapper>("application", "json"));
|
||||||
|
mappers.putMapper(std::make_shared<FakeMapper>("text", "html"));
|
||||||
|
|
||||||
for(auto& t : data.tokens) {
|
auto m = mappers.getMapper("text/HTML");
|
||||||
OATPP_LOGD(TAG, "token='%s'", t.toString()->c_str())
|
auto d = mappers.getDefaultMapper();
|
||||||
|
OATPP_ASSERT(m != nullptr)
|
||||||
|
OATPP_ASSERT(m->getInfo().httpContentType == "text/html")
|
||||||
|
OATPP_ASSERT(d->getInfo().httpContentType == "application/json")
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto& p : data.titleParams) {
|
{
|
||||||
OATPP_LOGD(TAG, "'%s'='%s'", p.first.toString()->c_str(), p.second.toString()->c_str())
|
OATPP_LOGD(TAG, "case 3 - default mapper")
|
||||||
|
ContentMappers mappers;
|
||||||
|
mappers.putMapper(std::make_shared<FakeMapper>("application", "json"));
|
||||||
|
mappers.putMapper(std::make_shared<FakeMapper>("text", "html"));
|
||||||
|
|
||||||
|
mappers.setDefaultMapper("text/html");
|
||||||
|
|
||||||
|
auto m = mappers.getMapper("application/JSON");
|
||||||
|
auto d = mappers.getDefaultMapper();
|
||||||
|
OATPP_ASSERT(m != nullptr)
|
||||||
|
OATPP_ASSERT(m->getInfo().httpContentType == "application/json")
|
||||||
|
OATPP_ASSERT(d->getInfo().httpContentType == "text/html")
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentMappers mappers;
|
|
||||||
|
{
|
||||||
|
OATPP_LOGD(TAG, "case 4 - select mapper")
|
||||||
|
ContentMappers mappers;
|
||||||
|
mappers.putMapper(std::make_shared<FakeMapper>("application", "json"));
|
||||||
|
mappers.putMapper(std::make_shared<FakeMapper>("text", "html"));
|
||||||
|
auto m= mappers.selectMapper(std::vector<oatpp::String>{
|
||||||
|
"application/json",
|
||||||
|
"text/html",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
OATPP_ASSERT(m->getInfo().httpContentType == "application/json" || m->getInfo().httpContentType == "text/html")
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
OATPP_LOGD(TAG, "case 5 - select mapper")
|
||||||
|
ContentMappers mappers;
|
||||||
|
mappers.putMapper(std::make_shared<FakeMapper>("application", "json"));
|
||||||
|
mappers.putMapper(std::make_shared<FakeMapper>("text", "html"));
|
||||||
|
auto m= mappers.selectMapper(std::vector<oatpp::String>{
|
||||||
|
"application/json;q=0.9",
|
||||||
|
"text/html;q=0.1",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
OATPP_ASSERT(m->getInfo().httpContentType == "application/json")
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
OATPP_LOGD(TAG, "case 6 - select mapper")
|
||||||
|
ContentMappers mappers;
|
||||||
|
mappers.putMapper(std::make_shared<FakeMapper>("application", "json"));
|
||||||
|
mappers.putMapper(std::make_shared<FakeMapper>("text", "html"));
|
||||||
|
auto m= mappers.selectMapper(std::vector<oatpp::String>{
|
||||||
|
"application/json;q=0.1",
|
||||||
|
"text/html;q=0.9",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
OATPP_ASSERT(m->getInfo().httpContentType == "text/html")
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
OATPP_LOGD(TAG, "case 7 - select mapper - corrupted input")
|
||||||
|
ContentMappers mappers;
|
||||||
|
mappers.putMapper(std::make_shared<FakeMapper>("application", "json"));
|
||||||
|
mappers.putMapper(std::make_shared<FakeMapper>("text", "html"));
|
||||||
|
auto m= mappers.selectMapper(std::vector<oatpp::String>{
|
||||||
|
"application/json;<anything>=0.5",
|
||||||
|
"text/html;q=",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
OATPP_ASSERT(m->getInfo().httpContentType == "application/json")
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentMappers richMappers;
|
||||||
|
|
||||||
|
richMappers.putMapper(std::make_shared<FakeMapper>("application", "json"));
|
||||||
|
richMappers.putMapper(std::make_shared<FakeMapper>("application", "xml"));
|
||||||
|
richMappers.putMapper(std::make_shared<FakeMapper>("application", "octet-stream"));
|
||||||
|
richMappers.putMapper(std::make_shared<FakeMapper>("text", "css"));
|
||||||
|
richMappers.putMapper(std::make_shared<FakeMapper>("text", "csv"));
|
||||||
|
richMappers.putMapper(std::make_shared<FakeMapper>("text", "html"));
|
||||||
|
|
||||||
|
{
|
||||||
|
OATPP_LOGD(TAG, "case 8 - select mapper - empty")
|
||||||
|
auto m = richMappers.selectMapper(
|
||||||
|
""
|
||||||
|
);
|
||||||
|
OATPP_ASSERT(m->getInfo().httpContentType == "application/json")
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
OATPP_LOGD(TAG, "case 9 - select mapper - corrupted input")
|
||||||
|
auto m = richMappers.selectMapper(
|
||||||
|
"application/*;q=0.8, text/*;q=0.9, *.*"
|
||||||
|
);
|
||||||
|
OATPP_ASSERT(m->getInfo().mimeType == "text")
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
OATPP_LOGD(TAG, "case 10 - select mapper ")
|
||||||
|
auto m = richMappers.selectMapper(
|
||||||
|
"application/*;q=0.8, text/*;q=0.9, */*"
|
||||||
|
);
|
||||||
|
OATPP_ASSERT(m->getInfo().httpContentType == "application/json")
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
OATPP_LOGD(TAG, "case 11 - select mapper ")
|
||||||
|
auto m = richMappers.selectMapper(
|
||||||
|
"application/*;q=0.9, text/*;q=0.8"
|
||||||
|
);
|
||||||
|
OATPP_ASSERT(m->getInfo().httpContentType == "application/json")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user