From 7df5f0a1c25428d760dd42f95757e84293028dac Mon Sep 17 00:00:00 2001 From: Test User Date: Fri, 24 Jul 2026 15:54:31 +0200 Subject: [PATCH] jamendo: send a User-Agent (Jamendo returns empty results without one) Jamendo API v3.0 answers HTTP 200 success with an empty result set to any request that carries no User-Agent header. reqwest sends none by default, so every search/detail/stream call came back empty and tracks would not resolve or play (jamendo resource not found). Set a UA on the JamApi client, like the SoundCloud provider does. Live-verified against the API: search, track detail, and stream-URL resolution all return data with the header present. Co-Authored-By: Claude Opus 4.8 (1M context) --- architecture/jamendo-provider.md | 5 +++++ jamendody/src/api.rs | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/architecture/jamendo-provider.md b/architecture/jamendo-provider.md index 5037bc1..47866e1 100644 --- a/architecture/jamendo-provider.md +++ b/architecture/jamendo-provider.md @@ -55,6 +55,11 @@ Objects (fields we read): - **album**: `id`, `name`, `artist_name`; `/albums/tracks` returns the album wrapping a `tracks[]` array of the same track shape. +**A `User-Agent` header is mandatory** (live-discovered 2026-07-24): Jamendo's +API returns HTTP 200 `success` with an **empty** result set to any request that +carries none — and `reqwest` sends none by default — so `JamApi` sets one. This +is silent (no error), so a missing UA looks exactly like "no matches". + Search parameters: `search` (free text across track/album/artist/tags), `namesearch` (name match), `tags` (AND) / `fuzzytags` (fuzzy OR), `order` (relevance, popularity, downloads, listens, releasedate, …). v1 uses diff --git a/jamendody/src/api.rs b/jamendody/src/api.rs index a58fce6..995f8c2 100644 --- a/jamendody/src/api.rs +++ b/jamendody/src/api.rs @@ -127,6 +127,10 @@ impl JamApi { ) -> Result { let http = reqwest::Client::builder() .timeout(timeout) + // Jamendo's API silently returns HTTP 200 with an empty result set + // (results_count: 0) to requests that carry no User-Agent — reqwest + // sends none by default — so a UA is mandatory, not cosmetic. + .user_agent(concat!("Mozilla/5.0 crabidy/", env!("CARGO_PKG_VERSION"))) .build() .map_err(|err| FetchError::Http(err.to_string()))?; Ok(Self {