Feat: transformer plugin support map from body to header (#892)

This commit is contained in:
澄潭
2024-03-29 16:20:16 +08:00
committed by GitHub
parent 717e3bf51f
commit e844daea66
6 changed files with 350 additions and 174 deletions

View File

@@ -243,6 +243,8 @@ func parseConfig(json gjson.Result, config *TransformerConfig, log wrapper.Log)
return errors.Wrapf(err, "failed to new transformer")
}
log.Infof("transform config is: reqRules:%+v, respRules:%+v", config.reqRules, config.respRules)
return nil
}
@@ -312,11 +314,17 @@ func onHttpRequestHeaders(ctx wrapper.HttpContext, config TransformerConfig, log
if hs["content-type"] != nil {
contentType = hs["content-type"][0]
}
if config.reqTrans.IsBodyChange() && isValidRequestContentType(contentType) {
ctx.SetContext("content-type", contentType)
isValidRequestContent := isValidRequestContentType(contentType)
isBodyChange := config.reqTrans.IsBodyChange()
needBodyMapSource := config.reqTrans.NeedBodyMapSource()
log.Debugf("contentType:%s, isValidRequestContent:%v, isBodyChange:%v, needBodyMapSource:%v",
contentType, isValidRequestContent, isBodyChange, needBodyMapSource)
if isBodyChange && isValidRequestContent {
delete(hs, "content-length")
ctx.SetContext("content-type", contentType)
} else {
ctx.DontReadRequestBody()
}
qs, err := parseQueryByPath(path)
@@ -328,26 +336,26 @@ func onHttpRequestHeaders(ctx wrapper.HttpContext, config TransformerConfig, log
ctx.SetContext("headers", hs)
ctx.SetContext("querys", qs)
var mapSourceData MapSourceData
switch config.reqTrans.GetMapSource() {
case "headers":
mapSourceData.mapSourceType = "headers"
mapSourceData.kvs = hs
case "querys":
mapSourceData.mapSourceType = "querys"
mapSourceData.kvs = qs
case "self":
if !isValidRequestContent || (!isBodyChange && !needBodyMapSource) {
ctx.DontReadRequestBody()
} else if needBodyMapSource {
// we need do transform during body phase
ctx.SetContext("need_head_trans", struct{}{})
log.Debug("delay header's transform to body phase")
return types.HeaderStopIteration
}
default:
log.Warnf("invalid mapSource in request header: %v", config.reqTrans.GetMapSource())
return types.ActionContinue
mapSourceData := make(map[string]MapSourceData)
mapSourceData["headers"] = MapSourceData{
mapSourceType: "headers",
kvs: hs,
}
mapSourceData["querys"] = MapSourceData{
mapSourceType: "querys",
kvs: qs,
}
if config.reqTrans.IsHeaderChange() {
if config.reqTrans.GetMapSource() == "self" {
mapSourceData.mapSourceType = "headers"
mapSourceData.kvs = hs
}
if err = config.reqTrans.TransformHeaders(host, path, hs, mapSourceData); err != nil {
log.Warnf("failed to transform request headers: %v", err)
return types.ActionContinue
@@ -355,10 +363,6 @@ func onHttpRequestHeaders(ctx wrapper.HttpContext, config TransformerConfig, log
}
if config.reqTrans.IsQueryChange() {
if config.reqTrans.GetMapSource() == "self" {
mapSourceData.mapSourceType = "querys"
mapSourceData.kvs = qs
}
if err = config.reqTrans.TransformQuerys(host, path, qs, mapSourceData); err != nil {
log.Warnf("failed to transform request query params: %v", err)
return types.ActionContinue
@@ -381,7 +385,7 @@ func onHttpRequestHeaders(ctx wrapper.HttpContext, config TransformerConfig, log
}
func onHttpRequestBody(ctx wrapper.HttpContext, config TransformerConfig, body []byte, log wrapper.Log) types.Action {
if config.reqTrans == nil || !config.reqTrans.IsBodyChange() {
if config.reqTrans == nil {
return types.ActionContinue
}
@@ -406,51 +410,80 @@ func onHttpRequestBody(ctx wrapper.HttpContext, config TransformerConfig, body [
return types.ActionContinue
}
var mapSourceData MapSourceData
mapSourceData := make(map[string]MapSourceData)
var hs map[string][]string
var qs map[string][]string
switch config.reqTrans.GetMapSource() {
case "headers":
{
hs = ctx.GetContext("headers").(map[string][]string)
if hs == nil {
log.Warn("failed to get request headers")
hs = ctx.GetContext("headers").(map[string][]string)
if hs == nil {
log.Warn("failed to get request headers")
return types.ActionContinue
}
if hs[":authority"] == nil {
log.Warn(errGetRequestHost.Error())
return types.ActionContinue
}
if hs[":path"] == nil {
log.Warn(errGetRequestPath.Error())
return types.ActionContinue
}
mapSourceData["headers"] = MapSourceData{
mapSourceType: "headers",
kvs: hs,
}
qs = ctx.GetContext("querys").(map[string][]string)
if qs == nil {
log.Warn("failed to get request querys")
return types.ActionContinue
}
mapSourceData["querys"] = MapSourceData{
mapSourceType: "querys",
kvs: qs,
}
switch structuredBody.(type) {
case map[string]interface{}:
mapSourceData["body"] = MapSourceData{
mapSourceType: "bodyJson",
json: structuredBody.(map[string]interface{})["body"].([]byte),
}
case map[string][]string:
mapSourceData["body"] = MapSourceData{
mapSourceType: "bodyKv",
kvs: structuredBody.(map[string][]string),
}
}
if ctx.GetContext("need_head_trans") != nil {
if config.reqTrans.IsHeaderChange() {
if err = config.reqTrans.TransformHeaders(host, path, hs, mapSourceData); err != nil {
log.Warnf("failed to transform request headers: %v", err)
return types.ActionContinue
}
if hs[":authority"] == nil {
log.Warn(errGetRequestHost.Error())
return types.ActionContinue
}
if hs[":path"] == nil {
log.Warn(errGetRequestPath.Error())
return types.ActionContinue
}
mapSourceData.mapSourceType = "headers"
mapSourceData.kvs = hs
}
case "querys":
{
qs = ctx.GetContext("querys").(map[string][]string)
if qs == nil {
log.Warn("failed to get request querys")
if config.reqTrans.IsQueryChange() {
if err = config.reqTrans.TransformQuerys(host, path, qs, mapSourceData); err != nil {
log.Warnf("failed to transform request query params: %v", err)
return types.ActionContinue
}
mapSourceData.mapSourceType = "querys"
mapSourceData.kvs = qs
path, err = constructPath(path, qs)
if err != nil {
log.Warnf("failed to construct path: %v", err)
return types.ActionContinue
}
hs[":path"] = []string{path}
}
case "body", "self":
switch structuredBody.(type) {
case map[string]interface{}:
mapSourceData.mapSourceType = "bodyJson"
mapSourceData.json = structuredBody.(map[string]interface{})["body"].([]byte)
case map[string][]string:
mapSourceData.mapSourceType = "bodyKv"
mapSourceData.kvs = structuredBody.(map[string][]string)
headers := reconvertHeaders(hs)
if err = proxywasm.ReplaceHttpRequestHeaders(headers); err != nil {
log.Warnf("failed to replace request headers: %v", err)
return types.ActionContinue
}
default:
log.Warnf("invalid mapSource in request body: %v", config.reqTrans.GetMapSource())
}
if !config.reqTrans.IsBodyChange() {
return types.ActionContinue
}
@@ -495,21 +528,28 @@ func onHttpResponseHeaders(ctx wrapper.HttpContext, config TransformerConfig, lo
if hs["content-type"] != nil {
contentType = hs["content-type"][0]
}
if config.respTrans.IsBodyChange() && isValidResponseContentType(contentType) {
ctx.SetContext("content-type", contentType)
isValidResponseContent := isValidResponseContentType(contentType)
isBodyChange := config.respTrans.IsBodyChange()
needBodyMapSource := config.respTrans.NeedBodyMapSource()
if isBodyChange && isValidResponseContent {
delete(hs, "content-length")
ctx.SetContext("content-type", contentType)
} else {
ctx.DontReadResponseBody()
}
var mapSourceData MapSourceData
switch config.respTrans.GetMapSource() {
case "headers", "self":
mapSourceData.mapSourceType = "headers"
mapSourceData.kvs = hs
default:
log.Warnf("invalid mapSource in response header: %v", config.respTrans.GetMapSource())
return types.ActionContinue
if !isValidResponseContent || (!isBodyChange && !needBodyMapSource) {
ctx.DontReadResponseBody()
} else if needBodyMapSource {
// we need do transform during body phase
ctx.SetContext("need_head_trans", struct{}{})
return types.HeaderStopIteration
}
mapSourceData := make(map[string]MapSourceData)
mapSourceData["headers"] = MapSourceData{
mapSourceType: "headers",
kvs: hs,
}
if config.respTrans.IsHeaderChange() {
@@ -529,7 +569,7 @@ func onHttpResponseHeaders(ctx wrapper.HttpContext, config TransformerConfig, lo
}
func onHttpResponseBody(ctx wrapper.HttpContext, config TransformerConfig, body []byte, log wrapper.Log) types.Action {
if config.respTrans == nil || !config.respTrans.IsBodyChange() {
if config.respTrans == nil {
return types.ActionContinue
}
@@ -554,30 +594,48 @@ func onHttpResponseBody(ctx wrapper.HttpContext, config TransformerConfig, body
return types.ActionContinue
}
var mapSourceData MapSourceData
switch config.respTrans.GetMapSource() {
case "headers":
{
hs := ctx.GetContext("headers").(map[string][]string)
if hs == nil {
log.Warn("failed to get response headers")
mapSourceData := make(map[string]MapSourceData)
var hs map[string][]string
hs = ctx.GetContext("headers").(map[string][]string)
if hs == nil {
log.Warn("failed to get response headers")
return types.ActionContinue
}
mapSourceData["headers"] = MapSourceData{
mapSourceType: "headers",
kvs: hs,
}
switch structuredBody.(type) {
case map[string]interface{}:
mapSourceData["body"] = MapSourceData{
mapSourceType: "bodyJson",
json: structuredBody.(map[string]interface{})["body"].([]byte),
}
case map[string][]string:
mapSourceData["body"] = MapSourceData{
mapSourceType: "bodyKv",
kvs: structuredBody.(map[string][]string),
}
}
if ctx.GetContext("need_head_trans") != nil {
if config.respTrans.IsHeaderChange() {
if err = config.respTrans.TransformHeaders(host, path, hs, mapSourceData); err != nil {
log.Warnf("failed to transform response headers: %v", err)
return types.ActionContinue
}
mapSourceData.mapSourceType = "headers"
mapSourceData.kvs = hs
}
case "body", "self":
switch structuredBody.(type) {
case map[string]interface{}:
mapSourceData.mapSourceType = "bodyJson"
mapSourceData.json = structuredBody.(map[string]interface{})["body"].([]byte)
case map[string][]string:
mapSourceData.mapSourceType = "bodyKv"
mapSourceData.kvs = structuredBody.(map[string][]string)
headers := reconvertHeaders(hs)
if err = proxywasm.ReplaceHttpResponseHeaders(headers); err != nil {
log.Warnf("failed to replace response headers: %v", err)
return types.ActionContinue
}
default:
log.Warnf("invalid mapSource in response body: %v", config.respTrans.GetMapSource())
}
if !config.respTrans.IsBodyChange() {
return types.ActionContinue
}
@@ -657,36 +715,34 @@ func newTransformRule(rules []gjson.Result) (res []TransformRule, err error) {
}
type Transformer interface {
TransformHeaders(host, path string, hs map[string][]string, mapSourceData MapSourceData) error
TransformQuerys(host, path string, qs map[string][]string, mapSourceData MapSourceData) error
TransformBody(host, path string, body interface{}, mapSourceData MapSourceData) error
TransformHeaders(host, path string, hs map[string][]string, mapSourceData map[string]MapSourceData) error
TransformQuerys(host, path string, qs map[string][]string, mapSourceData map[string]MapSourceData) error
TransformBody(host, path string, body interface{}, mapSourceData map[string]MapSourceData) error
IsHeaderChange() bool
IsQueryChange() bool
IsBodyChange() bool
GetMapSource() string
NeedBodyMapSource() bool
}
var _ Transformer = (*requestTransformer)(nil)
var _ Transformer = (*responseTransformer)(nil)
type requestTransformer struct {
headerHandler *kvHandler
queryHandler *kvHandler
bodyHandler *requestBodyHandler
isHeaderChange bool
isQueryChange bool
isBodyChange bool
// 目前插件在对request做map转换的时候只支持最多一个映射来源
// 取值headersquerysbodyself
mapSource string
headerHandler *kvHandler
queryHandler *kvHandler
bodyHandler *requestBodyHandler
isHeaderChange bool
isQueryChange bool
isBodyChange bool
needBodyMapSource bool
}
func newRequestTransformer(config *TransformerConfig) (Transformer, error) {
headerKvtGroup, isHeaderChange, withHeaderMapKvt, err := newKvtGroup(config.reqRules, "headers")
headerKvtGroup, isHeaderChange, _, err := newKvtGroup(config.reqRules, "headers")
if err != nil {
return nil, errors.Wrap(err, "failed to new kvt group for headers")
}
queryKvtGroup, isQueryChange, withQueryMapKvt, err := newKvtGroup(config.reqRules, "querys")
queryKvtGroup, isQueryChange, _, err := newKvtGroup(config.reqRules, "querys")
if err != nil {
return nil, errors.Wrap(err, "failed to new kvt group for querys")
}
@@ -695,12 +751,7 @@ func newRequestTransformer(config *TransformerConfig) (Transformer, error) {
return nil, errors.Wrap(err, "failed to new kvt group for body")
}
mapSource := getMapSourceFromRule(config.reqRules)
// TODO: not support mapping headers or querys from body in requestTransformer before #582 is fixed
if mapSource == "body" && (withHeaderMapKvt || withQueryMapKvt) {
return nil, errors.Wrap(err, "not support mapping headers or querys from body in requestTransformer")
}
bodyMapSource := bodyMapSourceInRule(config.reqRules)
return &requestTransformer{
headerHandler: &kvHandler{headerKvtGroup},
@@ -709,22 +760,22 @@ func newRequestTransformer(config *TransformerConfig) (Transformer, error) {
formDataHandler: &kvHandler{bodyKvtGroup},
jsonHandler: &jsonHandler{bodyKvtGroup},
},
isHeaderChange: isHeaderChange,
isQueryChange: isQueryChange,
isBodyChange: isBodyChange,
mapSource: mapSource,
isHeaderChange: isHeaderChange,
isQueryChange: isQueryChange,
isBodyChange: isBodyChange,
needBodyMapSource: bodyMapSource,
}, nil
}
func (t requestTransformer) TransformHeaders(host, path string, hs map[string][]string, mapSourceData MapSourceData) error {
func (t requestTransformer) TransformHeaders(host, path string, hs map[string][]string, mapSourceData map[string]MapSourceData) error {
return t.headerHandler.handle(host, path, hs, mapSourceData)
}
func (t requestTransformer) TransformQuerys(host, path string, qs map[string][]string, mapSourceData MapSourceData) error {
func (t requestTransformer) TransformQuerys(host, path string, qs map[string][]string, mapSourceData map[string]MapSourceData) error {
return t.queryHandler.handle(host, path, qs, mapSourceData)
}
func (t requestTransformer) TransformBody(host, path string, body interface{}, mapSourceData MapSourceData) error {
func (t requestTransformer) TransformBody(host, path string, body interface{}, mapSourceData map[string]MapSourceData) error {
switch body.(type) {
case map[string][]string:
return t.bodyHandler.formDataHandler.handle(host, path, body.(map[string][]string), mapSourceData)
@@ -744,23 +795,22 @@ func (t requestTransformer) TransformBody(host, path string, body interface{}, m
return nil
}
func (t requestTransformer) IsHeaderChange() bool { return t.isHeaderChange }
func (t requestTransformer) IsQueryChange() bool { return t.isQueryChange }
func (t requestTransformer) IsBodyChange() bool { return t.isBodyChange }
func (t requestTransformer) GetMapSource() string { return t.mapSource }
func (t requestTransformer) IsHeaderChange() bool { return t.isHeaderChange }
func (t requestTransformer) IsQueryChange() bool { return t.isQueryChange }
func (t requestTransformer) IsBodyChange() bool { return t.isBodyChange }
func (t requestTransformer) NeedBodyMapSource() bool { return t.needBodyMapSource }
type responseTransformer struct {
headerHandler *kvHandler
bodyHandler *responseBodyHandler
isHeaderChange bool
isBodyChange bool
// 目前插件在对response做map转换的时候只支持最多一个映射来源
mapSource string
headerHandler *kvHandler
bodyHandler *responseBodyHandler
isHeaderChange bool
isBodyChange bool
needBodyMapSource bool
}
func newResponseTransformer(config *TransformerConfig) (Transformer, error) {
headerKvtGroup, isHeaderChange, withHeaderMapKvt, err := newKvtGroup(config.respRules, "headers")
headerKvtGroup, isHeaderChange, _, err := newKvtGroup(config.respRules, "headers")
if err != nil {
return nil, errors.Wrap(err, "failed to new kvt group for headers")
}
@@ -768,30 +818,27 @@ func newResponseTransformer(config *TransformerConfig) (Transformer, error) {
if err != nil {
return nil, errors.Wrap(err, "failed to new kvt group for body")
}
mapSource := getMapSourceFromRule(config.respRules)
// TODO: not support mapping headers from body in responseTransformer before #582 is fixed
if mapSource == "body" && withHeaderMapKvt {
return nil, errors.Wrap(err, "not support mapping headers from body in responseTransformer")
}
bodyMapSource := bodyMapSourceInRule(config.respRules)
return &responseTransformer{
headerHandler: &kvHandler{headerKvtGroup},
bodyHandler: &responseBodyHandler{&jsonHandler{bodyKvtGroup}},
isHeaderChange: isHeaderChange,
isBodyChange: isBodyChange,
mapSource: mapSource,
headerHandler: &kvHandler{headerKvtGroup},
bodyHandler: &responseBodyHandler{&jsonHandler{bodyKvtGroup}},
isHeaderChange: isHeaderChange,
isBodyChange: isBodyChange,
needBodyMapSource: bodyMapSource,
}, nil
}
func (t responseTransformer) TransformHeaders(host, path string, hs map[string][]string, mapSourceData MapSourceData) error {
func (t responseTransformer) TransformHeaders(host, path string, hs map[string][]string, mapSourceData map[string]MapSourceData) error {
return t.headerHandler.handle(host, path, hs, mapSourceData)
}
func (t responseTransformer) TransformQuerys(host, path string, qs map[string][]string, mapSourceData MapSourceData) error {
func (t responseTransformer) TransformQuerys(host, path string, qs map[string][]string, mapSourceData map[string]MapSourceData) error {
// the response does not need to transform the query params, always returns nil
return nil
}
func (t responseTransformer) TransformBody(host, path string, body interface{}, mapSourceData MapSourceData) error {
func (t responseTransformer) TransformBody(host, path string, body interface{}, mapSourceData map[string]MapSourceData) error {
switch body.(type) {
case map[string]interface{}:
m := body.(map[string]interface{})
@@ -808,10 +855,10 @@ func (t responseTransformer) TransformBody(host, path string, body interface{},
return nil
}
func (t responseTransformer) IsHeaderChange() bool { return t.isHeaderChange }
func (t responseTransformer) IsQueryChange() bool { return false } // the response does not need to transform the query params, always returns false
func (t responseTransformer) IsBodyChange() bool { return t.isBodyChange }
func (t responseTransformer) GetMapSource() string { return t.mapSource }
func (t responseTransformer) IsHeaderChange() bool { return t.isHeaderChange }
func (t responseTransformer) IsQueryChange() bool { return false } // the response does not need to transform the query params, always returns false
func (t responseTransformer) IsBodyChange() bool { return t.isBodyChange }
func (t responseTransformer) NeedBodyMapSource() bool { return t.needBodyMapSource }
type requestBodyHandler struct {
formDataHandler *kvHandler
@@ -830,7 +877,7 @@ type jsonHandler struct {
kvtOps []kvtOperation
}
func (h kvHandler) handle(host, path string, kvs map[string][]string, mapSourceData MapSourceData) error {
func (h kvHandler) handle(host, path string, kvs map[string][]string, mapSourceData map[string]MapSourceData) error {
// arbitary order. for example: remove → rename → replace → add → append → map → dedupe
for _, kvtOp := range h.kvtOps {
@@ -887,17 +934,29 @@ func (h kvHandler) handle(host, path string, kvs map[string][]string, mapSourceD
// map: 若指定 fromKey 不存在则无操作;否则将 fromKey 的值映射给 toKey 的值
for _, map_ := range kvtOp.mapKvtGroup {
fromKey, toKey := map_.fromKey, map_.toKey
if mapSourceData.mapSourceType == "headers" {
if kvtOp.mapSource == "headers" {
fromKey = strings.ToLower(fromKey)
}
if fromValue, ok := mapSourceData.search(fromKey); ok {
switch mapSourceData.mapSourceType {
source, exist := mapSourceData[kvtOp.mapSource]
if !exist {
proxywasm.LogWarnf("map key failed, source:%s not exists", kvtOp.mapSource)
continue
}
proxywasm.LogDebugf("search key:%s in source:%s", fromKey, kvtOp.mapSource)
if fromValue, ok := source.search(fromKey); ok {
switch source.mapSourceType {
case "headers", "querys", "bodyKv":
kvs[toKey] = fromValue.([]string)
// TODO: not support mapping headers or querys from body before #582 is fixed
// case "bodyJson":
// kvs[toKey] = fromValue
// }
proxywasm.LogDebugf("map key:%s to key:%s success, value is: %v", fromKey, toKey, fromValue)
case "bodyJson":
if valueJson, ok := fromValue.(gjson.Result); ok {
valueStr := valueJson.String()
if valueStr != "" {
kvs[toKey] = []string{valueStr}
proxywasm.LogDebugf("map key:%s to key:%s success, values is:%s", fromKey, toKey, valueStr)
}
}
}
}
}
@@ -938,7 +997,7 @@ func (h kvHandler) handle(host, path string, kvs map[string][]string, mapSourceD
}
// only for body
func (h jsonHandler) handle(host, path string, oriData []byte, mapSourceData MapSourceData) (data []byte, err error) {
func (h jsonHandler) handle(host, path string, oriData []byte, mapSourceData map[string]MapSourceData) (data []byte, err error) {
// arbitary order. for example: remove → rename → replace → add → append → map → dedupe
if !gjson.ValidBytes(oriData) {
return nil, errors.New("invalid json body")
@@ -1054,14 +1113,30 @@ func (h jsonHandler) handle(host, path string, oriData []byte, mapSourceData Map
// map: 若指定 fromKey 不存在则无操作;否则将 fromKey 的值映射给 toKey 的值
for _, map_ := range kvtOp.mapKvtGroup {
fromKey, toKey := map_.fromKey, map_.toKey
if mapSourceData.mapSourceType == "headers" {
if kvtOp.mapSource == "headers" {
fromKey = strings.ToLower(fromKey)
}
if fromValue, ok := mapSourceData.search(fromKey); ok {
// search返回的类型为[]string或者gjson.Result.Value()
// sjson.SetBytes()能够直接处理[]byte其他更复杂的数据类型均会json.Marshall化
if data, err = sjson.SetBytes(data, toKey, fromValue); err != nil {
return nil, errors.Wrap(err, errMap.Error())
source, exist := mapSourceData[kvtOp.mapSource]
if !exist {
proxywasm.LogWarnf("map key failed, source:%s not exists", kvtOp.mapSource)
continue
}
proxywasm.LogDebugf("search key:%s in source:%s", fromKey, kvtOp.mapSource)
if fromValue, ok := source.search(fromKey); ok {
switch source.mapSourceType {
case "headers", "querys", "bodyKv":
if data, err = sjson.SetBytes(data, toKey, fromValue); err != nil {
return nil, errors.Wrap(err, errMap.Error())
}
proxywasm.LogDebugf("map key:%s to key:%s success, value is: %v", fromKey, toKey, fromValue)
case "bodyJson":
if valueJson, ok := fromValue.(gjson.Result); ok {
if data, err = sjson.SetBytes(data, toKey, valueJson.Value()); err != nil {
return nil, errors.Wrap(err, errMap.Error())
}
proxywasm.LogDebugf("map key:%s to key:%s success, value is: %v", fromKey, toKey, fromValue)
}
}
}
}
@@ -1226,10 +1301,17 @@ func newKvtGroup(rules []TransformRule, typ string) (g []kvtOperation, isChange
kvtOp.renameKvtGroup = append(kvtOp.renameKvtGroup, renameKvt{p.renameParam.oldKey, p.renameParam.newKey, p.valueType})
case "map":
if typ == "headers" {
p.mapParam.fromKey = strings.ToLower(p.mapParam.fromKey)
p.mapParam.toKey = strings.ToLower(p.mapParam.toKey)
}
kvtOp.mapSource = r.mapSource
if kvtOp.mapSource == "self" {
kvtOp.mapSource = typ
r.mapSource = typ
}
if kvtOp.mapSource == "headers" {
p.mapParam.fromKey = strings.ToLower(p.mapParam.fromKey)
}
kvtOp.mapKvtGroup = append(kvtOp.mapKvtGroup, mapKvt{p.mapParam.fromKey, p.mapParam.toKey})
case "dedupe":
if typ == "headers" {
@@ -1301,20 +1383,19 @@ func (msdata MapSourceData) search(fromKey string) (interface{}, bool) {
if !fromValue.Exists() {
return nil, false
}
return fromValue.Value(), true
return fromValue, true
default:
return "", false
}
}
func getMapSourceFromRule(rules []TransformRule) string {
// 如果rules中不含map转换要求则返回空字符串
func bodyMapSourceInRule(rules []TransformRule) bool {
for _, r := range rules {
if r.operate == "map" {
return r.mapSource
if r.operate == "map" && r.mapSource == "body" {
return true
}
}
return ""
return false
}
type kvtReg struct {