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: - https://github.com/socketio/socket.io-client-java/issues/650 - https://github.com/socketio/socket.io-client-java/issues/555 - https://github.com/socketio/socket.io-client-java/issues/233
This commit is contained in:
@@ -7,7 +7,6 @@ import okhttp3.WebSocket;
|
|||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@@ -58,21 +57,16 @@ public class IO {
|
|||||||
opts = new Options();
|
opts = new Options();
|
||||||
}
|
}
|
||||||
|
|
||||||
URL parsed = Url.parse(uri);
|
Url.ParsedURI parsed = Url.parse(uri);
|
||||||
URI source;
|
URI source = parsed.uri;
|
||||||
try {
|
String id = parsed.id;
|
||||||
source = parsed.toURI();
|
|
||||||
} catch (URISyntaxException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
String id = Url.extractId(parsed);
|
|
||||||
String path = parsed.getPath();
|
|
||||||
boolean sameNamespace = managers.containsKey(id)
|
boolean sameNamespace = managers.containsKey(id)
|
||||||
&& managers.get(id).nsps.containsKey(path);
|
&& managers.get(id).nsps.containsKey(source.getPath());
|
||||||
boolean newConnection = opts.forceNew || !opts.multiplex || sameNamespace;
|
boolean newConnection = opts.forceNew || !opts.multiplex || sameNamespace;
|
||||||
Manager io;
|
Manager io;
|
||||||
|
|
||||||
String query = parsed.getQuery();
|
String query = source.getQuery();
|
||||||
if (query != null && (opts.query == null || opts.query.isEmpty())) {
|
if (query != null && (opts.query == null || opts.query.isEmpty())) {
|
||||||
opts.query = query;
|
opts.query = query;
|
||||||
}
|
}
|
||||||
@@ -92,7 +86,7 @@ public class IO {
|
|||||||
io = managers.get(id);
|
io = managers.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return io.socket(parsed.getPath(), opts);
|
return io.socket(source.getPath(), opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,11 @@
|
|||||||
package io.socket.client;
|
package io.socket.client;
|
||||||
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class Url {
|
public class Url {
|
||||||
|
|
||||||
private static Pattern PATTERN_HTTP = Pattern.compile("^http|ws$");
|
|
||||||
private static Pattern PATTERN_HTTPS = Pattern.compile("^(http|ws)s$");
|
|
||||||
/**
|
/**
|
||||||
* Expected format: "[id:password@]host[:port]"
|
* Expected format: "[id:password@]host[:port]"
|
||||||
*/
|
*/
|
||||||
@@ -18,11 +13,17 @@ public class Url {
|
|||||||
|
|
||||||
private Url() {}
|
private Url() {}
|
||||||
|
|
||||||
public static URL parse(String uri) throws URISyntaxException {
|
static class ParsedURI {
|
||||||
return parse(new URI(uri));
|
public final URI uri;
|
||||||
|
public final String id;
|
||||||
|
|
||||||
|
public ParsedURI(URI uri, String id) {
|
||||||
|
this.uri = uri;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static URL parse(URI uri) {
|
public static ParsedURI parse(URI uri) {
|
||||||
String protocol = uri.getScheme();
|
String protocol = uri.getScheme();
|
||||||
if (protocol == null || !protocol.matches("^https?|wss?$")) {
|
if (protocol == null || !protocol.matches("^https?|wss?$")) {
|
||||||
protocol = "https";
|
protocol = "https";
|
||||||
@@ -30,9 +31,9 @@ public class Url {
|
|||||||
|
|
||||||
int port = uri.getPort();
|
int port = uri.getPort();
|
||||||
if (port == -1) {
|
if (port == -1) {
|
||||||
if (PATTERN_HTTP.matcher(protocol).matches()) {
|
if ("http".equals(protocol) || "ws".equals(protocol)) {
|
||||||
port = 80;
|
port = 80;
|
||||||
} else if (PATTERN_HTTPS.matcher(protocol).matches()) {
|
} else if ("https".equals(protocol) || "wss".equals(protocol)) {
|
||||||
port = 443;
|
port = 443;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,35 +51,18 @@ public class Url {
|
|||||||
// might happen on some of Samsung Devices such as S4.
|
// might happen on some of Samsung Devices such as S4.
|
||||||
_host = extractHostFromAuthorityPart(uri.getRawAuthority());
|
_host = extractHostFromAuthorityPart(uri.getRawAuthority());
|
||||||
}
|
}
|
||||||
try {
|
URI completeUri = URI.create(protocol + "://"
|
||||||
return new URL(protocol + "://"
|
+ (userInfo != null ? userInfo + "@" : "")
|
||||||
+ (userInfo != null ? userInfo + "@" : "")
|
+ _host
|
||||||
+ _host
|
+ (port != -1 ? ":" + port : "")
|
||||||
+ (port != -1 ? ":" + port : "")
|
+ path
|
||||||
+ path
|
+ (query != null ? "?" + query : "")
|
||||||
+ (query != null ? "?" + query : "")
|
+ (fragment != null ? "#" + fragment : ""));
|
||||||
+ (fragment != null ? "#" + fragment : ""));
|
String id = protocol + "://" + _host + ":" + port;
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
throw new RuntimeException(e);
|
return new ParsedURI(completeUri, id);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String extractId(String url) throws MalformedURLException {
|
|
||||||
return extractId(new URL(url));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String extractId(URL url) {
|
|
||||||
String protocol = url.getProtocol();
|
|
||||||
int port = url.getPort();
|
|
||||||
if (port == -1) {
|
|
||||||
if (PATTERN_HTTP.matcher(protocol).matches()) {
|
|
||||||
port = 80;
|
|
||||||
} else if (PATTERN_HTTPS.matcher(protocol).matches()) {
|
|
||||||
port = 443;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return protocol + "://" + url.getHost() + ":" + port;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String extractHostFromAuthorityPart(String authority)
|
private static String extractHostFromAuthorityPart(String authority)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,9 +4,7 @@ import org.junit.Test;
|
|||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.JUnit4;
|
import org.junit.runners.JUnit4;
|
||||||
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.hamcrest.CoreMatchers.not;
|
import static org.hamcrest.CoreMatchers.not;
|
||||||
@@ -15,58 +13,85 @@ import static org.junit.Assert.assertThat;
|
|||||||
@RunWith(JUnit4.class)
|
@RunWith(JUnit4.class)
|
||||||
public class UrlTest {
|
public class UrlTest {
|
||||||
|
|
||||||
|
private URI parse(String uri) {
|
||||||
|
return Url.parse(URI.create(uri)).uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String extractId(String uri) {
|
||||||
|
return Url.parse(URI.create(uri)).id;
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parse() throws URISyntaxException {
|
public void parse() {
|
||||||
assertThat(Url.parse("http://username:password@host:8080/directory/file?query#ref").toString(),
|
assertThat(parse("http://username:password@host:8080/directory/file?query#ref").toString(),
|
||||||
is("http://username:password@host:8080/directory/file?query#ref"));
|
is("http://username:password@host:8080/directory/file?query#ref"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parseRelativePath() throws URISyntaxException {
|
public void parseRelativePath() {
|
||||||
URL url = Url.parse("https://woot.com/test");
|
URI uri = parse("https://woot.com/test");
|
||||||
assertThat(url.getProtocol(), is("https"));
|
assertThat(uri.getScheme(), is("https"));
|
||||||
assertThat(url.getHost(), is("woot.com"));
|
assertThat(uri.getHost(), is("woot.com"));
|
||||||
assertThat(url.getPath(), is("/test"));
|
assertThat(uri.getPath(), is("/test"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parseNoProtocol() throws URISyntaxException {
|
public void parseNoProtocol() {
|
||||||
URL url = Url.parse("//localhost:3000");
|
URI uri = parse("//localhost:3000");
|
||||||
assertThat(url.getProtocol(), is("https"));
|
assertThat(uri.getScheme(), is("https"));
|
||||||
assertThat(url.getHost(), is("localhost"));
|
assertThat(uri.getHost(), is("localhost"));
|
||||||
assertThat(url.getPort(), is(3000));
|
assertThat(uri.getPort(), is(3000));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parseNamespace() throws URISyntaxException {
|
public void parseNamespace() {
|
||||||
assertThat(Url.parse("http://woot.com/woot").getPath(), is("/woot"));
|
assertThat(parse("http://woot.com/woot").getPath(), is("/woot"));
|
||||||
assertThat(Url.parse("http://google.com").getPath(), is("/"));
|
assertThat(parse("http://google.com").getPath(), is("/"));
|
||||||
assertThat(Url.parse("http://google.com/").getPath(), is("/"));
|
assertThat(parse("http://google.com/").getPath(), is("/"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parseDefaultPort() throws URISyntaxException {
|
public void parseDefaultPort() {
|
||||||
assertThat(Url.parse("http://google.com/").toString(), is("http://google.com:80/"));
|
assertThat(parse("http://google.com/").toString(), is("http://google.com:80/"));
|
||||||
assertThat(Url.parse("https://google.com/").toString(), is("https://google.com:443/"));
|
assertThat(parse("https://google.com/").toString(), is("https://google.com:443/"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void extractId() throws MalformedURLException {
|
public void testWsProtocol() {
|
||||||
String id1 = Url.extractId("http://google.com:80/");
|
URI uri = parse("ws://woot.com/test");
|
||||||
String id2 = Url.extractId("http://google.com/");
|
assertThat(uri.getScheme(), is("ws"));
|
||||||
String id3 = Url.extractId("https://google.com/");
|
assertThat(uri.getHost(), is("woot.com"));
|
||||||
|
assertThat(uri.getPort(), is(80));
|
||||||
|
assertThat(uri.getPath(), is("/test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWssProtocol() {
|
||||||
|
URI uri = parse("wss://woot.com/test");
|
||||||
|
assertThat(uri.getScheme(), is("wss"));
|
||||||
|
assertThat(uri.getHost(), is("woot.com"));
|
||||||
|
assertThat(uri.getPort(), is(443));
|
||||||
|
assertThat(uri.getPath(), is("/test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void extractId() {
|
||||||
|
String id1 = extractId("http://google.com:80/");
|
||||||
|
String id2 = extractId("http://google.com/");
|
||||||
|
String id3 = extractId("https://google.com/");
|
||||||
assertThat(id1, is(id2));
|
assertThat(id1, is(id2));
|
||||||
assertThat(id1, is(not(id3)));
|
assertThat(id1, is(not(id3)));
|
||||||
assertThat(id2, is(not(id3)));
|
assertThat(id2, is(not(id3)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void ipv6() throws URISyntaxException, MalformedURLException {
|
public void ipv6() {
|
||||||
String url = "http://[::1]";
|
String url = "http://[::1]";
|
||||||
URL parsed = Url.parse(url);
|
URI parsed = parse(url);
|
||||||
assertThat(parsed.getProtocol(), is("http"));
|
assertThat(parsed.getScheme(), is("http"));
|
||||||
assertThat(parsed.getHost(), is("[::1]"));
|
assertThat(parsed.getHost(), is("[::1]"));
|
||||||
assertThat(parsed.getPort(), is(80));
|
assertThat(parsed.getPort(), is(80));
|
||||||
assertThat(Url.extractId(url), is("http://[::1]:80"));
|
assertThat(extractId(url), is("http://[::1]:80"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user