From 369fb2e527e6ab06ae42cc9efe741832600a74a1 Mon Sep 17 00:00:00 2001
From: bontric <benjohnwie@gmail.com>
Date: Thu, 6 Sep 2018 15:58:12 +0200
Subject: [PATCH] Reformat/update MailboxSession implementation

---
 .../bramble/mailbox/MailboxSession.java       | 141 +++++++++++-------
 1 file changed, 86 insertions(+), 55 deletions(-)

diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxSession.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxSession.java
index c8c2f1bb0..8aac031fb 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxSession.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxSession.java
@@ -9,6 +9,8 @@ import org.briarproject.bramble.api.transport.StreamContext;
 import org.briarproject.bramble.api.transport.StreamReaderFactory;
 import org.briarproject.bramble.api.transport.StreamWriter;
 import org.briarproject.bramble.api.transport.StreamWriterFactory;
+import org.briarproject.bramble.mailbox.protocol.MailboxMessage;
+import org.briarproject.bramble.mailbox.protocol.MailboxMessage.TYPE;
 import org.briarproject.bramble.mailbox.protocol.MailboxProtocol;
 import org.briarproject.bramble.mailbox.protocol.MailboxRequest;
 import org.briarproject.bramble.mailbox.protocol.MailboxRequestEnd;
