From 46e8e4343acba876b9540b9fc77a5c85faa10939 Mon Sep 17 00:00:00 2001 From: Sebastian Silva Date: Fri, 4 May 2018 05:48:38 -0500 Subject: [PATCH] Fix WebDAV by requesting new ETag. (#3230) * Fix WebDAV by requesting new ETag conditionally For me. this was saving only the first time and subsequently failing. Having revised the requests, I noticed it didn't get a new ETag after saving. Seems not all WebDAV implementations return a new ETag in PUT requests. In my WebDAV service (WsgiDAV) - ETag is only served from a HEAD request. So if no ETag is found with PUT - we request one with HEAD. This patch fixes error handling and should also work with servers that provide ETag directly upon PUT. * Add tweak from PMario --- core/modules/savers/put.js | 50 ++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/core/modules/savers/put.js b/core/modules/savers/put.js index be9817cf8..e1fd7a8c2 100644 --- a/core/modules/savers/put.js +++ b/core/modules/savers/put.js @@ -15,6 +15,24 @@ to the current URL, such as a WebDAV server. /*global $tw: false */ "use strict"; +/* +Retrieve ETag if available +*/ +var RetrieveETag = function(self) { + var headers = { "Accept": "*/*;charset=UTF-8" }; + $tw.utils.httpRequest({ + url: self.uri(), + type: "HEAD", + headers: headers, + callback: function(err, data, xhr) { + if(!err) { + self.etag = xhr.getResponseHeader("ETag").replace(/^W\//,""); + } + } + }); +}; + + /* Select the appropriate saver module and set it up */ @@ -34,16 +52,7 @@ var PutSaver = function(wiki) { } } }); - // Retrieve ETag if available - $tw.utils.httpRequest({ - url: uri, - type: "HEAD", - callback: function(err, data, xhr) { - if(!err) { - self.etag = xhr.getResponseHeader("ETag"); - } - } - }); + RetrieveETag(this); }; PutSaver.prototype.uri = function() { @@ -69,15 +78,20 @@ PutSaver.prototype.save = function(text, method, callback) { data: text, callback: function(err, data, xhr) { if(err) { - callback(err); - } else if(xhr.status === 200 || xhr.status === 201) { - self.etag = xhr.getResponseHeader("ETag"); - callback(null); // success - } else if(xhr.status === 412) { // edit conflict - var message = $tw.language.getString("Error/EditConflict"); - callback(message); + // response is textual: "XMLHttpRequest error code: 412" + const status = Number(err.substring(err.indexOf(':') + 2, err.length)) + if(status === 412) { // edit conflict + var message = $tw.language.getString("Error/EditConflict"); + callback(message); + } else { + callback(err); // fail + } } else { - callback(xhr.responseText); // fail + self.etag = xhr.getResponseHeader("ETag"); + if (self.etag == null) { + RetrieveETag(self); + } + callback(null); // success } } });