/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["Connection"]; const {Log} = ChromeUtils.import("chrome://remote/content/Log.jsm"); const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); XPCOMUtils.defineLazyGetter(this, "log", Log.get); XPCOMUtils.defineLazyServiceGetter(this, "UUIDGen", "@mozilla.org/uuid-generator;1", "nsIUUIDGenerator"); class Connection { constructor(transport) { this.id = UUIDGen.generateUUID().toString(); this.transport = transport; this.transport.hooks = this; this.transport.ready(); this.defaultSession = null; this.sessions = new Map(); } /** * Register a new Session to forward the messages to. * Session without any `id` attribute will be considered to be the * default one, to which messages without `sessionId` attribute are * forwarded to. Only one such session can be registered. * * @param Session session */ registerSession(session) { if (!session.id) { if (this.defaultSession) { throw new Error("Default session is already set on Connection," + "can't register another one."); } this.defaultSession = session; } this.sessions.set(session.id, session); } send(message) { log.trace(`<-(connection ${this.id}) ${JSON.stringify(message)}`); this.transport.send(message); } error(id, e) { const error = { message: e.message, data: e.stack, }; this.send({id, error}); } deserialize(data) { const id = data.id; const method = data.method; const params = data.params || {}; return {id, method, params}; } // transport hooks onPacket(packet) { log.trace(`(connection ${this.id})-> ${JSON.stringify(packet)}`); let message = {id: null}; try { message = this.deserialize(packet); const { sessionId } = packet; if (!sessionId) { if (!this.defaultSession) { throw new Error(`Connection is missing a default Session.`); } this.defaultSession.onMessage(message); } else { const session = this.sessions.get(sessionId); if (!session) { throw new Error(`Session '${sessionId}' doesn't exists.`); } session.onMessage(message); } } catch (e) { log.warn(e); this.error(message.id, e); } } close() { this.transport.close(); this.sessions.clear(); } onClosed(status) {} toString() { return `[object Connection ${this.id}]`; } }