This is an automated email from the ASF dual-hosted git repository.

gongchao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git


The following commit(s) were added to refs/heads/master by this push:
     new 63d3d18428 [bugfix] Fix http header being incorrectly encoded. (#3108)
63d3d18428 is described below

commit 63d3d184280d1c02306ff96d7ece4f0eb268e1a8
Author: yunfan24 <[email protected]>
AuthorDate: Sat Mar 22 11:44:16 2025 +0800

    [bugfix] Fix http header being incorrectly encoded. (#3108)
    
    Co-authored-by: aias00 <[email protected]>
---
 e2e/data/monitor-http.json                         |  5 ++
 .../collector/collect/http/HttpCollectImpl.java    | 69 ++++++++++++++++++----
 .../common/entity/job/protocol/HttpProtocol.java   |  6 ++
 .../src/main/resources/define/app-api.yml          | 18 ++++++
 4 files changed, 88 insertions(+), 10 deletions(-)

diff --git a/e2e/data/monitor-http.json b/e2e/data/monitor-http.json
index c53fcb7ef2..c8280dd1b5 100644
--- a/e2e/data/monitor-http.json
+++ b/e2e/data/monitor-http.json
@@ -73,6 +73,11 @@
       "field": "successCode",
       "type": 4,
       "paramValue": "200, 201"
+    },
+    {
+      "field": "enableUrlEncoding",
+      "type": 1,
+      "paramValue": true
     }
   ]
 }
\ No newline at end of file
diff --git 
a/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/http/HttpCollectImpl.java
 
b/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/http/HttpCollectImpl.java
index ac461a5b03..4014151f20 100644
--- 
a/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/http/HttpCollectImpl.java
+++ 
b/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/http/HttpCollectImpl.java
@@ -86,6 +86,7 @@ import org.springframework.http.HttpMethod;
 import org.springframework.http.MediaType;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
+import org.springframework.web.util.UriUtils;
 import org.xml.sax.InputSource;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
@@ -509,13 +510,37 @@ public class HttpCollectImpl extends AbstractCollect {
         }
         // params
         Map<String, String> params = httpProtocol.getParams();
