diff options
Diffstat (limited to 'src/com/isode/stroke/session')
-rw-r--r-- | src/com/isode/stroke/session/BasicSessionStream.java | 73 | ||||
-rw-r--r-- | src/com/isode/stroke/session/Session.java | 59 | ||||
-rw-r--r-- | src/com/isode/stroke/session/SessionStream.java | 20 |
3 files changed, 105 insertions, 47 deletions
diff --git a/src/com/isode/stroke/session/BasicSessionStream.java b/src/com/isode/stroke/session/BasicSessionStream.java index 9ba862d..4048363 100644 --- a/src/com/isode/stroke/session/BasicSessionStream.java +++ b/src/com/isode/stroke/session/BasicSessionStream.java @@ -20,6 +20,7 @@ import com.isode.stroke.parser.PayloadParserFactoryCollection; import com.isode.stroke.serializer.PayloadSerializerCollection; import com.isode.stroke.signals.Slot; import com.isode.stroke.signals.Slot1; +import com.isode.stroke.signals.SignalConnection; import com.isode.stroke.streamstack.CompressionLayer; import com.isode.stroke.streamstack.ConnectionLayer; import com.isode.stroke.streamstack.StreamStack; @@ -29,6 +30,8 @@ import com.isode.stroke.streamstack.XMPPLayer; import com.isode.stroke.tls.Certificate; import com.isode.stroke.tls.CertificateVerificationError; import com.isode.stroke.tls.TLSContextFactory; +import com.isode.stroke.tls.TLSOptions; +import com.isode.stroke.tls.TLSError; public class BasicSessionStream extends SessionStream { @@ -38,7 +41,8 @@ public class BasicSessionStream extends SessionStream { PayloadParserFactoryCollection payloadParserFactories, PayloadSerializerCollection payloadSerializers, TLSContextFactory tlsContextFactory, - TimerFactory timerFactory) { + TimerFactory timerFactory, + TLSOptions tlsOptions) { available = false; this.connection = connection; this.payloadParserFactories = payloadParserFactories; @@ -52,40 +56,40 @@ public class BasicSessionStream extends SessionStream { this.compressionLayer = null; this.tlsLayer = null; this.whitespacePingLayer = null; - + this.tlsOptions_ = tlsOptions; xmppLayer = new XMPPLayer(payloadParserFactories, payloadSerializers, streamType); - xmppLayer.onStreamStart.connect(new Slot1<ProtocolHeader>() { + onStreamStartConnection = xmppLayer.onStreamStart.connect(new Slot1<ProtocolHeader>() { public void call(ProtocolHeader p1) { handleStreamStartReceived(p1); } }); - xmppLayer.onElement.connect(new Slot1<Element>() { + onElementConnection = xmppLayer.onElement.connect(new Slot1<Element>() { public void call(Element p1) { handleElementReceived(p1); } }); - xmppLayer.onError.connect(new Slot() { + onErrorConnection = xmppLayer.onError.connect(new Slot() { public void call() { handleXMPPError(); } }); - xmppLayer.onDataRead.connect(new Slot1<SafeByteArray>() { + onDataReadConnection = xmppLayer.onDataRead.connect(new Slot1<SafeByteArray>() { public void call(SafeByteArray p1) { handleDataRead(p1); } }); - xmppLayer.onWriteData.connect(new Slot1<SafeByteArray>() { + onWriteDataConnection = xmppLayer.onWriteData.connect(new Slot1<SafeByteArray>() { public void call(SafeByteArray p1) { handleDataWritten(p1); } }); - connection.onDisconnected.connect(new Slot1<Connection.Error>() { + onDisconnectedConnection = connection.onDisconnected.connect(new Slot1<Connection.Error>() { public void call(Connection.Error p1) { handleConnectionFinished(p1); @@ -99,6 +103,28 @@ public class BasicSessionStream extends SessionStream { } + /** + * User will have to call disconnect() method to free up the resources. + */ + @Override + public void disconnect() { + if(tlsLayer != null) { + onErrorConnection.disconnect(); + onConnectedConnection.disconnect(); + tlsLayer = null; + } + whitespacePingLayer = null; + streamStack = null; + onDisconnectedConnection.disconnect(); + connectionLayer = null; + onStreamStartConnection.disconnect(); + onElementConnection.disconnect(); + onErrorConnection.disconnect(); + onDataReadConnection.disconnect(); + onWriteDataConnection.disconnect(); + xmppLayer = null; + } + public void writeHeader(ProtocolHeader header) { assert available; xmppLayer.writeHeader(header); @@ -133,18 +159,18 @@ public class BasicSessionStream extends SessionStream { public void addTLSEncryption() { assert available; - tlsLayer = new TLSLayer(tlsContextFactory); + tlsLayer = new TLSLayer(tlsContextFactory, tlsOptions_); if (hasTLSCertificate() && !tlsLayer.setClientCertificate(getTLSCertificate())) { - onClosed.emit(new Error(Error.Type.InvalidTLSCertificateError)); + onClosed.emit(new SessionStreamError(SessionStreamError.Type.InvalidTLSCertificateError)); } else { streamStack.addLayer(tlsLayer); - tlsLayer.onError.connect(new Slot() { + onErrorConnection = tlsLayer.onError.connect(new Slot1<TLSError>() { - public void call() { - handleTLSError(); + public void call(TLSError e) { + handleTLSError(e); } }); - tlsLayer.onConnected.connect(new Slot() { + onConnectedConnection = tlsLayer.onConnected.connect(new Slot() { public void call() { handleTLSConnected(); @@ -211,25 +237,25 @@ public class BasicSessionStream extends SessionStream { private void handleXMPPError() { available = false; - onClosed.emit(new Error(Error.Type.ParseError)); + onClosed.emit(new SessionStreamError(SessionStreamError.Type.ParseError)); } private void handleTLSConnected() { onTLSEncrypted.emit(); } - private void handleTLSError() { + private void handleTLSError(TLSError error) { available = false; - onClosed.emit(new Error(Error.Type.TLSError)); + onClosed.emit(error); } private void handleConnectionFinished(Connection.Error error) { available = false; if (Connection.Error.ReadError.equals(error)) { - onClosed.emit(new Error(Error.Type.ConnectionReadError)); + onClosed.emit(new SessionStreamError(SessionStreamError.Type.ConnectionReadError)); } else if (error != null) { - onClosed.emit(new Error(Error.Type.ConnectionWriteError)); + onClosed.emit(new SessionStreamError(SessionStreamError.Type.ConnectionWriteError)); } else { onClosed.emit(null); @@ -262,5 +288,12 @@ public class BasicSessionStream extends SessionStream { private TLSLayer tlsLayer; private WhitespacePingLayer whitespacePingLayer; private StreamStack streamStack; - + private TLSOptions tlsOptions_; + private SignalConnection onErrorConnection; + private SignalConnection onConnectedConnection; + private SignalConnection onDisconnectedConnection; + private SignalConnection onStreamStartConnection; + private SignalConnection onElementConnection; + private SignalConnection onDataReadConnection; + private SignalConnection onWriteDataConnection; } diff --git a/src/com/isode/stroke/session/Session.java b/src/com/isode/stroke/session/Session.java index 815be02..0255627 100644 --- a/src/com/isode/stroke/session/Session.java +++ b/src/com/isode/stroke/session/Session.java @@ -22,6 +22,7 @@ import com.isode.stroke.serializer.PayloadSerializerCollection; import com.isode.stroke.signals.Signal1; import com.isode.stroke.signals.Slot; import com.isode.stroke.signals.Slot1; +import com.isode.stroke.signals.SignalConnection; import com.isode.stroke.streamstack.ConnectionLayer; import com.isode.stroke.streamstack.StreamStack; import com.isode.stroke.streamstack.XMPPLayer; @@ -46,27 +47,31 @@ public abstract class Session { public Session( final Connection connection, final PayloadParserFactoryCollection payloadParserFactories, - final PayloadSerializerCollection payloadSerializers, - final EventLoop eventLoop) { + final PayloadSerializerCollection payloadSerializers) { this.connection = connection; - this.eventLoop = eventLoop; this.payloadParserFactories = payloadParserFactories; this.payloadSerializers = payloadSerializers; + xmppLayer = null; + connectionLayer = null; + streamStack = null; finishing = false; } public void startSession() { initializeStreamStack(); - handleSessionStarted(); + handleSessionStarted(); } public void finishSession() { + if (finishing) { + return; + } finishing = true; - connection.disconnect(); - handleSessionFinished(null); - finishing = false; - onSessionFinished.emit(null); + if (xmppLayer != null) { + xmppLayer.writeFooter(); + } + connection.disconnect(); } public void sendElement(Element stanza) { @@ -94,11 +99,14 @@ public abstract class Session { } protected void finishSession(SessionError error) { + if (finishing) { + return; + } finishing = true; - connection.disconnect(); - handleSessionFinished(error); - finishing = false; - onSessionFinished.emit(error); + if (xmppLayer != null) { + xmppLayer.writeFooter(); + } + connection.disconnect(); } protected void handleSessionStarted() { @@ -133,7 +141,7 @@ public abstract class Session { }); xmppLayer.onDataRead.connect(onDataRead); xmppLayer.onWriteData.connect(onDataWritten); - connection.onDisconnected.connect(new Slot1<Connection.Error>() { + onDisconnectedConnection = connection.onDisconnected.connect(new Slot1<Connection.Error>() { public void call(Connection.Error p1) { handleDisconnected(p1); @@ -151,28 +159,33 @@ public abstract class Session { public StreamStack getStreamStack() { return streamStack; - - } - /*void setFinished();*/ /* This seems to be unused in Swiften*/ + /*protected void setFinished();*/ /* This seems to be unused in Swiften*/ private void handleDisconnected(Connection.Error connectionError) { + onDisconnectedConnection.disconnect(); if (connectionError != null) { switch (connectionError) { case ReadError: - finishSession(SessionError.ConnectionReadError); + handleSessionFinished(SessionError.ConnectionReadError); + onSessionFinished.emit(SessionError.ConnectionReadError); break; case WriteError: - finishSession(SessionError.ConnectionWriteError); + handleSessionFinished(SessionError.ConnectionWriteError); + onSessionFinished.emit(SessionError.ConnectionWriteError); break; } - } else { - finishSession(); + } + else { + SessionError error = null; + handleSessionFinished(error); + onSessionFinished.emit(error); } } - private JID localJID; - private JID remoteJID; + + private JID localJID = new JID(); + private JID remoteJID = new JID(); private Connection connection; private PayloadParserFactoryCollection payloadParserFactories; private PayloadSerializerCollection payloadSerializers; @@ -180,5 +193,5 @@ public abstract class Session { private ConnectionLayer connectionLayer; private StreamStack streamStack; private boolean finishing; - private final EventLoop eventLoop; + private SignalConnection onDisconnectedConnection; } diff --git a/src/com/isode/stroke/session/SessionStream.java b/src/com/isode/stroke/session/SessionStream.java index 3171ec0..78d5588 100644 --- a/src/com/isode/stroke/session/SessionStream.java +++ b/src/com/isode/stroke/session/SessionStream.java @@ -6,12 +6,13 @@ * Copyright (c) 2010-2014, Isode Limited, London, England. * All rights reserved. */ -package com.isode.stroke.session; +package com.isode.stroke.session; import java.util.List; import com.isode.stroke.base.SafeByteArray; import com.isode.stroke.base.ByteArray; +import com.isode.stroke.base.Error; import com.isode.stroke.elements.Element; import com.isode.stroke.elements.ProtocolHeader; import com.isode.stroke.signals.Signal; @@ -22,7 +23,7 @@ import com.isode.stroke.tls.CertificateWithKey; public abstract class SessionStream { - public static class Error implements com.isode.stroke.base.Error { + public static class SessionStreamError implements Error { public enum Type { @@ -33,7 +34,7 @@ public abstract class SessionStream { ConnectionWriteError } - public Error(Type type) { + public SessionStreamError(Type type) { this.type = type; } public final Type type; @@ -64,7 +65,18 @@ public abstract class SessionStream { public abstract void setWhitespacePingEnabled(boolean enabled); public abstract void resetXMPPParser(); - + + public abstract void disconnect(); + + protected void finalize() throws Throwable { + try { + disconnect(); + } + finally { + super.finalize(); + } + } + public void setTLSCertificate(CertificateWithKey cert) { certificate = cert; } |