Skip to content

Commit 2d351c3

Browse files
committed
perf: http body check
1 parent 662a4a4 commit 2d351c3

File tree

1 file changed

+136
-9
lines changed
  • packages/service/core/workflow/dispatch/tools

1 file changed

+136
-9
lines changed

packages/service/core/workflow/dispatch/tools/http468.ts

Lines changed: 136 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -120,34 +120,155 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
120120
2. Replace newline strings
121121
*/
122122
const replaceJsonBodyString = (text: string) => {
123-
const valToStr = (val: any) => {
123+
// Check if the variable is in quotes
124+
const isVariableInQuotes = (text: string, variable: string) => {
125+
const index = text.indexOf(variable);
126+
if (index === -1) return false;
127+
128+
// 计算变量前面的引号数量
129+
const textBeforeVar = text.substring(0, index);
130+
const matches = textBeforeVar.match(/"/g) || [];
131+
132+
// 如果引号数量为奇数,则变量在引号内
133+
return matches.length % 2 === 1;
134+
};
135+
const valToStr = (val: any, isQuoted = false) => {
124136
if (val === undefined) return 'null';
125137
if (val === null) return 'null';
126138

127139
if (typeof val === 'object') return JSON.stringify(val);
128140

129141
if (typeof val === 'string') {
142+
if (isQuoted) {
143+
return val.replace(/(?<!\\)"/g, '\\"');
144+
}
130145
try {
131-
const parsed = JSON.parse(val);
132-
if (typeof parsed === 'object') {
133-
return JSON.stringify(parsed);
134-
}
146+
JSON.parse(val);
135147
return val;
136148
} catch (error) {
137149
const str = JSON.stringify(val);
150+
138151
return str.startsWith('"') && str.endsWith('"') ? str.slice(1, -1) : str;
139152
}
140153
}
141154

142155
return String(val);
143156
};
157+
// Test cases for variable replacement in JSON body
158+
// const bodyTest = () => {
159+
// const testData = [
160+
// // 基本字符串替换
161+
// {
162+
// body: `{"name":"{{name}}","age":"18"}`,
163+
// variables: [{ key: '{{name}}', value: '测试' }],
164+
// result: `{"name":"测试","age":"18"}`
165+
// },
166+
// // 特殊字符处理
167+
// {
168+
// body: `{"text":"{{text}}"}`,
169+
// variables: [{ key: '{{text}}', value: '包含"引号"和\\反斜杠' }],
170+
// result: `{"text":"包含\\"引号\\"和\\反斜杠"}`
171+
// },
172+
// // 数字类型处理
173+
// {
174+
// body: `{"count":{{count}},"price":{{price}}}`,
175+
// variables: [
176+
// { key: '{{count}}', value: '42' },
177+
// { key: '{{price}}', value: '99.99' }
178+
// ],
179+
// result: `{"count":42,"price":99.99}`
180+
// },
181+
// // 布尔值处理
182+
// {
183+
// body: `{"isActive":{{isActive}},"hasData":{{hasData}}}`,
184+
// variables: [
185+
// { key: '{{isActive}}', value: 'true' },
186+
// { key: '{{hasData}}', value: 'false' }
187+
// ],
188+
// result: `{"isActive":true,"hasData":false}`
189+
// },
190+
// // 对象类型处理
191+
// {
192+
// body: `{"user":{{user}},"user2":"{{user2}}"}`,
193+
// variables: [
194+
// { key: '{{user}}', value: `{"id":1,"name":"张三"}` },
195+
// { key: '{{user2}}', value: `{"id":1,"name":"张三"}` }
196+
// ],
197+
// result: `{"user":{"id":1,"name":"张三"},"user2":"{\\"id\\":1,\\"name\\":\\"张三\\"}"}`
198+
// },
199+
// // 数组类型处理
200+
// {
201+
// body: `{"items":{{items}}}`,
202+
// variables: [{ key: '{{items}}', value: '[1, 2, 3]' }],
203+
// result: `{"items":[1,2,3]}`
204+
// },
205+
// // null 和 undefined 处理
206+
// {
207+
// body: `{"nullValue":{{nullValue}},"undefinedValue":{{undefinedValue}}}`,
208+
// variables: [
209+
// { key: '{{nullValue}}', value: 'null' },
210+
// { key: '{{undefinedValue}}', value: 'undefined' }
211+
// ],
212+
// result: `{"nullValue":null,"undefinedValue":null}`
213+
// },
214+
// // 嵌套JSON结构
215+
// {
216+
// body: `{"data":{"nested":{"value":"{{nestedValue}}"}}}`,
217+
// variables: [{ key: '{{nestedValue}}', value: '嵌套值' }],
218+
// result: `{"data":{"nested":{"value":"嵌套值"}}}`
219+
// },
220+
// // 多变量替换
221+
// {
222+
// body: `{"first":"{{first}}","second":"{{second}}","third":{{third}}}`,
223+
// variables: [
224+
// { key: '{{first}}', value: '第一' },
225+
// { key: '{{second}}', value: '第二' },
226+
// { key: '{{third}}', value: '3' }
227+
// ],
228+
// result: `{"first":"第一","second":"第二","third":3}`
229+
// },
230+
// // JSON字符串作为变量值
231+
// {
232+
// body: `{"config":{{config}}}`,
233+
// variables: [{ key: '{{config}}', value: '{"setting":"enabled","mode":"advanced"}' }],
234+
// result: `{"config":{"setting":"enabled","mode":"advanced"}}`
235+
// }
236+
// ];
237+
238+
// for (let i = 0; i < testData.length; i++) {
239+
// const item = testData[i];
240+
// let bodyStr = item.body;
241+
// for (const variable of item.variables) {
242+
// const isQuote = isVariableInQuotes(bodyStr, variable.key);
243+
// bodyStr = bodyStr.replace(variable.key, valToStr(variable.value, isQuote));
244+
// }
245+
// bodyStr = bodyStr.replace(/(".*?")\s*:\s*undefined\b/g, '$1:null');
246+
247+
// console.log(bodyStr === item.result, i);
248+
// if (bodyStr !== item.result) {
249+
// console.log(bodyStr);
250+
// console.log(item.result);
251+
// } else {
252+
// try {
253+
// JSON.parse(item.result);
254+
// } catch (error) {
255+
// console.log('反序列化异常', i, item.result);
256+
// }
257+
// }
258+
// }
259+
// };
260+
// bodyTest();
144261

145262
// 1. Replace {{key.key}} variables
146263
const regex1 = /\{\{\$([^.]+)\.([^$]+)\$\}\}/g;
147264
const matches1 = [...text.matchAll(regex1)];
148265
matches1.forEach((match) => {
149266
const nodeId = match[1];
150267
const id = match[2];
268+
const fullMatch = match[0];
269+
270+
// 检查变量是否在引号内
271+
const isInQuotes = isVariableInQuotes(text, fullMatch);
151272

152273
const variableVal = (() => {
153274
if (nodeId === VARIABLE_NODE_ID) {
@@ -165,9 +286,9 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
165286
return getReferenceVariableValue({ value: input.value, nodes: runtimeNodes, variables });
166287
})();
167288

168-
const formatVal = valToStr(variableVal);
289+
const formatVal = valToStr(variableVal, isInQuotes);
169290

170-
const regex = new RegExp(`\\{\\{\\$(${nodeId}\\.${id})\\$\\}\\}`, 'g');
291+
const regex = new RegExp(`\\{\\{\\$(${nodeId}\\.${id})\\$\\}\\}`, '');
171292
text = text.replace(regex, () => formatVal);
172293
});
173294

@@ -176,10 +297,16 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
176297
const matches2 = text.match(regex2) || [];
177298
const uniqueKeys2 = [...new Set(matches2.map((match) => match.slice(2, -2)))];
178299
for (const key of uniqueKeys2) {
179-
text = text.replace(new RegExp(`{{(${key})}}`, 'g'), () => valToStr(allVariables[key]));
300+
const fullMatch = `{{${key}}}`;
301+
// 检查变量是否在引号内
302+
const isInQuotes = isVariableInQuotes(text, fullMatch);
303+
304+
text = text.replace(new RegExp(`{{(${key})}}`, ''), () =>
305+
valToStr(allVariables[key], isInQuotes)
306+
);
180307
}
181308

182-
return text.replace(/(".*?")\s*:\s*undefined\b/g, '$1: null');
309+
return text.replace(/(".*?")\s*:\s*undefined\b/g, '$1:null');
183310
};
184311

185312
httpReqUrl = replaceStringVariables(httpReqUrl);

0 commit comments

Comments
 (0)