fix: remove trailing slash or space before constructing s3 uri (#516)
Closes #496
This commit is contained in:
parent
d53b24bfb4
commit
39ae0cfe6d
2 changed files with 111 additions and 3 deletions
106
app/server/utils/restic.test.ts
Normal file
106
app/server/utils/restic.test.ts
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
import { describe, expect, test } from "bun:test";
|
||||||
|
import { buildRepoUrl } from "./restic";
|
||||||
|
|
||||||
|
describe("buildRepoUrl", () => {
|
||||||
|
describe("S3 backend", () => {
|
||||||
|
test("should build URL without trailing slash", () => {
|
||||||
|
const config = {
|
||||||
|
backend: "s3" as const,
|
||||||
|
endpoint: "https://s3.amazonaws.com",
|
||||||
|
bucket: "my-bucket",
|
||||||
|
accessKeyId: "test",
|
||||||
|
secretAccessKey: "test",
|
||||||
|
};
|
||||||
|
expect(buildRepoUrl(config)).toBe("s3:https://s3.amazonaws.com/my-bucket");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should trim trailing slash from endpoint", () => {
|
||||||
|
const config = {
|
||||||
|
backend: "s3" as const,
|
||||||
|
endpoint: "https://s3.xxxxxxxxx.net/",
|
||||||
|
bucket: "backup",
|
||||||
|
accessKeyId: "test",
|
||||||
|
secretAccessKey: "test",
|
||||||
|
};
|
||||||
|
expect(buildRepoUrl(config)).toBe("s3:https://s3.xxxxxxxxx.net/backup");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should trim trailing whitespace from endpoint", () => {
|
||||||
|
const config = {
|
||||||
|
backend: "s3" as const,
|
||||||
|
endpoint: "https://s3.amazonaws.com/ ",
|
||||||
|
bucket: "my-bucket",
|
||||||
|
accessKeyId: "test",
|
||||||
|
secretAccessKey: "test",
|
||||||
|
};
|
||||||
|
expect(buildRepoUrl(config)).toBe("s3:https://s3.amazonaws.com/my-bucket");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should trim leading and trailing whitespace from endpoint", () => {
|
||||||
|
const config = {
|
||||||
|
backend: "s3" as const,
|
||||||
|
endpoint: " https://s3.amazonaws.com/ ",
|
||||||
|
bucket: "my-bucket",
|
||||||
|
accessKeyId: "test",
|
||||||
|
secretAccessKey: "test",
|
||||||
|
};
|
||||||
|
expect(buildRepoUrl(config)).toBe("s3:https://s3.amazonaws.com/my-bucket");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("R2 backend", () => {
|
||||||
|
test("should build URL without trailing slash", () => {
|
||||||
|
const config = {
|
||||||
|
backend: "r2" as const,
|
||||||
|
endpoint: "https://myaccount.r2.cloudflarestorage.com",
|
||||||
|
bucket: "my-bucket",
|
||||||
|
accessKeyId: "test",
|
||||||
|
secretAccessKey: "test",
|
||||||
|
};
|
||||||
|
expect(buildRepoUrl(config)).toBe("s3:myaccount.r2.cloudflarestorage.com/my-bucket");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should trim trailing slash from endpoint", () => {
|
||||||
|
const config = {
|
||||||
|
backend: "r2" as const,
|
||||||
|
endpoint: "https://myaccount.r2.cloudflarestorage.com/",
|
||||||
|
bucket: "backup",
|
||||||
|
accessKeyId: "test",
|
||||||
|
secretAccessKey: "test",
|
||||||
|
};
|
||||||
|
expect(buildRepoUrl(config)).toBe("s3:myaccount.r2.cloudflarestorage.com/backup");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should strip protocol and trailing slash", () => {
|
||||||
|
const config = {
|
||||||
|
backend: "r2" as const,
|
||||||
|
endpoint: "https://myaccount.r2.cloudflarestorage.com/",
|
||||||
|
bucket: "my-bucket",
|
||||||
|
accessKeyId: "test",
|
||||||
|
secretAccessKey: "test",
|
||||||
|
};
|
||||||
|
expect(buildRepoUrl(config)).toBe("s3:myaccount.r2.cloudflarestorage.com/my-bucket");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should trim whitespace and strip protocol", () => {
|
||||||
|
const config = {
|
||||||
|
backend: "r2" as const,
|
||||||
|
endpoint: " https://myaccount.r2.cloudflarestorage.com/ ",
|
||||||
|
bucket: "my-bucket",
|
||||||
|
accessKeyId: "test",
|
||||||
|
secretAccessKey: "test",
|
||||||
|
};
|
||||||
|
expect(buildRepoUrl(config)).toBe("s3:myaccount.r2.cloudflarestorage.com/my-bucket");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("other backends", () => {
|
||||||
|
test("should build local repository URL", () => {
|
||||||
|
const config = {
|
||||||
|
backend: "local" as const,
|
||||||
|
path: "/path/to/repo",
|
||||||
|
};
|
||||||
|
expect(buildRepoUrl(config)).toBe("/path/to/repo");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -43,10 +43,12 @@ export const buildRepoUrl = (config: RepositoryConfig): string => {
|
||||||
switch (config.backend) {
|
switch (config.backend) {
|
||||||
case "local":
|
case "local":
|
||||||
return config.path;
|
return config.path;
|
||||||
case "s3":
|
case "s3": {
|
||||||
return `s3:${config.endpoint}/${config.bucket}`;
|
const endpoint = config.endpoint.trim().replace(/\/$/, "");
|
||||||
|
return `s3:${endpoint}/${config.bucket}`;
|
||||||
|
}
|
||||||
case "r2": {
|
case "r2": {
|
||||||
const endpoint = config.endpoint.replace(/^https?:\/\//, "");
|
const endpoint = config.endpoint.trim().replace(/^https?:\/\//, "").replace(/\/$/, "");
|
||||||
return `s3:${endpoint}/${config.bucket}`;
|
return `s3:${endpoint}/${config.bucket}`;
|
||||||
}
|
}
|
||||||
case "gcs":
|
case "gcs":
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue