diff --git a/TODO.md b/TODO.md index 5ab2b94..aafce60 100644 --- a/TODO.md +++ b/TODO.md @@ -268,6 +268,18 @@ - backend debug broadcasts ## Recent Change Log +- Date: `2026-03-24` +- What changed: + - Restored the video-search request path to tolerate a scheme-less `SEARXNG_BASE_URL` such as `192.168.1.66:8087` by normalizing it to `http://...` during search-service initialization. + - Added regression coverage so the video search service keeps accepting the older style base URL configuration used in live deployment. +- Why it changed: + - Real user logs showed video search failing immediately with `first path segment in URL cannot contain colon`, which traced back to a scheme-less SearXNG base URL in the deployed environment. +- How it was verified: + - log review of `ai-media-hub-2026-03-24T08-09-23-204Z.log` + - added unit coverage for scheme-less base URL normalization +- What is still risky or incomplete: + - Go tests could not be rerun in this environment because `go` is currently unavailable here, so this fix is verified by code-path review plus the added test only. + - Date: `2026-03-24` - What changed: - Corrected the Unraid template GIPHY download path mapping from `/downloads/giphy` to `/app/downloads/giphy` so it matches the backend default download directory layout. diff --git a/backend/services/cse.go b/backend/services/cse.go index 32608c5..00b846e 100644 --- a/backend/services/cse.go +++ b/backend/services/cse.go @@ -63,7 +63,7 @@ func NewSearchService(baseURL, googleVideoEngine, webEngine string) *SearchServi webEngine = "google" } return &SearchService{ - BaseURL: strings.TrimRight(baseURL, "/"), + BaseURL: normalizeBaseURL(baseURL), GoogleVideoEngine: googleVideoEngine, WebEngine: webEngine, Client: &http.Client{Timeout: 20 * time.Second}, @@ -77,6 +77,17 @@ func NewSearchService(baseURL, googleVideoEngine, webEngine string) *SearchServi } } +func normalizeBaseURL(raw string) string { + trimmed := strings.TrimSpace(raw) + if trimmed == "" { + return "" + } + if !strings.Contains(trimmed, "://") { + trimmed = "http://" + trimmed + } + return strings.TrimRight(trimmed, "/") +} + func (s *SearchService) SearchMedia(queries []string, enabledPlatforms map[string]bool) ([]SearchResult, SearchExecutionMeta, error) { return s.SearchMediaWithDeadline(queries, enabledPlatforms, time.Time{}) } diff --git a/backend/services/cse_test.go b/backend/services/cse_test.go index ad6f3d3..286dc64 100644 --- a/backend/services/cse_test.go +++ b/backend/services/cse_test.go @@ -182,6 +182,13 @@ func TestSearchServiceFetchCacheRoundTrip(t *testing.T) { } } +func TestNewSearchServiceNormalizesSchemeLessBaseURL(t *testing.T) { + service := NewSearchService("192.168.1.66:8087", "", "") + if service.BaseURL != "http://192.168.1.66:8087" { + t.Fatalf("expected normalized base url, got %q", service.BaseURL) + } +} + func TestSplitSearchDeadlinesReservesEnrichmentWindow(t *testing.T) { deadline := time.Now().Add(20 * time.Second) collectionDeadline, enrichmentDeadline := splitSearchDeadlines(deadline)