no auto for webdav depth

This commit is contained in:
fyears 2024-01-16 01:22:54 +08:00
parent cabca54d80
commit c33a9ecfa4
9 changed files with 70 additions and 296 deletions

View File

@ -48,10 +48,10 @@ export interface DropboxConfig {
export type WebdavAuthType = "digest" | "basic"; export type WebdavAuthType = "digest" | "basic";
export type WebdavDepthType = export type WebdavDepthType =
| "auto" | "auto" // deprecated on 20240116
| "auto_unknown" | "auto_unknown" // deprecated on 20240116
| "auto_1" | "auto_1" // deprecated on 20240116
| "auto_infinity" | "auto_infinity" // deprecated on 20240116
| "manual_1" | "manual_1"
| "manual_infinity"; | "manual_infinity";
@ -60,9 +60,14 @@ export interface WebdavConfig {
username: string; username: string;
password: string; password: string;
authType: WebdavAuthType; authType: WebdavAuthType;
manualRecursive: boolean; // deprecated in 0.3.6, use depth
depth?: WebdavDepthType; depth?: WebdavDepthType;
remoteBaseDir?: string; remoteBaseDir?: string;
/**
* @deprecated
*/
manualRecursive: boolean; // deprecated in 0.3.6, use depth
} }
export interface OnedriveConfig { export interface OnedriveConfig {

View File

@ -224,8 +224,7 @@
"settings_webdav_auth": "Auth Type", "settings_webdav_auth": "Auth Type",
"settings_webdav_auth_desc": "If no password, this option would be ignored.", "settings_webdav_auth_desc": "If no password, this option would be ignored.",
"settings_webdav_depth": "Depth Header Sent To Servers", "settings_webdav_depth": "Depth Header Sent To Servers",
"settings_webdav_depth_desc": "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\".", "settings_webdav_depth_desc": "Webdav servers should be configured to allow requests with header Depth being '1' or 'Infinity'. If you are not sure what's this, choose \"depth='1'\". If you are sure your server supports depth='infinity', please choose that to get way better performance.",
"settings_webdav_depth_auto": "auto detect",
"settings_webdav_depth_1": "only supports depth='1'", "settings_webdav_depth_1": "only supports depth='1'",
"settings_webdav_depth_inf": "supports depth='infinity'", "settings_webdav_depth_inf": "supports depth='infinity'",
"settings_webdav_connect_succ": "Great! The webdav server can be accessed.", "settings_webdav_connect_succ": "Great! The webdav server can be accessed.",

View File

@ -224,8 +224,7 @@
"settings_webdav_auth": "鉴权类型", "settings_webdav_auth": "鉴权类型",
"settings_webdav_auth_desc": "如果不填写密码,本设置会被忽略。", "settings_webdav_auth_desc": "如果不填写密码,本设置会被忽略。",
"settings_webdav_depth": "发送到服务器的 Depth header", "settings_webdav_depth": "发送到服务器的 Depth header",
"settings_webdav_depth_desc": "Webdav 服务器会被设为接收 Depth header 为“1”或“Infinity”请求。本插件需要得知此信息。如果您不清楚如何设置可以选择“自动检测”", "settings_webdav_depth_desc": "Webdav 服务器会被设为接收 Depth header 为“1”或“Infinity”请求。如果您不清楚如何设置可以选择 depth='1'。如果那你确认服务器支持 depth='infinity',请选择它,会获得更加好的性能。",
"settings_webdav_depth_auto": "自动检测",
"settings_webdav_depth_1": "只支持 depth='1'", "settings_webdav_depth_1": "只支持 depth='1'",
"settings_webdav_depth_inf": "支持 depth='infinity'", "settings_webdav_depth_inf": "支持 depth='infinity'",
"settings_webdav_connect_succ": "很好!可以连接上 Webdav 服务器。", "settings_webdav_connect_succ": "很好!可以连接上 Webdav 服务器。",

View File

@ -224,8 +224,7 @@
"settings_webdav_auth": "鑑權型別", "settings_webdav_auth": "鑑權型別",
"settings_webdav_auth_desc": "如果不填寫密碼,本設定會被忽略。", "settings_webdav_auth_desc": "如果不填寫密碼,本設定會被忽略。",
"settings_webdav_depth": "傳送到伺服器的 Depth header", "settings_webdav_depth": "傳送到伺服器的 Depth header",
"settings_webdav_depth_desc": "Webdav 伺服器會被設為接收 Depth header 為“1”或“Infinity”請求。本外掛需要得知此資訊。如果您不清楚如何設定可以選擇“自動檢測”", "settings_webdav_depth_desc": "Webdav 伺服器會被設為接收 Depth header 為“1”或“Infinity”請求。如果您不清楚如何設定可以選擇 depth='1'。如果那你確認伺服器支援 depth='infinity',請選擇它,會獲得更加好的效能。",
"settings_webdav_depth_auto": "自動檢測",
"settings_webdav_depth_1": "只支援 depth='1'", "settings_webdav_depth_1": "只支援 depth='1'",
"settings_webdav_depth_inf": "支援 depth='infinity'", "settings_webdav_depth_inf": "支援 depth='infinity'",
"settings_webdav_connect_succ": "很好!可以連線上 Webdav 伺服器。", "settings_webdav_connect_succ": "很好!可以連線上 Webdav 伺服器。",

View File

@ -66,7 +66,6 @@ import type { LangType, LangTypeAndAuto, TransItemType } from "./i18n";
import { DeletionOnRemote, MetadataOnRemote } from "./metadataOnRemote"; import { DeletionOnRemote, MetadataOnRemote } from "./metadataOnRemote";
import { SyncAlgoV2Modal } from "./syncAlgoV2Notice"; import { SyncAlgoV2Modal } from "./syncAlgoV2Notice";
import { applyPresetRulesInplace } from "./presetRules";
import { applyLogWriterInplace, log } from "./moreOnLog"; import { applyLogWriterInplace, log } from "./moreOnLog";
import AggregateError from "aggregate-error"; import AggregateError from "aggregate-error";
@ -443,7 +442,6 @@ export default class RemotelySavePlugin extends Plugin {
this.currSyncMsg = ""; this.currSyncMsg = "";
await this.loadSettings(); await this.loadSettings();
await this.checkIfPresetRulesFollowed();
// lang should be load early, but after settings // lang should be load early, but after settings
this.i18n = new I18n(this.settings.lang!, async (lang: LangTypeAndAuto) => { this.i18n = new I18n(this.settings.lang!, async (lang: LangTypeAndAuto) => {
@ -868,10 +866,18 @@ export default class RemotelySavePlugin extends Plugin {
this.settings.onedrive.remoteBaseDir = ""; this.settings.onedrive.remoteBaseDir = "";
} }
if (this.settings.webdav.manualRecursive === undefined) { if (this.settings.webdav.manualRecursive === undefined) {
this.settings.webdav.manualRecursive = false; this.settings.webdav.manualRecursive = true;
} }
if (this.settings.webdav.depth === undefined) { if (
this.settings.webdav.depth = "auto_unknown"; this.settings.webdav.depth === undefined ||
this.settings.webdav.depth === "auto" ||
this.settings.webdav.depth === "auto_1" ||
this.settings.webdav.depth === "auto_infinity" ||
this.settings.webdav.depth === "auto_unknown"
) {
// auto is deprecated as of 20240116
this.settings.webdav.depth = "manual_1";
this.settings.webdav.manualRecursive = true;
} }
if (this.settings.webdav.remoteBaseDir === undefined) { if (this.settings.webdav.remoteBaseDir === undefined) {
this.settings.webdav.remoteBaseDir = ""; this.settings.webdav.remoteBaseDir = "";
@ -910,13 +916,6 @@ export default class RemotelySavePlugin extends Plugin {
await this.saveSettings(); await this.saveSettings();
} }
async checkIfPresetRulesFollowed() {
const res = applyPresetRulesInplace(this.settings);
if (res.changed) {
await this.saveSettings();
}
}
async saveSettings() { async saveSettings() {
await this.saveData(normalConfigToMessy(this.settings)); await this.saveData(normalConfigToMessy(this.settings));
} }

View File

@ -1,69 +0,0 @@
import type {
RemotelySavePluginSettings,
WebdavConfig,
WebdavDepthType,
} from "./baseTypes";
const RULES = {
webdav: {
depth: [
{
url: "^https://(.+).teracloud.jp/.+",
depth: "auto_1",
manualRecursive: true,
},
{
url: "^https://dav.jianguoyun.com/dav/",
depth: "auto_1",
manualRecursive: true,
},
],
},
};
export const applyWebdavPresetRulesInplace = (
webdav: Partial<WebdavConfig> | undefined
) => {
if (webdav === undefined) {
return {
changed: false,
webdav: webdav,
};
}
for (const { url, depth, manualRecursive } of RULES.webdav.depth) {
if (
webdav.address !== undefined &&
new RegExp(url).test(webdav.address) &&
webdav.depth !== undefined &&
webdav.depth.startsWith("auto_") &&
webdav.depth !== depth
) {
webdav.depth = depth as WebdavDepthType;
webdav.manualRecursive = manualRecursive;
return {
changed: true,
webdav: webdav,
};
}
}
return {
changed: false,
webdav: webdav,
};
};
export const applyPresetRulesInplace = (
settings: RemotelySavePluginSettings | undefined
) => {
if (settings === undefined) {
return {
changed: false,
settings: settings,
};
}
const webdavRes = applyWebdavPresetRulesInplace(settings.webdav);
return {
changed: webdavRes.changed,
settings: settings,
};
};

View File

@ -166,8 +166,8 @@ export const DEFAULT_WEBDAV_CONFIG = {
username: "", username: "",
password: "", password: "",
authType: "basic", authType: "basic",
manualRecursive: false, manualRecursive: true,
depth: "auto_unknown", depth: "manual_1",
remoteBaseDir: "", remoteBaseDir: "",
} as WebdavConfig; } as WebdavConfig;
@ -279,56 +279,19 @@ export class WrappedWebdavClient {
} }
// adjust depth parameter // adjust depth parameter
if (this.webdavConfig.depth === "auto_unknown") { if (
let testPassed = false; this.webdavConfig.depth === "auto" ||
try { this.webdavConfig.depth === "auto_1" ||
const res = await this.client.customRequest(`/${this.remoteBaseDir}/`, { this.webdavConfig.depth === "auto_infinity" ||
method: "PROPFIND", this.webdavConfig.depth === "auto_unknown"
headers: { ) {
Depth: "infinity", this.webdavConfig.depth = "manual_1";
Accept: "text/plain,application/xml", this.webdavConfig.manualRecursive = true;
}, if (this.saveUpdatedConfigFunc !== undefined) {
// responseType: "text", await this.saveUpdatedConfigFunc();
} as any); log.info(
if (res.status === 403) { `webdav depth="auto_???" is changed to ${this.webdavConfig.depth}`
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.remoteBaseDir}/`,
{
method: "PROPFIND",
headers: {
Depth: "1",
Accept: "text/plain,application/xml",
},
// responseType: "text",
} as any
);
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}`
);
}
} }
} }
}; };
@ -453,7 +416,10 @@ export const listAllFromRemote = async (client: WrappedWebdavClient) => {
let contents = [] as FileStat[]; let contents = [] as FileStat[];
if ( if (
client.webdavConfig.depth === "auto" ||
client.webdavConfig.depth === "auto_unknown" ||
client.webdavConfig.depth === "auto_1" || client.webdavConfig.depth === "auto_1" ||
client.webdavConfig.depth === "auto_infinity" /* don't trust auto now */ ||
client.webdavConfig.depth === "manual_1" client.webdavConfig.depth === "manual_1"
) { ) {
// the remote doesn't support infinity propfind, // the remote doesn't support infinity propfind,

View File

@ -43,7 +43,6 @@ import {
import { messyConfigToNormal } from "./configPersist"; import { messyConfigToNormal } from "./configPersist";
import type { TransItemType } from "./i18n"; import type { TransItemType } from "./i18n";
import { checkHasSpecialCharForDir } from "./misc"; import { checkHasSpecialCharForDir } from "./misc";
import { applyWebdavPresetRulesInplace } from "./presetRules";
import { import {
applyLogWriterInplace, applyLogWriterInplace,
@ -1462,16 +1461,16 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
.setValue(this.plugin.settings.webdav.address) .setValue(this.plugin.settings.webdav.address)
.onChange(async (value) => { .onChange(async (value) => {
this.plugin.settings.webdav.address = value.trim(); this.plugin.settings.webdav.address = value.trim();
// deprecate auto on 20240116, force to manual_1
if ( if (
this.plugin.settings.webdav.depth === "auto" ||
this.plugin.settings.webdav.depth === "auto_1" || this.plugin.settings.webdav.depth === "auto_1" ||
this.plugin.settings.webdav.depth === "auto_infinity" this.plugin.settings.webdav.depth === "auto_infinity" ||
this.plugin.settings.webdav.depth === "auto_unknown"
) { ) {
this.plugin.settings.webdav.depth = "auto_unknown"; this.plugin.settings.webdav.depth = "manual_1";
} }
// TODO: any more elegant way?
applyWebdavPresetRulesInplace(this.plugin.settings.webdav);
// normally saved // normally saved
await this.plugin.saveSettings(); await this.plugin.saveSettings();
}) })
@ -1487,11 +1486,14 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
.setValue(this.plugin.settings.webdav.username) .setValue(this.plugin.settings.webdav.username)
.onChange(async (value) => { .onChange(async (value) => {
this.plugin.settings.webdav.username = value.trim(); this.plugin.settings.webdav.username = value.trim();
// deprecate auto on 20240116, force to manual_1
if ( if (
this.plugin.settings.webdav.depth === "auto" ||
this.plugin.settings.webdav.depth === "auto_1" || this.plugin.settings.webdav.depth === "auto_1" ||
this.plugin.settings.webdav.depth === "auto_infinity" this.plugin.settings.webdav.depth === "auto_infinity" ||
this.plugin.settings.webdav.depth === "auto_unknown"
) { ) {
this.plugin.settings.webdav.depth = "auto_unknown"; this.plugin.settings.webdav.depth = "manual_1";
} }
await this.plugin.saveSettings(); await this.plugin.saveSettings();
}); });
@ -1507,11 +1509,14 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
.setValue(this.plugin.settings.webdav.password) .setValue(this.plugin.settings.webdav.password)
.onChange(async (value) => { .onChange(async (value) => {
this.plugin.settings.webdav.password = value.trim(); this.plugin.settings.webdav.password = value.trim();
// deprecate auto on 20240116, force to manual_1
if ( if (
this.plugin.settings.webdav.depth === "auto" ||
this.plugin.settings.webdav.depth === "auto_1" || this.plugin.settings.webdav.depth === "auto_1" ||
this.plugin.settings.webdav.depth === "auto_infinity" this.plugin.settings.webdav.depth === "auto_infinity" ||
this.plugin.settings.webdav.depth === "auto_unknown"
) { ) {
this.plugin.settings.webdav.depth = "auto_unknown"; this.plugin.settings.webdav.depth = "manual_1";
} }
await this.plugin.saveSettings(); await this.plugin.saveSettings();
}); });
@ -1544,41 +1549,23 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
.setName(t("settings_webdav_depth")) .setName(t("settings_webdav_depth"))
.setDesc(t("settings_webdav_depth_desc")) .setDesc(t("settings_webdav_depth_desc"))
.addDropdown((dropdown) => { .addDropdown((dropdown) => {
dropdown.addOption("auto", t("settings_webdav_depth_auto"));
dropdown.addOption("manual_1", t("settings_webdav_depth_1")); dropdown.addOption("manual_1", t("settings_webdav_depth_1"));
dropdown.addOption("manual_infinity", t("settings_webdav_depth_inf")); dropdown.addOption("manual_infinity", t("settings_webdav_depth_inf"));
let initVal: WebdavDepthType = "auto"; dropdown
const autoOptions: Set<WebdavDepthType> = new Set([ .setValue(this.plugin.settings.webdav.depth || "manual_1")
"auto_unknown", .onChange(async (val) => {
"auto_1", if (val === "manual_1") {
"auto_infinity", this.plugin.settings.webdav.depth = "manual_1";
]); this.plugin.settings.webdav.manualRecursive = true;
if (autoOptions.has(this.plugin.settings.webdav.depth as any)) { } else if (val === "manual_infinity") {
initVal = "auto"; this.plugin.settings.webdav.depth = "manual_infinity";
} else { this.plugin.settings.webdav.manualRecursive = false;
initVal = this.plugin.settings.webdav.depth || "auto"; }
}
type DepthOption = "auto" | "manual_1" | "manual_infinity"; // normally save
dropdown.setValue(initVal).onChange(async (val) => { await this.plugin.saveSettings();
if (val === "auto") { });
this.plugin.settings.webdav.depth = "auto_unknown";
this.plugin.settings.webdav.manualRecursive = false;
} else if (val === "manual_1") {
this.plugin.settings.webdav.depth = "manual_1";
this.plugin.settings.webdav.manualRecursive = true;
} else if (val === "manual_infinity") {
this.plugin.settings.webdav.depth = "manual_infinity";
this.plugin.settings.webdav.manualRecursive = false;
}
// TODO: any more elegant way?
applyWebdavPresetRulesInplace(this.plugin.settings.webdav);
// normally save
await this.plugin.saveSettings();
});
}); });
let newWebdavRemoteBaseDir = let newWebdavRemoteBaseDir =

View File

@ -1,111 +0,0 @@
import { expect } from "chai";
import type { WebdavConfig } from "../src/baseTypes";
import { applyWebdavPresetRulesInplace } from "../src/presetRules";
describe("Preset rules tests", () => {
it("should check undefined correctly", () => {
let x: Partial<WebdavConfig> | undefined = undefined;
const y = applyWebdavPresetRulesInplace(x);
expect(y.webdav === undefined);
expect(!y.changed);
});
it("should check empty object", () => {
let x: Partial<WebdavConfig> | undefined = {};
const y = applyWebdavPresetRulesInplace(x);
expect(y.webdav).deep.equals({});
expect(!y.changed);
});
it("should modify depths correctly", () => {
let x: Partial<WebdavConfig> = {
address: "https://example.teracloud.jp/dav/",
depth: "auto_unknown",
};
let y = applyWebdavPresetRulesInplace(x);
expect(x.depth === "auto_1");
expect(y.changed);
x = {
address: "https://example.teracloud.jp/dav/example",
depth: "auto_unknown",
};
y = applyWebdavPresetRulesInplace(x);
expect(x.depth === "auto_1");
expect(y.changed);
x = {
address: "https://dav.jianguoyun.com/dav/",
depth: "auto_unknown",
};
y = applyWebdavPresetRulesInplace(x);
expect(x.depth === "auto_1");
expect(y.changed);
x = {
address: "https://dav.jianguoyun.com/dav/",
depth: "auto_infinity",
};
y = applyWebdavPresetRulesInplace(x);
expect(x.depth === "auto_1");
expect(y.changed);
});
it("should not modify depths if depths is set automatically correctly", () => {
let x: Partial<WebdavConfig> = {
address: "https://dav.jianguoyun.com/dav/",
depth: "auto_1",
};
let y = applyWebdavPresetRulesInplace(x);
expect(x.depth === "auto_1");
expect(!y.changed);
});
it("should not modify depths if depths have been set manually", () => {
let x: Partial<WebdavConfig> = {
address: "https://example.teracloud.jp/dav/",
depth: "manual_infinity",
};
let y = applyWebdavPresetRulesInplace(x);
expect(x.depth === "manual_infinity");
expect(!y.changed);
x = {
address: "https://example.teracloud.jp/dav/example",
depth: "manual_1",
};
y = applyWebdavPresetRulesInplace(x);
expect(x.depth === "manual_1");
expect(!y.changed);
});
it("should not modify depths when urls are not in preset rules", () => {
let x: Partial<WebdavConfig> = {
address: "https://teracloud.jp/dav/",
depth: "auto_unknown",
};
applyWebdavPresetRulesInplace(x);
expect(x.depth === "auto_unknown");
x = {
address: "https://dav.jianguoyun.com/dav_example",
depth: "auto_unknown",
};
applyWebdavPresetRulesInplace(x);
expect(x.depth === "auto_unknown");
x = {
address: "",
depth: "auto_unknown",
};
applyWebdavPresetRulesInplace(x);
expect(x.depth === "auto_unknown");
x = {
address: "https://dav.jianguoyun.com/dav/",
depth: "what" as any,
};
applyWebdavPresetRulesInplace(x);
expect(x.depth === ("what" as any));
});
});