@@ -1653,6 +1653,13 @@ else if (names != null) {
16531653 String k = ind < 0 ? kv : kv .substring (0 , ind );
16541654 Object v = ind < 0 ? null : kv .substring (ind + 1 );
16551655
1656+ // query 已经转义
1657+ // try {
1658+ // v = URLDecoder.decode((String) v, StringUtil.UTF_8);
1659+ // } catch (Throwable e) {
1660+ // e.printStackTrace();
1661+ // }
1662+
16561663 try {
16571664 v = JSON .parse (v );
16581665 } catch (Throwable e ) {
@@ -1821,11 +1828,11 @@ else if (recordType > 0) {
18211828 JSONObject document = JSON .newJSONObject ();
18221829 document .put ("from" , 2 ); // 0-测试工具,1-CI/CD,2-流量录制
18231830 document .put ("name" , "[Record] " + new java .util .Date ().toLocaleString ());
1824- document .put ("type" , reqType );
18251831 document .put ("method" , method == null ? "GET" : method .name ());
1832+ document .put ("type" , reqType );
18261833 document .put ("url" , branch );
18271834 document .put ("header" , StringUtil .isEmpty (hs , true ) ? null : hs .trim ());
1828- document .put ("request" , isSQL ? "{}" : (reqBody != null && ! reqBody .isEmpty () ? JSON .toJSONString (reqBody ) : (StringUtil .isEmail (body ) ? "{}" : body )));
1835+ document .put ("request" , isSQL ? "{}" : (reqBody != null && ! reqBody .isEmpty () ? JSON .toJSONString (reqBody ) : (StringUtil .isEmpty (body ) ? "{}" : body )));
18291836 if (isSQL ) {
18301837 // 没有名称,除非 args 传对象而不是数组
18311838 // JSONList args = req.getJSONArray("args");
@@ -1849,7 +1856,7 @@ else if (recordType > 0) {
18491856 }
18501857 else {
18511858 // Random <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1852- Map <String , ?> m = isSQL ? null : reqBody ;
1859+ Map <String , ?> m = isSQL ? null : ( reqBody != null && ! reqBody . isEmpty () ? reqBody : ( isBodyEmpty ? map : JSON . parseObject ( body ))) ;
18531860 String config = isSQL ? hs : parseRandomConfig ("" , m );
18541861
18551862 JSONObject random = JSON .newJSONObject ();
@@ -2021,8 +2028,9 @@ protected Long getContentLength(String s, MediaType contentType) {
20212028 protected String sendRequest (HttpSession session , HttpMethod method , String url , String body , HttpHeaders headers ) {
20222029 String rspBody = null ;
20232030 try {
2024- // 为JSON请求设置默认的Content-Type
2025- if (body != null && method != HttpMethod .GET && !headers .containsKey (HttpHeaders .CONTENT_TYPE )) {
2031+ // 为JSON请求设置默认的 Content-Type
2032+ boolean hasContentType = headers .containsKey (HttpHeaders .CONTENT_TYPE ) || headers .containsKey (HttpHeaders .CONTENT_TYPE .toLowerCase ());
2033+ if (body != null && method != HttpMethod .GET && ! hasContentType ) {
20262034 // 尝试解析JSON来判断内容类型
20272035 try {
20282036 JSON .parse (body );
@@ -2034,13 +2042,13 @@ protected String sendRequest(HttpSession session, HttpMethod method, String url,
20342042 }
20352043
20362044 // 设置默认的Accept header
2037- if (!headers .containsKey (HttpHeaders .ACCEPT )) {
2045+ if (! ( headers .containsKey (HttpHeaders .ACCEPT ) || headers . containsKey ( HttpHeaders . ACCEPT . toLowerCase ()) )) {
20382046 headers .setAccept (Arrays .asList (MediaType .APPLICATION_JSON , MediaType .TEXT_PLAIN ));
20392047 }
20402048
20412049 // 为大文本body,设置适当的Content-Type和分块传输
20422050 if (body != null && body .length () > 1024 * 1024 ) { // 超过1MB
2043- if (!headers . containsKey ( HttpHeaders . CONTENT_TYPE ) ) {
2051+ if (! hasContentType ) {
20442052 headers .setContentType (MediaType .TEXT_PLAIN );
20452053 }
20462054 // 设置分块传输
@@ -2094,8 +2102,11 @@ protected String sendRequest(HttpSession session, HttpMethod method, String url,
20942102 }
20952103 }
20962104
2097- SESSION_MAP .put (session .getId (), session );
2098- httpServletResponse .setHeader (APIJSON_DELEGATE_ID , session .getId ());
2105+ String id = session == null ? null : session .getId ();
2106+ if (id != null ) {
2107+ SESSION_MAP .put (id , session );
2108+ httpServletResponse .setHeader (APIJSON_DELEGATE_ID , id );
2109+ }
20992110
21002111 return rspBody ;
21012112 }
@@ -2425,13 +2436,13 @@ public String execute(@RequestBody String request, HttpSession session) {
24252436 } else if (sqlRest .startsWith ("`" + userIdKey + "`" ) || sqlRest .startsWith ("[" + userIdKey + "]" ) || sqlRest .startsWith ("\" " + userIdKey + "\" " )) {
24262437 key = "`" + userIdKey + "`" ;
24272438 } else {
2428- throw new IllegalArgumentException ("SQL WHERE 后必须接着 " + idKey + " 或 " + idKey + " = ? 或 IN(?,? ..) !" );
2439+ throw new IllegalArgumentException ("SQL WHERE 后必须接着 " + idKey + " 或 " + userIdKey + " = ? 或 IN(?, ? . ..) !" );
24292440 }
24302441
24312442 sqlRest = sqlRest .substring (key .length ()).trim ();
24322443 boolean isEq = sqlRest .startsWith ("=" );
24332444 if (! (isEq || sqlRest .startsWith ("IN(" ) || sqlRest .startsWith ("in(" ))) {
2434- throw new IllegalArgumentException ("SQL WHERE " + key + " 后必须接着 = ? 或 IN(?, ? ...) ! " );
2445+ throw new IllegalArgumentException ("SQL WHERE " + key + " 后必须接着 = ? 或 IN(?, ? ...) ! " );
24352446 }
24362447
24372448 sqlRest = sqlRest .substring (isEq ? 1 : "IN(" .length ()).trim ();
@@ -2486,21 +2497,20 @@ public String execute(@RequestBody String request, HttpSession session) {
24862497 //
24872498 //}
24882499
2489- List <Map <String , Object >> find = null ;
2500+ List <Map <String , Object >> list = null ;
24902501 Set <Entry <String , List <Map <String , Object >>>> set = sqlautoMap == null ? null : sqlautoMap .entrySet ();
24912502 if (set != null ) {
24922503 for (Entry <String , List <Map <String , Object >>> entry : set ) {
24932504 String sqlauto = StringUtil .trim (entry == null ? null : entry .getKey ());
2494- List < Map < String , Object >> list = sqlauto .equalsIgnoreCase (trimmedSQL ) ? entry .getValue () : null ;
2505+ list = sqlauto .equalsIgnoreCase (trimmedSQL ) ? entry .getValue () : null ;
24952506 if (list != null && ! list .isEmpty ()) {
2496- find = list ;
2497- Log .d (TAG , "execute " + sql + " : find match rows = " + JSON .toJSONString (find , true ));
2507+ Log .d (TAG , "execute " + sql + " : find match rows = " + JSON .toJSONString (list , true ));
24982508 break ;
24992509 }
25002510 }
25012511 }
25022512
2503- if (find == null ) {
2513+ if (list == null || list . isEmpty () ) {
25042514 throw new IllegalAccessException ("严格模式下 DELETE/UPDATE SQL 只允许 Document 表 sqlauto 字段值,请提前写入并刷新后端服务配置!" );
25052515 }
25062516 }
@@ -2523,6 +2533,9 @@ public String execute(@RequestBody String request, HttpSession session) {
25232533 if ("?" .endsWith (as )) {
25242534 int j = arg == null ? -1 : arg .size () - (arr .length - i );
25252535 as = j < 0 || j > arg .size () ? null : arg .getString (j );
2536+ if (StringUtil .isEmail (as )) {
2537+ throw new IllegalArgumentException ("SQL LIMIT ? 对应的 args[" + j + "] = " + as + " 不合法!" );
2538+ }
25262539 }
25272540
25282541 try {
@@ -2580,8 +2593,8 @@ public String execute(@RequestBody String request, HttpSession session) {
25802593 connection .setAutoCommit (false );
25812594 // connection.beginRequest();
25822595 int rows = ((PreparedStatement ) statement ).executeUpdate ();
2583- if (rows >= maxCount ) {
2584- throw new UnsupportedOperationException ("实际影响数量超过上限 " + maxCount + " ! 已回滚变更" );
2596+ if (rows > maxCount ) {
2597+ throw new UnsupportedOperationException ("实际影响数量 " + rows + " 超过上限 " + maxCount + " ! 已回滚变更" );
25852598 }
25862599 } catch (Throwable e ) {
25872600 connection .rollback ();
@@ -2595,7 +2608,7 @@ public String execute(@RequestBody String request, HttpSession session) {
25952608 }
25962609 } else {
25972610 if (arg != null && ! arg .isEmpty ()) {
2598- throw new UnsupportedOperationException ("非预编译模式不允许传参 arg !" );
2611+ throw new UnsupportedOperationException ("非预编译模式不允许传参 args !" );
25992612 }
26002613
26012614 if (EXECUTE_STRICTLY ) {
@@ -2604,8 +2617,8 @@ public String execute(@RequestBody String request, HttpSession session) {
26042617 connection .setAutoCommit (false );
26052618 // connection.beginRequest();
26062619 int rows = statement .executeUpdate (sql );
2607- if (rows >= maxCount ) {
2608- throw new UnsupportedOperationException ("实际影响数量超过上限 " + maxCount + " ! 已回滚变更" );
2620+ if (rows > maxCount ) {
2621+ throw new UnsupportedOperationException ("实际影响数量 " + rows + " 超过上限 " + maxCount + " ! 已回滚变更" );
26092622 }
26102623 } catch (Throwable e ) {
26112624 connection .rollback ();
@@ -2646,6 +2659,9 @@ public String execute(@RequestBody String request, HttpSession session) {
26462659
26472660 // try {
26482661 updateCount = statement .getUpdateCount ();
2662+ if (WRITE_STRICTLY && isWrite && updateCount > maxCount ) {
2663+ throw new IllegalArgumentException ("实际影响数量 " + updateCount + " 超过上限 " + maxCount + " ! 已回滚变更" );
2664+ }
26492665 // } catch (Throwable e) {
26502666 // e.printStackTrace();
26512667 // }
0 commit comments