mirror of
https://github.com/ONLYOFFICE/server.git
synced 2026-02-10 18:05:07 +08:00
[wopi] Fix downloadfile handler for wopi; fix bug 66612
# Conflicts: # DocService/sources/canvasservice.js # DocService/sources/wopiClient.js
This commit is contained in:
@ -2242,7 +2242,7 @@ exports.install = function(server, callbackFunction) {
|
||||
let queryParams = decoded.queryParams;
|
||||
data.lang = queryParams.lang || queryParams.ui || "en-US";
|
||||
}
|
||||
if (decoded.fileInfo) {
|
||||
if (wopiClient.isWopiJwtToken(decoded)) {
|
||||
let fileInfo = decoded.fileInfo;
|
||||
if (openCmd) {
|
||||
openCmd.format = wopiClient.getFileTypeByInfo(fileInfo);
|
||||
@ -2397,7 +2397,7 @@ exports.install = function(server, callbackFunction) {
|
||||
}
|
||||
|
||||
//todo make required fields
|
||||
if (decoded.url || decoded.payload|| (decoded.key && !decoded.fileInfo)) {
|
||||
if (decoded.url || decoded.payload|| (decoded.key && !wopiClient.isWopiJwtToken(decoded))) {
|
||||
ctx.logger.warn('fillDataFromJwt token has invalid format');
|
||||
res = false;
|
||||
}
|
||||
@ -2438,7 +2438,7 @@ exports.install = function(server, callbackFunction) {
|
||||
isDecoded = true;
|
||||
let decoded = checkJwtRes.decoded;
|
||||
let fillDataFromJwtRes = false;
|
||||
if (decoded.fileInfo) {
|
||||
if (wopiClient.isWopiJwtToken(decoded)) {
|
||||
//wopi
|
||||
fillDataFromJwtRes = fillDataFromWopiJwt(decoded, data);
|
||||
} else if (decoded.editorConfig && undefined !== decoded.editorConfig.ds_view) {
|
||||
|
||||
@ -1598,6 +1598,7 @@ exports.downloadFile = function(req, res) {
|
||||
let authorization;
|
||||
let isInJwtToken = false;
|
||||
let errorDescription;
|
||||
let headers;
|
||||
let authRes = yield docsCoServer.getRequestParams(ctx, req);
|
||||
if (authRes.code === constants.NO_ERROR) {
|
||||
let decoded = authRes.params;
|
||||
@ -1610,6 +1611,8 @@ exports.downloadFile = function(req, res) {
|
||||
} else if (decoded.url && -1 !== tenDownloadFileAllowExt.indexOf(decoded.fileType)) {
|
||||
url = decoded.url;
|
||||
isInJwtToken = true;
|
||||
} else if (wopiClient.isWopiJwtToken(decoded)) {
|
||||
({url, headers} = wopiClient.getWopiFileUrl(ctx, decoded.fileInfo, decoded.userAuth));
|
||||
} else if (!tenTokenEnableBrowser) {
|
||||
//todo token required
|
||||
if (decoded.url) {
|
||||
@ -1638,11 +1641,12 @@ exports.downloadFile = function(req, res) {
|
||||
res.sendStatus(filterStatus);
|
||||
return;
|
||||
}
|
||||
let headers;
|
||||
|
||||
if (req.get('Range')) {
|
||||
headers = {
|
||||
'Range': req.get('Range')
|
||||
if (!headers) {
|
||||
headers = {};
|
||||
}
|
||||
headers['Range'] = req.get('Range');
|
||||
}
|
||||
|
||||
yield utils.downloadUrlPromise(ctx, url, tenDownloadTimeout, tenDownloadMaxBytes, authorization, isInJwtToken, headers, res);
|
||||
|
||||
@ -63,6 +63,7 @@ const cfgTokenEnableBrowser = config.get('services.CoAuthoring.token.enable.brow
|
||||
const cfgCallbackRequestTimeout = config.get('services.CoAuthoring.server.callbackRequestTimeout');
|
||||
const cfgNewFileTemplate = config.get('services.CoAuthoring.server.newFileTemplate');
|
||||
const cfgDownloadTimeout = config.get('FileConverter.converter.downloadTimeout');
|
||||
const cfgMaxDownloadBytes = config.get('FileConverter.converter.maxDownloadBytes');
|
||||
const cfgWopiFileInfoBlockList = config.get('wopi.fileInfoBlockList');
|
||||
const cfgWopiWopiZone = config.get('wopi.wopiZone');
|
||||
const cfgWopiPdfView = config.get('wopi.pdfView');
|
||||
@ -289,6 +290,25 @@ function getFileTypeByInfo(fileInfo) {
|
||||
fileType = fileInfo.FileExtension ? fileInfo.FileExtension.substr(1) : fileType;
|
||||
return fileType.toLowerCase();
|
||||
}
|
||||
function getWopiFileUrl(ctx, fileInfo, userAuth) {
|
||||
const tenMaxDownloadBytes = ctx.getCfg('FileConverter.converter.maxDownloadBytes', cfgMaxDownloadBytes);
|
||||
let url;
|
||||
let headers = {'X-WOPI-MaxExpectedSize': tenMaxDownloadBytes};
|
||||
if (fileInfo?.FileUrl) {
|
||||
//Requests to the FileUrl can not be signed using proof keys. The FileUrl is used exactly as provided by the host, so it does not necessarily include the access token, which is required to construct the expected proof.
|
||||
url = fileInfo.FileUrl;
|
||||
} else if (fileInfo?.TemplateSource) {
|
||||
url = fileInfo.TemplateSource;
|
||||
} else if (userAuth) {
|
||||
url = `${userAuth.wopiSrc}/contents?access_token=${userAuth.access_token}`;
|
||||
fillStandardHeaders(ctx, headers, url, userAuth.access_token);
|
||||
}
|
||||
ctx.logger.debug('getWopiFileUrl url=%s; headers=%j', url, headers);
|
||||
return {url, headers};
|
||||
}
|
||||
function isWopiJwtToken(decoded) {
|
||||
return !!decoded.fileInfo;
|
||||
}
|
||||
function getLastModifiedTimeFromCallbacks(callbacks) {
|
||||
for (let i = callbacks.length; i >= 0; --i) {
|
||||
let callback = callbacks[i];
|
||||
@ -952,6 +972,8 @@ exports.fillStandardHeaders = fillStandardHeaders;
|
||||
exports.getWopiUnlockMarker = getWopiUnlockMarker;
|
||||
exports.getWopiModifiedMarker = getWopiModifiedMarker;
|
||||
exports.getFileTypeByInfo = getFileTypeByInfo;
|
||||
exports.getWopiFileUrl = getWopiFileUrl;
|
||||
exports.isWopiJwtToken = isWopiJwtToken;
|
||||
exports.dummyCheckFileInfo = dummyCheckFileInfo;
|
||||
exports.dummyGetFile = dummyGetFile;
|
||||
exports.dummyOk = dummyOk;
|
||||
|
||||
@ -429,7 +429,6 @@ function* downloadFile(ctx, uri, fileFrom, withAuthorization, isInJwtToken, opt_
|
||||
return res;
|
||||
}
|
||||
function* downloadFileFromStorage(ctx, strPath, dir, opt_specialDir) {
|
||||
const tenMaxDownloadBytes = ctx.getCfg('FileConverter.converter.maxDownloadBytes', cfgMaxDownloadBytes);
|
||||
var list = yield storage.listObjects(ctx, strPath, opt_specialDir);
|
||||
ctx.logger.debug('downloadFileFromStorage list %s', list.toString());
|
||||
//create dirs
|
||||
@ -1002,7 +1001,6 @@ function* spawnProcess(ctx, builderParams, tempDirs, dataConvert, authorProps, g
|
||||
}
|
||||
|
||||
function* ExecuteTask(ctx, task) {
|
||||
const tenMaxDownloadBytes = ctx.getCfg('FileConverter.converter.maxDownloadBytes', cfgMaxDownloadBytes);
|
||||
const tenForgottenFiles = ctx.getCfg('services.CoAuthoring.server.forgottenfiles', cfgForgottenFiles);
|
||||
const tenForgottenFilesName = ctx.getCfg('services.CoAuthoring.server.forgottenfilesname', cfgForgottenFilesName);
|
||||
var startDate = null;
|
||||
@ -1039,19 +1037,8 @@ function* ExecuteTask(ctx, task) {
|
||||
withAuthorization = false;
|
||||
isInJwtToken = true;
|
||||
let fileInfo = wopiParams.commonInfo?.fileInfo;
|
||||
let userAuth = wopiParams.userAuth;
|
||||
fileSize = fileInfo?.Size;
|
||||
if (fileInfo?.FileUrl) {
|
||||
//Requests to the FileUrl can not be signed using proof keys. The FileUrl is used exactly as provided by the host, so it does not necessarily include the access token, which is required to construct the expected proof.
|
||||
url = fileInfo.FileUrl;
|
||||
} else if (fileInfo?.TemplateSource) {
|
||||
url = fileInfo.TemplateSource;
|
||||
} else if (userAuth) {
|
||||
url = `${userAuth.wopiSrc}/contents?access_token=${userAuth.access_token}`;
|
||||
headers = {'X-WOPI-MaxExpectedSize': tenMaxDownloadBytes};
|
||||
wopiClient.fillStandardHeaders(ctx, headers, url, userAuth.access_token);
|
||||
}
|
||||
ctx.logger.debug('wopi url=%s; headers=%j', url, headers);
|
||||
({url, headers} = wopiClient.getWopiFileUrl(ctx, fileInfo, wopiParams.userAuth));
|
||||
}
|
||||
if (undefined === fileSize || fileSize > 0) {
|
||||
error = yield* downloadFile(ctx, url, dataConvert.fileFrom, withAuthorization, isInJwtToken, headers);
|
||||
|
||||
Reference in New Issue
Block a user