Skip to content

Commit e57160a

Browse files
fix: fix usage with ws:// scheme
The URL constructor does not support the ws:// scheme, and would throw: > java.net.MalformedURLException: unknown protocol: ws Related: - #650 - #555 - #233 Backported from 67fd5f3
1 parent 48bf83f commit e57160a

File tree

3 files changed

+84
-81
lines changed

3 files changed

+84
-81
lines changed

Diff for: src/main/java/io/socket/client/IO.java

+7-13
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
import java.net.URI;
99
import java.net.URISyntaxException;
10-
import java.net.URL;
1110
import java.util.concurrent.ConcurrentHashMap;
1211
import java.util.logging.Level;
1312
import java.util.logging.Logger;
@@ -58,17 +57,12 @@ public static Socket socket(URI uri, Options opts) {
5857
opts = new Options();
5958
}
6059

61-
URL parsed = Url.parse(uri);
62-
URI source;
63-
try {
64-
source = parsed.toURI();
65-
} catch (URISyntaxException e) {
66-
throw new RuntimeException(e);
67-
}
68-
String id = Url.extractId(parsed);
69-
String path = parsed.getPath();
60+
Url.ParsedURI parsed = Url.parse(uri);
61+
URI source = parsed.uri;
62+
String id = parsed.id;
63+
7064
boolean sameNamespace = managers.containsKey(id)
71-
&& managers.get(id).nsps.containsKey(path);
65+
&& managers.get(id).nsps.containsKey(source.getPath());
7266
boolean newConnection = opts.forceNew || !opts.multiplex || sameNamespace;
7367
Manager io;
7468

@@ -87,12 +81,12 @@ public static Socket socket(URI uri, Options opts) {
8781
io = managers.get(id);
8882
}
8983

90-
String query = parsed.getQuery();
84+
String query = source.getQuery();
9185
if (query != null && (opts.query == null || opts.query.isEmpty())) {
9286
opts.query = query;
9387
}
9488

95-
return io.socket(parsed.getPath(), opts);
89+
return io.socket(source.getPath(), opts);
9690
}
9791

9892

Diff for: src/main/java/io/socket/client/Url.java

+22-38
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,39 @@
11
package io.socket.client;
22

3-
import java.net.MalformedURLException;
43
import java.net.URI;
5-
import java.net.URISyntaxException;
6-
import java.net.URL;
7-
import java.util.regex.Pattern;
84
import java.util.regex.Matcher;
5+
import java.util.regex.Pattern;
96

