fix: where HTTP node URL, JSON text, and raw text template rendering could not find the corresponding rendering variables (#745)

main
Zhj 2 months ago committed by GitHub
parent ff00dcb31b
commit 4ff734f15f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 78
      backend/api/handler/coze/workflow_service_test.go
  2. 10
      backend/domain/workflow/internal/canvas/convert/type_convert.go
  3. 578
      backend/domain/workflow/internal/canvas/examples/httprequester/http_implicit_dependencies.json
  4. 112
      backend/domain/workflow/internal/nodes/httprequester/adapt.go
  5. 20
      backend/domain/workflow/internal/nodes/httprequester/http_requester.go

@ -4655,7 +4655,7 @@ func TestJsonSerializationDeserializationWithWarning(t *testing.T) {
})
}
func TestSetAppVariablesFOrSubProcesses(t *testing.T) {
func TestSetAppVariablesForSubProcesses(t *testing.T) {
mockey.PatchConvey("app variables for sub_process", t, func() {
r := newWfTestRunner(t)
defer r.closeFn()
@ -4672,3 +4672,79 @@ func TestSetAppVariablesFOrSubProcesses(t *testing.T) {
})
}
func TestHttpImplicitDependencies(t *testing.T) {
mockey.PatchConvey("test http implicit dependencies", t, func() {
r := newWfTestRunner(t)
defer r.closeFn()
r.appVarS.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return("1.0", nil).AnyTimes()
idStr := r.load("httprequester/http_implicit_dependencies.json")
r.publish(idStr, "v0.0.1", true)
runner := mockcode.NewMockRunner(r.ctrl)
runner.EXPECT().Run(gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, request *coderunner.RunRequest) (*coderunner.RunResponse, error) {
in := request.Params["input"]
_ = in
result := make(map[string]any)
err := sonic.UnmarshalString(in.(string), &result)
if err != nil {
return nil, err
}
return &coderunner.RunResponse{
Result: result,
}, nil
}).AnyTimes()
code.SetCodeRunner(runner)
mockey.PatchConvey("test http node implicit dependencies", func() {
input := map[string]string{
"input": "a",
}
result, _ := r.openapiSyncRun(idStr, input)
batchRets := result["batch"].([]any)
loopRets := result["loop"].([]any)
for _, r := range batchRets {
assert.Contains(t, []any{
"http://echo.apifox.com/anything?aa=1.0&cc=1",
"http://echo.apifox.com/anything?aa=1.0&cc=2",
}, r)
}
for _, r := range loopRets {
assert.Contains(t, []any{
"http://echo.apifox.com/anything?a=1&m=123",
"http://echo.apifox.com/anything?a=2&m=123",
}, r)
}
})
mockey.PatchConvey("node debug http node implicit dependencies", func() {
exeID := r.nodeDebug(idStr, "109387",
withNDInput(map[string]string{
"__apiInfo_url_87fc7c69536cae843fa7f5113cf0067b": "m",
"__apiInfo_url_ac86361e3cd503952e71986dc091fa6f": "a",
"__body_bodyData_json_ac86361e3cd503952e71986dc091fa6f": "b",
"__body_bodyData_json_f77817a7cf8441279e1cfd8af4eeb1da": "1",
}))
e := r.getProcess(idStr, exeID, withSpecificNodeID("109387"))
e.assertSuccess()
ret := make(map[string]any)
err := sonic.UnmarshalString(e.output, &ret)
assert.Nil(t, err)
err = sonic.UnmarshalString(ret["body"].(string), &ret)
assert.Nil(t, err)
assert.Equal(t, ret["url"].(string), "http://echo.apifox.com/anything?a=a&m=m")
})
})
}

@ -144,7 +144,7 @@ func CanvasBlockInputToTypeInfo(b *vo.BlockInput) (tInfo *vo.TypeInfo, err error
}
tInfo.Properties[subV.Name] = subTInfo
} else if b.Value.Type == vo.BlockInputValueTypeObjectRef {
subV, err := parseParam(subVAny)
subV, err := ParseParam(subVAny)
if err != nil {
return nil, err
}
@ -195,7 +195,7 @@ func CanvasBlockInputToFieldInfo(b *vo.BlockInput, path einoCompose.FieldPath, p
for i := range paramList {
paramAny := paramList[i]
param, err := parseParam(paramAny)
param, err := ParseParam(paramAny)
if err != nil {
return nil, err
}
@ -343,7 +343,7 @@ func parseBlockInputRef(content any) (*vo.BlockInputReference, error) {
return p, nil
}
func parseParam(v any) (*vo.Param, error) {
func ParseParam(v any) (*vo.Param, error) {
if pa, ok := v.(*vo.Param); ok {
return pa, nil
}
@ -497,7 +497,7 @@ func SetOutputTypesForNodeSchema(n *vo.Node, ns *schema.NodeSchema) error {
func SetOutputsForNodeSchema(n *vo.Node, ns *schema.NodeSchema) error {
for _, vAny := range n.Data.Outputs {
param, err := parseParam(vAny)
param, err := ParseParam(vAny)
if err != nil {
return err
}
@ -565,7 +565,7 @@ func BlockInputToNamedTypeInfo(name string, b *vo.BlockInput) (*vo.NamedTypeInfo
}
tInfo.Properties = append(tInfo.Properties, subNInfo)
} else if b.Value.Type == vo.BlockInputValueTypeObjectRef {
subV, err := parseParam(subVAny)
subV, err := ParseParam(subVAny)
if err != nil {
return nil, err
}

@ -0,0 +1,578 @@
{
"nodes": [
{
"id": "100001",
"type": "1",
"meta": {
"position": {
"x": 180,
"y": 26.950000000000003
}
},
"data": {
"nodeMeta": {
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
"subTitle": "",
"title": "开始"
},
"outputs": [
{
"type": "string",
"name": "input",
"required": false
}
],
"trigger_parameters": []
}
},
{
"id": "900001",
"type": "2",
"meta": {
"position": {
"x": 2880,
"y": 13.950000000000003
}
},
"data": {
"nodeMeta": {
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
"subTitle": "",
"title": "结束"
},
"inputs": {
"terminatePlan": "returnVariables",
"inputParameters": [
{
"name": "batch",
"input": {
"type": "list",
"schema": {
"type": "string"
},
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "125743",
"name": "output"
},
"rawMeta": {
"type": 99
}
}
}
},
{
"name": "loop",
"input": {
"type": "list",
"schema": {
"type": "string"
},
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "122230",
"name": "output"
},
"rawMeta": {
"type": 99
}
}
}
}
]
}
}
},
{
"id": "122230",
"type": "21",
"meta": {
"position": {
"x": 941.8355065195586,
"y": -65.71715145436308
},
"canvasPosition": {
"x": 560,
"y": 319.9
}
},
"data": {
"nodeMeta": {
"title": "循环",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Loop-v2.jpg",
"description": "用于通过设定循环次数和逻辑,重复执行一系列任务",
"mainColor": "#00B2B2",
"subTitle": "循环"
},
"inputs": {
"loopType": "array",
"loopCount": {
"type": "integer",
"value": {
"type": "literal",
"content": "10"
}
},
"variableParameters": [
{
"name": "m",
"input": {
"type": "string",
"value": {
"type": "literal",
"content": "123",
"rawMeta": {
"type": 1
}
}
}
}
],
"inputParameters": [
{
"name": "input",
"input": {
"type": "list",
"value": {
"type": "literal",
"content": "[\"1\",\"2\"]",
"rawMeta": {
"type": 99
}
},
"schema": {
"type": "string"
}
}
}
]
},
"outputs": [
{
"name": "output",
"input": {
"type": "list",
"schema": {
"type": "string"
},
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "164858",
"name": "url"
},
"rawMeta": {
"type": 1
}
}
}
}
]
},
"blocks": [
{
"id": "109387",
"type": "45",
"meta": {
"position": {
"x": 180,
"y": 0
}
},
"data": {
"nodeMeta": {
"title": "HTTP 请求",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-HTTP.png",
"description": "用于发送API请求,从接口返回数据",
"mainColor": "#3071F2",
"subTitle": "HTTP 请求"
},
"inputParameters": [],
"inputs": {
"apiInfo": {
"method": "GET",
"url": "http://echo.apifox.com/anything?a={{block_output_122230.input}}&m={{block_output_122230.m}}"
},
"body": {
"bodyType": "JSON",
"bodyData": {
"binary": {
"fileURL": {
"type": "string",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "",
"name": ""
}
}
}
},
"json": "{\n \"index\": {{block_output_122230.index}},\n \"value\": \"{{block_output_122230.input}}\"\n}"
}
},
"headers": [],
"params": [],
"auth": {
"authType": "BEARER_AUTH",
"authData": {
"customData": {
"addTo": "header"
}
},
"authOpen": false
},
"setting": {
"timeout": 120,
"retryTimes": 3
},
"settingOnError": {}
},
"outputs": [
{
"type": "string",
"name": "body"
},
{
"type": "integer",
"name": "statusCode"
},
{
"type": "string",
"name": "headers"
}
],
"settingOnError": {}
}
},
{
"id": "164858",
"type": "5",
"meta": {
"position": {
"x": 640,
"y": 12
}
},
"data": {
"nodeMeta": {
"title": "代码_1",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Code-v2.jpg",
"description": "编写代码,处理输入变量来生成返回值",
"mainColor": "#00B2B2",
"subTitle": "代码"
},
"inputs": {
"inputParameters": [
{
"name": "input",
"input": {
"type": "string",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "109387",
"name": "body"
},
"rawMeta": {
"type": 1
}
}
}
}
],
"code": "import json\nasync def main(args: Args) -> Output:\n params = args.params\n input_string = params['input']\n return json.loads(input_string)",
"language": 3,
"settingOnError": {
"processType": 1,
"timeoutMs": 60000,
"retryTimes": 0
}
},
"outputs": [
{
"type": "object",
"name": "args",
"schema": []
},
{
"type": "string",
"name": "url"
}
]
}
}
],
"edges": [
{
"sourceNodeID": "122230",
"targetNodeID": "109387",
"sourcePortID": "loop-function-inline-output"
},
{
"sourceNodeID": "109387",
"targetNodeID": "164858"
},
{
"sourceNodeID": "164858",
"targetNodeID": "122230",
"targetPortID": "loop-function-inline-input"
}
]
},
{
"id": "125743",
"type": "28",
"meta": {
"position": {
"x": 2090,
"y": 13
},
"canvasPosition": {
"x": 1680,
"y": 306.9
}
},
"data": {
"nodeMeta": {
"title": "批处理",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Batch-v2.jpg",
"description": "通过设定批量运行次数和逻辑,运行批处理体内的任务",
"mainColor": "#00B2B2",
"subTitle": "批处理"
},
"inputs": {
"concurrentSize": {
"type": "integer",
"value": {
"type": "literal",
"content": "10"
}
},
"batchSize": {
"type": "integer",
"value": {
"type": "literal",
"content": "100"
}
},
"inputParameters": [
{
"name": "input",
"input": {
"type": "list",
"value": {
"type": "literal",
"content": "[\"1\",\"2\"]",
"rawMeta": {
"type": 99
}
},
"schema": {
"type": "string"
}
}
}
]
},
"outputs": [
{
"name": "output",
"input": {
"type": "list",
"schema": {
"type": "string"
},
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "182572",
"name": "url"
},
"rawMeta": {
"type": 1
}
}
}
}
]
},
"blocks": [
{
"id": "191311",
"type": "45",
"meta": {
"position": {
"x": 180,
"y": 0
}
},
"data": {
"nodeMeta": {
"title": "HTTP 请求_1",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-HTTP.png",
"description": "用于发送API请求,从接口返回数据",
"mainColor": "#3071F2",
"subTitle": "HTTP 请求"
},
"inputParameters": [],
"inputs": {
"apiInfo": {
"method": "GET",
"url": "http://echo.apifox.com/anything?cc={{block_output_125743.input}}&aa={{global_variable_app[\"app\"]}}"
},
"body": {
"bodyType": "JSON",
"bodyData": {
"binary": {
"fileURL": {
"type": "string",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "",
"name": ""
}
}
}
},
"json": "{\n \"value\": {{block_output_125743.index}}\n}"
}
},
"headers": [],
"params": [],
"auth": {
"authType": "BEARER_AUTH",
"authData": {
"customData": {
"addTo": "header"
}
},
"authOpen": false
},
"setting": {
"timeout": 120,
"retryTimes": 3
},
"settingOnError": {}
},
"outputs": [
{
"type": "string",
"name": "body"
},
{
"type": "integer",
"name": "statusCode"
},
{
"type": "string",
"name": "headers"
}
],
"settingOnError": {}
}
},
{
"id": "182572",
"type": "5",
"meta": {
"position": {
"x": 640,
"y": 12
}
},
"data": {
"nodeMeta": {
"title": "代码_3",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Code-v2.jpg",
"description": "编写代码,处理输入变量来生成返回值",
"mainColor": "#00B2B2",
"subTitle": "代码"
},
"inputs": {
"inputParameters": [
{
"name": "input",
"input": {
"type": "string",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "191311",
"name": "body"
},
"rawMeta": {
"type": 1
}
}
}
}
],
"code": "import json\nasync def main(args: Args) -> Output:\n params = args.params\n input_string = params['input']\n return json.loads(input_string)",
"language": 3,
"settingOnError": {
"processType": 1,
"timeoutMs": 60000,
"retryTimes": 0
}
},
"outputs": [
{
"type": "string",
"name": "url"
}
]
}
}
],
"edges": [
{
"sourceNodeID": "125743",
"targetNodeID": "191311",
"sourcePortID": "batch-function-inline-output"
},
{
"sourceNodeID": "191311",
"targetNodeID": "182572"
},
{
"sourceNodeID": "182572",
"targetNodeID": "125743",
"targetPortID": "batch-function-inline-input"
}
]
}
],
"edges": [
{
"sourceNodeID": "100001",
"targetNodeID": "122230"
},
{
"sourceNodeID": "125743",
"targetNodeID": "900001",
"sourcePortID": "batch-output"
},
{
"sourceNodeID": "122230",
"targetNodeID": "125743",
"sourcePortID": "loop-output"
}
],
"versions": {
"loop": "v2"
}
}

