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

weizhou pushed a commit to branch 4.18
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.18 by this push:
     new 90baae3dcdf utils: fix RBD URI if credentials contains slash (#7708)
90baae3dcdf is described below

commit 90baae3dcdf021bacfc526edf0eb9e9e15f1ce4c
Author: Wei Zhou <[email protected]>
AuthorDate: Mon Jul 24 14:29:01 2023 +0800

    utils: fix RBD URI if credentials contains slash (#7708)
---
 ui/src/views/infra/AddPrimaryStorage.vue           |  5 ----
 utils/src/main/java/com/cloud/utils/UriUtils.java  | 31 ++++++++++++++--------
 .../test/java/com/cloud/utils/UriUtilsTest.java    | 14 +++++++++-
 3 files changed, 33 insertions(+), 17 deletions(-)

diff --git a/ui/src/views/infra/AddPrimaryStorage.vue 
b/ui/src/views/infra/AddPrimaryStorage.vue
index b6f7922d797..c1c733dbb80 100644
--- a/ui/src/views/infra/AddPrimaryStorage.vue
+++ b/ui/src/views/infra/AddPrimaryStorage.vue
@@ -586,11 +586,6 @@ export default {
     },
     rbdURL (monitor, pool, id, secret) {
       var url
-      /*  Replace the + and / symbols by - and _ to have URL-safe base64 going 
to the API
-          It's hacky, but otherwise we'll confuse java.net.URI which splits 
the incoming URI
-      */
-      secret = secret.replace(/\+/g, '-')
-      secret = secret.replace(/\//g, '_')
       if (id !== null && secret !== null) {
         monitor = id + ':' + secret + '@' + monitor
       }
diff --git a/utils/src/main/java/com/cloud/utils/UriUtils.java 
b/utils/src/main/java/com/cloud/utils/UriUtils.java
index e68b5307f0e..dffc0106e8a 100644
--- a/utils/src/main/java/com/cloud/utils/UriUtils.java
+++ b/utils/src/main/java/com/cloud/utils/UriUtils.java
@@ -619,21 +619,30 @@ public class UriUtils {
     }
 
     private static UriInfo getRbdUrlInfo(String url) {
-        int secondSlash = StringUtils.ordinalIndexOf(url, "/", 2);
-        int thirdSlash = StringUtils.ordinalIndexOf(url, "/", 3);
+        if (url == null || !url.toLowerCase().startsWith("rbd://")) {
+            throw new CloudRuntimeException("RBD URL must start with 
\"rbd://\"");
+        }
+        String schema = StringUtils.substring(url, 0, 6);
+        url = StringUtils.substring(url, 6, url.length());
         int firstAt = StringUtils.indexOf(url, "@");
-        int lastColon = StringUtils.lastIndexOf(url,":");
-        int lastSquareBracket = StringUtils.lastIndexOf(url,"]");
-        int startOfHost = Math.max(secondSlash, firstAt) + 1;
-        int endOfHost = lastColon < startOfHost ? (thirdSlash > 0 ? thirdSlash 
: url.length() + 1) :
+        String credentials = (firstAt == -1) ? null : 
StringUtils.substring(url, 0, firstAt);
+        String hostInfo = (firstAt == -1) ? url : StringUtils.substring(url, 
firstAt + 1, url.length());
+
+        int firstSlash = StringUtils.indexOf(hostInfo, "/");
+        int lastColon = StringUtils.lastIndexOf(hostInfo,":");
+        int lastSquareBracket = StringUtils.lastIndexOf(hostInfo,"]");
+        int endOfHost = lastColon == -1 ? (firstSlash > 0 ? firstSlash : 
hostInfo.length() + 1) :
                 (lastSquareBracket > lastColon ? lastSquareBracket + 1 : 
lastColon);
-        String storageHosts = StringUtils.substring(url, startOfHost, 
endOfHost);
+        String storageHosts = StringUtils.substring(hostInfo, 0, endOfHost);
         String firstHost = storageHosts.split(",")[0];
-        String strBeforeHosts = StringUtils.substring(url, 0, startOfHost);
-        String strAfterHosts = StringUtils.substring(url, endOfHost);
+        String strAfterHosts = StringUtils.substring(hostInfo, endOfHost);
         try {
-            URI uri = new URI(UriUtils.encodeURIComponent(strBeforeHosts + 
firstHost + strAfterHosts));
-            return new UriInfo(uri.getScheme(), storageHosts, uri.getPath(), 
uri.getUserInfo(), uri.getPort());
+            URI uri = new URI(UriUtils.encodeURIComponent(schema + firstHost + 
strAfterHosts));
+            if (credentials != null) {
+                credentials = credentials.replace("+", "-");
+                credentials = credentials.replace("/", "_");
+            }
+            return new UriInfo(uri.getScheme(), storageHosts, uri.getPath(), 
credentials, uri.getPort());
         } catch (URISyntaxException e) {
             throw new CloudRuntimeException(url + " is not a valid uri for 
RBD");
         }
diff --git a/utils/src/test/java/com/cloud/utils/UriUtilsTest.java 
b/utils/src/test/java/com/cloud/utils/UriUtilsTest.java
index db02e607d63..1a3ae17f584 100644
--- a/utils/src/test/java/com/cloud/utils/UriUtilsTest.java
+++ b/utils/src/test/java/com/cloud/utils/UriUtilsTest.java
@@ -103,10 +103,14 @@ public class UriUtilsTest {
     }
 
     private void testGetUriInfoInternal(String url, String host) {
+        testGetUriInfoInternal(url, host, url);
+    }
+
+    private void testGetUriInfoInternal(String url, String host, String 
newUrl) {
         UriUtils.UriInfo uriInfo = UriUtils.getUriInfo(url);
 
         Assert.assertEquals(host, uriInfo.getStorageHost());
-        Assert.assertEquals(url, uriInfo.toString());
+        Assert.assertEquals(newUrl, uriInfo.toString());
     }
 
     @Test
@@ -122,6 +126,10 @@ public class UriUtilsTest {
         String url6 = String.format("rbd://%s:3300", host);
         String url7 = String.format("rbd://%s", host);
         String url8 = String.format("rbd://user@%s", host);
+        String url9 = 
String.format("rbd://cloudstack:AQD+hJxklW1RGRAAA56oHGN6d+WPDLss2b05Cw==@%s:3300/cloudstack",
 host);
+        String url10 = 
String.format("rbd://cloudstack:AQDlhZxkgdmiKRAA8uHt/O9jqoBp2Iwdk2MjjQ==@%s:3300/cloudstack",
 host);
+        String url11 = 
String.format("rbd://cloudstack:AQD-hJxklW1RGRAAA56oHGN6d-WPDLss2b05Cw==@%s:3300/cloudstack",
 host);
+        String url12 = 
String.format("rbd://cloudstack:AQDlhZxkgdmiKRAA8uHt_O9jqoBp2Iwdk2MjjQ==@%s:3300/cloudstack",
 host);
 
         testGetUriInfoInternal(url0, host);
         testGetUriInfoInternal(url1, host);
@@ -132,6 +140,10 @@ public class UriUtilsTest {
         testGetUriInfoInternal(url6, host);
         testGetUriInfoInternal(url7, host);
         testGetUriInfoInternal(url8, host);
+        testGetUriInfoInternal(url9, host, url11);
+        testGetUriInfoInternal(url10, host, url12);
+        testGetUriInfoInternal(url11, host);
+        testGetUriInfoInternal(url12, host);
     }
 
     @Test

Reply via email to