Skip to content

Commit

Permalink
Throw exceptions from RFB constructor
Browse files Browse the repository at this point in the history
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 novnc#460
  • Loading branch information
DirectXMan12 committed Mar 26, 2015
1 parent 58ded70 commit d9fc1c7
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 48 deletions.
62 changes: 34 additions & 28 deletions include/rfb.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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') {
Expand Down
22 changes: 14 additions & 8 deletions include/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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'));
Expand Down
30 changes: 18 additions & 12 deletions vnc_auto.html
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down

0 comments on commit d9fc1c7

Please sign in to comment.