Skip to content

Commit 45f8b10

Browse files
committed
Merge pull request #88 from pusher/set-proxy-option
Create setProxy method in options.
2 parents 352d72b + d9db397 commit 45f8b10

File tree

9 files changed

+98
-38
lines changed

9 files changed

+98
-38
lines changed

src/main/java/com/pusher/client/PusherOptions.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.io.IOException;
44
import java.io.InputStream;
5+
import java.net.Proxy;
56
import java.util.Properties;
67

78
/**
@@ -34,6 +35,7 @@ public class PusherOptions {
3435
private long activityTimeout = DEFAULT_ACTIVITY_TIMEOUT;
3536
private long pongTimeout = DEFAULT_PONG_TIMEOUT;
3637
private Authorizer authorizer;
38+
private Proxy proxy = Proxy.NO_PROXY;
3739

3840
/**
3941
* Gets whether an encrypted (SSL) connection should be used when connecting
@@ -196,21 +198,44 @@ public String buildUrl(final String apiKey) {
196198
: wsPort, apiKey, URI_SUFFIX);
197199
}
198200

201+
/**
202+
*
203+
* The default value is Proxy.NO_PROXY.
204+
*
205+
* @param proxy
206+
* Specify a proxy, e.g. <code>options.setProxy( new Proxy( Proxy.Type.HTTP, new InetSocketAddress( "proxyaddress", 80 ) ) )</code>;
207+
* @return this, for chaining
208+
*/
209+
public PusherOptions setProxy(Proxy proxy){
210+
if (proxy == null) {
211+
throw new IllegalArgumentException("proxy must not be null (instead use Proxy.NO_PROXY)");
212+
}
213+
this.proxy = proxy;
214+
return this;
215+
}
216+
217+
/**
218+
* @returns The proxy to be used when opening a websocket connection to Pusher.
219+
*/
220+
public Proxy getProxy() {
221+
return this.proxy;
222+
}
223+
199224
private static String readVersionFromProperties() {
200225
InputStream inStream = null;
201226
try {
202227
final Properties p = new Properties();
203228
inStream = PusherOptions.class.getResourceAsStream("/pusher.properties");
204229
p.load(inStream);
205230
String version = (String)p.get("version");
206-
231+
207232
// If the properties file contents indicates the version is being run
208233
// from source then replace with a dev indicator. Otherwise the Pusher
209234
// Socket API will reject the connection.
210235
if(version.equals(SRC_LIB_DEV_VERSION)) {
211236
version = LIB_DEV_VERSION;
212237
}
213-
238+
214239
if (version != null && version.length() > 0) {
215240
return version;
216241
}

src/main/java/com/pusher/client/connection/websocket/WebSocketClientWrapper.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.pusher.client.connection.websocket;
22

33
import java.io.IOException;
4+
import java.net.Proxy;
45
import java.net.URI;
56
import java.security.KeyManagementException;
67
import java.security.NoSuchAlgorithmException;
@@ -21,9 +22,9 @@
2122
public class WebSocketClientWrapper extends WebSocketClient {
2223

2324
private static final String WSS_SCHEME = "wss";
24-
private final WebSocketListener proxy;
25+
private final WebSocketListener webSocketListener;
2526

26-
public WebSocketClientWrapper(final URI uri, final WebSocketListener proxy) throws SSLException {
27+
public WebSocketClientWrapper(final URI uri, final Proxy proxy, final WebSocketListener webSocketListener) throws SSLException {
2728
super(uri);
2829

2930
if (uri.getScheme().equals(WSS_SCHEME)) {
@@ -51,27 +52,27 @@ public WebSocketClientWrapper(final URI uri, final WebSocketListener proxy) thro
5152
throw new SSLException(e);
5253
}
5354
}
54-
55-
this.proxy = proxy;
55+
this.webSocketListener = webSocketListener;
56+
setProxy(proxy);
5657
}
5758

5859
@Override
5960
public void onOpen(final ServerHandshake handshakedata) {
60-
proxy.onOpen(handshakedata);
61+
webSocketListener.onOpen(handshakedata);
6162
}
6263

6364
@Override
6465
public void onMessage(final String message) {
65-
proxy.onMessage(message);
66+
webSocketListener.onMessage(message);
6667
}
6768

6869
@Override
6970
public void onClose(final int code, final String reason, final boolean remote) {
70-
proxy.onClose(code, reason, remote);
71+
webSocketListener.onClose(code, reason, remote);
7172
}
7273

7374
@Override
7475
public void onError(final Exception ex) {
75-
proxy.onError(ex);
76+
webSocketListener.onError(ex);
7677
}
7778
}

src/main/java/com/pusher/client/connection/websocket/WebSocketConnection.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.pusher.client.connection.websocket;
22

3+
import java.net.Proxy;
34
import java.net.URI;
45
import java.net.URISyntaxException;
56
import java.util.HashMap;
@@ -34,15 +35,21 @@ public class WebSocketConnection implements InternalConnection, WebSocketListene
3435
private final ActivityTimer activityTimer;
3536
private final Map<ConnectionState, Set<ConnectionEventListener>> eventListeners = new HashMap<ConnectionState, Set<ConnectionEventListener>>();
3637
private final URI webSocketUri;
38+
private final Proxy proxy;
3739

3840
private volatile ConnectionState state = ConnectionState.DISCONNECTED;
3941
private WebSocketClient underlyingConnection;
4042
private String socketId;
4143

42-
public WebSocketConnection(final String url, final long activityTimeout, final long pongTimeout,
44+
public WebSocketConnection(
45+
final String url,
46+
final long activityTimeout,
47+
final long pongTimeout,
48+
final Proxy proxy,
4349
final Factory factory) throws URISyntaxException {
4450
webSocketUri = new URI(url);
4551
activityTimer = new ActivityTimer(activityTimeout, pongTimeout);
52+
this.proxy = proxy;
4653
this.factory = factory;
4754

4855
for (final ConnectionState state : ConnectionState.values()) {
@@ -55,13 +62,13 @@ public WebSocketConnection(final String url, final long activityTimeout, final l
5562
@Override
5663
public void connect() {
5764
factory.getEventQueue().execute(new Runnable() {
65+
5866
@Override
5967
public void run() {
6068
if (state == ConnectionState.DISCONNECTED) {
6169
try {
6270
underlyingConnection = factory
63-
.newWebSocketClientWrapper(webSocketUri, WebSocketConnection.this);
64-
71+
.newWebSocketClientWrapper(webSocketUri, proxy, WebSocketConnection.this);
6572
updateState(ConnectionState.CONNECTING);
6673
underlyingConnection.connect();
6774
}

src/main/java/com/pusher/client/util/Factory.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.pusher.client.util;
22

3+
import java.net.Proxy;
34
import java.net.URI;
45
import java.net.URISyntaxException;
56
import java.util.concurrent.ExecutorService;
@@ -54,7 +55,7 @@ public synchronized InternalConnection getConnection(final String apiKey, final
5455
if (connection == null) {
5556
try {
5657
connection = new WebSocketConnection(options.buildUrl(apiKey), options.getActivityTimeout(),
57-
options.getPongTimeout(), this);
58+
options.getPongTimeout(), options.getProxy(), this);
5859
}
5960
catch (final URISyntaxException e) {
6061
throw new IllegalArgumentException("Failed to initialise connection", e);
@@ -63,8 +64,8 @@ public synchronized InternalConnection getConnection(final String apiKey, final
6364
return connection;
6465
}
6566

66-
public WebSocketClient newWebSocketClientWrapper(final URI uri, final WebSocketListener proxy) throws SSLException {
67-
return new WebSocketClientWrapper(uri, proxy);
67+
public WebSocketClient newWebSocketClientWrapper(final URI uri, final Proxy proxy, final WebSocketListener webSocketListener) throws SSLException {
68+
return new WebSocketClientWrapper(uri, proxy, webSocketListener);
6869
}
6970

7071
public synchronized ExecutorService getEventQueue() {

src/test/java/com/pusher/client/EndToEndTest.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static org.mockito.Matchers.*;
44
import static org.mockito.Mockito.*;
55

6+
import java.net.Proxy;
67
import java.net.URI;
78

89
import org.java_websocket.handshake.ServerHandshake;
@@ -38,6 +39,7 @@ public class EndToEndTest {
3839
+ PRIVATE_CHANNEL_NAME + "\",\"auth\":\"" + AUTH_KEY + "\"}}";
3940
private static final long ACTIVITY_TIMEOUT = 120000;
4041
private static final long PONG_TIMEOUT = 120000;
42+
private static final Proxy proxy = Proxy.NO_PROXY;
4143

4244
private @Mock Authorizer mockAuthorizer;
4345
private @Mock ConnectionEventListener mockConnectionEventListener;
@@ -52,17 +54,18 @@ public class EndToEndTest {
5254
public void setUp() throws Exception {
5355
pusherOptions = new PusherOptions().setAuthorizer(mockAuthorizer).setEncrypted(false);
5456

55-
connection = new WebSocketConnection(pusherOptions.buildUrl(API_KEY), ACTIVITY_TIMEOUT, PONG_TIMEOUT, factory);
57+
connection = new WebSocketConnection(pusherOptions.buildUrl(API_KEY), ACTIVITY_TIMEOUT, PONG_TIMEOUT, proxy, factory);
5658

5759
when(factory.getEventQueue()).thenReturn(new InstantExecutor());
5860
when(factory.getTimers()).thenReturn(new DoNothingExecutor());
59-
when(factory.newWebSocketClientWrapper(any(URI.class), any(WebSocketListener.class))).thenAnswer(
61+
when(factory.newWebSocketClientWrapper(any(URI.class), any(Proxy.class), any(WebSocketListener.class))).thenAnswer(
6062
new Answer<WebSocketClientWrapper>() {
6163
@Override
6264
public WebSocketClientWrapper answer(final InvocationOnMock invocation) throws Throwable {
6365
final URI uri = (URI)invocation.getArguments()[0];
64-
final WebSocketListener proxy = (WebSocketListener)invocation.getArguments()[1];
65-
testWebsocket = new TestWebSocketClientWrapper(uri, proxy);
66+
final Proxy proxy = (Proxy)invocation.getArguments()[1];
67+
final WebSocketListener webSocketListener = (WebSocketListener)invocation.getArguments()[2];
68+
testWebsocket = new TestWebSocketClientWrapper(uri, proxy, webSocketListener);
6669
return testWebsocket;
6770
}
6871
});

src/test/java/com/pusher/client/PusherOptionsTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
import org.mockito.Mock;
99
import org.mockito.runners.MockitoJUnitRunner;
1010

11+
import java.net.InetAddress;
12+
import java.net.InetSocketAddress;
13+
import java.net.Proxy;
14+
1115
@RunWith(MockitoJUnitRunner.class)
1216
public class PusherOptionsTest {
1317

@@ -93,4 +97,17 @@ public void testCustomHostAndPortNonSSLURLIsCorrect() {
9397
assertEquals(pusherOptions.buildUrl(API_KEY), "ws://subdomain.example.com:8080/app/" + API_KEY
9498
+ "?client=java-client&protocol=5&version=" + PusherOptions.LIB_VERSION);
9599
}
100+
101+
@Test
102+
public void testSetProxy(){
103+
Proxy newProxy = new Proxy( Proxy.Type.HTTP, new InetSocketAddress( "proxyaddress", 80 ) );
104+
pusherOptions.setProxy(newProxy);
105+
assertEquals(pusherOptions.getProxy(), newProxy);
106+
}
107+
108+
@Test
109+
public void testGetProxyReturnDefaultProxy(){
110+
assertEquals(pusherOptions.getProxy(), Proxy.NO_PROXY);
111+
}
112+
96113
}

src/test/java/com/pusher/client/TestWebSocketClientWrapper.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static org.junit.Assert.*;
44

5+
import java.net.Proxy;
56
import java.net.URI;
67
import java.nio.channels.NotYetConnectedException;
78
import java.util.ArrayList;
@@ -17,8 +18,8 @@ public class TestWebSocketClientWrapper extends WebSocketClientWrapper {
1718
private final List<String> messagesSent = new ArrayList<String>();
1819
private boolean connectCalled = false;
1920

20-
public TestWebSocketClientWrapper(final URI uri, final WebSocketListener proxy) throws SSLException {
21-
super(uri, proxy);
21+
public TestWebSocketClientWrapper(final URI uri, final Proxy proxy, final WebSocketListener webSocketListener) throws SSLException {
22+
super(uri, proxy, webSocketListener);
2223
}
2324

2425
void assertConnectCalled() {

src/test/java/com/pusher/client/connection/websocket/WebSocketClientWrapperTest.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static org.mockito.Mockito.verify;
44

5+
import java.net.Proxy;
56
import java.net.URI;
67
import java.net.URISyntaxException;
78

@@ -18,36 +19,37 @@
1819
public class WebSocketClientWrapperTest {
1920

2021
private WebSocketClientWrapper wrapper;
21-
private @Mock WebSocketListener mockProxy;
22+
private @Mock WebSocketListener mockListener;
2223
private @Mock ServerHandshake mockHandshake;
24+
private Proxy mockProxy = Proxy.NO_PROXY;
2325

2426
@Before
2527
public void setUp() throws URISyntaxException, SSLException {
26-
wrapper = new WebSocketClientWrapper(new URI("http://www.test.com"), mockProxy);
28+
wrapper = new WebSocketClientWrapper(new URI("http://www.test.com"), mockProxy, mockListener);
2729
}
2830

2931
@Test
30-
public void testOnOpenCallIsDelegatedToTheProxy() {
32+
public void testOnOpenCallIsDelegatedToTheListener() {
3133
wrapper.onOpen(mockHandshake);
32-
verify(mockProxy).onOpen(mockHandshake);
34+
verify(mockListener).onOpen(mockHandshake);
3335
}
3436

3537
@Test
36-
public void testOnMessageIsDelegatedToTheProxy() {
38+
public void testOnMessageIsDelegatedToTheListener() {
3739
wrapper.onMessage("hello");
38-
verify(mockProxy).onMessage("hello");
40+
verify(mockListener).onMessage("hello");
3941
}
4042

4143
@Test
42-
public void testOnCloseIsDelegatedToTheProxy() {
44+
public void testOnCloseIsDelegatedToTheListener() {
4345
wrapper.onClose(1, "reason", true);
44-
verify(mockProxy).onClose(1, "reason", true);
46+
verify(mockListener).onClose(1, "reason", true);
4547
}
4648

4749
@Test
48-
public void testOnErrorIsDelegatedToTheProxy() {
50+
public void testOnErrorIsDelegatedToTheListener() {
4951
final Exception e = new Exception();
5052
wrapper.onError(e);
51-
verify(mockProxy).onError(e);
53+
verify(mockListener).onError(e);
5254
}
5355
}

src/test/java/com/pusher/client/connection/websocket/WebSocketConnectionTest.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import static org.mockito.Matchers.*;
55
import static org.mockito.Mockito.*;
66

7+
import java.net.InetSocketAddress;
8+
import java.net.Proxy;
79
import java.net.URI;
810
import java.net.URISyntaxException;
911

@@ -33,6 +35,7 @@ public class WebSocketConnectionTest {
3335
private static final String CONN_ESTABLISHED_EVENT = "{\"event\":\"pusher:connection_established\",\"data\":\"{\\\"socket_id\\\":\\\"21112.816204\\\"}\"}";
3436
private static final String INCOMING_MESSAGE = "{\"event\":\"" + EVENT_NAME
3537
+ "\",\"channel\":\"my-channel\",\"data\":{\"fish\":\"chips\"}}";
38+
private static final Proxy PROXY = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxyaddress", 80));
3639

3740
@Mock
3841
private ChannelManager mockChannelManager;
@@ -48,27 +51,27 @@ public class WebSocketConnectionTest {
4851
@Before
4952
public void setUp() throws URISyntaxException, SSLException {
5053
when(factory.getChannelManager()).thenReturn(mockChannelManager);
51-
when(factory.newWebSocketClientWrapper(any(URI.class), any(WebSocketConnection.class))).thenReturn(
54+
when(factory.newWebSocketClientWrapper(any(URI.class), any(Proxy.class), any(WebSocketConnection.class))).thenReturn(
5255
mockUnderlyingConnection);
5356
when(factory.getEventQueue()).thenReturn(new InstantExecutor());
5457
when(factory.getTimers()).thenReturn(new DoNothingExecutor());
5558

56-
connection = new WebSocketConnection(URL, ACTIVITY_TIMEOUT, PONG_TIMEOUT, factory);
59+
connection = new WebSocketConnection(URL, ACTIVITY_TIMEOUT, PONG_TIMEOUT, PROXY, factory);
5760
connection.bind(ConnectionState.ALL, mockEventListener);
5861
}
5962

6063
@Test
6164
public void testUnbindingWhenNotAlreadyBoundReturnsFalse() throws URISyntaxException {
6265
final ConnectionEventListener listener = mock(ConnectionEventListener.class);
63-
final WebSocketConnection connection = new WebSocketConnection(URL, ACTIVITY_TIMEOUT, PONG_TIMEOUT, factory);
66+
final WebSocketConnection connection = new WebSocketConnection(URL, ACTIVITY_TIMEOUT, PONG_TIMEOUT, PROXY, factory);
6467
final boolean unbound = connection.unbind(ConnectionState.ALL, listener);
6568
assertEquals(false, unbound);
6669
}
6770

6871
@Test
6972
public void testUnbindingWhenBoundReturnsTrue() throws URISyntaxException {
7073
final ConnectionEventListener listener = mock(ConnectionEventListener.class);
71-
final WebSocketConnection connection = new WebSocketConnection(URL, ACTIVITY_TIMEOUT, PONG_TIMEOUT, factory);
74+
final WebSocketConnection connection = new WebSocketConnection(URL, ACTIVITY_TIMEOUT, PONG_TIMEOUT, PROXY, factory);
7275

7376
connection.bind(ConnectionState.ALL, listener);
7477

@@ -106,7 +109,7 @@ public void testConnectDoesNotCallConnectOnUnderlyingConnectionIfAlreadyInConnec
106109

107110
@Test
108111
public void testListenerDoesNotReceiveConnectingEventIfItIsOnlyBoundToTheConnectedEvent() throws URISyntaxException {
109-
connection = new WebSocketConnection(URL, ACTIVITY_TIMEOUT, PONG_TIMEOUT, factory);
112+
connection = new WebSocketConnection(URL, ACTIVITY_TIMEOUT, PONG_TIMEOUT, PROXY, factory);
110113
connection.bind(ConnectionState.CONNECTED, mockEventListener);
111114
connection.connect();
112115

@@ -199,7 +202,7 @@ public void testOnCloseCallbackUpdatesStateToDisconnected() {
199202

200203
@Test
201204
public void testOnCloseCallbackDoesNotCallListenerIfItIsNotBoundToDisconnectedEvent() throws URISyntaxException {
202-
connection = new WebSocketConnection(URL, ACTIVITY_TIMEOUT, PONG_TIMEOUT, factory);
205+
connection = new WebSocketConnection(URL, ACTIVITY_TIMEOUT, PONG_TIMEOUT, PROXY, factory);
203206
connection.bind(ConnectionState.CONNECTED, mockEventListener);
204207

205208
connection.connect();

0 commit comments

Comments
 (0)