(c *gin.Context, fileID int64, uploadFile *model.UploadFile, ext string)
| 265 | } |
| 266 | |
| 267 | func serveUploadFilePreview(c *gin.Context, fileID int64, uploadFile *model.UploadFile, ext string) error { |
| 268 | contentType := uploadFile.MimeType |
| 269 | if contentType == "" { |
| 270 | switch ext { |
| 271 | case ".txt": |
| 272 | contentType = "text/plain; charset=utf-8" |
| 273 | case ".html", ".htm": |
| 274 | contentType = "text/html; charset=utf-8" |
| 275 | case ".md": |
| 276 | contentType = "text/markdown; charset=utf-8" |
| 277 | default: |
| 278 | contentType = "application/octet-stream" |
| 279 | } |
| 280 | } |
| 281 | |
| 282 | downloadName := path.Base(strings.TrimSpace(uploadFile.FileName)) |
| 283 | if downloadName == "" || downloadName == "." || downloadName == "/" { |
| 284 | downloadName = "preview.bin" |
| 285 | } |
| 286 | c.Header("Content-Disposition", `inline; filename="`+downloadName+`"; filename*=UTF-8''`+url.QueryEscape(downloadName)) |
| 287 | |
| 288 | if config.StorageType == "aliyun_oss" { |
| 289 | storageImpl, ok := storage.StorageInstance.(*storage.AliyunOSSStorage) |
| 290 | if !ok { |
| 291 | c.JSON(http.StatusInternalServerError, model.FileError.ToResponse(errors.New("无法获取OSS客户端"))) |
| 292 | return fmt.Errorf("failed to get oss storage for sandbox output preview") |
| 293 | } |
| 294 | |
| 295 | c.Header("Content-Type", contentType) |
| 296 | |
| 297 | fileSize := uploadFile.Size |
| 298 | rangeHeader := c.GetHeader("Range") |
| 299 | if rangeHeader != "" { |
| 300 | start, end := parseRangeHeaderForPreview(rangeHeader, fileSize) |
| 301 | if start < 0 || start >= fileSize || end < start { |
| 302 | c.Header("Content-Range", fmt.Sprintf("bytes */%d", fileSize)) |
| 303 | c.Status(http.StatusRequestedRangeNotSatisfiable) |
| 304 | return nil |
| 305 | } |
| 306 | |
| 307 | contentLength := end - start + 1 |
| 308 | c.Header("Content-Range", fmt.Sprintf("bytes %d-%d/%d", start, end, fileSize)) |
| 309 | c.Header("Content-Length", fmt.Sprintf("%d", contentLength)) |
| 310 | c.Status(http.StatusPartialContent) |
| 311 | |
| 312 | rangeReader, err := openAIUploadFileOSSRangeObject(storageImpl, uploadFile.Key, start, end) |
| 313 | if err != nil { |
| 314 | c.JSON(http.StatusInternalServerError, model.FileError.ToResponse(fmt.Errorf("oss range request error: %w", err))) |
| 315 | return err |
| 316 | } |
| 317 | defer rangeReader.Close() |
| 318 | |
| 319 | buffer := make([]byte, 32*1024) |
| 320 | _, err = io.CopyBuffer(c.Writer, rangeReader, buffer) |
| 321 | if err != nil && err != io.EOF { |
| 322 | return err |
| 323 | } |
| 324 | return nil |
no test coverage detected