diff --git a/backend/services/assetService/service/minimax_service.go b/backend/services/assetService/service/minimax_service.go index 2a14bf3..6906827 100644 --- a/backend/services/assetService/service/minimax_service.go +++ b/backend/services/assetService/service/minimax_service.go @@ -61,6 +61,7 @@ type minimaxService struct { config *config.AssetConfig jobs map[string]*ImageGenerationJob jobsLock sync.RWMutex + client *http.Client } // NewMinimaxService 创建 MiniMax 服务 @@ -68,6 +69,7 @@ func NewMinimaxService(cfg *config.AssetConfig) MinimaxService { svc := &minimaxService{ config: cfg, jobs: make(map[string]*ImageGenerationJob), + client: &http.Client{Timeout: 120 * time.Second}, } go svc.cleanupExpiredJobs() return svc @@ -111,7 +113,11 @@ func (s *minimaxService) GetJob(ctx context.Context, jobID string, userID, starI return nil, fmt.Errorf("access denied") } - return job, nil + // Copy data to avoid race + result := *job + result.Images = make([]string, len(job.Images)) + copy(result.Images, job.Images) + return &result, nil } // processJob 异步处理任务 @@ -192,7 +198,6 @@ func (s *minimaxService) callMiniMaxAPI(model, prompt, aspectRatio string, refs return nil, err } - client := &http.Client{Timeout: 120 * time.Second} req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(jsonData)) if err != nil { return nil, err @@ -200,12 +205,17 @@ func (s *minimaxService) callMiniMaxAPI(model, prompt, aspectRatio string, refs req.Header.Set("Authorization", "Bearer "+apiKey) req.Header.Set("Content-Type", "application/json") - resp, err := client.Do(req) + resp, err := s.client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + body, _ := io.ReadAll(resp.Body) + return nil, fmt.Errorf("API returned status %d: %s", resp.StatusCode, string(body)) + } + var result struct { Images []struct { URL string `json:"url"` @@ -224,13 +234,14 @@ func (s *minimaxService) callMiniMaxAPI(model, prompt, aspectRatio string, refs // compressImageIfNeeded 下载并压缩图片 func (s *minimaxService) compressImageIfNeeded(imageURL string) (string, error) { - resp, err := http.Get(imageURL) + client := &http.Client{Timeout: 30 * time.Second} + resp, err := client.Get(imageURL) if err != nil { return "", err } defer resp.Body.Close() - imgData, err := io.ReadAll(resp.Body) + imgData, err := io.ReadAll(io.LimitReader(resp.Body, 10*1024*1024)) // 10MB limit if err != nil { return "", err } @@ -295,6 +306,9 @@ func validateURL(rawURL string) error { if err != nil { return err } + if u.Scheme != "http" && u.Scheme != "https" { + return fmt.Errorf("unsupported scheme: %s", u.Scheme) + } host := u.Hostname() ip := net.ParseIP(host)