| 708 | } |
| 709 | |
| 710 | func (f *FileService) GetPreviewContent(op request.FileContentReq) (response.FileInfo, error) { |
| 711 | if files.ShouldDenySensitiveFileRead(op.Path) { |
| 712 | return response.FileInfo{}, buserr.New("ErrSensitiveFileRead") |
| 713 | } |
| 714 | info, err := files.NewFileInfo(files.FileOption{ |
| 715 | Path: op.Path, |
| 716 | Expand: false, |
| 717 | IsDetail: op.IsDetail, |
| 718 | }) |
| 719 | if err != nil { |
| 720 | return response.FileInfo{}, err |
| 721 | } |
| 722 | |
| 723 | if files.IsBinaryPreviewFile(info.MimeType, info.Extension) { |
| 724 | return response.FileInfo{}, buserr.New("ErrFileCanNotRead") |
| 725 | } |
| 726 | if files.IsBlockDevice(info.FileMode) { |
| 727 | return response.FileInfo{FileInfo: *info}, nil |
| 728 | } |
| 729 | |
| 730 | file, err := os.Open(op.Path) |
| 731 | if err != nil { |
| 732 | return response.FileInfo{}, err |
| 733 | } |
| 734 | defer file.Close() |
| 735 | |
| 736 | headBuf := make([]byte, 1024) |
| 737 | n, err := file.Read(headBuf) |
| 738 | if err != nil && err != io.EOF { |
| 739 | return response.FileInfo{}, err |
| 740 | } |
| 741 | headBuf = headBuf[:n] |
| 742 | |
| 743 | if len(headBuf) > 0 && files.DetectBinary(headBuf) { |
| 744 | return response.FileInfo{FileInfo: *info}, nil |
| 745 | } |
| 746 | |
| 747 | const maxSize = 10 * 1024 * 1024 |
| 748 | if info.Size <= maxSize { |
| 749 | if _, err := file.Seek(0, 0); err != nil { |
| 750 | return response.FileInfo{}, err |
| 751 | } |
| 752 | content, err := io.ReadAll(file) |
| 753 | if err != nil { |
| 754 | return response.FileInfo{}, err |
| 755 | } |
| 756 | info.Content = string(content) |
| 757 | } else { |
| 758 | lines, err := files.TailFromEnd(op.Path, 300) |
| 759 | if err != nil { |
| 760 | return response.FileInfo{}, err |
| 761 | } |
| 762 | info.Content = strings.Join(lines, "\n") |
| 763 | } |
| 764 | |
| 765 | content := []byte(info.Content) |
| 766 | if len(content) > 1024 { |
| 767 | content = content[:1024] |