feat(net/ghttp): add AutoDecodingBody configuration for ghttp.Server

This commit is contained in:
John Guo
2025-03-13 11:14:41 +08:00
parent bb696bb281
commit f45f71149e
2 changed files with 30 additions and 8 deletions

View File

@ -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())
}
}

View File

@ -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,
}
}