github.com/cloudwego/hertz@v0.9.3/pkg/app/server/binding/internal/decoder/sonic_required.go (about)

     1  // Copyright 2023 CloudWeGo Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  
    16  //go:build (linux || windows || darwin) && amd64 && !gjson
    17  // +build linux windows darwin
    18  // +build amd64
    19  // +build !gjson
    20  
    21  package decoder
    22  
    23  import (
    24  	"strings"
    25  
    26  	"github.com/bytedance/sonic"
    27  	"github.com/cloudwego/hertz/internal/bytesconv"
    28  	"github.com/cloudwego/hertz/pkg/common/utils"
    29  	"github.com/cloudwego/hertz/pkg/protocol"
    30  	"github.com/cloudwego/hertz/pkg/protocol/consts"
    31  )
    32  
    33  func checkRequireJSON(req *protocol.Request, tagInfo TagInfo) bool {
    34  	if !tagInfo.Required {
    35  		return true
    36  	}
    37  	ct := bytesconv.B2s(req.Header.ContentType())
    38  	if !strings.EqualFold(utils.FilterContentType(ct), consts.MIMEApplicationJSON) {
    39  		return false
    40  	}
    41  	node, _ := sonic.Get(req.Body(), stringSliceForInterface(tagInfo.JSONName)...)
    42  	if !node.Exists() {
    43  		idx := strings.LastIndex(tagInfo.JSONName, ".")
    44  		if idx > 0 {
    45  			// There should be a superior if it is empty, it will report 'true' for required
    46  			node, _ := sonic.Get(req.Body(), stringSliceForInterface(tagInfo.JSONName[:idx])...)
    47  			if !node.Exists() {
    48  				return true
    49  			}
    50  		}
    51  		return false
    52  	}
    53  	return true
    54  }
    55  
    56  func stringSliceForInterface(s string) (ret []interface{}) {
    57  	x := strings.Split(s, ".")
    58  	for _, val := range x {
    59  		ret = append(ret, val)
    60  	}
    61  	return
    62  }
    63  
    64  func keyExist(req *protocol.Request, tagInfo TagInfo) bool {
    65  	ct := bytesconv.B2s(req.Header.ContentType())
    66  	if utils.FilterContentType(ct) != consts.MIMEApplicationJSON {
    67  		return false
    68  	}
    69  	node, _ := sonic.Get(req.Body(), stringSliceForInterface(tagInfo.JSONName)...)
    70  	return node.Exists()
    71  }