+        boolean enableUrlEncoding = 
Boolean.parseBoolean(httpProtocol.getEnableUrlEncoding());
+        StringBuilder queryParams = new StringBuilder();
+        
         if (params != null && !params.isEmpty()) {
             for (Map.Entry<String, String> param : params.entrySet()) {
-                if (StringUtils.hasText(param.getValue())) {
-                    requestBuilder.addParameter(param.getKey(), 
TimeExpressionUtil.calculate(param.getValue()));
+                String key = param.getKey();
+                String value = param.getValue();
+
+                if (!StringUtils.hasText(key)) {
+                    continue;
+                }
+
+                if (queryParams.length() > 0) {
+                    queryParams.append("&");
+                }
+
+                if (enableUrlEncoding) {
+                    key = UriUtils.encodeQueryParam(key, "UTF-8");
+                }
+                queryParams.append(key);
+
+                if (StringUtils.hasText(value)) {
+                    String calculatedValue = 
TimeExpressionUtil.calculate(value);
+                    if (enableUrlEncoding) {
+                        calculatedValue = 
UriUtils.encodeQueryParam(calculatedValue, "UTF-8");
+                    }
+                    queryParams.append("=").append(calculatedValue);
                 }
             }
         }
+        
         // The default request header can be overridden if customized
         // keep-alive
         requestBuilder.addHeader(HttpHeaders.CONNECTION, 
NetworkConstants.KEEP_ALIVE);
@@ -525,8 +550,7 @@ public class HttpCollectImpl extends AbstractCollect {
         if (headers != null && !headers.isEmpty()) {
             for (Map.Entry<String, String> header : headers.entrySet()) {
                 if (StringUtils.hasText(header.getValue())) {
-                    
requestBuilder.addHeader(CollectUtil.replaceUriSpecialChar(header.getKey()),
-                            
CollectUtil.replaceUriSpecialChar(header.getValue()));
+                    requestBuilder.addHeader(header.getKey(), 
header.getValue());
                 }
             }
         }
@@ -560,11 +584,29 @@ public class HttpCollectImpl extends AbstractCollect {
             requestBuilder.setEntity(new 
StringEntity(httpProtocol.getPayload(), StandardCharsets.UTF_8));
         }
 
-        // uri
-        String uri = CollectUtil.replaceUriSpecialChar(httpProtocol.getUrl());
-        if (IpDomainUtil.isHasSchema(httpProtocol.getHost())) {
+        // uri encode
+        String uri;
+        if (enableUrlEncoding) {
+            // if the url contains parameters directly
+            if (httpProtocol.getUrl().contains("?")) {
+                String path = httpProtocol.getUrl().substring(0, 
httpProtocol.getUrl().indexOf("?"));
+                String query = 
httpProtocol.getUrl().substring(httpProtocol.getUrl().indexOf("?") + 1);
+                uri = UriUtils.encodePath(path, "UTF-8") + "?" + 
UriUtils.encodeQuery(query, "UTF-8");
+            } else {
+                uri = UriUtils.encodePath(httpProtocol.getUrl(), "UTF-8");
+            }
+        } else {
+            uri = httpProtocol.getUrl();
+        }
 
-            requestBuilder.setUri(httpProtocol.getHost() + ":" + 
httpProtocol.getPort() + uri);
+        // append query params
+        if (queryParams.length() > 0) {
+            uri += (uri.contains("?") ? "&" : "?") + queryParams.toString();
+        }
+        
+        String finalUri;
+        if (IpDomainUtil.isHasSchema(httpProtocol.getHost())) {
+            finalUri = httpProtocol.getHost() + ":" + httpProtocol.getPort() + 
uri;
         } else {
             String ipAddressType = 
IpDomainUtil.checkIpAddressType(httpProtocol.getHost());
             String baseUri = NetworkConstants.IPV6.equals(ipAddressType)
@@ -572,11 +614,18 @@ public class HttpCollectImpl extends AbstractCollect {
                     : String.format("%s:%s%s", httpProtocol.getHost(), 
httpProtocol.getPort(), uri);
             boolean ssl = Boolean.parseBoolean(httpProtocol.getSsl());
             if (ssl) {
-                requestBuilder.setUri(NetworkConstants.HTTPS_HEADER + baseUri);
+                finalUri = NetworkConstants.HTTPS_HEADER + baseUri;
             } else {
-                requestBuilder.setUri(NetworkConstants.HTTP_HEADER + baseUri);
+                finalUri = NetworkConstants.HTTP_HEADER + baseUri;
             }
         }
+        
+        try {
+            requestBuilder.setUri(finalUri);
+        } catch (IllegalArgumentException e) {
+            log.warn("Invalid URI with illegal characters: {}. User has 
disabled URL encoding, not applying any encoding.", finalUri);
+            throw e;
+        }
 
         // custom timeout
         int timeout = CollectUtil.getTimeout(httpProtocol.getTimeout(), 0);
diff --git 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/HttpProtocol.java
 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/HttpProtocol.java
index add42475f8..1b48e4871a 100644
--- 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/HttpProtocol.java
+++ 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/HttpProtocol.java
@@ -95,6 +95,12 @@ public class HttpProtocol implements CommonRequestProtocol, 
Protocol {
      */
     private List<String> successCodes;
 
+    /**
+     * Whether to enable URL encoding for the path. Default is true.
+     * When true, the URL path will be encoded. When false, the URL path will 
not be encoded.
+     */
+    private String enableUrlEncoding = "true";
+
     /**
      * authentication information
      */
diff --git a/hertzbeat-manager/src/main/resources/define/app-api.yml 
b/hertzbeat-manager/src/main/resources/define/app-api.yml
index 13ad461a82..9d8af7ef18 100644
--- a/hertzbeat-manager/src/main/resources/define/app-api.yml
+++ b/hertzbeat-manager/src/main/resources/define/app-api.yml
@@ -246,6 +246,20 @@ params:
     defaultValue: '200, 201'
     # hide param-true or false
     hide: true
+  # field-param field key
+  - field: enableUrlEncoding
+    # name-param field display i18n name
+    name:
+      zh-CN: 启用URL编码(UTF-8)
+      en-US: Enable URL Encoding(UTF-8)
+    # type-param field type(most mapping the html input type)
+    type: boolean
+    # required-true or false
+    required: true
+    # default value
+    defaultValue: true
+    # hide param-true or false
+    hide: true
 # collect metrics config list
 metrics:
   # metrics - summary
@@ -286,6 +300,8 @@ metrics:
       method: ^_^httpMethod^_^
       # if enabled https
       ssl: ^_^ssl^_^
+      # enable url encoding
+      enableUrlEncoding: ^_^enableUrlEncoding^_^
       # http request payload
       payload: ^_^payload^_^
       # http request header content
@@ -344,6 +360,8 @@ metrics:
       method: GET
       # if enabled https
       ssl: ^_^ssl^_^
+      # enable url encoding
+      enableUrlEncoding: ^_^enableUrlEncoding^_^
       authorization:
         # http auth type: Basic Auth, Digest Auth, Bearer Token
         type: ^_^authType^_^


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to