full detect code

This commit is contained in:
fyears 2022-03-12 22:42:54 +08:00
parent 479d2a4fac
commit 915d027b12
4 changed files with 106 additions and 27 deletions

View File

@ -26,7 +26,12 @@ export interface DropboxConfig {
} }
export type WebdavAuthType = "digest" | "basic"; export type WebdavAuthType = "digest" | "basic";
export type WebdavDepthType = "auto_unknown" | "auto_1" | "auto_infinity" | "manual_1" | "manual_infinity"; export type WebdavDepthType =
| "auto_unknown"
| "auto_1"
| "auto_infinity"
| "manual_1"
| "manual_infinity";
export interface WebdavConfig { export interface WebdavConfig {
address: string; address: string;

View File

@ -41,11 +41,17 @@ export class RemoteClient {
this.s3Config = s3Config; this.s3Config = s3Config;
this.s3Client = s3.getS3Client(this.s3Config); this.s3Client = s3.getS3Client(this.s3Config);
} else if (serviceType === "webdav") { } else if (serviceType === "webdav") {
if (vaultName === undefined) { if (vaultName === undefined || saveUpdatedConfigFunc === undefined) {
throw Error("remember to provide vault name while init webdav client"); throw Error(
"remember to provide vault name and callback while init webdav client"
);
} }
this.webdavConfig = webdavConfig; this.webdavConfig = webdavConfig;
this.webdavClient = webdav.getWebdavClient(this.webdavConfig, vaultName); this.webdavClient = webdav.getWebdavClient(
this.webdavConfig,
vaultName,
saveUpdatedConfigFunc
);
} else if (serviceType === "dropbox") { } else if (serviceType === "dropbox") {
if (vaultName === undefined || saveUpdatedConfigFunc === undefined) { if (vaultName === undefined || saveUpdatedConfigFunc === undefined) {
throw Error( throw Error(

View File

@ -118,6 +118,7 @@ export const DEFAULT_WEBDAV_CONFIG = {
password: "", password: "",
authType: "basic", authType: "basic",
manualRecursive: false, manualRecursive: false,
depth: "auto_unknown",
} as WebdavConfig; } as WebdavConfig;
const getWebdavPath = (fileOrFolderPath: string, vaultName: string) => { const getWebdavPath = (fileOrFolderPath: string, vaultName: string) => {
@ -166,10 +167,16 @@ export class WrappedWebdavClient {
vaultName: string; vaultName: string;
client: WebDAVClient; client: WebDAVClient;
vaultFolderExists: boolean; vaultFolderExists: boolean;
constructor(webdavConfig: WebdavConfig, vaultName: string) { saveUpdatedConfigFunc: () => Promise<any>;
constructor(
webdavConfig: WebdavConfig,
vaultName: string,
saveUpdatedConfigFunc: () => Promise<any>
) {
this.webdavConfig = webdavConfig; this.webdavConfig = webdavConfig;
this.vaultName = vaultName; this.vaultName = vaultName;
this.vaultFolderExists = false; this.vaultFolderExists = false;
this.saveUpdatedConfigFunc = saveUpdatedConfigFunc;
} }
init = async () => { init = async () => {
@ -208,14 +215,68 @@ export class WrappedWebdavClient {
this.vaultFolderExists = true; this.vaultFolderExists = true;
} }
} }
// adjust depth parameter
if (this.webdavConfig.depth === "auto_unknown") {
let testPassed = false;
try {
const res = await this.client.customRequest(`/${this.vaultName}`, {
method: "PROPFIND",
headers: {
Depth: "Infinity",
},
responseType: "text",
});
if (res.status === 403) {
throw Error("not support Infinity, get 403");
} else {
testPassed = true;
this.webdavConfig.depth = "auto_infinity";
this.webdavConfig.manualRecursive = false;
}
} catch (error) {
testPassed = false;
}
if (!testPassed) {
try {
const res = await this.client.customRequest(`/${this.vaultName}`, {
method: "PROPFIND",
headers: {
Depth: "1",
},
responseType: "text",
});
testPassed = true;
this.webdavConfig.depth = "auto_1";
this.webdavConfig.manualRecursive = true;
} catch (error) {
testPassed = false;
}
}
if (testPassed) {
// the depth option has been changed
// save the setting
if (this.saveUpdatedConfigFunc !== undefined) {
await this.saveUpdatedConfigFunc();
log.info(
`webdav depth="auto_unknown" is changed to ${this.webdavConfig.depth}`
);
}
}
}
}; };
} }
export const getWebdavClient = ( export const getWebdavClient = (
webdavConfig: WebdavConfig, webdavConfig: WebdavConfig,
vaultName: string vaultName: string,
saveUpdatedConfigFunc: () => Promise<any>
) => { ) => {
return new WrappedWebdavClient(webdavConfig, vaultName); return new WrappedWebdavClient(
webdavConfig,
vaultName,
saveUpdatedConfigFunc
);
}; };
export const getRemoteMeta = async ( export const getRemoteMeta = async (
@ -318,7 +379,10 @@ export const listFromRemote = async (
await client.init(); await client.init();
let contents = [] as FileStat[]; let contents = [] as FileStat[];
if (client.webdavConfig.manualRecursive) { if (
client.webdavConfig.depth === "auto_1" ||
client.webdavConfig.depth === "manual_1"
) {
// the remote doesn't support infinity propfind, // the remote doesn't support infinity propfind,
// we need to do a bfs here // we need to do a bfs here
const q = new Queue([`/${client.vaultName}`]); const q = new Queue([`/${client.vaultName}`]);

View File

@ -1076,7 +1076,7 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
new Setting(webdavDiv) new Setting(webdavDiv)
.setName("depth header sent to servers") .setName("depth header sent to servers")
.setDesc( .setDesc(
"Webdav servers should be configured to allow requests with header Depth being '1' or 'infinity'. The plugin needs to know this info. If you are not sure what's this, choose \"auto\"." "Webdav servers should be configured to allow requests with header Depth being '1' or 'Infinity'. The plugin needs to know this info. If you are not sure what's this, choose \"auto\"."
) )
.addDropdown((dropdown) => { .addDropdown((dropdown) => {
dropdown.addOption("auto", "auto detect"); dropdown.addOption("auto", "auto detect");
@ -1084,17 +1084,19 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
dropdown.addOption("manual_infinity", "only supports depth='infinity'"); dropdown.addOption("manual_infinity", "only supports depth='infinity'");
let initVal = "auto"; let initVal = "auto";
const autoOptions: Set<WebdavDepthType> = new Set(["auto_unknown", "auto_1", "auto_infinity"]); const autoOptions: Set<WebdavDepthType> = new Set([
"auto_unknown",
"auto_1",
"auto_infinity",
]);
if (autoOptions.has(this.plugin.settings.webdav.depth)) { if (autoOptions.has(this.plugin.settings.webdav.depth)) {
initVal = "auto"; initVal = "auto";
} else { } else {
initVal = this.plugin.settings.webdav.depth || "auto"; initVal = this.plugin.settings.webdav.depth || "auto";
} }
type DepthOption = "auto" | "manual_1" | "manual_infinity" type DepthOption = "auto" | "manual_1" | "manual_infinity";
dropdown dropdown.setValue(initVal).onChange(async (val: DepthOption) => {
.setValue( initVal)
.onChange(async (val: DepthOption) => {
if (val === "auto") { if (val === "auto") {
this.plugin.settings.webdav.depth = "auto_unknown"; this.plugin.settings.webdav.depth = "auto_unknown";
this.plugin.settings.webdav.manualRecursive = false; this.plugin.settings.webdav.manualRecursive = false;
@ -1116,13 +1118,15 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
button.setButtonText("Check"); button.setButtonText("Check");
button.onClick(async () => { button.onClick(async () => {
new Notice("Checking..."); new Notice("Checking...");
const self = this;
const client = new RemoteClient( const client = new RemoteClient(
"webdav", "webdav",
undefined, undefined,
this.plugin.settings.webdav, this.plugin.settings.webdav,
undefined, undefined,
undefined, undefined,
this.app.vault.getName() this.app.vault.getName(),
() => self.plugin.saveSettings()
); );
const res = await client.checkConnectivity(); const res = await client.checkConnectivity();
if (res) { if (res) {