107
public class Url {
118

12-
private static Pattern PATTERN_HTTP = Pattern.compile("^http|ws$");
13-
private static Pattern PATTERN_HTTPS = Pattern.compile("^(http|ws)s$");
149
/**
1510
* Expected format: "[id:password@]host[:port]"
1611
*/
1712
private static Pattern PATTERN_AUTHORITY = Pattern.compile("^(.*@)?([^:]+)(:\\d+)?$");
1813

1914
private Url() {}
2015

21-
public static URL parse(String uri) throws URISyntaxException {
22-
return parse(new URI(uri));
16+
static class ParsedURI {
17+
public final URI uri;
18+
public final String id;
19+
20+
public ParsedURI(URI uri, String id) {
21+
this.uri = uri;
22+
this.id = id;
23+
}
2324
}
2425

25-
public static URL parse(URI uri) {
26+
public static ParsedURI parse(URI uri) {
2627
String protocol = uri.getScheme();
2728
if (protocol == null || !protocol.matches("^https?|wss?$")) {
2829
protocol = "https";
2930
}
3031

3132
int port = uri.getPort();
3233
if (port == -1) {
33-
if (PATTERN_HTTP.matcher(protocol).matches()) {
34+
if ("http".equals(protocol) || "ws".equals(protocol)) {
3435
port = 80;
35-
} else if (PATTERN_HTTPS.matcher(protocol).matches()) {
36+
} else if ("https".equals(protocol) || "wss".equals(protocol)) {
3637
port = 443;
3738
}
3839
}
@@ -50,35 +51,18 @@ public static URL parse(URI uri) {
5051
// might happen on some of Samsung Devices such as S4.
5152
_host = extractHostFromAuthorityPart(uri.getRawAuthority());
5253
}
53-
try {
54-
return new URL(protocol + "://"
55-
+ (userInfo != null ? userInfo + "@" : "")
56-
+ _host
57-
+ (port != -1 ? ":" + port : "")
58-
+ path
59-
+ (query != null ? "?" + query : "")
60-
+ (fragment != null ? "#" + fragment : ""));
61-
} catch (MalformedURLException e) {
62-
throw new RuntimeException(e);
63-
}
64-
}
65-
66-
public static String extractId(String url) throws MalformedURLException {
67-
return extractId(new URL(url));
54+
URI completeUri = URI.create(protocol + "://"
55+
+ (userInfo != null ? userInfo + "@" : "")
56+
+ _host
57+
+ (port != -1 ? ":" + port : "")
58+
+ path
59+
+ (query != null ? "?" + query : "")
60+
+ (fragment != null ? "#" + fragment : ""));
61+
String id = protocol + "://" + _host + ":" + port;
62+
63+
return new ParsedURI(completeUri, id);
6864
}
6965

70-
public static String extractId(URL url) {
71-
String protocol = url.getProtocol();
72-
int port = url.getPort();
73-
if (port == -1) {
74-
if (PATTERN_HTTP.matcher(protocol).matches()) {
75-
port = 80;
76-
} else if (PATTERN_HTTPS.matcher(protocol).matches()) {
77-
port = 443;
78-
}
79-
}
80-
return protocol + "://" + url.getHost() + ":" + port;
81-
}
8266

8367
private static String extractHostFromAuthorityPart(String authority)
8468
{

Diff for: src/test/java/io/socket/client/UrlTest.java

+55-30
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
import org.junit.runner.RunWith;
55
import org.junit.runners.JUnit4;
66

7-
import java.net.MalformedURLException;
8-
import java.net.URISyntaxException;
9-
import java.net.URL;
7+
import java.net.URI;
108

119
import static org.hamcrest.CoreMatchers.is;
1210
import static org.hamcrest.CoreMatchers.not;
@@ -15,58 +13,85 @@
1513
@RunWith(JUnit4.class)
1614
public class UrlTest {
1715

16+
private URI parse(String uri) {
17+
return Url.parse(URI.create(uri)).uri;
18+
}
19+
20+
private String extractId(String uri) {
21+
return Url.parse(URI.create(uri)).id;
22+
}
23+
1824
@Test
19-
public void parse() throws URISyntaxException {
20-
assertThat(Url.parse("http://username:password@host:8080/directory/file?query#ref").toString(),
25+
public void parse() {
26+
assertThat(parse("http://username:password@host:8080/directory/file?query#ref").toString(),
2127
is("http://username:password@host:8080/directory/file?query#ref"));
2228
}
2329

2430
@Test
25-
public void parseRelativePath() throws URISyntaxException {
26-
URL url = Url.parse("https://woot.com/test");
27-
assertThat(url.getProtocol(), is("https"));
28-
assertThat(url.getHost(), is("woot.com"));
29-
assertThat(url.getPath(), is("/test"));
31+
public void parseRelativePath() {
32+
URI uri = parse("https://woot.com/test");
33+
assertThat(uri.getScheme(), is("https"));
34+
assertThat(uri.getHost(), is("woot.com"));
35+
assertThat(uri.getPath(), is("/test"));
3036
}
3137

3238
@Test
33-
public void parseNoProtocol() throws URISyntaxException {
34-
URL url = Url.parse("//localhost:3000");
35-
assertThat(url.getProtocol(), is("https"));
36-
assertThat(url.getHost(), is("localhost"));
37-
assertThat(url.getPort(), is(3000));
39+
public void parseNoProtocol() {
40+
URI uri = parse("//localhost:3000");
41+
assertThat(uri.getScheme(), is("https"));
42+
assertThat(uri.getHost(), is("localhost"));
43+
assertThat(uri.getPort(), is(3000));
3844
}
3945

4046
@Test
41-
public void parseNamespace() throws URISyntaxException {
42-
assertThat(Url.parse("http://woot.com/woot").getPath(), is("/woot"));
43-
assertThat(Url.parse("http://google.com").getPath(), is("/"));
44-
assertThat(Url.parse("http://google.com/").getPath(), is("/"));
47+
public void parseNamespace() {
48+
assertThat(parse("http://woot.com/woot").getPath(), is("/woot"));
49+
assertThat(parse("http://google.com").getPath(), is("/"));
50+
assertThat(parse("http://google.com/").getPath(), is("/"));
4551
}
4652

4753
@Test
48-
public void parseDefaultPort() throws URISyntaxException {
49-
assertThat(Url.parse("http://google.com/").toString(), is("http://google.com:80/"));
50-
assertThat(Url.parse("https://google.com/").toString(), is("https://google.com:443/"));
54+
public void parseDefaultPort() {
55+
assertThat(parse("http://google.com/").toString(), is("http://google.com:80/"));
56+
assertThat(parse("https://google.com/").toString(), is("https://google.com:443/"));
5157
}
5258

5359
@Test
54-
public void extractId() throws MalformedURLException {
55-
String id1 = Url.extractId("http://google.com:80/");
56-
String id2 = Url.extractId("http://google.com/");
57-
String id3 = Url.extractId("https://google.com/");
60+
public void testWsProtocol() {
61+
URI uri = parse("ws://woot.com/test");
62+
assertThat(uri.getScheme(), is("ws"));
63+
assertThat(uri.getHost(), is("woot.com"));
64+
assertThat(uri.getPort(), is(80));
65+
assertThat(uri.getPath(), is("/test"));
66+
}
67+
68+
@Test
69+
public void testWssProtocol() {
70+
URI uri = parse("wss://woot.com/test");
71+
assertThat(uri.getScheme(), is("wss"));
72+
assertThat(uri.getHost(), is("woot.com"));
73+
assertThat(uri.getPort(), is(443));
74+
assertThat(uri.getPath(), is("/test"));
75+
}
76+
77+
@Test
78+
public void extractId() {
79+
String id1 = extractId("http://google.com:80/");
80+
String id2 = extractId("http://google.com/");
81+
String id3 = extractId("https://google.com/");
5882
assertThat(id1, is(id2));
5983
assertThat(id1, is(not(id3)));
6084
assertThat(id2, is(not(id3)));
6185
}
6286

6387
@Test
64-
public void ipv6() throws URISyntaxException, MalformedURLException {
88+
public void ipv6() {
6589
String url = "http://[::1]";
66-
URL parsed = Url.parse(url);
67-
assertThat(parsed.getProtocol(), is("http"));
90+
URI parsed = parse(url);
91+
assertThat(parsed.getScheme(), is("http"));
6892
assertThat(parsed.getHost(), is("[::1]"));
6993
assertThat(parsed.getPort(), is(80));
70-
assertThat(Url.extractId(url), is("http://[::1]:80"));
94+
assertThat(extractId(url), is("http://[::1]:80"));
7195
}
96+
7297
}

0 commit comments

Comments
 (0)