According to rfc3986, revise the logic of changing the authority in the URL (#9170)

This commit is contained in:
huazhongming 2021-11-03 10:59:39 +08:00 committed by GitHub
parent 4efdb8f4d6
commit fa245c7a1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 122 additions and 47 deletions

View File

@ -187,7 +187,7 @@ class URL implements Serializable {
String path, String path,
Map<String, String> parameters) { Map<String, String> parameters) {
if (StringUtils.isEmpty(username) if (StringUtils.isEmpty(username)
&& StringUtils.isNotEmpty(password)) { && StringUtils.isNotEmpty(password)) {
throw new IllegalArgumentException("Invalid url, password without username!"); throw new IllegalArgumentException("Invalid url, password without username!");
} }
@ -197,15 +197,15 @@ class URL implements Serializable {
} }
protected URL(String protocol, protected URL(String protocol,
String username, String username,
String password, String password,
String host, String host,
int port, int port,
String path, String path,
Map<String, String> parameters, Map<String, String> parameters,
boolean modifiable) { boolean modifiable) {
if (StringUtils.isEmpty(username) if (StringUtils.isEmpty(username)
&& StringUtils.isNotEmpty(password)) { && StringUtils.isNotEmpty(password)) {
throw new IllegalArgumentException("Invalid url, password without username!"); throw new IllegalArgumentException("Invalid url, password without username!");
} }
@ -215,7 +215,7 @@ class URL implements Serializable {
} }
public static URL cacheableValueOf(String url) { public static URL cacheableValueOf(String url) {
URL cachedURL = cachedURLs.get(url); URL cachedURL = cachedURLs.get(url);
if (cachedURL != null) { if (cachedURL != null) {
return cachedURL; return cachedURL;
} }
@ -292,7 +292,7 @@ class URL implements Serializable {
} }
} }
return newMap.isEmpty() ? new ServiceConfigURL(url.getProtocol(), url.getUsername(), url.getPassword(), url.getHost(), url.getPort(), url.getPath(), (Map<String, String>) null, url.getAttributes()) return newMap.isEmpty() ? new ServiceConfigURL(url.getProtocol(), url.getUsername(), url.getPassword(), url.getHost(), url.getPort(), url.getPath(), (Map<String, String>) null, url.getAttributes())
: new ServiceConfigURL(url.getProtocol(), url.getUsername(), url.getPassword(), url.getHost(), url.getPort(), url.getPath(), newMap, url.getAttributes()); : new ServiceConfigURL(url.getProtocol(), url.getUsername(), url.getPassword(), url.getHost(), url.getPort(), url.getPath(), newMap, url.getAttributes());
} }
public static String encode(String value) { public static String encode(String value) {
@ -364,13 +364,53 @@ class URL implements Serializable {
return returnURL(newURLAddress); return returnURL(newURLAddress);
} }
/**
* refer to https://datatracker.ietf.org/doc/html/rfc3986
*
* @return authority
*/
public String getAuthority() { public String getAuthority() {
if (StringUtils.isEmpty(getUsername()) StringBuilder ret = new StringBuilder();
&& StringUtils.isEmpty(getPassword())) {
return null; ret.append(getUserInformation());
if (StringUtils.isNotEmpty(getHost())) {
if (StringUtils.isNotEmpty(getUsername()) || StringUtils.isNotEmpty(getPassword())) {
ret.append("@");
}
ret.append(getHost());
if (getPort() != 0) {
ret.append(":");
ret.append(getPort());
}
} }
return (getUsername() == null ? "" : getUsername())
+ ":" + (getPassword() == null ? "" : getPassword()); return ret.length() == 0 ? null : ret.toString();
}
/**
* refer to https://datatracker.ietf.org/doc/html/rfc3986
*
* @return user information
*/
public String getUserInformation() {
StringBuilder ret = new StringBuilder();
if (StringUtils.isEmpty(getUsername()) && StringUtils.isEmpty(getPassword())) {
return ret.toString();
}
if (StringUtils.isNotEmpty(getUsername())) {
ret.append(getUsername());
}
ret.append(":");
if (StringUtils.isNotEmpty(getPassword())) {
ret.append(getPassword());
}
return ret.length() == 0 ? null : ret.toString();
} }
public String getHost() { public String getHost() {
@ -1201,7 +1241,7 @@ class URL implements Serializable {
boolean first = true; boolean first = true;
for (Map.Entry<String, String> entry : new TreeMap<>(getParameters()).entrySet()) { for (Map.Entry<String, String> entry : new TreeMap<>(getParameters()).entrySet()) {
if (StringUtils.isNotEmpty(entry.getKey()) if (StringUtils.isNotEmpty(entry.getKey())
&& (includes == null || includes.contains(entry.getKey()))) { && (includes == null || includes.contains(entry.getKey()))) {
if (first) { if (first) {
if (concat) { if (concat) {
buf.append('?'); buf.append('?');
@ -1330,7 +1370,7 @@ class URL implements Serializable {
return getServiceInterface(); return getServiceInterface();
} }
return getServiceInterface() + return getServiceInterface() +
COLON_SEPARATOR + getVersion(); COLON_SEPARATOR + getVersion();
} }
/** /**

View File

@ -393,8 +393,8 @@ public class URLTest {
URL url1 = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"); URL url1 = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan");
assertURLStrDecoder(url1); assertURLStrDecoder(url1);
assertThat(url1.toString(), anyOf( assertThat(url1.toString(), anyOf(
equalTo("dubbo://10.20.130.230:20880/context/path?version=1.0.0&application=morgan"), equalTo("dubbo://10.20.130.230:20880/context/path?version=1.0.0&application=morgan"),
equalTo("dubbo://10.20.130.230:20880/context/path?application=morgan&version=1.0.0")) equalTo("dubbo://10.20.130.230:20880/context/path?application=morgan&version=1.0.0"))
); );
} }
@ -403,8 +403,8 @@ public class URLTest {
URL url1 = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"); URL url1 = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan");
assertURLStrDecoder(url1); assertURLStrDecoder(url1);
assertThat(url1.toFullString(), anyOf( assertThat(url1.toFullString(), anyOf(
equalTo("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"), equalTo("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"),
equalTo("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan&version=1.0.0")) equalTo("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan&version=1.0.0"))
); );
} }
@ -935,21 +935,21 @@ public class URLTest {
Assertions.assertEquals(url4, url5); Assertions.assertEquals(url4, url5);
URL url6 = URL.valueOf("consumer://30.225.20.150/org.apache.dubbo.rpc.service.GenericService?application=" + URL url6 = URL.valueOf("consumer://30.225.20.150/org.apache.dubbo.rpc.service.GenericService?application=" +
"dubbo-demo-api-consumer&category=consumers&check=false&dubbo=2.0.2&generic=true&interface=" + "dubbo-demo-api-consumer&category=consumers&check=false&dubbo=2.0.2&generic=true&interface=" +
"org.apache.dubbo.demo.DemoService&pid=7375&side=consumer&sticky=false&timestamp=1599556506417"); "org.apache.dubbo.demo.DemoService&pid=7375&side=consumer&sticky=false&timestamp=1599556506417");
URL url7 = URL.valueOf("consumer://30.225.20.150/org.apache.dubbo.rpc.service.GenericService?application=" + URL url7 = URL.valueOf("consumer://30.225.20.150/org.apache.dubbo.rpc.service.GenericService?application=" +
"dubbo-demo-api-consumer&category=consumers&check=false&dubbo=2.0.2&generic=true&interface=" + "dubbo-demo-api-consumer&category=consumers&check=false&dubbo=2.0.2&generic=true&interface=" +
"org.apache.dubbo.demo.DemoService&pid=7375&side=consumer&sticky=false&timestamp=2299556506417"); "org.apache.dubbo.demo.DemoService&pid=7375&side=consumer&sticky=false&timestamp=2299556506417");
assertEquals(url6, url7); assertEquals(url6, url7);
URL url8 = URL.valueOf("consumer://30.225.20.150/org.apache.dubbo.rpc.service.GenericService?application=" + URL url8 = URL.valueOf("consumer://30.225.20.150/org.apache.dubbo.rpc.service.GenericService?application=" +
"dubbo-demo-api-consumer&category=consumers&check=false&dubbo=2.0.2&interface=" + "dubbo-demo-api-consumer&category=consumers&check=false&dubbo=2.0.2&interface=" +
"org.apache.dubbo.demo.DemoService&pid=7375&side=consumer&sticky=false&timestamp=2299556506417"); "org.apache.dubbo.demo.DemoService&pid=7375&side=consumer&sticky=false&timestamp=2299556506417");
assertNotEquals(url7, url8); assertNotEquals(url7, url8);
URL url9 = URL.valueOf("consumer://30.225.20.150/org.apache.dubbo.rpc.service.GenericService?application=" + URL url9 = URL.valueOf("consumer://30.225.20.150/org.apache.dubbo.rpc.service.GenericService?application=" +
"dubbo-demo-api-consumer&category=consumers&check=true&dubbo=2.0.2&interface=" + "dubbo-demo-api-consumer&category=consumers&check=true&dubbo=2.0.2&interface=" +
"org.apache.dubbo.demo.DemoService&pid=7375&side=consumer&sticky=false&timestamp=2299556506417"); "org.apache.dubbo.demo.DemoService&pid=7375&side=consumer&sticky=false&timestamp=2299556506417");
assertNotEquals(url8, url9); assertNotEquals(url8, url9);
} }
@ -1014,31 +1014,32 @@ public class URLTest {
assertFalse(actual1); assertFalse(actual1);
assertTrue(actual2); assertTrue(actual2);
} }
@Test @Test
public void testHashcode() { public void testHashcode() {
URL url1 = URL.valueOf("consumer://30.225.20.150/org.apache.dubbo.rpc.service.GenericService?application=" + URL url1 = URL.valueOf("consumer://30.225.20.150/org.apache.dubbo.rpc.service.GenericService?application=" +
"dubbo-demo-api-consumer&category=consumers&check=false&dubbo=2.0.2&generic=true&interface=" + "dubbo-demo-api-consumer&category=consumers&check=false&dubbo=2.0.2&generic=true&interface=" +
"org.apache.dubbo.demo.DemoService&pid=7375&side=consumer&sticky=false&timestamp=1599556506417"); "org.apache.dubbo.demo.DemoService&pid=7375&side=consumer&sticky=false&timestamp=1599556506417");
URL url2 = URL.valueOf("consumer://30.225.20.150/org.apache.dubbo.rpc.service.GenericService?application=" + URL url2 = URL.valueOf("consumer://30.225.20.150/org.apache.dubbo.rpc.service.GenericService?application=" +
"dubbo-demo-api-consumer&category=consumers&check=false&dubbo=2.0.2&generic=true&interface=" + "dubbo-demo-api-consumer&category=consumers&check=false&dubbo=2.0.2&generic=true&interface=" +
"org.apache.dubbo.demo.DemoService&pid=7375&side=consumer&sticky=false&timestamp=2299556506417"); "org.apache.dubbo.demo.DemoService&pid=7375&side=consumer&sticky=false&timestamp=2299556506417");
assertEquals(url1.hashCode(), url2.hashCode()); assertEquals(url1.hashCode(), url2.hashCode());
URL url3 = URL.valueOf("consumer://30.225.20.150/org.apache.dubbo.rpc.service.GenericService?application=" + URL url3 = URL.valueOf("consumer://30.225.20.150/org.apache.dubbo.rpc.service.GenericService?application=" +
"dubbo-demo-api-consumer&category=consumers&check=false&dubbo=2.0.2&interface=" + "dubbo-demo-api-consumer&category=consumers&check=false&dubbo=2.0.2&interface=" +
"org.apache.dubbo.demo.DemoService&pid=7375&side=consumer&sticky=false&timestamp=2299556506417"); "org.apache.dubbo.demo.DemoService&pid=7375&side=consumer&sticky=false&timestamp=2299556506417");
assertNotEquals(url2.hashCode(), url3.hashCode()); assertNotEquals(url2.hashCode(), url3.hashCode());
URL url4 = URL.valueOf("consumer://30.225.20.150/org.apache.dubbo.rpc.service.GenericService?application=" + URL url4 = URL.valueOf("consumer://30.225.20.150/org.apache.dubbo.rpc.service.GenericService?application=" +
"dubbo-demo-api-consumer&category=consumers&check=true&dubbo=2.0.2&interface=" + "dubbo-demo-api-consumer&category=consumers&check=true&dubbo=2.0.2&interface=" +
"org.apache.dubbo.demo.DemoService&pid=7375&side=consumer&sticky=false&timestamp=2299556506417"); "org.apache.dubbo.demo.DemoService&pid=7375&side=consumer&sticky=false&timestamp=2299556506417");
assertNotEquals(url3.hashCode(), url4.hashCode()); assertNotEquals(url3.hashCode(), url4.hashCode());
} }
@Test @Test
public void testParameterContainPound() { public void testParameterContainPound() {
URL url = URL.valueOf( URL url = URL.valueOf(
"dubbo://ad@min:hello@1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan&pound=abcd#efg&protocol=registry"); "dubbo://ad@min:hello@1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan&pound=abcd#efg&protocol=registry");
Assertions.assertEquals("abcd#efg", url.getParameter("pound")); Assertions.assertEquals("abcd#efg", url.getParameter("pound"));
Assertions.assertEquals("registry", url.getParameter("protocol")); Assertions.assertEquals("registry", url.getParameter("protocol"));
} }
@ -1048,4 +1049,37 @@ public class URLTest {
URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan&noValue"); URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan&noValue");
Assertions.assertEquals("noValue", url.getParameter("noValue")); Assertions.assertEquals("noValue", url.getParameter("noValue"));
} }
@Test
public void testGetAuthority() {
URL url = URL.valueOf("admin1:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=app1");
assertEquals("admin1:hello1234@10.20.130.230:20880", url.getAuthority());
URL urlWithoutUsername = URL.valueOf(":hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=app1");
assertEquals(":hello1234@10.20.130.230:20880", urlWithoutUsername.getAuthority());
URL urlWithoutPassword = URL.valueOf("admin1:@10.20.130.230:20880/context/path?version=1.0.0&application=app1");
assertEquals("admin1:@10.20.130.230:20880", urlWithoutPassword.getAuthority());
URL urlWithoutUserInformation = URL.valueOf("10.20.130.230:20880/context/path?version=1.0.0&application=app1");
assertEquals("10.20.130.230:20880", urlWithoutUserInformation.getAuthority());
URL urlWithoutPort = URL.valueOf("admin1:hello1234@10.20.130.230/context/path?version=1.0.0&application=app1");
assertEquals("admin1:hello1234@10.20.130.230", urlWithoutPort.getAuthority());
}
@Test
public void testGetUserInformation() {
URL url = URL.valueOf("admin1:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=app1");
assertEquals("admin1:hello1234", url.getUserInformation());
URL urlWithoutUsername = URL.valueOf(":hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=app1");
assertEquals(":hello1234@10.20.130.230:20880", urlWithoutUsername.getAuthority());
URL urlWithoutPassword = URL.valueOf("admin1:@10.20.130.230:20880/context/path?version=1.0.0&application=app1");
assertEquals("admin1:@10.20.130.230:20880", urlWithoutPassword.getAuthority());
URL urlWithoutUserInformation = URL.valueOf("10.20.130.230:20880/context/path?version=1.0.0&application=app1");
assertEquals("10.20.130.230:20880", urlWithoutUserInformation.getAuthority());
}
} }

View File

@ -116,7 +116,8 @@ public class URL extends org.apache.dubbo.common.URL {
@Override @Override
public String getAuthority() { public String getAuthority() {
return super.getAuthority(); // Compatible with old version logicThe previous Authority only contained username and password information.
return super.getUserInformation();
} }
@Override @Override
@ -626,6 +627,6 @@ public class URL extends org.apache.dubbo.common.URL {
public org.apache.dubbo.common.URL getOriginalURL() { public org.apache.dubbo.common.URL getOriginalURL() {
return new org.apache.dubbo.common.URL(super.getProtocol(), super.getUsername(), super.getPassword(), return new org.apache.dubbo.common.URL(super.getProtocol(), super.getUsername(), super.getPassword(),
super.getHost(), super.getPort(), super.getPath(), super.getParameters()); super.getHost(), super.getPort(), super.getPath(), super.getParameters());
} }
} }

View File

@ -71,9 +71,9 @@ public class Curator5ZookeeperClient extends AbstractZookeeperClient<Curator5Zoo
.retryPolicy(new RetryNTimes(1, 1000)) .retryPolicy(new RetryNTimes(1, 1000))
.connectionTimeoutMs(timeout) .connectionTimeoutMs(timeout)
.sessionTimeoutMs(sessionExpireMs); .sessionTimeoutMs(sessionExpireMs);
String authority = url.getAuthority(); String userInformation = url.getUserInformation();
if (authority != null && authority.length() > 0) { if (userInformation != null && userInformation.length() > 0) {
builder = builder.authorization("digest", authority.getBytes()); builder = builder.authorization("digest", userInformation.getBytes());
} }
client = builder.build(); client = builder.build();
client.getConnectionStateListenable().addListener(new CuratorConnectionStateListener(url)); client.getConnectionStateListenable().addListener(new CuratorConnectionStateListener(url));

View File

@ -71,9 +71,9 @@ public class CuratorZookeeperClient extends AbstractZookeeperClient<CuratorZooke
.retryPolicy(new RetryNTimes(1, 1000)) .retryPolicy(new RetryNTimes(1, 1000))
.connectionTimeoutMs(timeout) .connectionTimeoutMs(timeout)
.sessionTimeoutMs(sessionExpireMs); .sessionTimeoutMs(sessionExpireMs);
String authority = url.getAuthority(); String userInformation = url.getUserInformation();
if (authority != null && authority.length() > 0) { if (userInformation != null && userInformation.length() > 0) {
builder = builder.authorization("digest", authority.getBytes()); builder = builder.authorization("digest", userInformation.getBytes());
} }
client = builder.build(); client = builder.build();
client.getConnectionStateListenable().addListener(new CuratorConnectionStateListener(url)); client.getConnectionStateListenable().addListener(new CuratorConnectionStateListener(url));