diff --git a/internal/service/cloud/clouddrive2.go b/internal/service/cloud/clouddrive2.go index 62afb61..776c554 100644 --- a/internal/service/cloud/clouddrive2.go +++ b/internal/service/cloud/clouddrive2.go @@ -87,15 +87,15 @@ func (p *cloudDrive2Provider) Resolve(ctx context.Context, fileRef string) (*Dir if ref == "/" { return nil, fmt.Errorf("%s: file reference required", p.name) } - if p.typ == TypeOpenList && isCloudVideoPlaybackCandidate(ref) { - if p.apiBase == nil { - return nil, fmt.Errorf("%s: pure 302 playback requires an OpenList API server address; configure server/api_url so /api/fs/get can return raw_url", p.name) - } + if p.typ == TypeOpenList && p.apiBase != nil { link, err := p.resolveOpenListAPIDirect(ctx, ref) - if err != nil { - return nil, fmt.Errorf("%s: pure 302 playback requires OpenList raw_url for %s: %w", p.name, ref, err) + if err == nil { + return link, nil + } + // API 获取直链失败:非视频文件(元数据)回退到 WebDAV;视频文件报错 + if isCloudVideoPlaybackCandidate(ref) { + return nil, fmt.Errorf("%s: resolve download URL for %s via API failed: %w", p.name, ref, err) } - return link, nil } if p.typ == TypeCloudDrive2 && isCloudVideoPlaybackCandidate(ref) { link, err := p.resolveCloudDAVRedirectDirect(ctx, ref) diff --git a/internal/service/cloud/openlist_list_test.go b/internal/service/cloud/openlist_list_test.go index 7dd6164..da18127 100644 --- a/internal/service/cloud/openlist_list_test.go +++ b/internal/service/cloud/openlist_list_test.go @@ -61,9 +61,10 @@ func TestOpenListWebDAVListAndResolve(t *testing.T) { if len(entries) != 1 || entries[0].ID != "/Cloud/Movie.mkv" || entries[0].Size != 1024 { t.Fatalf("entries = %#v", entries) } + // Video file: API fails → error (no WebDAV fallback for video) _, err = p.Resolve(context.Background(), entries[0].ID) - if err == nil || !strings.Contains(err.Error(), "pure 302 playback requires OpenList raw_url") { - t.Fatalf("openlist video resolve should require raw_url instead of WebDAV proxy fallback, err=%v", err) + if err == nil || !strings.Contains(err.Error(), "resolve download URL") || !strings.Contains(err.Error(), "via API failed") { + t.Fatalf("openlist video resolve should error on API failure, err=%v", err) } } diff --git a/internal/service/cloud/openlist_resolve_test.go b/internal/service/cloud/openlist_resolve_test.go index 2b9b976..0beebbb 100644 --- a/internal/service/cloud/openlist_resolve_test.go +++ b/internal/service/cloud/openlist_resolve_test.go @@ -195,10 +195,43 @@ func TestOpenListResolveDoesNotFallbackToWebDAVWhenAPIRawURLFails(t *testing.T) t.Fatal(err) } _, err = p.Resolve(context.Background(), "/Cloud/Movie.mkv") - if err == nil || !strings.Contains(err.Error(), "pure 302 playback requires OpenList raw_url") { - t.Fatalf("resolve error = %v, want raw_url requirement", err) + if err == nil || !strings.Contains(err.Error(), "resolve download URL") || !strings.Contains(err.Error(), "via API failed") { + t.Fatalf("resolve error = %v, want API resolve failure", err) } if davSeen { t.Fatal("openlist video resolve fell back to WebDAV after raw_url failure") } } + +func TestOpenListResolveMetadataUsesAPIInsteadOfWebDAV(t *testing.T) { + var gotPath, gotAuth string + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + gotPath = r.URL.Path + gotAuth = r.Header.Get("Authorization") + if r.Method != http.MethodPost || r.URL.Path != "/api/fs/get" { + t.Fatalf("unexpected request %s %s; metadata should use API, not WebDAV", r.Method, r.URL.Path) + } + w.Header().Set("Content-Type", "application/json") + _, _ = w.Write([]byte(`{"code":200,"data":{"raw_url":"https://cdn.example.test/poster.jpg?sign=1"}}`)) + })) + defer srv.Close() + + p, err := New(TypeOpenList, map[string]any{"server": srv.URL, "token": "alist-token"}, srv.Client()) + if err != nil { + t.Fatal(err) + } + // .nfo metadata file should use API, not WebDAV + link, err := p.Resolve(context.Background(), "/Cloud/Movie/Movie.nfo") + if err != nil { + t.Fatalf("resolve: %v", err) + } + if gotPath != "/api/fs/get" { + t.Fatalf("api path = %q, want /api/fs/get (metadata should not use WebDAV)", gotPath) + } + if gotAuth != "alist-token" { + t.Fatalf("Authorization = %q, want token", gotAuth) + } + if link.URL != "https://cdn.example.test/poster.jpg?sign=1" { + t.Fatalf("url = %q", link.URL) + } +}