mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 23:05:46 +00:00
fix(cover): sanitize server_index_key so Windows :port URLs work (#889)
* fix(cover): sanitize server_index_key on disk so Windows accepts ":port" URLs `serverIndexKeyFromUrl` (frontend) strips the URL scheme and leaves the rest of the host as the index key — for a Navidrome instance running on the default `:4533` port that is `host:4533/...`. On Linux/macOS the `:` is fine as a path segment; on Windows `CreateDirectory` rejects the whole path with `ERROR_INVALID_NAME` (os error 123). Result: every `cover_cache_ensure` and `cover_cache_peek_batch` rejected its promise and the album / now-playing / mainstage / lightbox surfaces stayed blank. Empirically verified — switching the active server to a colon-free reverse-proxy URL made the covers load again without any other change. Centralize the fix in a new `cover_server_dir(root, key)` helper next to the existing `cover_entity_relative_dir`: it runs `sanitize_path_segment` on the server key the same way kind/entity ids are already cleaned, so `host:4533` becomes `host_4533` and embedded URL paths collapse into one flat bucket instead of nested directories. Every call site that wants the server bucket — `cover_dir`, `count_cached_cover_ids`, `dir_usage_for_server`, the clear-server command, and `clear_cover_fetch_failures` in the backfill worker — now goes through it. The on-disk layout changes (no more colons, no more nested URL paths), so bump `LAYOUT_STAMP` to `canonical-segment-v4`. The existing stamp-mismatch sweep at startup wipes the legacy buckets — users with a previously-working (colon-free) layout rebuild the cache lazily as they browse. Library, offline, and hot-cache data are not touched. Adds two unit tests covering the sanitization on `cover_server_dir` and the `cover_dir` passthrough. Follow-up to #878 (which introduced `cover_cache_layout.rs` with `sanitize_path_segment` applied only to kind/entity_id). * chore(windows): silence dead_code warnings in debug taskbar_win build `lib.rs` gates `taskbar_win::init` on `cfg(not(debug_assertions))` (PR #866 — debug runs alongside an installed release instance and must not fight it for the taskbar subclass). The `update_taskbar_icon` command still ships in debug and early-returns until `init` populates the COM/HWND atomics, so the init-only helpers (icon HICONs, button IDs, subclass plumbing, `make_buttons`, `subclass_proc`, `init` itself) all look unused — 14 dead_code warnings on every Windows debug `cargo build`. File-level `#![cfg_attr(debug_assertions, allow(dead_code))]` suppresses those warnings only in the debug profile. Release builds keep the strict dead-code check, so a real removal would still surface there. * docs(release): CHANGELOG for windows cover-cache server-key fix (PR #889)
This commit is contained in:
committed by
GitHub
parent
ae2e123a14
commit
839c438a6d
@@ -10,7 +10,8 @@ use encode::write_webp_tier;
|
||||
use fetch::build_cover_art_url;
|
||||
use image::{DynamicImage, ImageReader};
|
||||
use psysonic_core::cover_cache_layout::{
|
||||
count_entities_with_canonical_tier, cover_root_disk_usage, server_cover_disk_usage,
|
||||
count_entities_with_canonical_tier, cover_root_disk_usage, cover_server_dir,
|
||||
server_cover_disk_usage,
|
||||
};
|
||||
use psysonic_library::cover_backfill::{
|
||||
clear_cover_fetch_failures, collect_cover_backfill_batch, collect_cover_progress,
|
||||
@@ -400,7 +401,7 @@ fn spawn_derive_remaining_tiers(
|
||||
|
||||
/// Entity dirs with canonical `800.webp` under `album/` and `artist/` (segment layout).
|
||||
pub(crate) fn count_cached_cover_ids(root: &Path, server_index_key: &str) -> i64 {
|
||||
let keyed = count_entities_with_canonical_tier(&root.join(server_index_key));
|
||||
let keyed = count_entities_with_canonical_tier(&cover_server_dir(root, server_index_key));
|
||||
if keyed > 0 {
|
||||
return keyed;
|
||||
}
|
||||
@@ -419,7 +420,7 @@ pub(crate) fn count_cached_cover_ids(root: &Path, server_index_key: &str) -> i64
|
||||
}
|
||||
|
||||
pub(crate) fn dir_usage_for_server(root: &Path, server_index_key: &str) -> (u64, u64) {
|
||||
server_cover_disk_usage(&root.join(server_index_key))
|
||||
server_cover_disk_usage(&cover_server_dir(root, server_index_key))
|
||||
}
|
||||
|
||||
pub(crate) fn dir_usage_at_root(root: &Path) -> (u64, u64) {
|
||||
@@ -693,7 +694,7 @@ pub async fn cover_cache_clear_server(
|
||||
) -> Result<(), String> {
|
||||
let st = state(&app)?;
|
||||
let guard = st.lock().await;
|
||||
let path = guard.root.join(&server_index_key);
|
||||
let path = cover_server_dir(&guard.root, &server_index_key);
|
||||
if path.is_dir() {
|
||||
std::fs::remove_dir_all(&path).map_err(|e| e.to_string())?;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user