22
33import java .io .IOException ;
44import java .net .InetSocketAddress ;
5- import java .net .Socket ;
65import java .net .URI ;
76import java .nio .ByteBuffer ;
87import java .nio .channels .ByteChannel ;
1211import java .nio .channels .SelectionKey ;
1312import java .nio .channels .SocketChannel ;
1413import java .nio .channels .spi .SelectorProvider ;
15- import java .util .List ;
1614import java .util .Map ;
1715import java .util .concurrent .CountDownLatch ;
1816
@@ -46,7 +44,7 @@ public abstract class WebSocketClient extends WebSocketAdapter implements Runnab
4644 /**
4745 * The URI this channel is supposed to connect to.
4846 */
49- private URI uri = null ;
47+ protected URI uri = null ;
5048
5149 private WebSocketImpl conn = null ;
5250 /**
@@ -70,24 +68,9 @@ public abstract class WebSocketClient extends WebSocketAdapter implements Runnab
7068
7169 private int timeout = 0 ;
7270
73- WebSocketClientFactory wsfactory = new WebSocketClientFactory () {
74- @ Override
75- public WebSocket createWebSocket ( WebSocketAdapter a , Draft d , Socket s ) {
76- return new WebSocketImpl ( WebSocketClient .this , d );
77- }
71+ private WebSocketClientFactory wsfactory = new DefaultWebSocketClientFactory ( this );
7872
79- @ Override
80- public WebSocket createWebSocket ( WebSocketAdapter a , List <Draft > d , Socket s ) {
81- return new WebSocketImpl ( WebSocketClient .this , d );
82- }
83-
84- @ Override
85- public ByteChannel wrapChannel ( SocketChannel channel , SelectionKey c , String host , int port ) {
86- if ( c == null )
87- return channel ;
88- return channel ;
89- }
90- };
73+ private InetSocketAddress proxyAddress = null ;
9174
9275 public WebSocketClient ( URI serverURI ) {
9376 this ( serverURI , new Draft_10 () );
@@ -198,12 +181,6 @@ public void send( byte[] data ) throws NotYetConnectedException {
198181 conn .send ( data );
199182 }
200183
201- private void tryToConnect ( InetSocketAddress remote ) throws IOException , InvalidHandshakeException {
202-
203- channel .connect ( remote );
204-
205- }
206-
207184 // Runnable IMPLEMENTATION /////////////////////////////////////////////////
208185 public void run () {
209186 if ( writethread == null )
@@ -220,10 +197,19 @@ private final void interruptableRun() {
220197 }
221198
222199 try {
223- String host = uri .getHost ();
224- int port = getPort ();
225- tryToConnect ( new InetSocketAddress ( host , port ) );
226- conn .channel = wrappedchannel = wsfactory .wrapChannel ( channel , null , host , port );
200+ String host ;
201+ int port ;
202+
203+ if ( proxyAddress != null ) {
204+ host = proxyAddress .getHostName ();
205+ port = proxyAddress .getPort ();
206+ } else {
207+ host = uri .getHost ();
208+ port = getPort ();
209+ }
210+ channel .connect ( new InetSocketAddress ( host , port ) );
211+ conn .channel = wrappedchannel = createProxyChannel ( wsfactory .wrapChannel ( channel , null , host , port ) );
212+
227213 timeout = 0 ; // since connect is over
228214 sendHandshake ();
229215 readthread = new Thread ( new WebsocketWriteThread () );
@@ -420,6 +406,26 @@ public InetSocketAddress getRemoteSocketAddress( WebSocket conn ) {
420406 public void onMessage ( ByteBuffer bytes ) {
421407 };
422408
409+ public class DefaultClientProxyChannel extends AbstractClientProxyChannel {
410+ public DefaultClientProxyChannel ( ByteChannel towrap ) {
411+ super ( towrap );
412+ }
413+ @ Override
414+ public String buildHandShake () {
415+ StringBuilder b = new StringBuilder ();
416+ String host = uri .getHost ();
417+ b .append ( "CONNECT " );
418+ b .append ( host );
419+ b .append ( ":" );
420+ b .append ( getPort () );
421+ b .append ( " HTTP/1.1\n " );
422+ b .append ( "Host: " );
423+ b .append ( host );
424+ b .append ( "\n " );
425+ return b .toString ();
426+ }
427+ }
428+
423429 public interface WebSocketClientFactory extends WebSocketFactory {
424430 public ByteChannel wrapChannel ( SocketChannel channel , SelectionKey key , String host , int port ) throws IOException ;
425431 }
@@ -439,4 +445,15 @@ public void run() {
439445 }
440446 }
441447 }
448+
449+ public ByteChannel createProxyChannel ( ByteChannel towrap ) {
450+ if ( proxyAddress != null ){
451+ return new DefaultClientProxyChannel ( towrap );
452+ }
453+ return towrap ;//no proxy in use
454+ }
455+
456+ public void setProxy ( InetSocketAddress proxyaddress ) {
457+ proxyAddress = proxyaddress ;
458+ }
442459}
0 commit comments