@@ -45,6 +47,7 @@ abstract class MailboxSession implements Runnable {
 
 	// Used to handle graceful session termination with END request
 	private AtomicBoolean remoteSessionFinished = new AtomicBoolean(false);
+	protected boolean running;
 
 	public MailboxSession(Executor ioExecutor,
 			KeyManager keyManager,
@@ -67,6 +70,14 @@ abstract class MailboxSession implements Runnable {
 		this.contactId = contactId;
 	}
 
+	/**
+	 * @return True if the session is running
+	 */
+	public boolean isRunning() {
+		return running;
+	}
+
+
 	/**
 	 * Creates and runs a duplex session which is used for sync streams between
 	 * mailbox and owner (user)
@@ -89,18 +100,6 @@ abstract class MailboxSession implements Runnable {
 		}
 	}
 
-	/**
-	 * Handle an incoming sync stream intended for the mailbox/client
-	 *
-	 * @param syncStream (previously decrypted) sync stream
-	 * @throws IOException
-	 */
-	protected void handleSyncStream(byte[] syncStream)
-			throws IOException {
-		InputStream is = new ByteArrayInputStream(syncStream);
-		syncSessionFactory.createIncomingSession(contactId, is).run();
-	}
-
 	/**
 	 * Get an encrypted Sync stream which can be stored on the mailbox by
 	 * issuing a STORE request
@@ -132,40 +131,6 @@ abstract class MailboxSession implements Runnable {
 	}
 
 
-	/**
-	 * Handles an encrypted stream which was stored on the mailbox and received
-	 * with a TAKE request.
-	 *
-	 * @param encryptedStream
-	 * @throws DbException
-	 * @throws IOException
-	 */
-	protected void handleEncryptedSyncStream(byte[] encryptedStream)
-			throws DbException, IOException {
-		// read tag from input stream
-		InputStream in = new ByteArrayInputStream(encryptedStream);
-		byte[] tag = new byte[TAG_LENGTH];
-		int offset = 0;
-		while (offset < tag.length) {
-			int read = in.read(tag, offset, tag.length - offset);
-			if (read == -1) throw new EOFException();
-			offset += read;
-		}
-
-		StreamContext ctx =
-				keyManager.getStreamContext(MailboxConstants.ID, tag);
-
-		if (ctx == null) {
-			throw new IOException("Received stream with unrecognisable tag");
-		}
-
-		InputStream reader = streamReaderFactory.createStreamReader(in, ctx);
-
-		syncSessionFactory.createIncomingSession(ctx.getContactId(), reader)
-				.run();
-	}
-
-
 	/**
 	 * Must be called if the session wants to receive and handle requests
 	 */
@@ -182,12 +147,22 @@ abstract class MailboxSession implements Runnable {
 		}
 	}
 
+	/**
+	 * Calls the appropriate handler for an incoming request
+	 *
+	 * NOTE: If a session does not support a specific request the appropriate
+	 * handler needs to be overwritten. This handler should throw a
+	 * {@link MailboxSessionHandleException}.
+	 * @param req
+	 */
 	private void handleRequest(MailboxRequest req) {
+
 		String error = null;
 		try {
 			switch (req.getType()) {
 				case STORE:
 					handleStore((MailboxRequestStore) req);
+					break;
 				case TAKE:
 					handleTake((MailboxRequestTake) req);
 					break;
@@ -196,6 +171,7 @@ abstract class MailboxSession implements Runnable {
 					break;
 				case END:
 					handleEnd((MailboxRequestEnd) req);
+					break;
 				default:
 					throw new MailboxSessionHandleException(
 							"Unsupported request type");
@@ -220,6 +196,11 @@ abstract class MailboxSession implements Runnable {
 		}
 	}
 
+	/**
+	 * Marks the remote side of the session as finished. The session is active
+	 * until this side of the session calls {@link #endSession()}
+	 * @param req
+	 */
 	private void handleEnd(MailboxRequestEnd req) {
 		synchronized (remoteSessionFinished) {
 			remoteSessionFinished.set(true);
@@ -227,9 +208,9 @@ abstract class MailboxSession implements Runnable {
 	}
 
 	/**
-	 * Must be called once at the end of a MailboxSession to signal the end to
-	 * the peer. This call blocks until the remote session signals that
-	 * the session has ended.
+	 * Must be called once at the end of a MailboxSession to signal the end of
+	 * the session to the peer. This call blocks until the remote session
+	 * signals that it was ended.
 	 */
 	protected void endSession()
 			throws InterruptedException, IOException {
@@ -239,16 +220,61 @@ abstract class MailboxSession implements Runnable {
 		while (!remoteSessionFinished.get()) {
 			remoteSessionFinished.wait();
 		}
+		running = false;
 	}
 
-	public abstract void handleSync(MailboxRequestSync req)
-			throws MailboxSessionHandleException;
 
-	public abstract void handleStore(MailboxRequestStore req)
-			throws MailboxSessionHandleException;
+	/**
+	 * Handles an incoming SYNC request. The request contains an unencrypted
+	 * BSP stream which is passed to a BSP IncomingSession
+	 *
+	 * @param req MailboxRequestTake
+	 */
+	public void handleSync(MailboxRequestSync req) {
+		try {
+			InputStream is = new ByteArrayInputStream(req.getSyncStream());
+			syncSessionFactory.createIncomingSession(contactId, is).run();
+		} catch (IOException e) {
+			logException(LOG, WARNING, e);
+		}
+	}
 
-	public abstract void handleTake(MailboxRequestTake req)
-			throws MailboxSessionHandleException;
+	/**
+	 * Handles an incoming TAKE request. The request contains an encrypted BSP
+	 * stream. From this stream, the tag is read and a StreamReader is created.
+	 * A BSP IncomingSession is created for the stream
+	 *
+	 * @param req MailboxRequestTake
+	 * @throws MailboxSessionHandleException
+	 */
+	public void handleTake(MailboxRequestTake req)
+			throws MailboxSessionHandleException {
+		InputStream in = new ByteArrayInputStream(req.getEncryptedSyncStream());
+		byte[] tag = new byte[TAG_LENGTH];
+		try {
+			// read tag from input stream
+			int offset = 0;
+			while (offset < tag.length) {
+				int read = in.read(tag, offset, tag.length - offset);
+				if (read == -1) throw new EOFException();
+				offset += read;
+			}
+
+			StreamContext ctx =
+					keyManager.getStreamContext(MailboxConstants.ID, tag);
+
+			if (ctx == null) {
+				throw new IOException("Received stream with unrecognisable tag");
+			}
+
+			InputStream reader = streamReaderFactory.createStreamReader(in, ctx);
+
+			syncSessionFactory.createIncomingSession(ctx.getContactId(), reader)
+					.run();
+		} catch (DbException | IOException e) {
+			throw new MailboxSessionHandleException(e.toString());
+		}
+	}
 
 	protected class MailboxSessionHandleException extends Exception {
 		public MailboxSessionHandleException(String error) {
@@ -256,4 +282,9 @@ abstract class MailboxSession implements Runnable {
 		}
 	}
 
+	public void handleStore(MailboxRequestStore req)
+			throws MailboxSessionHandleException{
+		// TODO: mailbox storage for Mailbox implementation
+	}
+
 }
-- 
GitLab