@ -23,10 +23,12 @@ import (
"github.com/cloudwego/eino/compose"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
"github.com/coze-dev/coze-studio/backend/pkg/lang/crypto"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
)
var extractBracesRegexp = regexp.MustCompile(`\{\{(.*?)}}`)
@ -43,9 +45,10 @@ func extractBracesContent(s string) []string {
}
type ImplicitNodeDependency struct {
NodeID string
FieldPath compose.FieldPath
TypeInfo *vo.TypeInfo
NodeID string
FieldPath compose.FieldPath
TypeInfo *vo.TypeInfo
IsIntermediateVar bool
}
func extractImplicitDependency(node *vo.Node, canvas *vo.Canvas) ([]*ImplicitNodeDependency, error) {
@ -84,14 +87,24 @@ func extractImplicitDependency(node *vo.Node, canvas *vo.Canvas) ([]*ImplicitNod
return nil, err
}
}
if node.Data.Inputs.Body.BodyType == string(BodyTypeRawText) {
rawTextVars := extractBracesContent(node.Data.Inputs.Body.BodyData.Json)
rawTextVars := extractBracesContent(node.Data.Inputs.Body.BodyData.RawText)
err = extractDependenciesFromVars(rawTextVars)
if err != nil {
return nil, err
}
}
nodeID2ParentID := make(map[string]string)
for _, n := range canvas.Nodes {
if len(n.Blocks) > 0 {
for _, block := range n.Blocks {
nodeID2ParentID[block.ID] = n.ID
}
}
}
var nodeFinder func(nodes []*vo.Node, nodeID string) *vo.Node
nodeFinder = func(nodes []*vo.Node, nodeID string) *vo.Node {
for i := range nodes {
@ -111,23 +124,78 @@ func extractImplicitDependency(node *vo.Node, canvas *vo.Canvas) ([]*ImplicitNod
if fNode == nil {
continue
}
tInfoMap := make(map[string]*vo.TypeInfo, len(node.Data.Outputs))
for _, vAny := range fNode.Data.Outputs {
v, err := vo.ParseVariable(vAny)
if err != nil {
return nil, err
intermediateVars := map[string]bool{}
tInfoMap := make(map[string]*vo.TypeInfo)
parentID, ok := nodeID2ParentID[node.ID]
if ok && parentID == fNode.ID {
// when referencing a composite node, the index field type is available by default
tInfoMap["index"] = &vo.TypeInfo{
Type: vo.DataTypeInteger,
}
tInfo, err := convert.CanvasVariableToTypeInfo(v)
if err != nil {
return nil, err
for _, p := range fNode.Data.Inputs.InputParameters {
tInfo, err := convert.CanvasBlockInputToTypeInfo(p.Input)
if err != nil {
return nil, err
}
if tInfo.Type != vo.DataTypeArray {
return nil, fmt.Errorf("when referencing a composite node, the input parameter must be an array type")
}
tInfoMap[p.Name] = tInfo.ElemTypeInfo
}
if fNode.Data.Inputs.Loop != nil {
for _, vAny := range fNode.Data.Inputs.Loop.VariableParameters {
v, err := convert.ParseParam(vAny)
if err != nil {
return nil, err
}
tInfo, err := convert.CanvasBlockInputToTypeInfo(v.Input)
if err != nil {
return nil, err
}
tInfoMap[v.Name] = tInfo
intermediateVars[v.Name] = true
}
}
} else if entity.NodeTypeMetas[entity.IDStrToNodeType(fNode.Type)].IsComposite {
for _, vAny := range fNode.Data.Outputs {
v, err := convert.ParseParam(vAny)
if err != nil {
return nil, err
}
tInfo, err := convert.CanvasBlockInputToTypeInfo(v.Input)
if err != nil {
return nil, err
}
tInfoMap[v.Name] = tInfo
}
} else {
for _, vAny := range fNode.Data.Outputs {
v, err := vo.ParseVariable(vAny)
if err != nil {
return nil, err
}
tInfo, err := convert.CanvasVariableToTypeInfo(v)
if err != nil {
return nil, err
}
tInfoMap[v.Name] = tInfo
}
tInfoMap[v.Name] = tInfo
}
tInfo, ok := getTypeInfoByPath(ds.FieldPath[0], ds.FieldPath[1:], tInfoMap)
if !ok {
return nil, fmt.Errorf("cannot find type info for dependency: %s", ds.FieldPath)
}
ds.TypeInfo = tInfo
if len(intermediateVars) > 0 {
ds.IsIntermediateVar = intermediateVars[strings.Join(ds.FieldPath, ".")]
}
}
return dependencies, nil
@ -152,7 +220,7 @@ var globalVariableRegex = regexp.MustCompile(`global_variable_\w+\s*\["(.*?)"]`)
func setHttpRequesterInputsForNodeSchema(n *vo.Node, ns *schema.NodeSchema, implicitNodeDependencies []*ImplicitNodeDependency) (err error) {
inputs := n.Data.Inputs
implicitPathVars := make(map[string]bool)
addImplicitVarsSources := func(prefix string, vars []string) error {
addImplicitVarsSources := func(prefix string, vars []string, parent *vo.Node) error {
for _, v := range vars {
if strings.HasPrefix(v, "block_output_") {
paths := strings.Split(strings.TrimPrefix(v, "block_output_"), ".")
@ -167,7 +235,8 @@ func setHttpRequesterInputsForNodeSchema(n *vo.Node, ns *schema.NodeSchema, impl
}
implicitPathVars[pathValue] = true
ns.SetInputType(pathValue, dep.TypeInfo)
ns.AddInputSource(&vo.FieldInfo{
filedInfo := &vo.FieldInfo{
Path: []string{pathValue},
Source: vo.FieldSource{
Ref: &vo.Reference{
@ -175,7 +244,12 @@ func setHttpRequesterInputsForNodeSchema(n *vo.Node, ns *schema.NodeSchema, impl
FromPath: dep.FieldPath,
},
},
})
}
if dep.IsIntermediateVar && parent != nil {
filedInfo.Source.Ref.VariableType = ptr.Of(vo.ParentIntermediate)
}
ns.AddInputSource(filedInfo)
}
}
}
@ -215,7 +289,7 @@ func setHttpRequesterInputsForNodeSchema(n *vo.Node, ns *schema.NodeSchema, impl
}
urlVars := extractBracesContent(inputs.APIInfo.URL)
err = addImplicitVarsSources("__apiInfo_url_", urlVars)
err = addImplicitVarsSources("__apiInfo_url_", urlVars, n.Parent())
if err != nil {
return err
}
@ -304,13 +378,13 @@ func setHttpRequesterInputsForNodeSchema(n *vo.Node, ns *schema.NodeSchema, impl
ns.AddInputSource(sources...)
case BodyTypeJSON:
jsonVars := extractBracesContent(inputs.Body.BodyData.Json)
err = addImplicitVarsSources("__body_bodyData_json_", jsonVars)
err = addImplicitVarsSources("__body_bodyData_json_", jsonVars, n.Parent())
if err != nil {
return err
}
case BodyTypeRawText:
rawTextVars := extractBracesContent(inputs.Body.BodyData.RawText)
err = addImplicitVarsSources("__body_bodyData_rawText_", rawTextVars)
err = addImplicitVarsSources("__body_bodyData_rawText_", rawTextVars, n.Parent())
if err != nil {
return err
}

@ -360,6 +360,11 @@ type HTTPRequester struct {
md5FieldMapping MD5FieldMapping
}
func adaptTemplate(template string) string {
return globalVariableReplaceRegexp.ReplaceAllString(template, "global_variable_$1.$2")
}
func (hg *HTTPRequester) Invoke(ctx context.Context, input map[string]any) (output map[string]any, err error) {
var (
req = &Request{}
@ -380,7 +385,7 @@ func (hg *HTTPRequester) Invoke(ctx context.Context, input map[string]any) (outp
Header: http.Header{},
}
httpURL, err := nodes.TemplateRender(hg.urlConfig.Tpl, req.URLVars)
httpURL, err := nodes.TemplateRender(adaptTemplate(hg.urlConfig.Tpl), req.URLVars)
if err != nil {
return nil, err
}
@ -524,7 +529,7 @@ func (b *BodyConfig) getBodyAndContentType(ctx context.Context, req *Request) (i
switch b.BodyType {
case BodyTypeJSON:
jsonString, err := nodes.TemplateRender(b.TextJsonConfig.Tpl, req.JsonVars)
jsonString, err := nodes.TemplateRender(adaptTemplate(b.TextJsonConfig.Tpl), req.JsonVars)
if err != nil {
return nil, contentType, err
}
@ -539,7 +544,7 @@ func (b *BodyConfig) getBodyAndContentType(ctx context.Context, req *Request) (i
body = strings.NewReader(form.Encode())
contentType = ContentTypeFormURLEncoded
case BodyTypeRawText:
textString, err := nodes.TemplateRender(b.TextPlainConfig.Tpl, req.TextPlainVars)
textString, err := nodes.TemplateRender(adaptTemplate(b.TextPlainConfig.Tpl), req.TextPlainVars)
if err != nil {
return nil, contentType, err
}
@ -632,7 +637,7 @@ func (hg *HTTPRequester) ToCallbackInput(_ context.Context, input map[string]any
result := make(map[string]any)
result["method"] = hg.method
u, err := nodes.TemplateRender(hg.urlConfig.Tpl, request.URLVars)
u, err := nodes.TemplateRender(adaptTemplate(hg.urlConfig.Tpl), request.URLVars)
if err != nil {
return nil, err
}
@ -666,7 +671,7 @@ func (hg *HTTPRequester) ToCallbackInput(_ context.Context, input map[string]any
result["body"] = nil
switch hg.bodyConfig.BodyType {
case BodyTypeJSON:
js, err := nodes.TemplateRender(hg.bodyConfig.TextJsonConfig.Tpl, request.JsonVars)
js, err := nodes.TemplateRender(adaptTemplate(hg.bodyConfig.TextJsonConfig.Tpl), request.JsonVars)
if err != nil {
return nil, err
}
@ -677,7 +682,7 @@ func (hg *HTTPRequester) ToCallbackInput(_ context.Context, input map[string]any
}
result["body"] = ret
case BodyTypeRawText:
tx, err := nodes.TemplateRender(hg.bodyConfig.TextPlainConfig.Tpl, request.TextPlainVars)
tx, err := nodes.TemplateRender(adaptTemplate(hg.bodyConfig.TextPlainConfig.Tpl), request.TextPlainVars)
if err != nil {
return nil, err
@ -729,7 +734,7 @@ func (hg *HTTPRequester) parserToRequest(input map[string]any) (*Request, error)
if strings.HasPrefix(urlKey, "global_variable_") {
urlKey = globalVariableReplaceRegexp.ReplaceAllString(urlKey, "global_variable_$1.$2")
}
nodes.SetMapValue(request.URLVars, strings.Split(urlKey, "."), value.(string))
nodes.SetMapValue(request.URLVars, strings.Split(urlKey, "."), value)
}
}
if strings.HasPrefix(key, headersPrefix) {
@ -777,7 +782,6 @@ func (hg *HTTPRequester) parserToRequest(input map[string]any) (*Request, error)
if formDataKey, ok := hg.md5FieldMapping.BodyMD5Mapping[formDataMd5Key]; ok {
request.FormDataVars[formDataKey] = value.(string)
}
}
if strings.HasPrefix(bodyKey, bodyFormURLEncodedPrefix) {

Loading…
Cancel
Save