Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions lib/db/db-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,13 @@ const initializer = combine(databaseSchema.parse({}), (set, get) => ({
proxy: Omit<FileProxy, "file_proxy_id" | "created_at">,
): FileProxy => {
let newProxy: FileProxy
const normalizedProxy = {
...proxy,
matching_pattern: normalizeMatchingPattern(proxy.matching_pattern),
}
set((state) => {
newProxy = {
...proxy,
...normalizedProxy,
file_proxy_id: state.idCounter.toString(),
created_at: new Date().toISOString(),
} as FileProxy
Expand All @@ -232,11 +236,13 @@ const initializer = combine(databaseSchema.parse({}), (set, get) => ({
matching_pattern?: string
}): FileProxy | undefined => {
const state = get()
const matchingPattern = query.matching_pattern
? normalizeMatchingPattern(query.matching_pattern)
: undefined
return state.file_proxies.find(
(p) =>
(query.file_proxy_id && p.file_proxy_id === query.file_proxy_id) ||
(query.matching_pattern &&
p.matching_pattern === query.matching_pattern),
(matchingPattern && p.matching_pattern === matchingPattern),
)
},

Expand All @@ -261,3 +267,11 @@ const initializer = combine(databaseSchema.parse({}), (set, get) => ({
return undefined
},
}))

function normalizeMatchingPattern(matching_pattern: string): string {
if (!matching_pattern.endsWith("/*")) {
return normalizePath(matching_pattern)
}

return `${normalizePath(matching_pattern.slice(0, -2))}/*`
}
30 changes: 30 additions & 0 deletions tests/routes/file-proxy01.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,33 @@ test("file proxy create validation - duplicate pattern", async () => {
status: 400,
})
})

test("file proxy patterns normalize leading slashes for lookup and duplicates", async () => {
const { axios } = await getTestServer()

const createRes = await axios.post("/file_proxies/create", {
proxy_type: "disk",
disk_path: "/tmp/test",
matching_pattern: "/normalized/*",
})
expect(createRes.status).toBe(200)
expect(createRes.data.file_proxy.matching_pattern).toBe("normalized/*")

const getWithLeadingSlash = await axios.get("/file_proxies/get", {
params: { matching_pattern: "/normalized/*" },
})
expect(getWithLeadingSlash.status).toBe(200)
expect(getWithLeadingSlash.data.file_proxy.file_proxy_id).toBe(
createRes.data.file_proxy.file_proxy_id,
)

await expect(
axios.post("/file_proxies/create", {
proxy_type: "http",
http_target_url: "https://example.com",
matching_pattern: "normalized/*",
}),
).rejects.toMatchObject({
status: 400,
})
})
6 changes: 3 additions & 3 deletions tests/routes/file-proxy04.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,14 @@ test("proxy pattern with leading slash normalization", async () => {
try {
await writeFile(join(tempDir, "normalized.txt"), "Normalized path content")

// Create proxy with pattern (without leading slash in pattern)
// Create proxy with a leading slash in the pattern
await axios.post("/file_proxies/create", {
proxy_type: "disk",
disk_path: tempDir,
matching_pattern: "slash-test/*",
matching_pattern: "/slash-test/*",
})

// Should work with leading slash in the request path
// Should normalize the proxy pattern and match the request path
const res = await axios.get("/files/download/slash-test/normalized.txt")
expect(res.status).toBe(200)
expect(res.data).toBe("Normalized path content")
Expand Down
Loading