Add option for setting float precision in Json string (#666)

This commit is contained in:
An Tao 2020-12-24 20:00:29 +08:00 committed by GitHub
parent 1cb8b17709
commit ec59dbbc3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 180 additions and 90 deletions

View File

@ -106,26 +106,28 @@
"xml"
],
//locations: An array of locations of static files for GET requests.
"locations": [{
//uri_prefix: The URI prefix of the location prefixed with "/", the default value is "" that disables the location.
//"uri_prefix": "/.well-known/acme-challenge/",
//default_content_type: The default content type of the static files without
//an extension. empty string by default.
"default_content_type": "text/plain",
//alias: The location in file system, if it is prefixed with "/", it
//presents an absolute path, otherwise it presents a relative path to
//the document_root path.
//The default value is "" which means use the document root path as the location base path.
"alias": "",
//is_case_sensitive: indicates whether the URI prefix is case sensitive.
"is_case_sensitive": false,
//allow_all: true by default. If it is set to false, only static files with a valid extension can be accessed.
"allow_all": true,
//is_recursive: true by default. If it is set to false, files in sub directories can't be accessed.
"is_recursive": true,
//filters: string array, the filters applied to the location.
"filters": []
}],
"locations": [
{
//uri_prefix: The URI prefix of the location prefixed with "/", the default value is "" that disables the location.
//"uri_prefix": "/.well-known/acme-challenge/",
//default_content_type: The default content type of the static files without
//an extension. empty string by default.
"default_content_type": "text/plain",
//alias: The location in file system, if it is prefixed with "/", it
//presents an absolute path, otherwise it presents a relative path to
//the document_root path.
//The default value is "" which means use the document root path as the location base path.
"alias": "",
//is_case_sensitive: indicates whether the URI prefix is case sensitive.
"is_case_sensitive": false,
//allow_all: true by default. If it is set to false, only static files with a valid extension can be accessed.
"allow_all": true,
//is_recursive: true by default. If it is set to false, files in sub directories can't be accessed.
"is_recursive": true,
//filters: string array, the filters applied to the location.
"filters": []
}
],
//max_connections: maximum connections number,100000 by default
"max_connections": 100000,
//max_connections_per_ip: maximum connections number per clinet,0 by default which means no limit
@ -145,6 +147,15 @@
"dynamic_views_output_path": "",
//enable_unicode_escaping_in_json: true by default, enable unicode escaping in json.
"enable_unicode_escaping_in_json": true,
//float_precision_in_json: set precision of float number in json.
"float_precision_in_json": {
//precision: 0 by default, 0 means use the default precision of the jsoncpp lib.
"precision": 0,
//precision_type: must be "significant" or "decimal", defaults to "significant" that means
//setting max number of significant digits in string, "decimal" means setting max number of
//digits after "." in string
"precision_type": "significant"
},
//log: Set log output, drogon output logs to stdout by default
"log": {
//log_path: Log file path,empty by default,in which case,logs are output to the stdout
@ -174,17 +185,19 @@
//0 means cache forever, the negative value means no cache
"static_files_cache_time": 5,
//simple_controllers_map: Used to configure mapping from path to simple controller
"simple_controllers_map": [{
"path": "/path/name",
"controller": "controllerClassName",
"http_methods": [
"get",
"post"
],
"filters": [
"FilterClassName"
]
}],
"simple_controllers_map": [
{
"path": "/path/name",
"controller": "controllerClassName",
"http_methods": [
"get",
"post"
],
"filters": [
"FilterClassName"
]
}
],
//idle_connection_timeout: Defaults to 60 seconds, the lifetime
//of the connection without read or write
"idle_connection_timeout": 60,
@ -227,25 +240,31 @@
"reuse_port": false
},
//plugins: Define all plugins running in the application
"plugins": [{
//name: The class name of the plugin
//"name": "drogon::plugin::SecureSSLRedirector",
//dependencies: Plugins that the plugin depends on. It can be commented out
"dependencies": [],
//config: The configuration of the plugin. This json object is the parameter to initialize the plugin.
//It can be commented out
"config": {
"ssl_redirect_exempt": [".*\\.jpg"],
"secure_ssl_host": "localhost:8849"
"plugins": [
{
//name: The class name of the plugin
//"name": "drogon::plugin::SecureSSLRedirector",
//dependencies: Plugins that the plugin depends on. It can be commented out
"dependencies": [],
//config: The configuration of the plugin. This json object is the parameter to initialize the plugin.
//It can be commented out
"config": {
"ssl_redirect_exempt": [
".*\\.jpg"
],
"secure_ssl_host": "localhost:8849"
}
}
}],
],
//custom_config: custom configuration for users. This object can be get by the app().getCustomConfig() method.
"custom_config": {
"realm": "drogonRealm",
"opaque": "drogonOpaque",
"credentials": [{
"user": "drogon",
"password": "dr0g0n"
}]
"credentials": [
{
"user": "drogon",
"password": "dr0g0n"
}
]
}
}

