Skip to content

Commit 38d184b

Browse files
committed
Fix for leaking WsSession in server container
1 parent 46b3129 commit 38d184b

File tree

12 files changed

+40
-42
lines changed

12 files changed

+40
-42
lines changed

client/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<parent>
44
<groupId>org.red5</groupId>
55
<artifactId>red5-parent</artifactId>
6-
<version>1.3.36</version>
6+
<version>1.3.37</version>
77
</parent>
88
<modelVersion>4.0.0</modelVersion>
99
<artifactId>red5-client</artifactId>

client/src/main/java/org/red5/client/Red5Client.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public final class Red5Client {
1818
/**
1919
* Current server version with revision
2020
*/
21-
public static final String VERSION = "Red5 Client 1.3.36";
21+
public static final String VERSION = "Red5 Client 1.3.37";
2222

2323
/**
2424
* Create a new Red5Client object using the connection local to the current thread A bit of magic that lets you access the red5 scope

common/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<parent>
44
<groupId>org.red5</groupId>
55
<artifactId>red5-parent</artifactId>
6-
<version>1.3.36</version>
6+
<version>1.3.37</version>
77
</parent>
88
<modelVersion>4.0.0</modelVersion>
99
<artifactId>red5-server-common</artifactId>
@@ -105,7 +105,7 @@
105105
<dependency>
106106
<groupId>net.engio</groupId>
107107
<artifactId>mbassador</artifactId>
108-
<version>1.3.36</version>
108+
<version>1.3.37</version>
109109
</dependency> -->
110110
<dependency>
111111
<groupId>junit</groupId>

common/src/main/java/org/red5/server/api/Red5.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public final class Red5 {
5757
/**
5858
* Server version with revision
5959
*/
60-
public static final String VERSION = "Red5 Server 1.3.36";
60+
public static final String VERSION = "Red5 Server 1.3.37";
6161

6262
/**
6363
* Server version for fmsVer requests

io/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<parent>
44
<groupId>org.red5</groupId>
55
<artifactId>red5-parent</artifactId>
6-
<version>1.3.36</version>
6+
<version>1.3.37</version>
77
</parent>
88
<modelVersion>4.0.0</modelVersion>
99
<artifactId>red5-io</artifactId>

io/src/main/java/org/red5/io/utils/TlsUtils.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,8 @@
2222
@SuppressWarnings({ "rawtypes", "unchecked" })
2323
public class TlsUtils {
2424

25-
private static byte[] DOWNGRADE_TLS11 = Hex.decodeStrict("444F574E47524400");
26-
27-
private static byte[] DOWNGRADE_TLS12 = Hex.decodeStrict("444F574E47524401");
25+
@SuppressWarnings("unused")
26+
private static byte[] DOWNGRADE_TLS11 = Hex.decodeStrict("444F574E47524400"), DOWNGRADE_TLS12 = Hex.decodeStrict("444F574E47524401");
2827

2928
public static final byte[] EMPTY_BYTES = new byte[0];
3029

@@ -608,15 +607,16 @@ public static int[] readUint16Array(int count, InputStream input) throws IOExcep
608607
}
609608

610609
public static ASN1Primitive readASN1Object(byte[] encoding) throws IOException {
611-
ASN1InputStream asn1 = new ASN1InputStream(encoding);
612-
ASN1Primitive result = asn1.readObject();
613-
if (null == result) {
614-
throw new IOException("AlertDescription.decode_error");
615-
}
616-
if (null != asn1.readObject()) {
617-
throw new IOException("AlertDescription.decode_error");
610+
try (ASN1InputStream asn1 = new ASN1InputStream(encoding)) {
611+
ASN1Primitive result = asn1.readObject();
612+
if (null == result) {
613+
throw new IOException("AlertDescription.decode_error");
614+
}
615+
if (null != asn1.readObject()) {
616+
throw new IOException("AlertDescription.decode_error");
617+
}
618+
return result;
618619
}
619-
return result;
620620
}
621621

622622
/** @deprecated Will be removed. Use readASN1Object in combination with requireDEREncoding instead */
@@ -739,6 +739,7 @@ static byte[] concat(byte[] a, byte[] b) {
739739
return c;
740740
}
741741

742+
@SuppressWarnings("unused")
742743
private static byte[] getCertificateVerifyHeader(String contextString) {
743744
int count = contextString.length();
744745
byte[] header = new byte[64 + count + 1];

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
<name>Red5</name>
2525
<description>The Red5 server</description>
2626
<groupId>org.red5</groupId>
27-
<version>1.3.36</version>
27+
<version>1.3.37</version>
2828
<url>https://github.com/Red5/red5-server</url>
2929
<inceptionYear>2005</inceptionYear>
3030
<organization>

server/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<parent>
44
<groupId>org.red5</groupId>
55
<artifactId>red5-parent</artifactId>
6-
<version>1.3.36</version>
6+
<version>1.3.37</version>
77
</parent>
88
<modelVersion>4.0.0</modelVersion>
99
<artifactId>red5-server</artifactId>

server/src/main/java/org/red5/net/websocket/WebSocketConnection.java

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public class WebSocketConnection extends AttributeStore implements Comparable<We
6363
private AtomicBoolean connected = new AtomicBoolean(false);
6464

6565
// associated websocket session
66-
private WeakReference<WsSession> wsSession;
66+
private final WsSession wsSession;
6767

6868
private WeakReference<WebSocketScope> scope;
6969

@@ -114,9 +114,9 @@ public WebSocketConnection(WebSocketScope scope, Session session) {
114114
log.debug("path: {}", path);
115115
}
116116
// cast ws session
117-
this.wsSession = new WeakReference<>((WsSession) session);
117+
this.wsSession = (WsSession) session;
118118
if (isDebug) {
119-
log.debug("ws session: {}", wsSession.get());
119+
log.debug("ws session: {}", wsSession);
120120
}
121121
// the websocket session id will be used for hash code comparison, its the only usable value currently
122122
wsSessionId = session.getId();
@@ -186,7 +186,7 @@ public void send(String data) throws UnsupportedEncodingException, IOException {
186186
}
187187
// process the incoming string
188188
if (StringUtils.isNotBlank(data)) {
189-
final WsSession session = wsSession.get();
189+
final WsSession session = wsSession;
190190
// attempt send only if the session is not closed
191191
if (session != null && !session.isClosed()) {
192192
try {
@@ -236,7 +236,7 @@ public void send(byte[] buf) throws IOException {
236236
if (isDebug) {
237237
log.debug("send binary: {}", Arrays.toString(buf));
238238
}
239-
WsSession session = wsSession.get();
239+
WsSession session = wsSession;
240240
if (session != null && session.isOpen()) {
241241
try {
242242
// send the bytes
@@ -281,7 +281,7 @@ public void sendPing(byte[] buf) throws IllegalArgumentException, IOException {
281281
if (isTrace) {
282282
log.trace("send ping: {}", buf);
283283
}
284-
WsSession session = wsSession.get();
284+
WsSession session = wsSession;
285285
if (session != null && session.isOpen()) {
286286
synchronized (wsSessionId) {
287287
// send the bytes
@@ -305,7 +305,7 @@ public void sendPong(byte[] buf) throws IllegalArgumentException, IOException {
305305
if (isTrace) {
306306
log.trace("send pong: {}", buf);
307307
}
308-
WsSession session = wsSession.get();
308+
WsSession session = wsSession;
309309
if (session != null && session.isOpen()) {
310310
synchronized (wsSessionId) {
311311
// send the bytes
@@ -324,15 +324,11 @@ public void sendPong(byte[] buf) throws IllegalArgumentException, IOException {
324324
public void close() {
325325
if (connected.compareAndSet(true, false)) {
326326
log.debug("close: {}", wsSessionId);
327-
WsSession session = wsSession != null ? wsSession.get() : null;
328-
// session has to be open, or user props cannot be retrieved
329-
if (session != null && session.isOpen()) {
330-
// trying to close the session nicely
331-
try {
332-
session.close();
333-
} catch (Exception e) {
334-
log.debug("Exception closing session", e);
335-
}
327+
// trying to close the session nicely
328+
try {
329+
wsSession.close();
330+
} catch (Exception e) {
331+
log.debug("Exception closing session", e);
336332
}
337333
// clean up our props
338334
attributes.clear();
@@ -351,7 +347,6 @@ public void close() {
351347
// disconnect from scope
352348
scope.get().removeConnection(this);
353349
// clear weak refs
354-
wsSession.clear();
355350
scope.clear();
356351
}
357352
}
@@ -369,7 +364,7 @@ public void timeoutAsync(long now) {
369364
// XXX(paul) only logging here as we should more than likely rely upon the container checking expiration
370365
log.trace("timeoutAsync: {} on session id: {} read: {} written: {}", now, wsSessionId, readBytes, writtenBytes);
371366
/*
372-
WsSession session = wsSession.get();
367+
WsSession session = wsSession;
373368
Map<String, Object> props = session.getUserProperties();
374369
log.debug("Session properties: {}", props);
375370
long maxIdleTimeout = session.getMaxIdleTimeout();
@@ -453,7 +448,7 @@ public void setOrigin(String origin) {
453448
* @return true if secure and false if unsecure or unconnected
454449
*/
455450
public boolean isSecure() {
456-
Optional<WsSession> opt = Optional.ofNullable(wsSession.get());
451+
Optional<WsSession> opt = Optional.ofNullable(wsSession);
457452
if (opt.isPresent()) {
458453
return (opt.get().isOpen() ? opt.get().isSecure() : false);
459454
}
@@ -672,12 +667,12 @@ public Object getUserProperty(String key) {
672667

673668
public void setWsSessionTimeout(long idleTimeout) {
674669
if (wsSession != null) {
675-
wsSession.get().setMaxIdleTimeout(idleTimeout);
670+
wsSession.setMaxIdleTimeout(idleTimeout);
676671
}
677672
}
678673

679674
public WsSession getWsSession() {
680-
return wsSession != null ? wsSession.get() : null;
675+
return wsSession != null ? wsSession : null;
681676
}
682677

683678
public long getReadBytes() {

server/src/main/java/org/red5/net/websocket/WebSocketScopeManager.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ public boolean addWebSocketScope(WebSocketScope webSocketScope) {
181181
log.debug("Removing unconnected connection: {} during ping loop", wsConn.getSessionId());
182182
// if the connection isn't connected, remove them
183183
wsScope.removeConnection(wsConn);
184+
// if connection is not connected, close it (ensure closed / removed)
185+
wsConn.close();
184186
}
185187
} catch (Exception e) {
186188
log.warn("Exception in WS pinger", e);

0 commit comments

Comments
 (0)