From f45f71149edcdab2c60e2c0a3abb1c64eef87f44 Mon Sep 17 00:00:00 2001 From: John Guo Date: Thu, 13 Mar 2025 11:14:41 +0800 Subject: [PATCH] feat(net/ghttp): add AutoDecodingBody configuration for ghttp.Server --- net/ghttp/ghttp_request_param.go | 32 +++++++++++++++++++++++++------- net/ghttp/ghttp_server_config.go | 6 +++++- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/net/ghttp/ghttp_request_param.go b/net/ghttp/ghttp_request_param.go index 6e44814c0..22aad61af 100644 --- a/net/ghttp/ghttp_request_param.go +++ b/net/ghttp/ghttp_request_param.go @@ -233,22 +233,40 @@ func (r *Request) parseBody() { if r.ContentLength == 0 { return } + // If it's a multipart request, it does not parse the body content. + contentType := r.Header.Get("Content-Type") + if gstr.Contains(contentType, "multipart/") { + return + } if body := r.GetBody(); len(body) > 0 { // Trim space/new line characters. body = bytes.TrimSpace(body) - // JSON format checks. - if body[0] == '{' && body[len(body)-1] == '}' { + + // json/xml content type checks. + if gstr.Contains(contentType, "/json") { _ = json.UnmarshalUseNumber(body, &r.bodyMap) + return } - // XML format checks. - if len(body) > 5 && bytes.EqualFold(body[:5], xmlHeaderBytes) { + if gstr.Contains(contentType, "/xml") { r.bodyMap, _ = gxml.DecodeWithoutRoot(body) + return } - if body[0] == '<' && body[len(body)-1] == '>' { - r.bodyMap, _ = gxml.DecodeWithoutRoot(body) + // Auto decoding body content. + if r.Server.config.AutoDecodingBody { + // JSON format checks. + if body[0] == '{' && body[len(body)-1] == '}' { + _ = json.UnmarshalUseNumber(body, &r.bodyMap) + } + // XML format checks. + if len(body) > 5 && bytes.EqualFold(body[:5], xmlHeaderBytes) { + r.bodyMap, _ = gxml.DecodeWithoutRoot(body) + } + if body[0] == '<' && body[len(body)-1] == '>' { + r.bodyMap, _ = gxml.DecodeWithoutRoot(body) + } } // Default parameters decoding. - if contentType := r.Header.Get("Content-Type"); (contentType == "" || !gstr.Contains(contentType, "multipart/")) && r.bodyMap == nil { + if r.bodyMap == nil { r.bodyMap, _ = gstr.Parse(r.GetBodyString()) } } diff --git a/net/ghttp/ghttp_server_config.go b/net/ghttp/ghttp_server_config.go index f5a6f4fe9..60d228c0b 100644 --- a/net/ghttp/ghttp_server_config.go +++ b/net/ghttp/ghttp_server_config.go @@ -205,7 +205,7 @@ type ServerConfig struct { // Logging. // ====================================================================================================== - Logger *glog.Logger `json:"logger"` // Logger specifies the logger for server. + Logger *glog.Logger `json:"logger"` // Logger directly specifies the logger for server. LogPath string `json:"logPath"` // LogPath specifies the directory for storing logging files. LogLevel string `json:"logLevel"` // LogLevel specifies the logging level for logger. LogStdout bool `json:"logStdout"` // LogStdout specifies whether printing logging content to stdout. @@ -267,6 +267,9 @@ type ServerConfig struct { // DumpRouterMap specifies whether automatically dumps router map when server starts. DumpRouterMap bool `json:"dumpRouterMap"` + + // AutoDecodingBody specifies whether automatically decodes request body using common encoding types: json/xml. + AutoDecodingBody bool `json:"auto_decoding_body"` } // NewConfig creates and returns a ServerConfig object with default configurations. @@ -313,6 +316,7 @@ func NewConfig() ServerConfig { Graceful: false, GracefulTimeout: 2, // seconds GracefulShutdownTimeout: 5, // seconds + AutoDecodingBody: true, } }