ImportHandler.js: ensure import connection closing happens at the right point

pull/3559/head
Ray Bellis 2019-02-08 14:46:05 +00:00
parent 62345ac8f7
commit b664eb488c
1 changed files with 36 additions and 35 deletions

View File

@ -118,8 +118,6 @@ async function doImport(req, res, padId)
let fileIsHTML = (fileEnding === ".html" || fileEnding === ".htm"); let fileIsHTML = (fileEnding === ".html" || fileEnding === ".htm");
let fileIsTXT = (fileEnding === ".txt"); let fileIsTXT = (fileEnding === ".txt");
let directDatabaseAccess = false;
if (fileIsEtherpad) { if (fileIsEtherpad) {
// we do this here so we can see if the pad has quite a few edits // we do this here so we can see if the pad has quite a few edits
let _pad = await padManager.getPad(padId); let _pad = await padManager.getPad(padId);
@ -132,12 +130,12 @@ async function doImport(req, res, padId)
const fsp_readFile = util.promisify(fs.readFile); const fsp_readFile = util.promisify(fs.readFile);
let _text = await fsp_readFile(srcFile, "utf8"); let _text = await fsp_readFile(srcFile, "utf8");
directDatabaseAccess = true; req.directDatabaseAccess = true;
await importEtherpad.setPadRaw(padId, _text); await importEtherpad.setPadRaw(padId, _text);
} }
// convert file to html if necessary // convert file to html if necessary
if (!importHandledByPlugin && !directDatabaseAccess) { if (!importHandledByPlugin && !req.directDatabaseAccess) {
if (fileIsTXT) { if (fileIsTXT) {
// Don't use convertor for text files // Don't use convertor for text files
useConvertor = false; useConvertor = false;
@ -162,7 +160,7 @@ async function doImport(req, res, padId)
} }
} }
if (!useConvertor && !directDatabaseAccess) { if (!useConvertor && !req.directDatabaseAccess) {
// Read the file with no encoding for raw buffer access. // Read the file with no encoding for raw buffer access.
let buf = await fsp_readFile(destFile); let buf = await fsp_readFile(destFile);
@ -180,7 +178,7 @@ async function doImport(req, res, padId)
// read the text // read the text
let text; let text;
if (!directDatabaseAccess) { if (!req.directDatabaseAccess) {
text = await fsp_readFile(destFile, "utf8"); text = await fsp_readFile(destFile, "utf8");
// Title needs to be stripped out else it appends it to the pad.. // Title needs to be stripped out else it appends it to the pad..
@ -195,7 +193,7 @@ async function doImport(req, res, padId)
} }
// change text of the pad and broadcast the changeset // change text of the pad and broadcast the changeset
if (!directDatabaseAccess) { if (!req.directDatabaseAccess) {
if (importHandledByPlugin || useConvertor || fileIsHTML) { if (importHandledByPlugin || useConvertor || fileIsHTML) {
try { try {
importHtml.setPadHTML(pad, text); importHtml.setPadHTML(pad, text);
@ -214,56 +212,59 @@ async function doImport(req, res, padId)
// direct Database Access means a pad user should perform a switchToPad // direct Database Access means a pad user should perform a switchToPad
// and not attempt to receive updated pad data // and not attempt to receive updated pad data
if (!directDatabaseAccess) { if (req.directDatabaseAccess) {
// tell clients to update return;
await padMessageHandler.updatePadClients(pad);
} }
if (!directDatabaseAccess) { // tell clients to update
// clean up temporary files await padMessageHandler.updatePadClients(pad);
/* // clean up temporary files
* TODO: directly delete the file and handle the eventual error. Checking
* before for existence is prone to race conditions, and does not handle any
* errors anyway.
*/
if (await fsp_exists(srcFile)) {
fsp_unlink(srcFile);
}
if (await fsp_exists(destFile)) { /*
fsp_unlink(destFile); * TODO: directly delete the file and handle the eventual error. Checking
} * before for existence is prone to race conditions, and does not handle any
* errors anyway.
*/
if (await fsp_exists(srcFile)) {
fsp_unlink(srcFile);
} }
return directDatabaseAccess; if (await fsp_exists(destFile)) {
fsp_unlink(destFile);
}
} }
exports.doImport = function (req, res, padId) exports.doImport = function (req, res, padId)
{ {
/**
* NB: abuse the 'req' object by storing an additional
* 'directDatabaseAccess' property on it so that it can
* be passed back in the HTML below.
*
* this is necessary because in the 'throw' paths of
* the function above there's no other way to return
* a value to the caller.
*/
let status = "ok"; let status = "ok";
let directDatabaseAccess; doImport(req, res, padId).catch(err => {
doImport(req, res, padId).then(result => {
directDatabaseAccess = result;
}).catch(err => {
// check for known errors and replace the status // check for known errors and replace the status
if (err == "uploadFailed" || err == "convertFailed" || err == "padHasData") { if (err == "uploadFailed" || err == "convertFailed" || err == "padHasData") {
status = err; status = err;
} else { } else {
throw err; throw err;
} }
}); }).then(() => {
// close the connection
// close the connection res.send(
res.send(
"<head> \ "<head> \
<script type='text/javascript' src='../../static/js/jquery.js'></script> \ <script type='text/javascript' src='../../static/js/jquery.js'></script> \
</head> \ </head> \
<script> \ <script> \
$(window).load(function(){ \ $(window).load(function(){ \
var impexp = window.parent.padimpexp.handleFrameCall('" + directDatabaseAccess +"', '" + status + "'); \ var impexp = window.parent.padimpexp.handleFrameCall('" + req.directDatabaseAccess +"', '" + status + "'); \
}) \ }) \
</script>" </script>"
); );
});
} }