fix(video): 视频结果下载 - 补齐 Grok 同源认证 (#158)
Co-authored-by: Danborad <Danborad@users.noreply.github.com>
This commit is contained in:
@@ -1035,7 +1035,7 @@ func runVideoTask(ctx context.Context, input canvasGenerationInput) (map[string]
|
||||
status := strings.ToLower(stringField(state, "status"))
|
||||
if status == "completed" || status == "succeeded" || status == "success" || status == "done" {
|
||||
if videoURL := newAPIVideoResultURL(state); videoURL != "" {
|
||||
data, mimeType, err := getExternalBinary(withProviderRequestKind(ctx, "download"), videoURL)
|
||||
data, mimeType, err := getProviderExternalBinary(withProviderRequestKind(ctx, "download"), input.Config, videoURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("视频结果下载失败(任务 %s):%w", id, err)
|
||||
}
|
||||
@@ -1291,7 +1291,7 @@ func queryNewAPIChannel2VideoTask(ctx context.Context, input canvasGenerationInp
|
||||
if videoURL == "" {
|
||||
return nil, status, fmt.Errorf("NewAPI Video Generations 任务 %s 已成功但没有返回视频地址", id)
|
||||
}
|
||||
data, mimeType, err := getExternalBinary(withProviderRequestKind(ctx, "download"), videoURL)
|
||||
data, mimeType, err := getProviderExternalBinary(withProviderRequestKind(ctx, "download"), input.Config, videoURL)
|
||||
if err != nil {
|
||||
return nil, status, fmt.Errorf("NewAPI Video Generations 视频结果下载失败(任务 %s):%w", id, err)
|
||||
}
|
||||
@@ -1871,6 +1871,27 @@ func getExternalBinary(ctx context.Context, rawURL string) ([]byte, string, erro
|
||||
return doBinary(req)
|
||||
}
|
||||
|
||||
func getProviderExternalBinary(ctx context.Context, config providerConfig, rawURL string) ([]byte, string, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, rawURL, nil)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
if sameProviderOrigin(config.BaseURL, rawURL) {
|
||||
req.Header.Set("Authorization", "Bearer "+config.APIKey)
|
||||
ApplyOutboundHeaders(req, config.Headers)
|
||||
}
|
||||
return doBinary(req)
|
||||
}
|
||||
|
||||
func sameProviderOrigin(baseURL string, rawURL string) bool {
|
||||
base, baseErr := url.Parse(strings.TrimSpace(baseURL))
|
||||
target, targetErr := url.Parse(strings.TrimSpace(rawURL))
|
||||
if baseErr != nil || targetErr != nil || base.Scheme == "" || base.Host == "" || target.Scheme == "" || target.Host == "" {
|
||||
return false
|
||||
}
|
||||
return strings.EqualFold(base.Scheme, target.Scheme) && strings.EqualFold(base.Host, target.Host)
|
||||
}
|
||||
|
||||
func doJSON(req *http.Request, target interface{}) error {
|
||||
data, mimeType, err := doBinary(req)
|
||||
if err != nil {
|
||||
|
||||
@@ -401,8 +401,8 @@ func TestRunVideoTaskUsesNestedURLBeforeResultURL(t *testing.T) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"code":"success","data":{"task_id":"video-1","status":"SUCCESS","result_url":"` + server.URL + `/v1/videos/video-1/content","data":{"status":"completed","url":"` + server.URL + `/files/video.mp4"}}}`))
|
||||
case "GET /files/video.mp4":
|
||||
if authorization := r.Header.Get("Authorization"); authorization != "" {
|
||||
t.Errorf("file Authorization = %q, want empty", authorization)
|
||||
if authorization := r.Header.Get("Authorization"); authorization != "Bearer test-key" {
|
||||
t.Errorf("file Authorization = %q, want Bearer test-key", authorization)
|
||||
}
|
||||
w.Header().Set("Content-Type", "video/mp4")
|
||||
_, _ = w.Write([]byte("video"))
|
||||
@@ -512,8 +512,8 @@ func TestRunVideoTaskUsesXAIVideoGenerationEndpoint(t *testing.T) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"status":"done","video":{"url":"` + server.URL + `/files/video.mp4"}}`))
|
||||
case "GET /files/video.mp4":
|
||||
if authorization := r.Header.Get("Authorization"); authorization != "" {
|
||||
t.Errorf("file Authorization = %q, want empty", authorization)
|
||||
if authorization := r.Header.Get("Authorization"); authorization != "Bearer test-key" {
|
||||
t.Errorf("file Authorization = %q, want Bearer test-key", authorization)
|
||||
}
|
||||
w.Header().Set("Content-Type", "video/mp4")
|
||||
_, _ = w.Write([]byte("video"))
|
||||
@@ -779,6 +779,9 @@ func TestRunNewAPIChannel1VideoTaskDownloadsSucceededObject(t *testing.T) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"id":"channel-1-task","status":"SUCCEEDED","object":"` + server.URL + `/video.mp4"}`))
|
||||
case "GET /video.mp4":
|
||||
if authorization := r.Header.Get("Authorization"); authorization != "" {
|
||||
t.Errorf("file Authorization = %q, want empty", authorization)
|
||||
}
|
||||
w.Header().Set("Content-Type", "video/mp4")
|
||||
_, _ = w.Write([]byte("video"))
|
||||
default:
|
||||
@@ -819,7 +822,7 @@ func TestRunNewAPIChannel2VideoTaskDownloadsTemporaryResult(t *testing.T) {
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
t.Fatalf("decode request: %v", err)
|
||||
}
|
||||
if body["model"] != "grok-image-video" || body["seconds"] != "10" || body["aspect_ratio"] != "9:16" || body["resolution"] != "720p" {
|
||||
if body["model"] != "grok-image-video" || body["seconds"] != "15" || body["aspect_ratio"] != "9:16" || body["resolution"] != "720p" {
|
||||
t.Errorf("body = %#v", body)
|
||||
}
|
||||
images, ok := body["image_urls"].([]interface{})
|
||||
@@ -837,6 +840,9 @@ func TestRunNewAPIChannel2VideoTaskDownloadsTemporaryResult(t *testing.T) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"code":"success","data":{"task_id":"grok-task","status":"SUCCESS","result_url":"` + server.URL + `/video.mp4"}}`))
|
||||
case "GET /video.mp4":
|
||||
if authorization := r.Header.Get("Authorization"); authorization != "Bearer test-key" {
|
||||
t.Errorf("file Authorization = %q, want Bearer test-key", authorization)
|
||||
}
|
||||
w.Header().Set("Content-Type", "video/mp4")
|
||||
_, _ = w.Write([]byte("video"))
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user