mirror of
https://github.com/remotely-save/remotely-save.git
synced 2024-06-07 21:10:45 +00:00
correct way for nextcloud
This commit is contained in:
parent
69e72eae1d
commit
7b3600a46f
132
src/fsWebdav.ts
132
src/fsWebdav.ts
@ -233,6 +233,7 @@ export class FakeFsWebdav extends FakeFs {
|
|||||||
|
|
||||||
supportNativePartial: boolean;
|
supportNativePartial: boolean;
|
||||||
isNextcloud: boolean;
|
isNextcloud: boolean;
|
||||||
|
nextcloudUploadServerAddress: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
webdavConfig: WebdavConfig,
|
webdavConfig: WebdavConfig,
|
||||||
@ -249,6 +250,7 @@ export class FakeFsWebdav extends FakeFs {
|
|||||||
|
|
||||||
this.supportNativePartial = false;
|
this.supportNativePartial = false;
|
||||||
this.isNextcloud = false;
|
this.isNextcloud = false;
|
||||||
|
this.nextcloudUploadServerAddress = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
async _init() {
|
async _init() {
|
||||||
@ -322,21 +324,50 @@ export class FakeFsWebdav extends FakeFs {
|
|||||||
await this._checkPartialSupport();
|
await this._checkPartialSupport();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_getnextcloudUploadServerAddress = () => {
|
||||||
|
const s = this.webdavConfig.address.split("/");
|
||||||
|
if (
|
||||||
|
s.length > 3 &&
|
||||||
|
s[s.length - 3] === "dav" &&
|
||||||
|
s[s.length - 2] === "files" &&
|
||||||
|
s[s.length - 1] !== ""
|
||||||
|
) {
|
||||||
|
s[s.length - 2] = "uploads";
|
||||||
|
return s.join("/");
|
||||||
|
}
|
||||||
|
throw Error(`cannot construct upload address for ${s}`);
|
||||||
|
};
|
||||||
|
|
||||||
async _checkPartialSupport() {
|
async _checkPartialSupport() {
|
||||||
const compliance = await this.client.getDAVCompliance(
|
const compliance = await this.client.getDAVCompliance(
|
||||||
`/${this.remoteBaseDir}/`
|
`/${this.remoteBaseDir}/`
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const c of compliance.compliance) {
|
for (const c of compliance.compliance) {
|
||||||
|
// nextcloud AND with an account
|
||||||
if (
|
if (
|
||||||
c.toLocaleLowerCase().includes("nextcloud") &&
|
c.toLocaleLowerCase().includes("nextcloud") &&
|
||||||
this.webdavConfig.username !== "" &&
|
this.webdavConfig.username !== "" &&
|
||||||
this.webdavConfig.password !== ""
|
this.webdavConfig.password !== ""
|
||||||
) {
|
) {
|
||||||
// nextcloud AND with an account
|
// the address is parsable
|
||||||
this.isNextcloud = true;
|
const s = this.webdavConfig.address.split("/");
|
||||||
console.debug(`isNextcloud=true`);
|
if (
|
||||||
return true;
|
s.length > 3 &&
|
||||||
|
s[s.length - 3] === "dav" &&
|
||||||
|
s[s.length - 2] === "files" &&
|
||||||
|
s[s.length - 1] !== ""
|
||||||
|
) {
|
||||||
|
this.isNextcloud = true;
|
||||||
|
this.nextcloudUploadServerAddress =
|
||||||
|
this._getnextcloudUploadServerAddress();
|
||||||
|
console.debug(
|
||||||
|
`isNextcloud=${this.isNextcloud}, uploadFolder=${this.nextcloudUploadServerAddress}`
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -530,16 +561,16 @@ export class FakeFsWebdav extends FakeFs {
|
|||||||
`we fail to write file partially, so downgrade to full and ignore the error:`
|
`we fail to write file partially, so downgrade to full and ignore the error:`
|
||||||
);
|
);
|
||||||
console.error(e);
|
console.error(e);
|
||||||
// throw e;
|
throw e;
|
||||||
this.isNextcloud = false;
|
// this.isNextcloud = false;
|
||||||
this.supportNativePartial = false;
|
// this.supportNativePartial = false;
|
||||||
return await this._writeFileFromRootFull(
|
// return await this._writeFileFromRootFull(
|
||||||
key,
|
// key,
|
||||||
content,
|
// content,
|
||||||
mtime,
|
// mtime,
|
||||||
ctime,
|
// ctime,
|
||||||
origKey
|
// origKey
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -586,40 +617,38 @@ export class FakeFsWebdav extends FakeFs {
|
|||||||
console.debug(`destUrl=${destUrl}`);
|
console.debug(`destUrl=${destUrl}`);
|
||||||
|
|
||||||
const getTmpFolder = (x: string) => {
|
const getTmpFolder = (x: string) => {
|
||||||
|
if (x.endsWith("/")) {
|
||||||
|
throw Error(`file to upload by chunk should not ends with /`);
|
||||||
|
}
|
||||||
const y = x.split("/");
|
const y = x.split("/");
|
||||||
y[y.length - 1] = `${y[y.length - 1]}-${nanoid()}`;
|
const z = encodeURI(`${y[y.length - 1]}`);
|
||||||
const nodot = y.join("/");
|
return z;
|
||||||
y[y.length - 1] = `.${y[y.length - 1]}`;
|
|
||||||
const withdot = y.join("/");
|
|
||||||
return {
|
|
||||||
withdot: withdot,
|
|
||||||
nodot: nodot,
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
const tmpFolders = getTmpFolder(key);
|
|
||||||
const tmpFolder = tmpFolders.withdot;
|
const uploadServerAddress = this.nextcloudUploadServerAddress;
|
||||||
const tmpFolderNoDot = tmpFolders.nodot;
|
console.debug(`uploadServerAddress=${uploadServerAddress}`);
|
||||||
console.debug(`tmpFolder=${tmpFolder}`);
|
const tmpFolderName = getTmpFolder(key);
|
||||||
const tmpFolderUrl = `${this.webdavConfig.address}/${encodeURI(tmpFolder)}`;
|
console.debug(`tmpFolderName=${tmpFolderName}`);
|
||||||
console.debug(`tmpFolderUrl=${tmpFolderUrl}`);
|
|
||||||
|
const clientForUpload = createClient(uploadServerAddress, {
|
||||||
|
username: this.webdavConfig.username,
|
||||||
|
password: this.webdavConfig.password,
|
||||||
|
headers: {
|
||||||
|
"Cache-Control": "no-cache",
|
||||||
|
},
|
||||||
|
authType:
|
||||||
|
this.webdavConfig.authType === "digest"
|
||||||
|
? AuthType.Digest
|
||||||
|
: AuthType.Password,
|
||||||
|
});
|
||||||
|
|
||||||
// create folder
|
// create folder
|
||||||
await this.client.createDirectory(tmpFolder, {
|
await clientForUpload.createDirectory(tmpFolderName, {
|
||||||
|
method: "MKCOL",
|
||||||
headers: {
|
headers: {
|
||||||
Destination: destUrl,
|
Destination: destUrl,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
try {
|
|
||||||
const tmpFolderResult = await this.client.stat(tmpFolder);
|
|
||||||
} catch (e) {
|
|
||||||
// not exists??
|
|
||||||
try {
|
|
||||||
// try to clean no dot folder
|
|
||||||
await this.client.deleteFile(tmpFolderNoDot);
|
|
||||||
} catch (e2) {}
|
|
||||||
this.isNextcloud = false;
|
|
||||||
throw Error(`cannot create hidden file into nextcloud: ${tmpFolder}`);
|
|
||||||
}
|
|
||||||
console.debug(`finish creating folder`);
|
console.debug(`finish creating folder`);
|
||||||
|
|
||||||
// upload by chunks
|
// upload by chunks
|
||||||
@ -631,13 +660,13 @@ export class FakeFsWebdav extends FakeFs {
|
|||||||
for (let i = 0; i < chunkRanges.length; ++i) {
|
for (let i = 0; i < chunkRanges.length; ++i) {
|
||||||
const { start, end } = chunkRanges[i];
|
const { start, end } = chunkRanges[i];
|
||||||
const tmpFileName = `${i + 1}`.padStart(5, "0");
|
const tmpFileName = `${i + 1}`.padStart(5, "0");
|
||||||
const tmpFileNameWithFolder = `${tmpFolder}/${tmpFileName}`;
|
const tmpFileNameWithFolder = `${tmpFolderName}/${tmpFileName}`;
|
||||||
console.debug(
|
console.debug(
|
||||||
`start to upload chunk ${
|
`start to upload chunk ${
|
||||||
i + 1
|
i + 1
|
||||||
} to ${tmpFileNameWithFolder} with startInclusive=${start}, endInclusive=${end}`
|
} to ${tmpFileNameWithFolder} with startInclusive=${start}, endInclusive=${end}`
|
||||||
);
|
);
|
||||||
await this.client.putFileContents(
|
await clientForUpload.putFileContents(
|
||||||
tmpFileNameWithFolder,
|
tmpFileNameWithFolder,
|
||||||
content.slice(start, end + 1),
|
content.slice(start, end + 1),
|
||||||
{
|
{
|
||||||
@ -651,9 +680,9 @@ export class FakeFsWebdav extends FakeFs {
|
|||||||
console.debug(`finish upload all chunks`);
|
console.debug(`finish upload all chunks`);
|
||||||
|
|
||||||
// move to assemble
|
// move to assemble
|
||||||
const fakeFileToMoveUrl = `${tmpFolderUrl}/.file`;
|
const fakeFileToMoveUrl = `${tmpFolderName}/.file`;
|
||||||
console.debug(`fakeFileToMoveUrl=${fakeFileToMoveUrl}`);
|
console.debug(`fakeFileToMoveUrl=${fakeFileToMoveUrl}`);
|
||||||
await this.client.customRequest(fakeFileToMoveUrl, {
|
await clientForUpload.customRequest(fakeFileToMoveUrl, {
|
||||||
method: "MOVE",
|
method: "MOVE",
|
||||||
headers: {
|
headers: {
|
||||||
Destination: destUrl,
|
Destination: destUrl,
|
||||||
@ -663,21 +692,6 @@ export class FakeFsWebdav extends FakeFs {
|
|||||||
console.debug(`finish moving file`);
|
console.debug(`finish moving file`);
|
||||||
// TODO: setting X-OC-Mtime
|
// TODO: setting X-OC-Mtime
|
||||||
|
|
||||||
// wait for anything broken??
|
|
||||||
await delay(1000);
|
|
||||||
|
|
||||||
// clean up!
|
|
||||||
console.debug(`try to clean up`);
|
|
||||||
try {
|
|
||||||
await this.client.deleteFile(tmpFolder);
|
|
||||||
console.debug(`finish clean up`);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(
|
|
||||||
`while cleaning chunks of nextcloud, some errors occur but we ignore them:`
|
|
||||||
);
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// stat
|
// stat
|
||||||
console.debug(`before stat origKey=${origKey}`);
|
console.debug(`before stat origKey=${origKey}`);
|
||||||
const k = await this.stat(origKey);
|
const k = await this.stat(origKey);
|
||||||
|
@ -686,7 +686,7 @@ export const splitFileSizeToChunkRanges = (
|
|||||||
) => {
|
) => {
|
||||||
if (totalSize < 0) {
|
if (totalSize < 0) {
|
||||||
throw Error(`totalSize should not be negative`);
|
throw Error(`totalSize should not be negative`);
|
||||||
}
|
}
|
||||||
if (chunkSize <= 0) {
|
if (chunkSize <= 0) {
|
||||||
throw Error(`chunkSize should not be negative or zero`);
|
throw Error(`chunkSize should not be negative or zero`);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user