View File

@ -106,26 +106,28 @@
"xml"
],
//locations: An array of locations of static files for GET requests.
"locations": [{
//uri_prefix: The URI prefix of the location prefixed with "/", the default value is "" that disables the location.
//"uri_prefix": "/.well-known/acme-challenge/",
//default_content_type: The default content type of the static files without
//an extension. empty string by default.
"default_content_type": "text/plain",
//alias: The location in file system, if it is prefixed with "/", it
//presents an absolute path, otherwise it presents a relative path to
//the document_root path.
//The default value is "" which means use the document root path as the location base path.
"alias": "",
//is_case_sensitive: indicates whether the URI prefix is case sensitive.
"is_case_sensitive": false,
//allow_all: true by default. If it is set to false, only static files with a valid extension can be accessed.
"allow_all": true,
//is_recursive: true by default. If it is set to false, files in sub directories can't be accessed.
"is_recursive": true,
//filters: string array, the filters applied to the location.
"filters": []
}],
"locations": [
{
//uri_prefix: The URI prefix of the location prefixed with "/", the default value is "" that disables the location.
//"uri_prefix": "/.well-known/acme-challenge/",
//default_content_type: The default content type of the static files without
//an extension. empty string by default.
"default_content_type": "text/plain",
//alias: The location in file system, if it is prefixed with "/", it
//presents an absolute path, otherwise it presents a relative path to
//the document_root path.
//The default value is "" which means use the document root path as the location base path.
"alias": "",
//is_case_sensitive: indicates whether the URI prefix is case sensitive.
"is_case_sensitive": false,
//allow_all: true by default. If it is set to false, only static files with a valid extension can be accessed.
"allow_all": true,
//is_recursive: true by default. If it is set to false, files in sub directories can't be accessed.
"is_recursive": true,
//filters: string array, the filters applied to the location.
"filters": []
}
],
//max_connections: maximum connections number,100000 by default
"max_connections": 100000,
//max_connections_per_ip: maximum connections number per clinet,0 by default which means no limit
@ -145,6 +147,15 @@
"dynamic_views_output_path": "",
//enable_unicode_escaping_in_json: true by default, enable unicode escaping in json.
"enable_unicode_escaping_in_json": true,
//float_precision_in_json: set precision of float number in json.
"float_precision_in_json": {
//precision: 0 by default, 0 means use the default precision of the jsoncpp lib.
"precision": 0,
//precision_type: must be "significant" or "decimal", defaults to "significant" that means
//setting max number of significant digits in string, "decimal" means setting max number of
//digits after "." in string
"precision_type": "significant"
},
//log: Set log output, drogon output logs to stdout by default
"log": {
//log_path: Log file path,empty by default,in which case,logs are output to the stdout
@ -174,17 +185,19 @@
//0 means cache forever, the negative value means no cache
"static_files_cache_time": 5,
//simple_controllers_map: Used to configure mapping from path to simple controller
"simple_controllers_map": [{
"path": "/path/name",
"controller": "controllerClassName",
"http_methods": [
"get",
"post"
],
"filters": [
"FilterClassName"
]
}],
"simple_controllers_map": [
{
"path": "/path/name",
"controller": "controllerClassName",
"http_methods": [
"get",
"post"
],
"filters": [
"FilterClassName"
]
}
],
//idle_connection_timeout: Defaults to 60 seconds, the lifetime
//of the connection without read or write
"idle_connection_timeout": 60,
@ -227,18 +240,22 @@
"reuse_port": false
},
//plugins: Define all plugins running in the application
"plugins": [{
//name: The class name of the plugin
//"name": "drogon::plugin::SecureSSLRedirector",
//dependencies: Plugins that the plugin depends on. It can be commented out
"dependencies": [],
//config: The configuration of the plugin. This json object is the parameter to initialize the plugin.
//It can be commented out
"config": {
"ssl_redirect_exempt": [".*\\.jpg"],
"secure_ssl_host": "localhost:8849"
"plugins": [
{
//name: The class name of the plugin
//"name": "drogon::plugin::SecureSSLRedirector",
//dependencies: Plugins that the plugin depends on. It can be commented out
"dependencies": [],
//config: The configuration of the plugin. This json object is the parameter to initialize the plugin.
//It can be commented out
"config": {
"ssl_redirect_exempt": [
".*\\.jpg"
],
"secure_ssl_host": "localhost:8849"
}
}
}],
],
//custom_config: custom configuration for users. This object can be get by the app().getCustomConfig() method.
"custom_config": {}
}

