improve ipv6 support, add tests
This commit is contained in:
@@ -111,7 +111,7 @@ public class Socket extends Emitter {
|
|||||||
private long pingInterval;
|
private long pingInterval;
|
||||||
private long pingTimeout;
|
private long pingTimeout;
|
||||||
private String id;
|
private String id;
|
||||||
private String hostname;
|
/*package*/ String hostname;
|
||||||
private String path;
|
private String path;
|
||||||
private String timestampParam;
|
private String timestampParam;
|
||||||
private List<String> transports;
|
private List<String> transports;
|
||||||
@@ -171,29 +171,27 @@ public class Socket extends Emitter {
|
|||||||
|
|
||||||
public Socket(Options opts) {
|
public Socket(Options opts) {
|
||||||
if (opts.host != null) {
|
if (opts.host != null) {
|
||||||
boolean ipv6uri = opts.host.indexOf(']') != -1;
|
String hostname = opts.host;
|
||||||
String[] pieces = ipv6uri ? opts.host.split("]:") : opts.host.split(":");
|
boolean ipv6 = hostname.split(":").length > 2;
|
||||||
boolean ipv6 = (pieces.length > 2 || opts.host.indexOf("::") == -1);
|
|
||||||
if (ipv6) {
|
if (ipv6) {
|
||||||
opts.hostname = opts.host;
|
int start = hostname.indexOf('[');
|
||||||
} else {
|
if (start != -1) hostname = hostname.substring(start + 1);
|
||||||
opts.hostname = pieces[0];
|
int end = hostname.lastIndexOf(']');
|
||||||
if (ipv6uri) {
|
if (end != -1) hostname = hostname.substring(0, end);
|
||||||
opts.hostname = opts.hostname.substring(1);
|
|
||||||
}
|
|
||||||
if (pieces.length > 1) {
|
|
||||||
opts.port = Integer.parseInt(pieces[pieces.length - 1]);
|
|
||||||
} else if (opts.port == -1) {
|
|
||||||
// if no port is specified manually, use the protocol default
|
|
||||||
opts.port = this.secure ? 443 : 80;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
opts.hostname = hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.secure = opts.secure;
|
this.secure = opts.secure;
|
||||||
|
|
||||||
|
if (opts.port == -1) {
|
||||||
|
// if no port is specified manually, use the protocol default
|
||||||
|
opts.port = this.secure ? 443 : 80;
|
||||||
|
}
|
||||||
|
|
||||||
this.sslContext = opts.sslContext != null ? opts.sslContext : defaultSSLContext;
|
this.sslContext = opts.sslContext != null ? opts.sslContext : defaultSSLContext;
|
||||||
this.hostname = opts.hostname != null ? opts.hostname : "localhost";
|
this.hostname = opts.hostname != null ? opts.hostname : "localhost";
|
||||||
this.port = opts.port != 0 ? opts.port : (this.secure ? 443 : 80);
|
this.port = opts.port;
|
||||||
this.query = opts.query != null ?
|
this.query = opts.query != null ?
|
||||||
ParseQS.decode(opts.query) : new HashMap<String, String>();
|
ParseQS.decode(opts.query) : new HashMap<String, String>();
|
||||||
this.upgrade = opts.upgrade;
|
this.upgrade = opts.upgrade;
|
||||||
|
|||||||
@@ -214,7 +214,8 @@ abstract public class Polling extends Transport {
|
|||||||
_query = "?" + _query;
|
_query = "?" + _query;
|
||||||
}
|
}
|
||||||
|
|
||||||
return schema + "://" + this.hostname + port + this.path + _query;
|
boolean ipv6 = this.hostname.contains(":");
|
||||||
|
return schema + "://" + (ipv6 ? "[" + this.hostname + "]" : this.hostname) + port + this.path + _query;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract protected void doWrite(byte[] data, Runnable fn);
|
abstract protected void doWrite(byte[] data, Runnable fn);
|
||||||
|
|||||||
@@ -1,15 +1,22 @@
|
|||||||
package io.socket.engineio.client.transports;
|
package io.socket.engineio.client.transports;
|
||||||
|
|
||||||
|
|
||||||
|
import io.socket.engineio.client.Transport;
|
||||||
|
import io.socket.engineio.parser.Packet;
|
||||||
|
import io.socket.engineio.parser.Parser;
|
||||||
|
import io.socket.parseqs.ParseQS;
|
||||||
|
import io.socket.thread.EventThread;
|
||||||
|
import io.socket.utf8.UTF8Exception;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import okhttp3.OkHttpClient.Builder;
|
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.RequestBody;
|
import okhttp3.RequestBody;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
import okhttp3.ResponseBody;
|
import okhttp3.ResponseBody;
|
||||||
import okhttp3.ws.WebSocketCall;
|
import okhttp3.ws.WebSocketCall;
|
||||||
import okhttp3.ws.WebSocketListener;
|
import okhttp3.ws.WebSocketListener;
|
||||||
|
import okio.Buffer;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -19,16 +26,6 @@ import java.util.TreeMap;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.net.ssl.SSLSocketFactory;
|
|
||||||
|
|
||||||
import io.socket.engineio.client.Transport;
|
|
||||||
import io.socket.engineio.parser.Packet;
|
|
||||||
import io.socket.engineio.parser.Parser;
|
|
||||||
import io.socket.parseqs.ParseQS;
|
|
||||||
import io.socket.thread.EventThread;
|
|
||||||
import io.socket.utf8.UTF8Exception;
|
|
||||||
import okio.Buffer;
|
|
||||||
|
|
||||||
import static okhttp3.ws.WebSocket.BINARY;
|
import static okhttp3.ws.WebSocket.BINARY;
|
||||||
import static okhttp3.ws.WebSocket.TEXT;
|
import static okhttp3.ws.WebSocket.TEXT;
|
||||||
|
|
||||||
@@ -222,6 +219,7 @@ public class WebSocket extends Transport {
|
|||||||
_query = "?" + _query;
|
_query = "?" + _query;
|
||||||
}
|
}
|
||||||
|
|
||||||
return schema + "://" + this.hostname + port + this.path + _query;
|
boolean ipv6 = this.hostname.contains(":");
|
||||||
|
return schema + "://" + (ipv6 ? "[" + this.hostname + "]" : this.hostname) + port + this.path + _query;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,23 +29,93 @@ public class SocketTest {
|
|||||||
assertThat(socket.filterUpgrades(upgrades), is(expected));
|
assertThat(socket.filterUpgrades(upgrades), is(expected));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void properlyParseHttpUriWithoutPort() throws URISyntaxException {
|
public void properlyParseHttpUriWithoutPort() throws URISyntaxException {
|
||||||
Socket client = new Socket("http://localhost");
|
Socket client = new Socket("http://localhost");
|
||||||
|
assertThat(client.hostname, is("localhost"));
|
||||||
assertThat(client.port, is(80));
|
assertThat(client.port, is(80));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void properlyParseHttpsUriWithoutPort() throws URISyntaxException {
|
public void properlyParseHttpsUriWithoutPort() throws URISyntaxException {
|
||||||
Socket client = new Socket("http://localhost");
|
Socket client = new Socket("https://localhost");
|
||||||
|
assertThat(client.hostname, is("localhost"));
|
||||||
assertThat(client.port, is(443));
|
assertThat(client.port, is(443));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void properlyParseWssUriWithoutPort() throws URISyntaxException {
|
public void properlyParseWssUriWithoutPort() throws URISyntaxException {
|
||||||
Socket client = new Socket("http://localhost");
|
Socket client = new Socket("wss://localhost");
|
||||||
|
assertThat(client.hostname, is("localhost"));
|
||||||
assertThat(client.port, is(443));
|
assertThat(client.port, is(443));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void properlyParseWssUriWithPort() throws URISyntaxException {
|
public void properlyParseWssUriWithPort() throws URISyntaxException {
|
||||||
Socket client = new Socket("http://localhost:2020");
|
Socket client = new Socket("wss://localhost:2020");
|
||||||
|
assertThat(client.hostname, is("localhost"));
|
||||||
assertThat(client.port, is(2020));
|
assertThat(client.port, is(2020));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void properlyParseHostWithPort() {
|
||||||
|
Socket.Options opts = new Socket.Options();
|
||||||
|
opts.host = "localhost";
|
||||||
|
opts.port = 8080;
|
||||||
|
Socket client = new Socket(opts);
|
||||||
|
assertThat(client.hostname, is("localhost"));
|
||||||
|
assertThat(client.port, is(8080));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void properlyParseIPv6UriWithoutPort() throws URISyntaxException {
|
||||||
|
Socket client = new Socket("http://[::1]");
|
||||||
|
assertThat(client.hostname, is("::1"));
|
||||||
|
assertThat(client.port, is(80));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void properlyParseIPv6UriWithPort() throws URISyntaxException {
|
||||||
|
Socket client = new Socket("http://[::1]:8080");
|
||||||
|
assertThat(client.hostname, is("::1"));
|
||||||
|
assertThat(client.port, is(8080));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void properlyParseIPv6HostWithoutPort1() {
|
||||||
|
Socket.Options opts = new Socket.Options();
|
||||||
|
opts.host = "[::1]";
|
||||||
|
Socket client = new Socket(opts);
|
||||||
|
assertThat(client.hostname, is("::1"));
|
||||||
|
assertThat(client.port, is(80));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void properlyParseIPv6HostWithoutPort2() {
|
||||||
|
Socket.Options opts = new Socket.Options();
|
||||||
|
opts.secure = true;
|
||||||
|
opts.host = "[::1]";
|
||||||
|
Socket client = new Socket(opts);
|
||||||
|
assertThat(client.hostname, is("::1"));
|
||||||
|
assertThat(client.port, is(443));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void properlyParseIPv6HostWithPort() {
|
||||||
|
Socket.Options opts = new Socket.Options();
|
||||||
|
opts.host = "[::1]";
|
||||||
|
opts.port = 8080;
|
||||||
|
Socket client = new Socket(opts);
|
||||||
|
assertThat(client.hostname, is("::1"));
|
||||||
|
assertThat(client.port, is(8080));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void properlyParseIPv6HostWithoutBrace() {
|
||||||
|
Socket.Options opts = new Socket.Options();
|
||||||
|
opts.host = "::1";
|
||||||
|
Socket client = new Socket(opts);
|
||||||
|
assertThat(client.hostname, is("::1"));
|
||||||
|
assertThat(client.port, is(80));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,30 @@ public class TransportTest {
|
|||||||
assertThat(polling.uri().matches("http://localhost/engine.io\\?(j=[0-9]+&)?t=[0-9]+-[0-9]+"), is(true));
|
assertThat(polling.uri().matches("http://localhost/engine.io\\?(j=[0-9]+&)?t=[0-9]+-[0-9]+"), is(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ipv6Uri() {
|
||||||
|
Transport.Options opt = new Transport.Options();
|
||||||
|
opt.path ="/engine.io";
|
||||||
|
opt.hostname = "::1";
|
||||||
|
opt.secure = false;
|
||||||
|
opt.port = 80;
|
||||||
|
opt.timestampRequests = false;
|
||||||
|
Polling polling = new Polling(opt);
|
||||||
|
assertThat(polling.uri(), containsString("http://[::1]/engine.io"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ipv6UriWithPort() {
|
||||||
|
Transport.Options opt = new Transport.Options();
|
||||||
|
opt.path ="/engine.io";
|
||||||
|
opt.hostname = "::1";
|
||||||
|
opt.secure = false;
|
||||||
|
opt.port = 8080;
|
||||||
|
opt.timestampRequests = false;
|
||||||
|
Polling polling = new Polling(opt);
|
||||||
|
assertThat(polling.uri(), containsString("http://[::1]:8080/engine.io"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void wsUri() {
|
public void wsUri() {
|
||||||
Transport.Options opt = new Transport.Options();
|
Transport.Options opt = new Transport.Options();
|
||||||
@@ -123,6 +147,30 @@ public class TransportTest {
|
|||||||
assertThat(ws.uri().matches("ws://localhost/engine.io\\?woot=[0-9]+"), is(true));
|
assertThat(ws.uri().matches("ws://localhost/engine.io\\?woot=[0-9]+"), is(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void wsIPv6Uri() {
|
||||||
|
Transport.Options opt = new Transport.Options();
|
||||||
|
opt.path ="/engine.io";
|
||||||
|
opt.hostname = "::1";
|
||||||
|
opt.secure = false;
|
||||||
|
opt.port = 80;
|
||||||
|
opt.timestampRequests = false;
|
||||||
|
WS ws = new WS(opt);
|
||||||
|
assertThat(ws.uri(), containsString("ws://[::1]/engine.io"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void wsIPv6UriWithPort() {
|
||||||
|
Transport.Options opt = new Transport.Options();
|
||||||
|
opt.path ="/engine.io";
|
||||||
|
opt.hostname = "::1";
|
||||||
|
opt.secure = false;
|
||||||
|
opt.port = 8080;
|
||||||
|
opt.timestampRequests = false;
|
||||||
|
WS ws = new WS(opt);
|
||||||
|
assertThat(ws.uri(), containsString("ws://[::1]:8080/engine.io"));
|
||||||
|
}
|
||||||
|
|
||||||
class Polling extends PollingXHR {
|
class Polling extends PollingXHR {
|
||||||
|
|
||||||
public Polling(Options opts) {
|
public Polling(Options opts) {
|
||||||
|
|||||||
Reference in New Issue
Block a user