mirror of
https://github.com/halejohn/Cloudreve.git
synced 2026-01-26 09:34:57 +08:00
Feat: creating upload session and credential from master server
This commit is contained in:
@@ -11,7 +11,7 @@ type StatusInfo struct {
|
||||
UploadLength string `json:"uploadLength"` // Uploaded length of the download in bytes.
|
||||
BitField string `json:"bitfield"` // Hexadecimal representation of the download progress. The highest bit corresponds to the piece at index 0. Any set bits indicate loaded pieces, while unset bits indicate not yet loaded and/or missing pieces. Any overflow bits at the end are set to zero. When the download was not started yet, this key will not be included in the response.
|
||||
DownloadSpeed string `json:"downloadSpeed"` // Download speed of this download measured in bytes/sec.
|
||||
UploadSpeed string `json:"uploadSpeed"` // Upload speed of this download measured in bytes/sec.
|
||||
UploadSpeed string `json:"uploadSpeed"` // LocalUpload speed of this download measured in bytes/sec.
|
||||
InfoHash string `json:"infoHash"` // InfoHash. BitTorrent only.
|
||||
NumSeeders string `json:"numSeeders"` // The number of seeders aria2 has connected to. BitTorrent only.
|
||||
Seeder string `json:"seeder"` // true if the local endpoint is a seeder. Otherwise false. BitTorrent only.
|
||||
@@ -60,7 +60,7 @@ type PeerInfo struct {
|
||||
AmChoking string `json:"amChoking"` // true if aria2 is choking the peer. Otherwise false.
|
||||
PeerChoking string `json:"peerChoking"` // true if the peer is choking aria2. Otherwise false.
|
||||
DownloadSpeed string `json:"downloadSpeed"` // Download speed (byte/sec) that this client obtains from the peer.
|
||||
UploadSpeed string `json:"uploadSpeed"` // Upload speed(byte/sec) that this client uploads to the peer.
|
||||
UploadSpeed string `json:"uploadSpeed"` // LocalUpload speed(byte/sec) that this client uploads to the peer.
|
||||
Seeder string `json:"seeder"` // true if this peer is a seeder. Otherwise false.
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ var (
|
||||
ErrExpired = serializer.NewError(serializer.CodeSignExpired, "签名已过期", nil)
|
||||
)
|
||||
|
||||
const CrHeaderPrefix = "X-Cr-"
|
||||
|
||||
// General 通用的认证接口
|
||||
var General Auth
|
||||
|
||||
@@ -69,7 +71,7 @@ func CheckRequest(instance Auth, r *http.Request) error {
|
||||
func getSignContent(r *http.Request) (rawSignString string) {
|
||||
// 读取所有body正文
|
||||
var body = []byte{}
|
||||
if strings.Contains(r.URL.Path, "/api/v3/slave/upload/") {
|
||||
if !strings.Contains(r.URL.Path, "/api/v3/slave/upload/") {
|
||||
if r.Body != nil {
|
||||
body, _ = ioutil.ReadAll(r.Body)
|
||||
_ = r.Body.Close()
|
||||
@@ -80,7 +82,7 @@ func getSignContent(r *http.Request) (rawSignString string) {
|
||||
// 决定要签名的header
|
||||
var signedHeader []string
|
||||
for k, _ := range r.Header {
|
||||
if strings.HasPrefix(k, "X-Cr-") && k != "X-Cr-Filename" {
|
||||
if strings.HasPrefix(k, CrHeaderPrefix) && k != CrHeaderPrefix+"Filename" {
|
||||
signedHeader = append(signedHeader, fmt.Sprintf("%s=%s", k, r.Header.Get(k)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,7 +308,6 @@ func (fs *FileSystem) Decompress(ctx context.Context, src, dst string) error {
|
||||
Size: uint64(size),
|
||||
Name: path.Base(dst),
|
||||
VirtualPath: path.Dir(dst),
|
||||
Mode: 0,
|
||||
})
|
||||
fileStream.Close()
|
||||
if err != nil {
|
||||
|
||||
@@ -14,7 +14,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
basePath = "/api/v3/slave"
|
||||
basePath = "/api/v3/slave"
|
||||
OverwriteHeader = auth.CrHeaderPrefix + "Overwrite"
|
||||
)
|
||||
|
||||
// Client to operate remote slave server
|
||||
@@ -79,20 +80,17 @@ func (c *remoteClient) CreateUploadSession(ctx context.Context, session *seriali
|
||||
}
|
||||
|
||||
func (c *remoteClient) GetUploadURL(ttl int64, sessionID string) (string, string, error) {
|
||||
base, err := url.Parse(c.policy.BaseURL)
|
||||
base, err := url.Parse(c.policy.Server)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
base.Path = path.Join(base.Path, "upload", sessionID)
|
||||
|
||||
base.Path = path.Join(base.Path, basePath, "upload", sessionID)
|
||||
req, err := http.NewRequest("POST", base.String(), nil)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
req.Header["X-Cr-Overwrite"] = []string{"true"}
|
||||
|
||||
req = auth.SignRequest(c.authInstance, req, ttl)
|
||||
return req.URL.String(), req.Header["Authorization"][0], nil
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ type WriteMode int
|
||||
const (
|
||||
Overwrite WriteMode = 0x00001
|
||||
// Append 只适用于本地策略
|
||||
Append = 0x00002
|
||||
Nop = 0x00004
|
||||
Append WriteMode = 0x00002
|
||||
Nop WriteMode = 0x00004
|
||||
)
|
||||
|
||||
type UploadTaskInfo struct {
|
||||
|
||||
@@ -2,6 +2,7 @@ package filesystem
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
model "github.com/cloudreve/Cloudreve/v3/models"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/cache"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/conf"
|
||||
@@ -53,31 +54,6 @@ func (fs *FileSystem) Trigger(ctx context.Context, name string, file fsctx.FileH
|
||||
return nil
|
||||
}
|
||||
|
||||
// HookSlaveUploadValidate Slave模式下对文件上传的一系列验证
|
||||
func HookSlaveUploadValidate(ctx context.Context, fs *FileSystem, file fsctx.FileHeader) error {
|
||||
policy := ctx.Value(fsctx.UploadPolicyCtx).(serializer.UploadPolicy)
|
||||
fileInfo := file.Info()
|
||||
|
||||
// 验证单文件尺寸
|
||||
if policy.MaxSize > 0 {
|
||||
if fileInfo.Size > policy.MaxSize {
|
||||
return ErrFileSizeTooBig
|
||||
}
|
||||
}
|
||||
|
||||
// 验证文件名
|
||||
if !fs.ValidateLegalName(ctx, fileInfo.FileName) {
|
||||
return ErrIllegalObjectName
|
||||
}
|
||||
|
||||
// 验证扩展名
|
||||
if len(policy.AllowedExtension) > 0 && !IsInExtensionList(policy.AllowedExtension, fileInfo.FileName) {
|
||||
return ErrFileExtensionNotAllowed
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// HookValidateFile 一系列对文件检验的集合
|
||||
func HookValidateFile(ctx context.Context, fs *FileSystem, file fsctx.FileHeader) error {
|
||||
fileInfo := file.Info()
|
||||
@@ -151,7 +127,7 @@ func HookCleanFileContent(ctx context.Context, fs *FileSystem, file fsctx.FileHe
|
||||
File: ioutil.NopCloser(strings.NewReader("")),
|
||||
SavePath: file.Info().SavePath,
|
||||
Size: 0,
|
||||
Model: fsctx.Overwrite,
|
||||
Mode: fsctx.Overwrite,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -203,6 +179,7 @@ func GenericAfterUpdate(ctx context.Context, fs *FileSystem, newFile fsctx.FileH
|
||||
|
||||
// SlaveAfterUpload Slave模式下上传完成钩子
|
||||
func SlaveAfterUpload(ctx context.Context, fs *FileSystem, fileHeader fsctx.FileHeader) error {
|
||||
return errors.New("")
|
||||
policy := ctx.Value(fsctx.UploadPolicyCtx).(serializer.UploadPolicy)
|
||||
fileInfo := fileHeader.Info()
|
||||
|
||||
@@ -287,10 +264,8 @@ func HookClearFileHeaderSize(ctx context.Context, fs *FileSystem, fileHeader fsc
|
||||
// HookTruncateFileTo 将物理文件截断至 size
|
||||
func HookTruncateFileTo(size uint64) Hook {
|
||||
return func(ctx context.Context, fs *FileSystem, fileHeader fsctx.FileHeader) error {
|
||||
if fs.Policy.Type == "local" {
|
||||
if driver, ok := fs.Handler.(local.Driver); ok {
|
||||
return driver.Truncate(ctx, fileHeader.Info().SavePath, size)
|
||||
}
|
||||
if handler, ok := fs.Handler.(local.Driver); ok {
|
||||
return handler.Truncate(ctx, fileHeader.Info().SavePath, size)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -97,13 +97,13 @@ func (c HTTPClient) Request(method, target string, body io.Reader, opts ...Optio
|
||||
}
|
||||
|
||||
if options.masterMeta && conf.SystemConfig.Mode == "master" {
|
||||
req.Header.Add("X-Cr-Site-Url", model.GetSiteURL().String())
|
||||
req.Header.Add("X-Cr-Site-Id", model.GetSettingByName("siteID"))
|
||||
req.Header.Add("X-Cr-Cloudreve-Version", conf.BackendVersion)
|
||||
req.Header.Add(auth.CrHeaderPrefix+"Site-Url", model.GetSiteURL().String())
|
||||
req.Header.Add(auth.CrHeaderPrefix+"Site-Id", model.GetSettingByName("siteID"))
|
||||
req.Header.Add(auth.CrHeaderPrefix+"Cloudreve-Version", conf.BackendVersion)
|
||||
}
|
||||
|
||||
if options.slaveNodeID != "" && conf.SystemConfig.Mode == "slave" {
|
||||
req.Header.Add("X-Cr-Node-Id", options.slaveNodeID)
|
||||
req.Header.Add(auth.CrHeaderPrefix+"Node-Id", options.slaveNodeID)
|
||||
}
|
||||
|
||||
if options.contentLength != -1 {
|
||||
|
||||
Reference in New Issue
Block a user