View File

@ -1143,6 +1143,26 @@ class HttpAppFramework : public trantor::NonCopyable
*/
virtual bool isUnicodeEscapingUsedInJson() const noexcept = 0;
/**
* @brief Set the float precision in Json string of HTTP requests or
* responses with json content.
*
* @param precision The maximum digits length.
* @param precisionType Must be "significant" or "decimal", defaults to
* "significant" that means setting max number of significant digits in
* string, "decimal" means setting max number of digits after "." in string
* @return HttpAppFramework&
*/
virtual HttpAppFramework &setFloatPrecisionInJson(
unsigned int precision,
const std::string &precisionType = "significant") noexcept = 0;
/**
* @brief Get the float precision set by the above method.
*
* @return std::pair<size_t, std::string>
*/
virtual const std::pair<unsigned int, std::string>
&getFloatPrecisionInJson() const noexcept = 0;
/// Create a database client
/**
* @param dbType The database type is one of

View File

@ -377,6 +377,14 @@ static void loadApp(const Json::Value &app)
auto unicodeEscaping =
app.get("enable_unicode_escaping_in_json", true).asBool();
drogon::app().setUnicodeEscapingInJson(unicodeEscaping);
auto &precision = app["float_precision_in_json"];
if (!precision.isNull())
{
auto precisionLength = precision.get("precision", 0).asUInt64();
auto precisionType =
precision.get("precision_type", "significant").asString();
drogon::app().setFloatPrecisionInJson(precisionLength, precisionType);
}
// log
loadLogSetting(app["log"]);
// run as daemon

View File

@ -395,7 +395,19 @@ class HttpAppFrameworkImpl : public HttpAppFramework
{
return usingUnicodeEscaping_;
}
virtual HttpAppFramework &setFloatPrecisionInJson(
unsigned int precision,
const std::string &precisionType = "significant") noexcept override
{
floatPrecisionInJson_ = std::make_pair(precision, precisionType);
return *this;
}
virtual const std::pair<unsigned int, std::string>
&getFloatPrecisionInJson() const noexcept override
{
return floatPrecisionInJson_;
}
virtual trantor::EventLoop *getLoop() const override;
virtual trantor::EventLoop *getIOLoop(size_t id) const override;
@ -581,6 +593,8 @@ class HttpAppFrameworkImpl : public HttpAppFramework
bool useGzip_{true};
bool useBrotli_{false};
bool usingUnicodeEscaping_{true};
std::pair<unsigned int, std::string> floatPrecisionInJson_{0,
"significant"};
bool usingCustomErrorHandler_{false};
size_t clientMaxBodySize_{1024 * 1024};
size_t clientMaxMemoryBodySize_{64 * 1024};

View File

@ -1,7 +1,7 @@
/**
*
* @file HttpRequestImpl.cc
* An Tao
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
@ -477,6 +477,12 @@ HttpRequestPtr HttpRequest::newHttpJsonRequest(const Json::Value &data)
{
builder["emitUTF8"] = true;
}
auto &precision = app().getFloatPrecisionInJson();
if (precision.first != 0)
{
builder["precision"] = precision.first;
builder["precisionType"] = precision.second;
}
});
auto req = std::make_shared<HttpRequestImpl>(nullptr);
req->setMethod(drogon::Get);

View File

@ -98,6 +98,12 @@ void HttpResponseImpl::generateBodyFromJson() const
{
builder["emitUTF8"] = true;
}
auto &precision = app().getFloatPrecisionInJson();
if (precision.first != 0)
{
builder["precision"] = precision.first;
builder["precisionType"] = precision.second;
}
});
bodyPtr_ = std::make_shared<HttpMessageStringBody>(
writeString(builder, *jsonPtr_));

@ -1 +1 @@
Subproject commit 38bfde8f37cbedcc4d98cc1784947c6c7734cef0
Subproject commit 714e3b51e4048fd79ebe3bf6c780e047530c002f