Liu Song’s Projects


~/Projects/flow

git clone https://code.lsong.org/flow

Commit

Commit
f1775d4fd116d7acbee29a4ee99ae54976995345
Author
Nick O'Leary <[email protected]>
Date
2021-07-26 14:21:52 +0100 +0100
Diffstat
 packages/node_modules/@node-red/nodes/core/network/21-httprequest.js | 23 
 test/nodes/core/network/21-httprequest_spec.js | 4 

Handle partially encoded url query strings in request node


diff --git a/packages/node_modules/@node-red/nodes/core/network/21-httprequest.js b/packages/node_modules/@node-red/nodes/core/network/21-httprequest.js
index bf193b6af3dec65e8035e5594835a651442b279a..afaa2b099f476f8e649e5bfa27040cd2a4b8bf22 100644
--- a/packages/node_modules/@node-red/nodes/core/network/21-httprequest.js
+++ b/packages/node_modules/@node-red/nodes/core/network/21-httprequest.js
@@ -135,7 +135,30 @@                     url = "http://"+url;
                 }
             }
 /**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+            // The Request module used in Node-RED 1.x was tolerant of query strings that
+            // were partially encoded. For example - "?a=hello%20there&b=20%"
+            // The GOT module doesn't like that.
+            // The following is an attempt to normalise the url to ensure it is properly
+            // encoded. We cannot just encode it directly as we don't want any valid
+            // encoded entity to end up doubly encoded.
+            if (url.indexOf("?") > -1) {
+                // Only do this if there is a query string to deal with
+                const [hostPath, ...queryString] = url.split("?")
+                const query = queryString.join("?");
+                if (query) {
+                    // Look for any instance of % not followed by two hex chars.
+                    // Replace any we find with %25.
+                    const escapedQueryString = query.replace(/(%.?.?)/g, function(v) {
+                        if (/^%[a-f0-9]{2}/i.test(v)) {
+                            return v;
+                        }
+                        return v.replace(/%/,"%25")
+                    })
+                    url = hostPath+"?"+escapedQueryString;
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * distributed under the License is distributed on an "AS IS" BASIS,
+            }
 
             var method = nodeMethod.toUpperCase() || "GET";
             if (msg.method && n.method && (n.method !== "use")) {     // warn if override option not set




diff --git a/test/nodes/core/network/21-httprequest_spec.js b/test/nodes/core/network/21-httprequest_spec.js
index c3ec942f73ae921b06f843d9dbcad343cef793cc..ea7776574e13e81f66cbdbedbae469e9f7a3712e 100644
--- a/test/nodes/core/network/21-httprequest_spec.js
+++ b/test/nodes/core/network/21-httprequest_spec.js
@@ -1145,7 +1145,7 @@                 n2.on("input", function(msg) {
                     try {
                         msg.should.have.property('payload',{
                             query:{ a: 'b', c:[ 'T24,0°|H80%|W S8,3m/s' ] },
-                            url: '/getQueryParams?a=b&c%5B0%5D.Text=T24,0%C2%B0%7CH80%25%7CW%20S8,3m/s'
+                            url: '/getQueryParams?a=b&c[0].Text=T24,0%C2%B0|H80%25|W%20S8,3m/s'
                         });
                         msg.should.have.property('statusCode',200);
                         msg.should.have.property('headers');
@@ -1154,8 +1154,8 @@                     } catch(err) {
                         done(err);
                     }
                 });
-    var testProxyPort = 10444;
  * You may obtain a copy of the License at
+ * See the License for the specific language governing permissions and
             });
         })
     });