add append mode for sabre
This commit is contained in:
parent
ae4e67f3b4
commit
f1a06a3f52
@ -248,7 +248,8 @@ export class FakeFsWebdav extends FakeFs {
|
|||||||
vaultFolderExists: boolean;
|
vaultFolderExists: boolean;
|
||||||
saveUpdatedConfigFunc: () => Promise<any>;
|
saveUpdatedConfigFunc: () => Promise<any>;
|
||||||
|
|
||||||
supportNativePartial: boolean;
|
supportApachePartial: boolean;
|
||||||
|
supportSabrePartial: boolean;
|
||||||
isNextcloud: boolean;
|
isNextcloud: boolean;
|
||||||
nextcloudUploadServerAddress: string;
|
nextcloudUploadServerAddress: string;
|
||||||
|
|
||||||
@ -265,7 +266,8 @@ export class FakeFsWebdav extends FakeFs {
|
|||||||
this.vaultFolderExists = false;
|
this.vaultFolderExists = false;
|
||||||
this.saveUpdatedConfigFunc = saveUpdatedConfigFunc;
|
this.saveUpdatedConfigFunc = saveUpdatedConfigFunc;
|
||||||
|
|
||||||
this.supportNativePartial = false;
|
this.supportApachePartial = false;
|
||||||
|
this.supportSabrePartial = false;
|
||||||
this.isNextcloud = false;
|
this.isNextcloud = false;
|
||||||
this.nextcloudUploadServerAddress = "";
|
this.nextcloudUploadServerAddress = "";
|
||||||
}
|
}
|
||||||
@ -401,15 +403,20 @@ export class FakeFsWebdav extends FakeFs {
|
|||||||
// taken from https://github.com/perry-mitchell/webdav-client/blob/master/source/operations/partialUpdateFileContents.ts
|
// taken from https://github.com/perry-mitchell/webdav-client/blob/master/source/operations/partialUpdateFileContents.ts
|
||||||
// which is under MIT license
|
// which is under MIT license
|
||||||
if (
|
if (
|
||||||
(compliance.server.includes("Apache") &&
|
compliance.server.includes("Apache") &&
|
||||||
compliance.compliance.includes(
|
compliance.compliance.includes("<http://apache.org/dav/propset/fs/1>")
|
||||||
"<http://apache.org/dav/propset/fs/1>"
|
|
||||||
)) ||
|
|
||||||
compliance.compliance.includes("sabredav-partialupdate")
|
|
||||||
) {
|
) {
|
||||||
this.supportNativePartial = true;
|
this.supportApachePartial = true;
|
||||||
console.debug(
|
console.debug(
|
||||||
`supportNativePartial=true, compliance=${JSON.stringify(compliance)}`
|
`supportApachePartial=true, compliance=${JSON.stringify(compliance)}`
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compliance.compliance.includes("sabredav-partialupdate")) {
|
||||||
|
this.supportSabrePartial = true;
|
||||||
|
console.debug(
|
||||||
|
`supportSabrePartial=true, compliance=${JSON.stringify(compliance)}`
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -581,7 +588,11 @@ export class FakeFsWebdav extends FakeFs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// larger than 10 MB
|
// larger than 10 MB
|
||||||
if (!this.isNextcloud && !this.supportNativePartial) {
|
if (
|
||||||
|
!this.isNextcloud &&
|
||||||
|
!this.supportApachePartial &&
|
||||||
|
!this.supportSabrePartial
|
||||||
|
) {
|
||||||
// give up and upload by whole, and directly return
|
// give up and upload by whole, and directly return
|
||||||
return await this._writeFileFromRootFull(
|
return await this._writeFileFromRootFull(
|
||||||
key,
|
key,
|
||||||
@ -602,8 +613,16 @@ export class FakeFsWebdav extends FakeFs {
|
|||||||
ctime,
|
ctime,
|
||||||
origKey
|
origKey
|
||||||
);
|
);
|
||||||
} else if (this.supportNativePartial) {
|
} else if (this.supportApachePartial) {
|
||||||
return await this._writeFileFromRootNativePartial(
|
return await this._writeFileFromRootApachePartial(
|
||||||
|
key,
|
||||||
|
content,
|
||||||
|
mtime,
|
||||||
|
ctime,
|
||||||
|
origKey
|
||||||
|
);
|
||||||
|
} else if (this.supportSabrePartial) {
|
||||||
|
return await this._writeFileFromRootSabrePartial(
|
||||||
key,
|
key,
|
||||||
content,
|
content,
|
||||||
mtime,
|
mtime,
|
||||||
@ -619,7 +638,7 @@ export class FakeFsWebdav extends FakeFs {
|
|||||||
console.error(e);
|
console.error(e);
|
||||||
throw e;
|
throw e;
|
||||||
// this.isNextcloud = false;
|
// this.isNextcloud = false;
|
||||||
// this.supportNativePartial = false;
|
// this.supportApachePartial = false;
|
||||||
// return await this._writeFileFromRootFull(
|
// return await this._writeFileFromRootFull(
|
||||||
// key,
|
// key,
|
||||||
// content,
|
// content,
|
||||||
@ -764,7 +783,7 @@ export class FakeFsWebdav extends FakeFs {
|
|||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _writeFileFromRootNativePartial(
|
async _writeFileFromRootApachePartial(
|
||||||
key: string,
|
key: string,
|
||||||
content: ArrayBuffer,
|
content: ArrayBuffer,
|
||||||
mtime: number,
|
mtime: number,
|
||||||
@ -786,6 +805,8 @@ export class FakeFsWebdav extends FakeFs {
|
|||||||
content.byteLength,
|
content.byteLength,
|
||||||
sizePerChunk
|
sizePerChunk
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// TODO: parallel
|
||||||
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];
|
||||||
await this.client.partialUpdateFileContents(
|
await this.client.partialUpdateFileContents(
|
||||||
@ -800,6 +821,47 @@ export class FakeFsWebdav extends FakeFs {
|
|||||||
return await this.stat(origKey);
|
return await this.stat(origKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _writeFileFromRootSabrePartial(
|
||||||
|
key: string,
|
||||||
|
content: ArrayBuffer,
|
||||||
|
mtime: number,
|
||||||
|
ctime: number,
|
||||||
|
origKey: string
|
||||||
|
): Promise<Entity> {
|
||||||
|
// firstly upload a 0-byte data
|
||||||
|
await this._writeFileFromRootFull(
|
||||||
|
key,
|
||||||
|
new ArrayBuffer(0),
|
||||||
|
mtime,
|
||||||
|
ctime,
|
||||||
|
origKey
|
||||||
|
);
|
||||||
|
|
||||||
|
// then "update" by chunks
|
||||||
|
const sizePerChunk = 5 * 1024 * 1024; // 5 mb
|
||||||
|
const chunkRanges = splitFileSizeToChunkRanges(
|
||||||
|
content.byteLength,
|
||||||
|
sizePerChunk
|
||||||
|
);
|
||||||
|
|
||||||
|
// diff from apachePartial: we use "append" header here for dufs...
|
||||||
|
// we cannot parallel here
|
||||||
|
for (let i = 0; i < chunkRanges.length; ++i) {
|
||||||
|
const { start, end } = chunkRanges[i];
|
||||||
|
await this.client.customRequest(key, {
|
||||||
|
method: "PATCH",
|
||||||
|
headers: {
|
||||||
|
"X-Update-Range": "append",
|
||||||
|
"Content-Type": "application/x-sabredav-partialupdate",
|
||||||
|
},
|
||||||
|
data: content.slice(start, end + 1),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// lastly return
|
||||||
|
return await this.stat(origKey);
|
||||||
|
}
|
||||||
|
|
||||||
async readFile(key: string): Promise<ArrayBuffer> {
|
async readFile(key: string): Promise<ArrayBuffer> {
|
||||||
if (key.endsWith("/")) {
|
if (key.endsWith("/")) {
|
||||||
throw Error(`you should not call readFile on ${key}`);
|
throw Error(`you should not call readFile on ${key}`);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user