From 5ddca9a1f6f664b20abec4cbfe6d7459d1660942 Mon Sep 17 00:00:00 2001 From: truewhile <62226914+truewhile@users.noreply.github.com> Date: Sat, 12 Sep 2026 22:31:30 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=20STRM=20=E6=92=AD=E6=94=BE?= =?UTF-8?q?=E7=AB=AF=E7=82=B9=E7=9A=84=20HEAD=20=E8=AF=B7=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/handler/handler.go | 1 + internal/handler/strm_routes_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/internal/handler/handler.go b/internal/handler/handler.go index b09cad2..9279ae3 100644 --- a/internal/handler/handler.go +++ b/internal/handler/handler.go @@ -24,6 +24,7 @@ func Register(r *gin.Engine, cfg *config.Config, log *zap.Logger, svc *service.C // STRM 播放端点:strm 文件内容指向这里,Emby/Infuse 直接请求(无 JWT)。 api.GET("/strm/play/:provider/:file", strmPlayHandler(svc)) + api.HEAD("/strm/play/:provider/:file", strmPlayHandler(svc)) // 115 中继/CloudDrive 授权回跳(authorization_id 会话 + 共享密钥校验) api.POST("/strm/oauth/callback", strm115OAuthCallbackHandler(svc)) api.GET("/strm/oauth/callback", strm115OAuthCallbackHandler(svc)) diff --git a/internal/handler/strm_routes_test.go b/internal/handler/strm_routes_test.go index b9c4c9f..30de7ac 100644 --- a/internal/handler/strm_routes_test.go +++ b/internal/handler/strm_routes_test.go @@ -3,6 +3,9 @@ package handler import ( "net/http" "net/http/httptest" + "net/url" + "os" + "path/filepath" "testing" "github.com/gin-gonic/gin" @@ -63,6 +66,7 @@ func TestStrmAdminRoutesAreRegistered(t *testing.T) { "POST /api/admin/strm/uploads/retry-failed", "POST /api/admin/strm/uploads/cancel-pending", "GET /api/strm/play/:provider/:file", + "HEAD /api/strm/play/:provider/:file", } { if !routes[want] { t.Fatalf("%s route is not registered", want) @@ -108,4 +112,27 @@ func TestStrmAccountsCRUD(t *testing.T) { if w.Code == http.StatusInternalServerError { t.Fatalf("strm play endpoint errored: %d", w.Code) } + videoPath := filepath.Join(t.TempDir(), "sample.mkv") + if err := os.WriteFile(videoPath, []byte("fake-video-bytes"), 0o644); err != nil { + t.Fatalf("write test video: %v", err) + } + if err := repos.StrmSyncPath.Create(t.Context(), &model.StrmSyncPath{ + Name: "local-test", + Provider: model.StrmProviderLocal, + RemotePath: filepath.Dir(videoPath), + Enabled: true, + }); err != nil { + t.Fatalf("create local sync path: %v", err) + } + + // VidHub 等客户端会先用 HEAD 探测 STRM 播放源,不能返回 405/404。 + req = httptest.NewRequest(http.MethodHead, "/api/strm/play/local/video.mkv?path="+url.QueryEscape(videoPath), nil) + w = httptest.NewRecorder() + router.ServeHTTP(w, req) + if w.Code != http.StatusOK { + t.Fatalf("HEAD strm play endpoint = %d, want 200", w.Code) + } + if w.Body.Len() != 0 { + t.Fatalf("HEAD strm play endpoint returned body: %q", w.Body.String()) + } }