diff --git a/ui/commands/exception.js b/ui/commands/exception.js index e25c0d5..3c6871d 100644 --- a/ui/commands/exception.js +++ b/ui/commands/exception.js @@ -15,7 +15,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -export default class Exception { +export default class Exception extends Error { /** * constructor * @@ -23,16 +23,6 @@ export default class Exception { * */ constructor(message) { - this.message = message; - } - - /** - * Return the error string - * - * @returns {string} Error message - * - */ - toString() { - return this.message; + super(message); } } diff --git a/ui/crypto.js b/ui/crypto.js index 299ac2f..3b72fc4 100644 --- a/ui/crypto.js +++ b/ui/crypto.js @@ -33,7 +33,7 @@ export async function hmac512(secret, data) { ["sign", "verify"] ); - return crypto.subtle.sign("HMAC", key, data); + return crypto.subtle.sign(key.algorithm, key, data); } export const GCMNonceSize = 12; diff --git a/ui/home_socketctl.js b/ui/home_socketctl.js index f70d99c..50ea8c6 100644 --- a/ui/home_socketctl.js +++ b/ui/home_socketctl.js @@ -167,7 +167,7 @@ export function build(ctx) { this.message = "ERR"; this.classStyle = "red flash"; this.windowClass = "red"; - this.status.description = connectionStatusDisconnected + ". Error: " + e; + this.status.description = connectionStatusDisconnected + ": " + e; }, failed(e) { ctx.connector.inputting = false; diff --git a/ui/socket.js b/ui/socket.js index 2218d4f..74ba284 100644 --- a/ui/socket.js +++ b/ui/socket.js @@ -74,7 +74,7 @@ class Dial { return reject(e); }; - ws.addEventListener("open", event => { + ws.addEventListener("open", _event => { myRes(ws); }); @@ -86,7 +86,7 @@ class Dial { myRej(event); }); - ws.addEventListener("error", event => { + ws.addEventListener("error", _event => { ws.close(); }); }); @@ -143,20 +143,7 @@ class Dial { bufferReader.readAsArrayBuffer(data); }); - }), - sdDataConvert = rawData => { - return rawData; - }, - sd = new sender.Sender( - async rawData => { - let data = await sdDataConvert(rawData); - - ws.send(data.buffer); - callbacks.outbound(data); - }, - 15, - 4096 - 64 // Server has a 4096 bytes receive buffer, can be no greater - ); + }); ws.addEventListener("message", event => { callbacks.inbound(event.data); @@ -165,13 +152,45 @@ class Dial { }); ws.addEventListener("error", event => { - rd.close(); + event.toString = () => { + return "WebSocket Error (" + event.code + ")"; + }; + + rd.closeWithReason(event); }); - ws.addEventListener("close", event => { - rd.close(); + ws.addEventListener("close", _event => { + rd.closeWithReason("Connection is closed"); }); + let sdDataConvert = rawData => { + return rawData; + }, + getSdDataConvert = () => { + return sdDataConvert; + }, + sd = new sender.Sender( + async rawData => { + try { + let data = await getSdDataConvert()(rawData); + + ws.send(data.buffer); + callbacks.outbound(data); + } catch (e) { + ws.close(); + rd.closeWithReason(e); + + if (process.env.NODE_ENV === "development") { + console.error(e); + } + + throw e; + } + }, + 15, + 4096 - 64 // Server has a 4096 bytes receive buffer, can be no greater + ); + let senderNonce = crypt.generateNonce(); sd.send(senderNonce); @@ -213,7 +232,7 @@ class Dial { r.feed(new reader.Buffer(new Uint8Array(decoded), () => {}), () => {}); } catch (e) { - r.close(); + r.closeWithReason(e); } }); @@ -319,10 +338,16 @@ export class Socket { } }); - streamHandler.serve().catch(() => {}); - callbacks.connected(); + streamHandler.serve().catch(e => { + if (process.env.NODE_ENV !== "development") { + return; + } + + console.trace(e); + }); + this.streamHandler = streamHandler; } catch (e) { callbacks.failed(e); diff --git a/ui/stream/exception.js b/ui/stream/exception.js index 38d38cf..0d16321 100644 --- a/ui/stream/exception.js +++ b/ui/stream/exception.js @@ -15,7 +15,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -export default class Exception { +export default class Exception extends Error { /** * constructor * @@ -24,17 +24,8 @@ export default class Exception { * */ constructor(message, temporary) { - this.message = message; + super(message); + this.temporary = temporary; } - - /** - * Return the error string - * - * @returns {string} Error message - * - */ - toString() { - return this.message; - } } diff --git a/ui/stream/reader.js b/ui/stream/reader.js index cc5e93c..a684cd2 100644 --- a/ui/stream/reader.js +++ b/ui/stream/reader.js @@ -222,12 +222,23 @@ export class Multiple { * */ close() { + return this.closeWithReason("Reader is closed"); + } + + /** + * close current reading + * + * @param {string} reason Reason + * + */ + closeWithReason(reason) { if (this.closed) { return; } this.closed = true; - this.subscribe.reject(new Exception("Reader is closed", false)); + this.subscribe.reject(new Exception(reason, false)); + this.subscribe.disable(reason); } /** @@ -317,17 +328,23 @@ export class Reader { * */ close() { + return this.closeWithReason("Reader is closed"); + } + + /** + * close current reading + * + * @param {string} reason Reason + * + */ + closeWithReason(reason) { if (this.closed) { return; } this.closed = true; - this.buffers.reject( - new Exception( - "Reader is closed, and thus " + "cannot be operated on", - false - ) - ); + this.buffers.reject(new Exception(reason, false)); + this.buffers.disable(reason); return this.multiple.close(); } diff --git a/ui/stream/sender.js b/ui/stream/sender.js index 5aef0a6..644a5ff 100644 --- a/ui/stream/sender.js +++ b/ui/stream/sender.js @@ -66,11 +66,7 @@ export class Sender { this.subscribe.reject(new Exception("Sender has been closed", false)); - try { - await this.sendingPoc; - } catch (e) { - // Do nothing - } + this.sendingPoc.catch(() => {}); this.reject(new Exception("Sending has been cancelled", true)); } diff --git a/ui/stream/subscribe.js b/ui/stream/subscribe.js index d3e55a1..00191c0 100644 --- a/ui/stream/subscribe.js +++ b/ui/stream/subscribe.js @@ -29,6 +29,7 @@ export class Subscribe { this.res = null; this.rej = null; this.pending = []; + this.disabled = null; } /** @@ -78,6 +79,10 @@ export class Subscribe { * */ subscribe() { + if (this.disabled) { + throw new Exception(this.disabled, false); + } + if (this.pending.length > 0) { let p = this.pending.shift(); @@ -111,4 +116,14 @@ export class Subscribe { }; }); } + + /** + * Disable current subscriber when all internal data is readed + * + * @param {string} reason Reason of the disable + * + */ + disable(reason) { + this.disabled = reason; + } }