mirror of
https://github.com/ONLYOFFICE/server.git
synced 2026-02-10 18:05:07 +08:00
[fix] azure command options
This commit is contained in:
13
.github/workflows/azureStorageTests.yml
vendored
13
.github/workflows/azureStorageTests.yml
vendored
@ -7,6 +7,7 @@ on:
|
|||||||
- 'tests/integration/withServerInstance/storage.tests.js'
|
- 'tests/integration/withServerInstance/storage.tests.js'
|
||||||
- 'Common/sources/storage/**'
|
- 'Common/sources/storage/**'
|
||||||
- 'DocService/sources/routes/static.js'
|
- 'DocService/sources/routes/static.js'
|
||||||
|
- '.github/workflows/azureStorageTests.yml'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
azure-storage-tests:
|
azure-storage-tests:
|
||||||
@ -62,6 +63,18 @@ jobs:
|
|||||||
},
|
},
|
||||||
"persistentStorage": {
|
"persistentStorage": {
|
||||||
"storageFolderName": "files/persistent"
|
"storageFolderName": "files/persistent"
|
||||||
|
},
|
||||||
|
"commandOptions": {
|
||||||
|
"az": {
|
||||||
|
"uploadData": {},
|
||||||
|
"uploadStream": {},
|
||||||
|
"download": {},
|
||||||
|
"syncCopyFromURL": {},
|
||||||
|
"listBlobsFlat": {
|
||||||
|
"maxPageSize": 1000
|
||||||
|
},
|
||||||
|
"deleteBlob": {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|||||||
@ -74,16 +74,19 @@ function getFilePath(storageCfg, strPath) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} input - Azure Blob command options
|
* @param {Object} baseOptions - Base options object
|
||||||
* @param {Object} storageCfg - Storage configuration
|
* @param {Object} storageCfg - Storage configuration
|
||||||
* @param {string} commandType - uploadData, uploadStream, download, etc.
|
* @param {string} commandType - uploadData, uploadStream, download, etc.
|
||||||
|
* @returns {Object|undefined} Merged options or undefined if empty
|
||||||
*/
|
*/
|
||||||
function applyCommandOptions(input, storageCfg, commandType) {
|
function applyCommandOptions(baseOptions, storageCfg, commandType) {
|
||||||
if (!storageCfg.commandOptions) return;
|
|
||||||
|
|
||||||
if (storageCfg.commandOptions.az && storageCfg.commandOptions.az[commandType]) {
|
if (storageCfg.commandOptions.az && storageCfg.commandOptions.az[commandType]) {
|
||||||
Object.assign(input, storageCfg.commandOptions.az[commandType]);
|
const configOptions = storageCfg.commandOptions.az[commandType];
|
||||||
|
if (configOptions && Object.keys(configOptions).length > 0) {
|
||||||
|
return {...baseOptions, ...configOptions};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return Object.keys(baseOptions).length > 0 ? baseOptions : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function listObjectsExec(storageCfg, prefix, output = []) {
|
async function listObjectsExec(storageCfg, prefix, output = []) {
|
||||||
@ -91,8 +94,8 @@ async function listObjectsExec(storageCfg, prefix, output = []) {
|
|||||||
const storageFolderName = storageCfg.storageFolderName;
|
const storageFolderName = storageCfg.storageFolderName;
|
||||||
const prefixWithFolder = storageFolderName ? `${storageFolderName}/${prefix}` : prefix;
|
const prefixWithFolder = storageFolderName ? `${storageFolderName}/${prefix}` : prefix;
|
||||||
|
|
||||||
const listOptions = {prefix: prefixWithFolder};
|
const baseOptions = {prefix: prefixWithFolder};
|
||||||
applyCommandOptions(listOptions, storageCfg, 'listBlobsFlat');
|
const listOptions = applyCommandOptions(baseOptions, storageCfg, 'listBlobsFlat');
|
||||||
|
|
||||||
for await (const blob of containerClient.listBlobsFlat(listOptions)) {
|
for await (const blob of containerClient.listBlobsFlat(listOptions)) {
|
||||||
const relativePath = storageFolderName ?
|
const relativePath = storageFolderName ?
|
||||||
@ -104,8 +107,7 @@ async function listObjectsExec(storageCfg, prefix, output = []) {
|
|||||||
|
|
||||||
async function deleteObjectsHelp(storageCfg, aKeys) {
|
async function deleteObjectsHelp(storageCfg, aKeys) {
|
||||||
const containerClient = getContainerClient(storageCfg);
|
const containerClient = getContainerClient(storageCfg);
|
||||||
const deleteOptions = {};
|
const deleteOptions = applyCommandOptions({}, storageCfg, 'deleteBlob');
|
||||||
applyCommandOptions(deleteOptions, storageCfg, 'deleteBlob');
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
aKeys.map(key => {
|
aKeys.map(key => {
|
||||||
return containerClient.deleteBlob(key.Key, deleteOptions);
|
return containerClient.deleteBlob(key.Key, deleteOptions);
|
||||||
@ -121,16 +123,14 @@ async function headObject(storageCfg, strPath) {
|
|||||||
|
|
||||||
async function getObject(storageCfg, strPath) {
|
async function getObject(storageCfg, strPath) {
|
||||||
const blobClient = getBlobClient(storageCfg, getFilePath(storageCfg, strPath));
|
const blobClient = getBlobClient(storageCfg, getFilePath(storageCfg, strPath));
|
||||||
const options = {};
|
const options = applyCommandOptions({}, storageCfg, 'download');
|
||||||
applyCommandOptions(options, storageCfg, 'download');
|
|
||||||
const response = await blobClient.download(options);
|
const response = await blobClient.download(options);
|
||||||
return await utils.stream2Buffer(response.readableStreamBody);
|
return await utils.stream2Buffer(response.readableStreamBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createReadStream(storageCfg, strPath) {
|
async function createReadStream(storageCfg, strPath) {
|
||||||
const blobClient = getBlobClient(storageCfg, getFilePath(storageCfg, strPath));
|
const blobClient = getBlobClient(storageCfg, getFilePath(storageCfg, strPath));
|
||||||
const options = {};
|
const options = applyCommandOptions({}, storageCfg, 'download');
|
||||||
applyCommandOptions(options, storageCfg, 'download');
|
|
||||||
const response = await blobClient.download(options);
|
const response = await blobClient.download(options);
|
||||||
return {
|
return {
|
||||||
contentLength: response.contentLength,
|
contentLength: response.contentLength,
|
||||||
@ -141,20 +141,17 @@ async function createReadStream(storageCfg, strPath) {
|
|||||||
async function putObject(storageCfg, strPath, buffer, contentLength) {
|
async function putObject(storageCfg, strPath, buffer, contentLength) {
|
||||||
const blobClient = getBlobClient(storageCfg, getFilePath(storageCfg, strPath));
|
const blobClient = getBlobClient(storageCfg, getFilePath(storageCfg, strPath));
|
||||||
|
|
||||||
const uploadOptions = {
|
const baseOptions = {
|
||||||
blobHTTPHeaders: {
|
blobHTTPHeaders: {
|
||||||
contentType: mime.getType(strPath),
|
contentType: mime.getType(strPath),
|
||||||
contentDisposition: utils.getContentDisposition(path.basename(strPath))
|
contentDisposition: utils.getContentDisposition(path.basename(strPath))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const uploadOptions = applyCommandOptions(baseOptions, storageCfg, 'uploadData');
|
||||||
|
|
||||||
if (buffer instanceof Buffer) {
|
if (buffer instanceof Buffer) {
|
||||||
// Handle Buffer upload
|
|
||||||
applyCommandOptions(uploadOptions, storageCfg, 'uploadData');
|
|
||||||
await blobClient.uploadData(buffer, uploadOptions);
|
await blobClient.uploadData(buffer, uploadOptions);
|
||||||
} else if (typeof buffer.pipe === 'function') {
|
} else if (typeof buffer.pipe === 'function') {
|
||||||
// Handle Stream upload
|
|
||||||
applyCommandOptions(uploadOptions, storageCfg, 'uploadStream');
|
|
||||||
await blobClient.uploadStream(buffer, undefined, undefined, uploadOptions);
|
await blobClient.uploadStream(buffer, undefined, undefined, uploadOptions);
|
||||||
} else {
|
} else {
|
||||||
throw new TypeError('Input must be Buffer or Readable stream');
|
throw new TypeError('Input must be Buffer or Readable stream');
|
||||||
@ -171,13 +168,13 @@ async function uploadObject(storageCfg, strPath, filePath) {
|
|||||||
contentDisposition: utils.getContentDisposition(path.basename(strPath))
|
contentDisposition: utils.getContentDisposition(path.basename(strPath))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
applyCommandOptions(uploadOptions, storageCfg, 'uploadStream');
|
const finalOptions = applyCommandOptions(uploadOptions, storageCfg, 'uploadStream');
|
||||||
|
|
||||||
await blockBlobClient.uploadStream(
|
await blockBlobClient.uploadStream(
|
||||||
uploadStream,
|
uploadStream,
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
uploadOptions
|
finalOptions
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,8 +189,7 @@ async function copyObject(storageCfgSrc, storageCfgDst, sourceKey, destinationKe
|
|||||||
expiresOn: new Date(Date.now() + 3600 * 1000)
|
expiresOn: new Date(Date.now() + 3600 * 1000)
|
||||||
}, new StorageSharedKeyCredential(storageCfgSrc.accessKeyId, storageCfgSrc.secretAccessKey)).toString();
|
}, new StorageSharedKeyCredential(storageCfgSrc.accessKeyId, storageCfgSrc.secretAccessKey)).toString();
|
||||||
|
|
||||||
const copyOptions = {};
|
const copyOptions = applyCommandOptions({}, storageCfgDst, 'syncCopyFromURL');
|
||||||
applyCommandOptions(copyOptions, storageCfgDst, 'syncCopyFromURL');
|
|
||||||
await destBlobClient.syncCopyFromURL(`${sourceBlobClient.url}?${sasToken}`, copyOptions);
|
await destBlobClient.syncCopyFromURL(`${sourceBlobClient.url}?${sasToken}`, copyOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,8 +199,7 @@ async function listObjects(storageCfg, strPath) {
|
|||||||
|
|
||||||
async function deleteObject(storageCfg, strPath) {
|
async function deleteObject(storageCfg, strPath) {
|
||||||
const blobClient = getBlobClient(storageCfg, getFilePath(storageCfg, strPath));
|
const blobClient = getBlobClient(storageCfg, getFilePath(storageCfg, strPath));
|
||||||
const options = {};
|
const options = applyCommandOptions({}, storageCfg, 'deleteBlob');
|
||||||
applyCommandOptions(options, storageCfg, 'deleteBlob');
|
|
||||||
await blobClient.delete(options);
|
await blobClient.delete(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user