summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSolly Ross <sross@redhat.com>2015-03-24 16:02:53 -0400
committerSolly Ross <sross@redhat.com>2015-03-26 17:10:24 -0400
commitd9fc1c7be45f7be9f127636d5d63c3c224f05d1d (patch)
tree486346dbc37c677b76baf350f6b21c76abf876d3
parent58ded70d150c31df2fbd78c0320af6edc72610fc (diff)
downloadnovnc-bug/throw-error-from-constructor.tar.gz
Throw exceptions from RFB constructorbug/throw-error-from-constructor
Previously, if an error was thrown from the Display constructor in the RFB constructor, we would attempt to use `RFB#updateState` to handle this. However, `RFB#updateState` attempts to close the WebSocket connection, which doesn't exist at this point. In the constructor, it's probably just better to raise an exception instead (making sure to clean up anything relevant). Fixes #460
-rw-r--r--include/rfb.js62
-rw-r--r--include/ui.js22
-rw-r--r--vnc_auto.html30
3 files changed, 66 insertions, 48 deletions
diff --git a/include/rfb.js b/include/rfb.js
index 6fcdab6..b9db39c 100644
--- a/include/rfb.js
+++ b/include/rfb.js
@@ -159,11 +159,13 @@ var RFB;
this._encStats[this._encodings[i][1]] = [0, 0];
}
+ // NB: nothing that needs explicit teardown should be done
+ // before this point, since this can throw an exception
try {
this._display = new Display({target: this._target});
} catch (exc) {
Util.Error("Display exception: " + exc);
- this._updateState('fatal', "No working Display");
+ throw exc;
}
this._keyboard = new Keyboard({target: this._focusContainer,
@@ -217,9 +219,11 @@ var RFB;
} else {
Util.Warn("Using web-socket-js bridge. Flash version: " + Util.Flash.version);
if (!Util.Flash || Util.Flash.version < 9) {
- this._updateState('fatal', "WebSockets or <a href='http://get.adobe.com/flashplayer'>Adobe Flash</a> is required");
+ this._cleanupSocket('fatal');
+ throw new Exception("WebSockets or <a href='http://get.adobe.com/flashplayer'>Adobe Flash</a> is required");
} else if (document.location.href.substr(0, 7) === 'file://') {
- this._updateState('fatal', "'file://' URL is incompatible with Adobe Flash");
+ this._cleanupSocket('fatal');
+ throw new Exception("'file://' URL is incompatible with Adobe Flash");
} else {
this._updateState('loaded', 'noVNC ready: WebSockets emulation, ' + rmode);
}
@@ -398,6 +402,32 @@ var RFB;
}
},
+ _cleanupSocket: function (state) {
+ if (this._sendTimer) {
+ clearInterval(this._sendTimer);
+ this._sendTimer = null;
+ }
+
+ if (this._msgTimer) {
+ clearInterval(this._msgTimer);
+ this._msgTimer = null;
+ }
+
+ if (this._display && this._display.get_context()) {
+ this._keyboard.ungrab();
+ this._mouse.ungrab();
+ if (state !== 'connect' && state !== 'loaded') {
+ this._display.defaultCursor();
+ }
+ if (Util.get_logging() !== 'debug' || state === 'loaded') {
+ // Show noVNC logo on load and when disconnected, unless in
+ // debug mode
+ this._display.clear();
+ }
+ }
+
+ this._sock.close();
+ },
/*
* Page states:
@@ -432,31 +462,7 @@ var RFB;
*/
if (state in {'disconnected': 1, 'loaded': 1, 'connect': 1,
'disconnect': 1, 'failed': 1, 'fatal': 1}) {
-
- if (this._sendTimer) {
- clearInterval(this._sendTimer);
- this._sendTimer = null;
- }
-
- if (this._msgTimer) {
- clearInterval(this._msgTimer);
- this._msgTimer = null;
- }
-
- if (this._display && this._display.get_context()) {
- this._keyboard.ungrab();
- this._mouse.ungrab();
- if (state !== 'connect' && state !== 'loaded') {
- this._display.defaultCursor();
- }
- if (Util.get_logging() !== 'debug' || state === 'loaded') {
- // Show noVNC logo on load and when disconnected, unless in
- // debug mode
- this._display.clear();
- }
- }
-
- this._sock.close();
+ this._cleanupSocket(state);
}
if (oldstate === 'fatal') {
diff --git a/include/ui.js b/include/ui.js
index a72d5fa..9355078 100644
--- a/include/ui.js
+++ b/include/ui.js
@@ -159,13 +159,19 @@ var UI;
},
initRFB: function () {
- UI.rfb = new RFB({'target': $D('noVNC_canvas'),
- 'onUpdateState': UI.updateState,
- 'onXvpInit': UI.updateXvpVisualState,
- 'onClipboard': UI.clipReceive,
- 'onFBUComplete': UI.FBUComplete,
- 'onFBResize': UI.updateViewDragButton,
- 'onDesktopName': UI.updateDocumentTitle});
+ try {
+ UI.rfb = new RFB({'target': $D('noVNC_canvas'),
+ 'onUpdateState': UI.updateState,
+ 'onXvpInit': UI.updateXvpVisualState,
+ 'onClipboard': UI.clipReceive,
+ 'onFBUComplete': UI.FBUComplete,
+ 'onFBResize': UI.updateViewDragButton,
+ 'onDesktopName': UI.updateDocumentTitle});
+ return true;
+ } catch (exc) {
+ UI.updateState(null, 'fatal', null, 'Unable to create RFB client -- ' + exc);
+ return false;
+ }
},
addMouseHandlers: function() {
@@ -772,7 +778,7 @@ var UI;
throw new Error("Must set host and port");
}
- UI.initRFB();
+ if (!UI.initRFB()) return;
UI.rfb.set_encrypt(UI.getSetting('encrypt'));
UI.rfb.set_true_color(UI.getSetting('true_color'));
diff --git a/vnc_auto.html b/vnc_auto.html
index 9fd2272..ec18ab8 100644
--- a/vnc_auto.html
+++ b/vnc_auto.html
@@ -216,18 +216,24 @@
return;
}
- rfb = new RFB({'target': $D('noVNC_canvas'),
- 'encrypt': WebUtil.getQueryVar('encrypt',
- (window.location.protocol === "https:")),
- 'repeaterID': WebUtil.getQueryVar('repeaterID', ''),
- 'true_color': WebUtil.getQueryVar('true_color', true),
- 'local_cursor': WebUtil.getQueryVar('cursor', true),
- 'shared': WebUtil.getQueryVar('shared', true),
- 'view_only': WebUtil.getQueryVar('view_only', false),
- 'onUpdateState': updateState,
- 'onXvpInit': xvpInit,
- 'onPasswordRequired': passwordRequired,
- 'onFBUComplete': FBUComplete});
+ try {
+ rfb = new RFB({'target': $D('noVNC_canvas'),
+ 'encrypt': WebUtil.getQueryVar('encrypt',
+ (window.location.protocol === "https:")),
+ 'repeaterID': WebUtil.getQueryVar('repeaterID', ''),
+ 'true_color': WebUtil.getQueryVar('true_color', true),
+ 'local_cursor': WebUtil.getQueryVar('cursor', true),
+ 'shared': WebUtil.getQueryVar('shared', true),
+ 'view_only': WebUtil.getQueryVar('view_only', false),
+ 'onUpdateState': updateState,
+ 'onXvpInit': xvpInit,
+ 'onPasswordRequired': passwordRequired,
+ 'onFBUComplete': FBUComplete});
+ } catch (exc) {
+ UI.updateState(null, 'fatal', null, 'Unable to create RFB client -- ' + exc);
+ return; // don't continue trying to connect
+ }
+
rfb.connect(host, port, password, path);
};
</script>