mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2025-11-25 03:15:19 +08:00
refactor: optimize stream, link, and resource management (#486)
* refactor: optimize stream, link, and resource management * Link.MFile改为io.ReadSeeker类型 * fix (crypt): read on closed response body * chore * chore * chore
This commit is contained in:
@@ -5,7 +5,6 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"maps"
|
||||
@@ -19,21 +18,15 @@ import (
|
||||
|
||||
func Proxy(w http.ResponseWriter, r *http.Request, link *model.Link, file model.Obj) error {
|
||||
if link.MFile != nil {
|
||||
defer link.MFile.Close()
|
||||
if clr, ok := link.MFile.(io.Closer); ok {
|
||||
defer clr.Close()
|
||||
}
|
||||
attachHeader(w, file)
|
||||
contentType := link.Header.Get("Content-Type")
|
||||
if contentType != "" {
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
}
|
||||
mFile := link.MFile
|
||||
if _, ok := mFile.(*os.File); !ok {
|
||||
mFile = &stream.RateLimitFile{
|
||||
File: mFile,
|
||||
Limiter: stream.ServerDownloadLimit,
|
||||
Ctx: r.Context(),
|
||||
}
|
||||
}
|
||||
http.ServeContent(w, r, file.GetName(), file.ModTime(), mFile)
|
||||
http.ServeContent(w, r, file.GetName(), file.ModTime(), link.MFile)
|
||||
return nil
|
||||
} else if link.RangeReadCloser != nil {
|
||||
attachHeader(w, file)
|
||||
|
||||
@@ -2,6 +2,7 @@ package ftp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
fs2 "io/fs"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -13,13 +14,13 @@ import (
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/op"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/stream"
|
||||
"github.com/OpenListTeam/OpenList/v4/server/common"
|
||||
ftpserver "github.com/fclairamb/ftpserverlib"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type FileDownloadProxy struct {
|
||||
ftpserver.FileTransfer
|
||||
reader stream.SStreamReadAtSeeker
|
||||
model.File
|
||||
io.Closer
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func OpenDownload(ctx context.Context, reqPath string, offset int64) (*FileDownloadProxy, error) {
|
||||
@@ -57,15 +58,24 @@ func OpenDownload(ctx context.Context, reqPath string, offset int64) (*FileDownl
|
||||
_ = ss.Close()
|
||||
return nil, err
|
||||
}
|
||||
return &FileDownloadProxy{reader: reader}, nil
|
||||
return &FileDownloadProxy{File: reader, Closer: ss, ctx: ctx}, nil
|
||||
}
|
||||
|
||||
func (f *FileDownloadProxy) Read(p []byte) (n int, err error) {
|
||||
n, err = f.reader.Read(p)
|
||||
n, err = f.File.Read(p)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = stream.ClientDownloadLimit.WaitN(f.reader.GetRawStream().Ctx, n)
|
||||
err = stream.ClientDownloadLimit.WaitN(f.ctx, n)
|
||||
return
|
||||
}
|
||||
|
||||
func (f *FileDownloadProxy) ReadAt(p []byte, off int64) (n int, err error) {
|
||||
n, err = f.File.ReadAt(p, off)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = stream.ClientDownloadLimit.WaitN(f.ctx, n)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -73,14 +83,6 @@ func (f *FileDownloadProxy) Write(p []byte) (n int, err error) {
|
||||
return 0, errs.NotSupport
|
||||
}
|
||||
|
||||
func (f *FileDownloadProxy) Seek(offset int64, whence int) (int64, error) {
|
||||
return f.reader.Seek(offset, whence)
|
||||
}
|
||||
|
||||
func (f *FileDownloadProxy) Close() error {
|
||||
return f.reader.Close()
|
||||
}
|
||||
|
||||
type OsFileInfoAdapter struct {
|
||||
obj model.Obj
|
||||
}
|
||||
|
||||
@@ -85,15 +85,15 @@ func Proxy(c *gin.Context) {
|
||||
}
|
||||
|
||||
func down(c *gin.Context, link *model.Link) {
|
||||
var err error
|
||||
if link.MFile != nil {
|
||||
defer func(ReadSeekCloser io.ReadCloser) {
|
||||
err := ReadSeekCloser.Close()
|
||||
if clr, ok := link.MFile.(io.Closer); ok {
|
||||
defer func(clr io.Closer) {
|
||||
err := clr.Close()
|
||||
if err != nil {
|
||||
log.Errorf("close data error: %s", err)
|
||||
log.Errorf("close link data error: %v", err)
|
||||
}
|
||||
}(link.MFile)
|
||||
}(clr)
|
||||
}
|
||||
var err error
|
||||
c.Header("Referrer-Policy", "no-referrer")
|
||||
c.Header("Cache-Control", "max-age=0, no-cache, no-store, must-revalidate")
|
||||
if setting.GetBool(conf.ForwardDirectLinkParams) {
|
||||
|
||||
@@ -390,14 +390,13 @@ func Link(c *gin.Context) {
|
||||
common.ErrorResp(c, err, 500)
|
||||
return
|
||||
}
|
||||
if link.MFile != nil {
|
||||
defer func(ReadSeekCloser io.ReadCloser) {
|
||||
err := ReadSeekCloser.Close()
|
||||
if clr, ok := link.MFile.(io.Closer); ok {
|
||||
defer func(clr io.Closer) {
|
||||
err := clr.Close()
|
||||
if err != nil {
|
||||
log.Errorf("close link data error: %v", err)
|
||||
}
|
||||
}(link.MFile)
|
||||
}(clr)
|
||||
}
|
||||
common.SuccessResp(c, link)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -187,7 +187,11 @@ func (b *s3Backend) GetObject(ctx context.Context, bucketName, objectName string
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rdr = link.MFile
|
||||
if rdr2, ok := link.MFile.(io.ReadCloser); ok {
|
||||
rdr = rdr2
|
||||
} else {
|
||||
rdr = io.NopCloser(link.MFile)
|
||||
}
|
||||
} else {
|
||||
remoteFileSize := file.GetSize()
|
||||
if length >= 0 && start+length >= remoteFileSize {
|
||||
|
||||
Reference in New Issue
Block a user