Skip to content

Commit 3128285

Browse files
committed
made SSLSocketChannel2 also work on SocketChannels in blocking mode and therefore"generalized" WebSocketServerFactory and WebSocketClientFactory
1 parent c89323b commit 3128285

File tree

5 files changed

+57
-18
lines changed

5 files changed

+57
-18
lines changed

src/main/java/org/java_websocket/SSLSocketChannel2.java

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.util.ArrayList;
1717
import java.util.Iterator;
1818
import java.util.List;
19+
import java.util.concurrent.ExecutionException;
1920
import java.util.concurrent.ExecutorService;
2021
import java.util.concurrent.Future;
2122

@@ -48,16 +49,20 @@ public class SSLSocketChannel2 implements ByteChannel, WrappedByteChannel {
4849

4950
protected SSLEngineResult res;
5051
protected SSLEngine sslEngine;
52+
protected final boolean isblocking;
53+
54+
public SSLSocketChannel2( SocketChannel channel , SSLEngine sslEngine , ExecutorService exec , SelectionKey key ) throws IOException {
55+
this.sc = channel;
5156

52-
public SSLSocketChannel2( SelectionKey key , SSLEngine sslEngine , ExecutorService exec ) throws IOException {
53-
this.sc = (SocketChannel) key.channel();
54-
this.key = key;
5557
this.sslEngine = sslEngine;
5658
this.exec = exec;
5759

5860
tasks = new ArrayList<Future<?>>( 3 );
59-
60-
this.key.interestOps( key.interestOps() | SelectionKey.OP_WRITE );
61+
if( key != null ) {
62+
key.interestOps( key.interestOps() | SelectionKey.OP_WRITE );
63+
this.key = key;
64+
}
65+
isblocking = channel.isBlocking();
6166

6267
sslEngine.setEnableSessionCreation( true );
6368
SSLSession session = sslEngine.getSession();
@@ -67,14 +72,34 @@ public SSLSocketChannel2( SelectionKey key , SSLEngine sslEngine , ExecutorServi
6772
processHandshake();
6873
}
6974

70-
private void processHandshake() throws IOException {
75+
private void consumeFutureUninterruptible( Future<?> f ) {
76+
try {
77+
boolean interrupted = false;
78+
while ( true ) {
79+
try {
80+
f.get();
81+
break;
82+
} catch ( InterruptedException e ) {
83+
interrupted = true;
84+
}
85+
}
86+
if( interrupted )
87+
Thread.currentThread().interrupt();
88+
} catch ( ExecutionException e ) {
89+
throw new RuntimeException( e );
90+
}
91+
}
92+
93+
private synchronized void processHandshake() throws IOException {
7194
if( !tasks.isEmpty() ) {
7295
Iterator<Future<?>> it = tasks.iterator();
7396
while ( it.hasNext() ) {
7497
Future<?> f = it.next();
7598
if( f.isDone() ) {
7699
it.remove();
77100
} else {
101+
if( isBlocking() )
102+
consumeFutureUninterruptible( f );
78103
return;
79104
}
80105
}
@@ -106,11 +131,11 @@ private synchronized ByteBuffer wrap( ByteBuffer b ) throws SSLException {
106131

107132
private synchronized ByteBuffer unwrap() throws SSLException {
108133
int rem;
109-
do{
134+
do {
110135
rem = inData.remaining();
111136
res = sslEngine.unwrap( inCrypt, inData );
112137
} while ( rem != inData.remaining() );
113-
138+
114139
inData.flip();
115140
return inData;
116141
}
@@ -146,9 +171,17 @@ public int write( ByteBuffer src ) throws IOException {
146171
}
147172

148173
public int read( ByteBuffer dst ) throws IOException {
149-
if( !isHandShakeComplete() ) {
150-
processHandshake();
174+
if( !dst.hasRemaining() )
151175
return 0;
176+
if( isBlocking() ) {
177+
while ( !isHandShakeComplete() ) {
178+
processHandshake();
179+
}
180+
} else {
181+
processHandshake();
182+
if( !isHandShakeComplete() ) {
183+
return 0;
184+
}
152185
}
153186

154187
int purged = readRemaining( dst );
@@ -173,8 +206,6 @@ public int read( ByteBuffer dst ) throws IOException {
173206
}
174207

175208
private int readRemaining( ByteBuffer dst ) throws SSLException {
176-
assert ( dst.hasRemaining() );
177-
178209
if( inData.hasRemaining() ) {
179210
return transfereTo( inData, dst );
180211
}
@@ -269,4 +300,9 @@ private int transfereTo( ByteBuffer from, ByteBuffer to ) {
269300

270301
}
271302

303+
@Override
304+
public boolean isBlocking() {
305+
return isblocking;
306+
}
307+
272308
}

src/main/java/org/java_websocket/WrappedByteChannel.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ public interface WrappedByteChannel extends ByteChannel {
1212

1313
public boolean isNeedRead();
1414
public int readMore( ByteBuffer dst ) throws SSLException;
15+
public boolean isBlocking();
1516
}

src/main/java/org/java_websocket/client/DefaultSSLWebSocketClientFactory.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.net.Socket;
44
import java.nio.channels.ByteChannel;
55
import java.nio.channels.SelectionKey;
6+
import java.nio.channels.SocketChannel;
67
import java.util.List;
78
import java.util.concurrent.ExecutorService;
89
import java.util.concurrent.Executors;
@@ -33,10 +34,10 @@ public DefaultSSLWebSocketClientFactory( SSLContext sslContext , ExecutorService
3334
}
3435

3536
@Override
36-
public ByteChannel wrapChannel( SelectionKey c, String host, int port ) throws IOException {
37+
public ByteChannel wrapChannel( SocketChannel channel, SelectionKey key, String host, int port ) throws IOException {
3738
SSLEngine e = sslcontext.createSSLEngine( host, port );
3839
e.setUseClientMode( true );
39-
return new SSLSocketChannel2( c, e, exec );
40+
return new SSLSocketChannel2( channel, e, exec, key );
4041
}
4142

4243
@Override

src/main/java/org/java_websocket/server/DefaultSSLWebSocketServerFactory.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.net.Socket;
44
import java.nio.channels.ByteChannel;
55
import java.nio.channels.SelectionKey;
6+
import java.nio.channels.SocketChannel;
67
import java.util.List;
78
import java.util.concurrent.ExecutorService;
89
import java.util.concurrent.Executors;
@@ -32,10 +33,10 @@ public DefaultSSLWebSocketServerFactory( SSLContext sslContext , ExecutorService
3233
}
3334

3435
@Override
35-
public ByteChannel wrapChannel( SelectionKey c ) throws IOException {
36+
public ByteChannel wrapChannel( SocketChannel channel, SelectionKey key ) throws IOException {
3637
SSLEngine e = sslcontext.createSSLEngine();
3738
e.setUseClientMode( false );
38-
return new SSLSocketChannel2( c, e, exec );
39+
return new SSLSocketChannel2( channel, e, exec, key );
3940
}
4041

4142
@Override

src/main/java/org/java_websocket/server/DefaultWebSocketServerFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public WebSocketImpl createWebSocket( WebSocketAdapter a, List<Draft> d, Socket
2020
return new WebSocketImpl( a, d, s );
2121
}
2222
@Override
23-
public SocketChannel wrapChannel( SelectionKey c ) {
24-
return (SocketChannel) c.channel();
23+
public SocketChannel wrapChannel( SocketChannel channel, SelectionKey key ) {
24+
return (SocketChannel) channel;
2525
}
2626
}

0 commit comments

Comments
 (0)