utils: fix RBD URI if credentials contains slash (#7708)

This commit is contained in:
Wei Zhou 2023-07-24 14:29:01 +08:00 committed by GitHub
parent f057f4b412
commit 90baae3dcd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 17 deletions

View File

@ -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
}

View File

@ -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");
}

View File

@ -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