commit 5a2a485a791faa7ef400cc9f41ea0bfeb8118cea
parent 9b5327ecd78668cba01cee0bd57472e3345cd7a3
Author: Dan Stillman <dstillman@zotero.org>
Date: Thu, 2 May 2013 01:14:51 -0400
Add a WebDAV verification step to ensure 404 on missing files
Diffstat:
3 files changed, 117 insertions(+), 79 deletions(-)
diff --git a/chrome/content/zotero/xpcom/storage.js b/chrome/content/zotero/xpcom/storage.js
@@ -51,6 +51,7 @@ Zotero.Sync.Storage = new function () {
this.ERROR_NOT_ALLOWED = -14;
this.ERROR_UNKNOWN = -15;
this.ERROR_FILE_MISSING_AFTER_UPLOAD = -16;
+ this.ERROR_NONEXISTENT_FILE_NOT_MISSING = -17;
// TEMP
this.__defineGetter__("defaultError", function () Zotero.getString('sync.storage.error.default', Zotero.appName));
diff --git a/chrome/content/zotero/xpcom/storage/webdav.js b/chrome/content/zotero/xpcom/storage/webdav.js
@@ -1211,89 +1211,120 @@ Zotero.Sync.Storage.WebDAV = (function () {
switch (req.status) {
case 207:
- // Test if Zotero directory is writable
- var testFileURI = uri.clone();
- testFileURI.spec += "zotero-test-file.prop";
- Zotero.HTTP.WebDAV.doPut(testFileURI, " ", function (req) {
- Zotero.debug(req.responseText);
- Zotero.debug(req.status);
-
- switch (req.status) {
- case 200:
- case 201:
- case 204:
- Zotero.HTTP.doGet(
- testFileURI,
- function (req) {
- Zotero.debug(req.responseText);
- Zotero.debug(req.status);
-
- switch (req.status) {
- case 200:
- // Delete test file
- Zotero.HTTP.WebDAV.doDelete(
- testFileURI,
- function (req) {
- Zotero.debug(req.responseText);
- Zotero.debug(req.status);
-
- switch (req.status) {
- case 200: // IIS 5.1 and Sakai return 200
- case 204:
- return deferred.resolve([uri, Zotero.Sync.Storage.SUCCESS]);
-
- case 401:
- return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_AUTH_FAILED]);
-
- case 403:
- return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_FORBIDDEN]);
+ // Test if missing files return 404s
+ var missingFileURI = uri.clone();
+ missingFileURI.spec += "nonexistent.prop";
+ Zotero.HTTP.promise("GET", missingFileURI, { successCodes: [404], debug: true })
+ .then(function () {
+ // Test if Zotero directory is writable
+ var testFileURI = uri.clone();
+ testFileURI.spec += "zotero-test-file.prop";
+ Zotero.HTTP.WebDAV.doPut(testFileURI, " ", function (req) {
+ Zotero.debug(req.responseText);
+ Zotero.debug(req.status);
+
+ switch (req.status) {
+ case 200:
+ case 201:
+ case 204:
+ Zotero.HTTP.doGet(
+ testFileURI,
+ function (req) {
+ Zotero.debug(req.responseText);
+ Zotero.debug(req.status);
+
+ switch (req.status) {
+ case 200:
+ // Delete test file
+ Zotero.HTTP.WebDAV.doDelete(
+ testFileURI,
+ function (req) {
+ Zotero.debug(req.responseText);
+ Zotero.debug(req.status);
- default:
- return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_UNKNOWN]);
+ switch (req.status) {
+ case 200: // IIS 5.1 and Sakai return 200
+ case 204:
+ return deferred.resolve([uri, Zotero.Sync.Storage.SUCCESS]);
+
+ case 401:
+ return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_AUTH_FAILED]);
+
+ case 403:
+ return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_FORBIDDEN]);
+
+ default:
+ return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_UNKNOWN]);
+ }
}
- }
- );
- return;
-
- case 401:
- return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_AUTH_FAILED]);
-
- case 403:
- return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_FORBIDDEN]);
-
- // This can happen with cloud storage services
- // backed by S3 or other eventually consistent
- // data stores.
- //
- // This can also be from IIS 6+, which is configured
- // not to serve .prop files.
- // http://support.microsoft.com/kb/326965
- case 404:
- return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_FILE_MISSING_AFTER_UPLOAD]);
-
- case 500:
- return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_SERVER_ERROR]);
-
- default:
- return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_UNKNOWN]);
+ );
+ return;
+
+ case 401:
+ return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_AUTH_FAILED]);
+
+ case 403:
+ return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_FORBIDDEN]);
+
+ // This can happen with cloud storage services
+ // backed by S3 or other eventually consistent
+ // data stores.
+ //
+ // This can also be from IIS 6+, which is configured
+ // not to serve .prop files.
+ // http://support.microsoft.com/kb/326965
+ case 404:
+ return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_FILE_MISSING_AFTER_UPLOAD]);
+
+ case 500:
+ return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_SERVER_ERROR]);
+
+ default:
+ return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_UNKNOWN]);
+ }
}
- }
- );
- return;
-
- case 401:
- return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_AUTH_FAILED]);
-
- case 403:
- return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_FORBIDDEN]);
-
- case 500:
- return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_SERVER_ERROR]);
-
- default:
- return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_UNKNOWN]);
+ );
+ return;
+
+ case 401:
+ return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_AUTH_FAILED]);
+
+ case 403:
+ return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_FORBIDDEN]);
+
+ case 500:
+ return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_SERVER_ERROR]);
+
+ default:
+ return deferred.resolve([uri, Zotero.Sync.Storage.ERROR_UNKNOWN]);
+ }
+ });
+ })
+ .catch(function (e) {
+ if (e instanceof Zotero.HTTP.UnexpectedStatusException) {
+ if (e.status >= 200 && e.status < 300) {
+ deferred.resolve([uri, Zotero.Sync.Storage.ERROR_NONEXISTENT_FILE_NOT_MISSING]);
+ }
+ else if (e.status == 401) {
+ deferred.resolve([uri, Zotero.Sync.Storage.ERROR_AUTH_FAILED]);
+ }
+ else if (e.status == 403) {
+ deferred.resolve([uri, Zotero.Sync.Storage.ERROR_FORBIDDEN]);
+ }
+ else if (e.status == 500) {
+ deferred.resolve([uri, Zotero.Sync.Storage.ERROR_SERVER_ERROR]);
+ }
+ else {
+ deferred.resolve([uri, Zotero.Sync.Storage.ERROR_UNKNOWN]);
+ }
}
- });
+ else {
+ Zotero.debug(e, 1);
+ Components.utils.reportError(e);
+ deferred.resolve([uri, Zotero.Sync.Storage.ERROR_UNKNOWN]);
+ }
+ })
+ .done();
return;
case 400:
@@ -1491,6 +1522,11 @@ Zotero.Sync.Storage.WebDAV = (function () {
Zotero.getString('sync.storage.error.checkFileSyncSettings')
]);
break;
+
+ case Zotero.Sync.Storage.ERROR_NONEXISTENT_FILE_NOT_MISSING:
+ var errorTitle = Zotero.getString('sync.storage.error.webdav.serverConfig.title');
+ var errorMessage = Zotero.getString('sync.storage.error.webdav.nonexistentFileNotMissing');
+ break;
}
if (!skipSuccessMessage) {
diff --git a/chrome/locale/en-US/zotero/zotero.properties b/chrome/locale/en-US/zotero/zotero.properties
@@ -849,6 +849,7 @@ sync.storage.error.webdav.loadURLForMoreInfo = Load your WebDAV URL in the brows
sync.storage.error.webdav.seeCertOverrideDocumentation = See the certificate override documentation for more information.
sync.storage.error.webdav.loadURL = Load WebDAV URL
sync.storage.error.webdav.fileMissingAfterUpload = A potential problem was found with your WebDAV server.\n\nAn uploaded file was not immediately available for download. There may be a short delay between when you upload files and when they become available, particularly if you are using a cloud storage service.\n\nIf Zotero file syncing appears to work normally, you can ignore this message. If you have trouble, please post to the Zotero Forums.
+sync.storage.error.webdav.nonexistentFileNotMissing = Your WebDAV server is claiming that a nonexistent file exists. Contact your WebDAV server administrator for assistance.
sync.storage.error.webdav.serverConfig.title = WebDAV Server Configuration Error
sync.storage.error.webdav.serverConfig = Your WebDAV server returned an internal error.