From b6964dc00fa193deb928a40a9bc89e0c106aeb56 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Wed, 23 Sep 2009 06:22:27 +0000 Subject: [PATCH] Display more helpful message for SSL certificate error during WebDAV server validation or sync --- .../content/zotero/preferences/preferences.js | 4 +- chrome/content/zotero/xpcom/storage.js | 15 ++++- chrome/content/zotero/xpcom/storage/webdav.js | 64 +++++++++++++------ 3 files changed, 60 insertions(+), 23 deletions(-) diff --git a/chrome/content/zotero/preferences/preferences.js b/chrome/content/zotero/preferences/preferences.js index 33fe2bdbd..d3ff25f13 100644 --- a/chrome/content/zotero/preferences/preferences.js +++ b/chrome/content/zotero/preferences/preferences.js @@ -262,7 +262,7 @@ function verifyStorageServer() { var usernameField = document.getElementById("storage-username"); var passwordField = document.getElementById("storage-password"); - var callback = function (uri, status) { + var callback = function (uri, status, error) { verifyButton.hidden = false; abortButton.hidden = true; progressMeter.hidden = true; @@ -287,7 +287,7 @@ function verifyStorageServer() { break; } - Zotero.Sync.Storage.checkServerCallback(uri, status, window); + Zotero.Sync.Storage.checkServerCallback(uri, status, window, false, error); } verifyButton.hidden = true; diff --git a/chrome/content/zotero/xpcom/storage.js b/chrome/content/zotero/xpcom/storage.js index e0ba1a8ae..50d1f6edb 100644 --- a/chrome/content/zotero/xpcom/storage.js +++ b/chrome/content/zotero/xpcom/storage.js @@ -677,14 +677,23 @@ Zotero.Sync.Storage = new function () { this.checkServer = function (module, callback) { - _session = new Zotero.Sync.Storage.Session(module, { onError: callback }); + _session = new Zotero.Sync.Storage.Session( + module, + { + onError: function (e) { + Zotero.debug(e, 1); + callback(null, null, e); + throw (e); + } + } + ); _session.initFromPrefs(); _session.checkServer(callback); } - this.checkServerCallback = function (uri, status, window, skipSuccessMessage) { - return _session.checkServerCallback(uri, status, window, skipSuccessMessage); + this.checkServerCallback = function (uri, status, window, skipSuccessMessage, e) { + return _session.checkServerCallback(uri, status, window, skipSuccessMessage, e); } diff --git a/chrome/content/zotero/xpcom/storage/webdav.js b/chrome/content/zotero/xpcom/storage/webdav.js index fe67c2eca..5311545de 100644 --- a/chrome/content/zotero/xpcom/storage/webdav.js +++ b/chrome/content/zotero/xpcom/storage/webdav.js @@ -188,6 +188,8 @@ Zotero.Sync.Storage.Session.WebDAV.prototype._getStorageModificationTime = funct var self = this; Zotero.Utilities.HTTP.doGet(uri, function (req) { + self._checkResponse(req, self); + var funcName = "Zotero.Sync.Storage._getStorageModificationTime()"; // mod_speling can return 300s for 404s with base name matches @@ -575,6 +577,8 @@ Zotero.Sync.Storage.Session.WebDAV.prototype.getLastSyncTime = function (callbac var self = this; Zotero.Utilities.HTTP.doOptions(this.rootURI, function (req) { + self._checkResponse(req, self); + if (req.status != 200) { self.onError("Unexpected status code " + req.status + " caching " + "authentication credentials in Zotero.Sync.Storage.Session.WebDAV.getLastSyncTime()"); @@ -722,6 +726,8 @@ Zotero.Sync.Storage.Session.WebDAV.prototype.checkServer = function (callback) { var request = Zotero.Utilities.HTTP.doOptions(uri, function (req) { // Timeout if (req.status == 0) { + self._checkResponse(req, self); + callback(uri, Zotero.Sync.Storage.ERROR_UNREACHABLE); return; } @@ -903,7 +909,7 @@ Zotero.Sync.Storage.Session.WebDAV.prototype.checkServer = function (callback) { } -Zotero.Sync.Storage.Session.WebDAV.prototype.checkServerCallback = function (uri, status, window, skipSuccessMessage) { +Zotero.Sync.Storage.Session.WebDAV.prototype.checkServerCallback = function (uri, status, window, skipSuccessMessage, e) { var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]. createInstance(Components.interfaces.nsIPromptService); @@ -911,6 +917,16 @@ Zotero.Sync.Storage.Session.WebDAV.prototype.checkServerCallback = function (uri var spec = uri.scheme + '://' + uri.hostPort + uri.path; } + // If there's an error, just display that + if (e) { + promptService.alert( + window, + Zotero.getString('general.error'), + e.toString() + ); + return false; + } + switch (status) { case Zotero.Sync.Storage.SUCCESS: if (!skipSuccessMessage) { @@ -1409,24 +1425,36 @@ Zotero.Sync.Storage.Session.WebDAV.prototype._deleteStorageFiles = function (fil /** - * Unused - * - * @inner - * @param {XMLHTTPRequest} req - * @throws + * Checks for an invalid SSL certificate and displays a nice error */ -Zotero.Sync.Storage.Session.WebDAV.prototype._checkResponse = function (req) { - if (!req.responseText) { - this.onError('Empty response from server'); - return; +Zotero.Sync.Storage.Session.WebDAV.prototype._checkResponse = function (req, obj) { + var channel = req.channel; + if (!channel instanceof Ci.nsIChannel) { + obj.onError('No HTTPS channel available'); } - if (!req.responseXML || - !req.responseXML.firstChild || - !(req.responseXML.firstChild.namespaceURI == 'DAV:' && - req.responseXML.firstChild.localName == 'multistatus') || - !req.responseXML.childNodes[0].firstChild) { - Zotero.debug(req.responseText); - this.onError('Invalid response from storage server'); - return; + var secInfo = channel.securityInfo; + if (secInfo instanceof Ci.nsITransportSecurityInfo) { + secInfo.QueryInterface(Ci.nsITransportSecurityInfo); + if ((secInfo.securityState & Ci.nsIWebProgressListener.STATE_IS_INSECURE) == Ci.nsIWebProgressListener.STATE_IS_INSECURE) { + var host = 'host'; + try { + host = channel.URI.host; + } + catch (e) { + Zotero.debug(e); + } + + var msg = "SSL certificate error connecting to " + host + ". " + + "Load your WebDAV URL in your browser for more information."; + + obj.onError(msg); + return; + } + else if ((secInfo.securityState & Ci.nsIWebProgressListener.STATE_IS_BROKEN) == Ci.nsIWebProgressListener.STATE_IS_BROKEN) { + var msg = "SSL connection error connecting to " + host + ". " + + "Load your WebDAV URL in your browser for more information."; + obj.onError(msg); + return; + } } }