From 20afda586943313617f99bafa686ea9407884348 Mon Sep 17 00:00:00 2001 From: O96u Date: Sun, 30 Aug 2026 12:33:33 +0800 Subject: [PATCH] =?UTF-8?q?release:=20v1.2.3=20=E2=80=94=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E7=AE=80=E7=9F=AD=E5=9B=BE=E7=89=87=E9=93=BE=E6=8E=A5?= =?UTF-8?q?=E5=9C=A8=E6=8C=89=E5=B9=B4/=E6=9C=88=E5=AD=98=E5=82=A8?= =?UTF-8?q?=E4=B8=8B=20404?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 开启简短链接时纯文件名直链先经 SQLite 索引反查完整 key,不再误解析为扁平 images/文件名路径。 --- CHANGELOG.md | 6 ++++++ docs-site/en/guide/changelog.md | 8 ++++++++ docs-site/guide/changelog.md | 8 ++++++++ package-lock.json | 4 ++-- package.json | 2 +- server/utils/serve-image-path.test.ts | 27 ++++++++++++++++++++++++--- server/utils/serve-image.ts | 9 ++++++++- 7 files changed, 57 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f504438..5fe03fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ ## [Unreleased] +## [1.2.3] - 2026-08-30 + +### 修复 + +- 开启「简短图片链接」且按年/月分组时,纯文件名直链(如 `/xxx.webp`)误解析为 `images/xxx.webp` 导致 404;现先经 SQLite 索引反查完整 key + ## [1.2.2] - 2026-08-30 ### 修复 diff --git a/docs-site/en/guide/changelog.md b/docs-site/en/guide/changelog.md index 04a22ac..00b41f3 100644 --- a/docs-site/en/guide/changelog.md +++ b/docs-site/en/guide/changelog.md @@ -4,6 +4,14 @@ Version history and notable changes. The full log is also in the repo root [CHAN --- +## [1.2.3] — 2026-08-30 + +### Fix + +- **Short links + date-based storage**: bare filename URLs (e.g. `https://host/xxx.webp`) no longer map to flat `images/xxx.webp`; SQLite index resolves the full `images/YYYY/MM/xxx.webp` key so thumbnails and short links work again + +--- + ## [1.2.2] — 2026-08-30 > **Restart the service** after upgrading so middleware and API updates take effect. diff --git a/docs-site/guide/changelog.md b/docs-site/guide/changelog.md index b2a90a3..d800f81 100644 --- a/docs-site/guide/changelog.md +++ b/docs-site/guide/changelog.md @@ -4,6 +4,14 @@ PicHost 版本历史与重要变更说明。完整记录亦见仓库根目录 [C --- +## [1.2.3] — 2026-08-30 + +### 修复 + +- **简短图片链接 + 按年/月分组**:纯文件名直链(如 `https://域名/xxx.webp`)不再误当成 `images/xxx.webp`,改为经 SQLite 索引反查 `images/年/月/xxx.webp`,缩略图与短链恢复正常 + +--- + ## [1.2.2] — 2026-08-30 > 升级后请**重启服务**使中间件与 API 生效。 diff --git a/package-lock.json b/package-lock.json index 2ce25a5..a440a9a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pichost", - "version": "1.2.2", + "version": "1.2.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pichost", - "version": "1.2.2", + "version": "1.2.3", "hasInstallScript": true, "license": "GPL-3.0-only", "dependencies": { diff --git a/package.json b/package.json index 351db72..8c6c544 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pichost", - "version": "1.2.2", + "version": "1.2.3", "description": "Self-hosted image hosting for your NAS / home server — Nuxt admin UI, local disk or S3-compatible storage, server-side WebP compression, referer protection, Twikoo/EasyImage compatible.", "homepage": "https://github.com/O96u/PicHost#readme", "repository": { diff --git a/server/utils/serve-image-path.test.ts b/server/utils/serve-image-path.test.ts index dccbb02..b8d74d6 100644 --- a/server/utils/serve-image-path.test.ts +++ b/server/utils/serve-image-path.test.ts @@ -1,10 +1,31 @@ -import { describe, expect, it } from 'vitest' +import { describe, expect, it, vi, afterEach } from 'vitest' +import { findImageKeyByDatePath, findImageKeyByFilename } from './image-index' import { requestPathToImageKey } from './serve-image' +vi.mock('./image-index', async (importOriginal) => { + const actual = await importOriginal() + return { + ...actual, + findImageKeyByFilename: vi.fn(actual.findImageKeyByFilename), + findImageKeyByDatePath: vi.fn(actual.findImageKeyByDatePath) + } +}) + describe('requestPathToImageKey hide folder', () => { - it('resolves bare filename to default folder flat key', () => { + afterEach(() => { + vi.mocked(findImageKeyByFilename).mockReset() + vi.mocked(findImageKeyByDatePath).mockReset() + }) + + it('resolves bare filename via index when hide folder is enabled', () => { + vi.mocked(findImageKeyByFilename).mockReturnValue('images/2026/08/demo.webp') expect(requestPathToImageKey('/demo.webp', { hideFolder: true })) - .toBe('images/demo.webp') + .toBe('images/2026/08/demo.webp') + }) + + it('does not guess flat images/name when hide folder is enabled', () => { + vi.mocked(findImageKeyByFilename).mockReturnValue(null) + expect(requestPathToImageKey('/demo.webp', { hideFolder: true })).toBeNull() }) it('resolves hidden date path to default folder key', () => { diff --git a/server/utils/serve-image.ts b/server/utils/serve-image.ts index b2dd418..2927d5b 100644 --- a/server/utils/serve-image.ts +++ b/server/utils/serve-image.ts @@ -8,7 +8,7 @@ import { } from './env' import { findImageKeyByDatePath, findImageKeyByFilename } from './image-index' import { validateImageKey } from './image-key' -import { toStorageKeyFromPublicPath } from './image-public-path' +import { isBareImageFilename, toStorageKeyFromPublicPath } from './image-public-path' import { buildPublicImageUrl } from './image-response' import { createImageStream, headImage } from './storage' import { getBackendRowForKey } from './storage/resolver' @@ -85,6 +85,13 @@ export function requestPathToImageKey( if (validateImageKey(raw)) return raw + // 简短链接:纯文件名须先走索引反查,不能猜成 images/文件名(与按年/月存储冲突) + if (options?.hideFolder && isBareImageFilename(raw)) { + const byFilename = findImageKeyByFilename(raw) + if (byFilename && validateImageKey(byFilename)) return byFilename + return null + } + const fromPublic = toStorageKeyFromPublicPath(raw) if (fromPublic) return fromPublic