Browse Source

重写download接口

gitlink
Sydonian 1 year ago
parent
commit
54c1e4e52e
3 changed files with 12 additions and 51 deletions
  1. +9
    -48
      client/internal/http/object.go
  2. +2
    -3
      common/pkgs/downloader/iterator.go
  3. +1
    -0
      common/pkgs/downloader/strip_iterator.go

+ 9
- 48
client/internal/http/object.go View File

@@ -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) {


+ 2
- 3
common/pkgs/downloader/iterator.go View File

@@ -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 {


+ 1
- 0
common/pkgs/downloader/strip_iterator.go View File

@@ -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,


Loading…
Cancel
Save