diff --git a/client/internal/http/object.go b/client/internal/http/object.go index 06c986a..f826a28 100644 --- a/client/internal/http/object.go +++ b/client/internal/http/object.go @@ -1,11 +1,10 @@ package http import ( - "fmt" "io" "mime/multipart" "net/http" - ul "net/url" + "net/url" "path" "time" @@ -13,7 +12,6 @@ import ( "gitlink.org.cn/cloudream/common/consts/errorcode" "gitlink.org.cn/cloudream/common/pkgs/logger" cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" - myhttp "gitlink.org.cn/cloudream/common/utils/http" stgglb "gitlink.org.cn/cloudream/storage/common/globals" "gitlink.org.cn/cloudream/storage/common/pkgs/downloader" ) @@ -115,58 +113,21 @@ func (s *ObjectService) Download(ctx *gin.Context) { ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "download object failed")) return } + defer file.File.Close() - mw := multipart.NewWriter(ctx.Writer) - defer mw.Close() + ctx.Header("Content-Disposition", "attachment; filename="+url.PathEscape(path.Base(file.Object.Path))) + ctx.Header("Content-Type", "application/octet-stream") + ctx.Header("Content-Transfer-Encoding", "binary") - ctx.Writer.Header().Set("Content-Type", fmt.Sprintf("%s;boundary=%s", myhttp.ContentTypeMultiPart, mw.Boundary())) - ctx.Writer.WriteHeader(http.StatusOK) - - sendSize := int64(0) - if req.PartSize == 0 { - sendSize, err = sendFileOnePart(mw, "file", path.Base(file.Object.Path), file.File) - } else { - sendSize, err = sendFileMultiPart(mw, "file", path.Base(file.Object.Path), file.File, req.PartSize) + n, err := io.Copy(ctx.Writer, file.File) + if err != nil { + ctx.String(http.StatusInternalServerError, err.Error()) } // TODO 当client不在某个代理节点上时如何处理? if stgglb.Local.NodeID != nil { - s.svc.AccessStat.AddAccessCounter(file.Object.ObjectID, file.Object.PackageID, *stgglb.Local.NodeID, float64(sendSize)/float64(file.Object.Size)) - } - - if err != nil { - log.Warnf("copying file: %s", err.Error()) - } -} - -func sendFileMultiPart(muWriter *multipart.Writer, fieldName, fileName string, file io.ReadCloser, partSize int64) (int64, error) { - total := int64(0) - for { - w, err := muWriter.CreateFormFile(fieldName, ul.PathEscape(fileName)) - if err != nil { - return 0, fmt.Errorf("create form file failed, err: %w", err) - } - - n, err := io.Copy(w, io.LimitReader(file, partSize)) - if err != nil { - return total, err - } - if n == 0 { - break - } - total += n + s.svc.AccessStat.AddAccessCounter(file.Object.ObjectID, file.Object.PackageID, *stgglb.Local.NodeID, float64(n)/float64(file.Object.Size)) } - return total, nil -} - -func sendFileOnePart(muWriter *multipart.Writer, fieldName, fileName string, file io.ReadCloser) (int64, error) { - w, err := muWriter.CreateFormFile(fieldName, ul.PathEscape(fileName)) - if err != nil { - return 0, fmt.Errorf("create form file failed, err: %w", err) - } - - n, err := io.Copy(w, file) - return n, err } func (s *ObjectService) UpdateInfo(ctx *gin.Context) { diff --git a/common/pkgs/downloader/iterator.go b/common/pkgs/downloader/iterator.go index 454be3e..21c979d 100644 --- a/common/pkgs/downloader/iterator.go +++ b/common/pkgs/downloader/iterator.go @@ -228,7 +228,7 @@ func (iter *DownloadObjectIterator) downloadECObject(req downloadReqeust2, ecRed totalReadLen = math2.Min(req.Raw.Length, totalReadLen) } - firstStripIndex := readPos / int64(ecRed.K) / int64(ecRed.ChunkSize) + firstStripIndex := readPos / ecRed.StripSize() stripIter := NewStripIterator(req.Detail.Object, blocks, ecRed, firstStripIndex, iter.downloader.strips, iter.downloader.cfg.ECStripPrefetchCount) defer stripIter.Close() @@ -244,8 +244,7 @@ func (iter *DownloadObjectIterator) downloadECObject(req downloadReqeust2, ecRed } readRelativePos := readPos - strip.Position - nextStripPos := strip.Position + int64(ecRed.K)*int64(ecRed.ChunkSize) - curReadLen := math2.Min(totalReadLen, nextStripPos-readPos) + curReadLen := math2.Min(totalReadLen, ecRed.StripSize()-readRelativePos) err = io2.WriteAll(pw, strip.Data[readRelativePos:readRelativePos+curReadLen]) if err != nil { diff --git a/common/pkgs/downloader/strip_iterator.go b/common/pkgs/downloader/strip_iterator.go index 82a2771..24cbf71 100644 --- a/common/pkgs/downloader/strip_iterator.go +++ b/common/pkgs/downloader/strip_iterator.go @@ -172,6 +172,7 @@ loop: dataBuf := make([]byte, int64(s.red.K*s.red.ChunkSize)) n, err := io.ReadFull(str, dataBuf) if err == io.ErrUnexpectedEOF { + // dataBuf中的内容可能不足一个条带,但仍然将其完整放入cache中,外部应该自行计算该从这个buffer中读多少数据 s.cache.Add(stripKey, ObjectECStrip{ Data: dataBuf, ObjectFileHash: s.object.FileHash,