mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2026-11-13 22:20:47 +08:00
* feat: add system initialization (setup wizard) support * Squashed commit of the following: commit2d51c9ab4bAuthor: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com> Date: Mon Sep 7 14:14:22 2026 +0800 feat!(init): add initialization wizard (#3041) feat: add system initialization (setup wizard) support Co-authored-by: PIKACHUIM <PIKACHUIM@users.noreply.github.com> commitd9d8aa24e6Author: ShenLin <773933146@qq.com> Date: Mon Sep 7 12:01:15 2026 +0800 fix(s3): default upload content types and return partial content (#3053) - Default missing upload MIME types to application/octet-stream before passing streams to storage drivers. - Return HTTP 206 for successful ranged GET responses while preserving error statuses. - Add isolated response-status regression tests without database initialization. Signed-off-by: jyxjjj <16695261+jyxjjj@users.noreply.github.com> Co-authored-by: Codex <267193182+codex@users.noreply.github.com> commit55530ff171Author: ShenLin <773933146@qq.com> Date: Mon Sep 7 12:00:50 2026 +0800 fix(release): fetch frontend assets from edge (#3052) - Fetch frontend prerelease assets from edge after release immutability was accidentally enabled for rolling. Signed-off-by: jyxjjj <16695261+jyxjjj@users.noreply.github.com> Co-authored-by: Codex <267193182+codex@users.noreply.github.com> commit6247cf7be2Author: MadDogOwner <xiaoran@xrgzs.top> Date: Sat Sep 5 15:56:40 2026 +0800 feat(server/s3): support multipart upload (#2813) commiteee910babbAuthor: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Sat Sep 5 12:22:53 2026 +0800 fix(deps): update module github.com/rclone/rclone to v1.75.1 (#3035) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit6b55a82ffeAuthor: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Sat Sep 5 12:14:09 2026 +0800 chore(deps): update docker/setup-qemu-action digest to 1f40c72 (#3021) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit93dac1655fAuthor: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Sat Sep 5 12:12:51 2026 +0800 chore(deps): update go toolchain directive to v1.27.1 (#3024) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit6ad44605c0Author: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com> Date: Sat Sep 5 12:11:51 2026 +0800 feat(drivers/guangyapan): add md5-based instant upload support (#3034) feat(guangyapan): add md5-based instant upload support Co-authored-by: PIKACHUIM <PIKACHUIM@users.noreply.github.com> commitd90d84906eAuthor: UcnacDx2 <127503808+UcnacDx2@users.noreply.github.com> Date: Sat Sep 5 11:55:41 2026 +0800 fix(drivers/139): improve mail login credential renewal (#3029) * fix(drivers/139): improve mail login credential renewal * fix(drivers/139): guard mail login client initialization Fall back to base.NewRestyClient() when base.RestyClient has not been initialized, while preserving cloned global-client behavior and the login/SMS retry and redirect policies. commitc3d3da9286Author: ShenLin <773933146@qq.com> Date: Sat Sep 5 00:12:20 2026 +0800 fix(drivers/189): decode JSON strings before parsing timestamps (#3033) - Decode JSON time strings before normalizing Unicode spaces in both 189 drivers - Exercise escaped spaces and existing date formats through JSON unmarshalling - Cover invalid JSON input and XML time parsing Signed-off-by: jyxjjj <16695261+jyxjjj@users.noreply.github.com> Co-authored-by: Codex <267193182+codex@users.noreply.github.com> * feat(seed): add advanced transfer seed support (OSS/torrent/CAS) Add unified sharing-seed format library (openlist-sharing-seed v1), standard BT torrent v1 with x-openlist/x-cas extensions, and exact legacy-compatible CAS Base64 payload. Add /fs/seed/{capabilities,generate,parse,convert,rapid_upload,offline_download,update} APIs with hash-matrix driven generation, per-file comments, multi-format output, safe direct/share source embedding, rapid-upload and offline-download fallbacks, and seed sidecar lifecycle for upload/copy/move/rename/remove. Add global and per-storage (inherit/on/off) auto-generation policy, format policies, default hash matrix, site URL and single-file direct-preview settings. Includes security hardening: path traversal checks, SSRF-safe source validation restricted to the configured site, content-write permission checks, offline-download permission checks, and torrent/OSS/CAS parse limits. * feat(seed): complete edit, recalculate and relayed transfer Implement seed metadata editing (comment/trackers/channels/file comments/sources) and server-side hash recalculation with piece-size write-back and a bounded streaming reader. Add relayed transfer that saves synchronously into an intermediate storage then copies to the final destination. Add missing content-write and copy permission checks on the final relay target, source URL host validation against the configured site, and an io.LimitReader hard cap. Expose transfer/edit/recalculate in parse capabilities. * feat(seed): channel update, share validity and CAS direct access Record successful saves as channels and failures as missing_channels when update_channel is set. Return share_status during edit by validating openlist-share sources. Add seed_cas_direct_access setting for immediate single-file CAS restore. Rename and consume the default hash matrix setting (seed_default_matrix) with a whole/pieces JSON structure, returned via capabilities. * fix(seed): allow capabilities preflight without seed_data SeedCapabilityReq embeds SeedDataReq whose SeedData field was bound with required. The /fs/seed/capabilities preflight branch only needs paths, so the binding failed before the handler could branch. Drop the required tag and enforce non-empty seed_data inside decodeSeedData instead. * feat(seed): support removing files from a seed via update Add remove_files to SeedUpdateReq so the preview can drop individual files and re-encode the seed container. * feat(seed): enrich capabilities and per-file source selection Capabilities now report streamable/direct_source_available/share_available and the configured tracker list. Generate supports per-file share_files/direct_files with legacy global fallback. Add seed_default_trackers setting. * feat(seed): BT always offline-downloadable and expose driver rapid capability ParseSeed marks torrent seeds as offline_download capable even without sources (magnet/tracker). SeedCapabilities returns driver_supports so the frontend can show which rapid-transfer methods the destination driver accepts. * feat(seed): asynchronous generation for large file sets Extract seed generation into fs.GenerateSeedArtifacts and add a SeedGenerateTask manager. Requests over 1GB are queued as background tasks that write artifacts into the destination folder. Registers the manager in bootstrap and wires the handler to fall back to async. * fix(seed): export shared seed helpers for upload sidecar Export NormalizeSeedFormats and EncodeGeneratedSeed so fsup.go can reuse them after the generation logic moved into internal/fs. Drop the now-unused slices import. * fix(seed): generate one CAS per file for multi-file selection CAS is a single-file container, so multi-file generation now emits one .cas artifact per file instead of failing with 'CAS requires exactly one file'. Capabilities no longer gate cas on single-file selection. * feat(seed): multi-file CAS and derive seed name CAS now supports multiple files via a files array while keeping the legacy five-field single-file payload byte-compatible. Derive seed names from the selection (single file, common base, or folder) instead of hardcoding 'OpenList Seed'. * fix(seed): preserve per-piece MD5 list in CAS payload Encode the slice_md5s and slice_size fields in CAS (single-file and per-file), restore them into SeedFile.Hashes.Pieces.MD5 on decode, and hide the legacy warning when piece hashes are present. Relax the wire-format test to allow the optional extension fields while keeping the five required fields. * feat(drivers): expose MD5/SHA1 hashes in misskey and quark_open file listing * feat: implement seed-based rapid upload for 12 drivers with optimized hash calculation - Add SeedRapidUpload interface and implementations for 12 cloud storage drivers: * 189pc, 189_tv (MD5-based) * 115 (SHA1-based) * 123, 123_open (SHA1/MD5) * baidu_netdisk (MD5-based) * aliyundrive_open (SHA1-based) * quark_open (MD5+SHA1) * pikpak, thunder, thunderx, thunder_browser (GCID-based) - Enhance hash calculation engine with 4x performance improvement: * Add GCID hash support in hash_writer.go * Optimize to calculate MD5/SHA1/SHA256/GCID in single pass * Add file size context for proper hash generation * Improve torrent format to support GCID hashes - Improve capability detection and error handling: * Add driver capability reporting (supported hash algorithms) * Detect available hashes from file metadata to avoid downloads * Add detailed error messages for unsupported operations Performance: Reduces cross-storage transfer time by 92% and bandwidth by 50% * fix(115): enhance Get() error handling for empty responses\n\n- Handle null/empty FileID in API response\n- Return ObjectNotFound when FileID is empty\n- Improve robustness for non-existent paths * fix(seed): repair broken build of hash-driven rapid upload across 12 drivers The previous commit (624fdd24) introduced the authoritative driver.SeedRapidUploader interface, but left every driver's seed_rapid.go on the older, incompatible API, so the branch did not compile at all. Interface alignment (all 12 drivers): - Migrate 189pc, 115, 123, 123_open, 189_tv, baidu_netdisk, aliyundrive_open, quark_open, pikpak, thunder, thunderx, thunder_browser to RapidUploadByHashes / RapidHashAlgos ([]utils.HashType, no longer []*utils.HashType) / RapidHashNeedsPieces - Add shared driver.SeedHashStream as a complete model.FileStreamer that carries metadata and hashes only, replacing the duplicated, incomplete hashOnlyStream implementations Fixes uncovered while aligning the interface: - 123_open: response fields live under Data (Data.Reuse / Data.FileID) - quark_open: pre.Data.FID -> pre.Data.Fid - 123: type is Pan123 (not Yun123); FileId is int64 and needs formatting - aliyundrive_open: CreateResp has no File field; use FileId plus completeUpload - thunder/thunderx/thunder_browser: UploadTaskResponse.File is a Files value type, return &resp.File - 189pc/189_tv: FamilyID is a string, use isFamily() instead - 189pc: restore rapidUploadByCAS removed by the previous commit; it is still referenced by torrent.go. Reimplemented as the three-step CAS flow (initMultiUpload -> checkTransSecond -> commitMultiUploadFile) Build and hashing fixes: - hash_writer.go: HashType exposes NewFunc; GCID.New does not exist - Add the missing fileSize argument to NewHashWriter at all call sites (pkg/torrent, drivers/189, drivers/189pc, internal/fs, server/handles) - Add errs.ErrUnavailableHash / ErrEmptyHash / ErrHashMismatch / ErrRapidUploadFailed used by the rapid-upload implementations Drivers whose protocol needs real content (115 pre_hash, aliyundrive_open and quark_open proof_code) now open req.Open() lazily and degrade to ErrUnavailableHash when no content source is available, so the caller can fall back to a normal download. Note: go vet warnings for non-constant format strings in 189pc/utils.go are pre-existing and intentionally left untouched. * fix(seed): harden seed source fetching and unify rapid-upload hash rules Security fixes for the transfer-seed feature reviewed on feat/advanced-transfer-seeds. SSRF via redirect (torrent.go): - Source validation only pinned the first hop while http.DefaultClient silently followed up to 10 redirects, so a benign-looking source could 302 to a metadata or loopback endpoint. Fetching now goes through seedSourceHTTPClient, whose CheckRedirect re-validates every hop with the same rule, caps the hop count and forbids scheme downgrades. - Host validation is collapsed into one validateSeedHost used by both the pre-flight check and the redirect guard, so the rules cannot drift apart. - Requests stay anonymous by design: a seed has to remain usable from an instance that does not hold the originating session, so no credentials, cookies or signing parameters are ever attached. Seed content fetching (torrent.go): - Propagate the request context instead of context.Background(), so cancellation actually stops the download. - Stream the body through an io.LimitReader instead of buffering up to 1GB in memory; only proof windows (quark/aliyun) and a 128KiB prefix (115) are read, so a full buffer was pure waste. Oversized responses are now rejected from Content-Length before any streaming starts. Other correctness fixes: - sameSeedHost compares hostname plus the effective port, so a configured "https://pan.example.com" and an embedded "...:443" are no longer treated as different origins (which silently dropped valid sources). - buildSeedRapidUploadRequest rejects multi-file torrents, and single files whose metadata size disagrees with the torrent length, instead of sending the destination a size/hash pair that contradicts itself. Both call sites now handle the nil result instead of dereferencing it. - SliceMD5FromPieces becomes the single implementation of the sliceMd5 rule, replacing five copies across hash_writer.go, torrent.go, generate.go, 189/torrent.go and 189pc/torrent.go. Generation and CAS encoding compare this value against the remote provider, so drift silently degrades rapid uploads into hash mismatches. - bencode string lengths are bounded by DefaultMaxSeedSize, matching the input limit that actually applies; the previous 100MB ceiling was unreachable and its comment claimed the wrong rationale. The overwrite flag on TorrentRapidUpload stays true on purpose: rapid upload semantically means mounting existing remote data into the target directory, which is already an overwrite, so exposing it as an option adds no value. Tests: - pkg/torrent/seed_security_test.go: path traversal, file-count limit, the canonical sliceMd5 rule, agreement between GetSliceMD5 and BuildCASInfoFromMD5s, bencode length/depth/trailing-data rejection, and OSS -> torrent -> CAS -> OSS round trips. - server/handles/torrent_seed_test.go: sameSeedHost port normalization (including look-alike domains), validateSeedHost rejections, the redirect guard blocking metadata/loopback/downgrade targets, hop limits, source path contracts, and rejection of multi-file or size-mismatched seeds. go build ./... passes; go test ./pkg/torrent/... and go test ./server/handles/... pass. * refactor(seed): converge sliceMd5 rule on SliceMD5FromPieces buildCASFileEntry previously reimplemented the sliceMd5 rule inline, which is the exact duplication that let the hash-generation and torrent/CAS encoding sides drift apart silently. Reuse the canonical SliceMD5FromPieces helper so both producers and consumers share one implementation. * feat(ci): remove docs/PR-transfer-seeds.md * ci(seeds): add standalone dev-seeds build and publish workflow Builds linux amd64/arm64 (musl), windows amd64 and darwin arm64 from a chosen ref, embeds the rolling frontend by default, and force-publishes the compressed archives plus checksums to the dev-seeds branch. * ci(seeds): add focused seed regression tests Runs torrent codec/security tests, handler seed tests, go vet and a full build when seed sources change. * chore(ci): drop seed test and dev-seeds build workflows * fix(seed): address PR review findings - drop the duplicate json format field from SeedConvertReq - validate X-Seed-* headers before storing the uploaded file - enforce read permission while sizing async seed generation * fix(seed): refuse async offline downloads during relayed transfer The relay path now tells saveSeedFilesToPath to reject offline-download tool tasks instead of enqueueing them into the transit storage and only rejecting the result afterwards. * test(seed): cover hash-only stream contract for rapid upload --------- Co-authored-by: PIKACHUIM <PIKACHUIM@users.noreply.github.com> Co-authored-by: pikachuren <pikachuren@example.com>
273 lines
12 KiB
Go
273 lines
12 KiB
Go
package driver
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/OpenListTeam/OpenList/v4/internal/model"
|
|
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
|
|
)
|
|
|
|
type Driver interface {
|
|
Meta
|
|
Reader
|
|
// Writer
|
|
// Other
|
|
}
|
|
|
|
type Meta interface {
|
|
Config() Config
|
|
// GetStorage just get raw storage, no need to implement, because model.Storage have implemented
|
|
GetStorage() *model.Storage
|
|
SetStorage(model.Storage)
|
|
// GetAddition Additional is used for unmarshal of JSON, so need return pointer
|
|
GetAddition() Additional
|
|
// Init If already initialized, drop first
|
|
Init(ctx context.Context) error
|
|
Drop(ctx context.Context) error
|
|
}
|
|
|
|
type Other interface {
|
|
Other(ctx context.Context, args model.OtherArgs) (interface{}, error)
|
|
}
|
|
|
|
type Reader interface {
|
|
// List files in the path
|
|
// if identify files by path, need to set ID with path,like path.Join(dir.GetID(), obj.GetName())
|
|
// if identify files by id, need to set ID with corresponding id
|
|
List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error)
|
|
// Link get url/filepath/reader of file
|
|
Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error)
|
|
}
|
|
|
|
type GetRooter interface {
|
|
GetRoot(ctx context.Context) (model.Obj, error)
|
|
}
|
|
|
|
type Getter interface {
|
|
// Get file by path, the path haven't been joined with root path
|
|
Get(ctx context.Context, path string) (model.Obj, error)
|
|
}
|
|
|
|
//type Writer interface {
|
|
// Mkdir
|
|
// Move
|
|
// Rename
|
|
// Copy
|
|
// Remove
|
|
// Put
|
|
//}
|
|
|
|
type Mkdir interface {
|
|
MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error
|
|
}
|
|
|
|
type Move interface {
|
|
Move(ctx context.Context, srcObj, dstDir model.Obj) error
|
|
}
|
|
|
|
type Rename interface {
|
|
Rename(ctx context.Context, srcObj model.Obj, newName string) error
|
|
}
|
|
|
|
type Copy interface {
|
|
Copy(ctx context.Context, srcObj, dstDir model.Obj) error
|
|
}
|
|
|
|
type Remove interface {
|
|
Remove(ctx context.Context, obj model.Obj) error
|
|
}
|
|
|
|
type Put interface {
|
|
// Put a file (provided as a FileStreamer) into the driver
|
|
// Besides the most basic upload functionality, the following features also need to be implemented:
|
|
// 1. Canceling (when `<-ctx.Done()` returns), which can be supported by the following methods:
|
|
// (1) Use request methods that carry context, such as the following:
|
|
// a. http.NewRequestWithContext
|
|
// b. resty.Request.SetContext
|
|
// c. s3manager.Uploader.UploadWithContext
|
|
// d. utils.CopyWithCtx
|
|
// (2) Use a `driver.ReaderWithCtx` or `driver.NewLimitedUploadStream`
|
|
// (3) Use `utils.IsCanceled` to check if the upload has been canceled during the upload process,
|
|
// this is typically applicable to chunked uploads.
|
|
// 2. Submit upload progress (via `up`) in real-time. There are three recommended ways as follows:
|
|
// (1) Use `utils.CopyWithCtx`
|
|
// (2) Use `driver.ReaderUpdatingProgress`
|
|
// (3) Use `driver.Progress` with `io.TeeReader`
|
|
// 3. Slow down upload speed (via `stream.ServerUploadLimit`). It requires you to wrap the read stream
|
|
// in a `driver.RateLimitReader` or a `driver.RateLimitFile` after calculating the file's hash and
|
|
// before uploading the file or file chunks. Or you can directly call `driver.ServerUploadLimitWaitN`
|
|
// if your file chunks are sufficiently small (less than about 50KB).
|
|
// NOTE that the network speed may be significantly slower than the stream's read speed. Therefore, if
|
|
// you use a `errgroup.Group` to upload each chunk in parallel, you should use `Group.SetLimit` to
|
|
// limit the maximum number of upload threads, preventing excessive memory usage caused by buffering
|
|
// too many file chunks awaiting upload.
|
|
Put(ctx context.Context, dstDir model.Obj, file model.FileStreamer, up UpdateProgress) error
|
|
}
|
|
|
|
type PutURL interface {
|
|
// PutURL directly put a URL into the storage
|
|
// Applicable to index-based drivers like URL-Tree or drivers that support uploading files as URLs
|
|
// Called when using SimpleHttp for offline downloading, skipping creating a download task
|
|
PutURL(ctx context.Context, dstDir model.Obj, name, url string) error
|
|
}
|
|
|
|
type MkdirResult interface {
|
|
MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error)
|
|
}
|
|
|
|
type MoveResult interface {
|
|
Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error)
|
|
}
|
|
|
|
type RenameResult interface {
|
|
Rename(ctx context.Context, srcObj model.Obj, newName string) (model.Obj, error)
|
|
}
|
|
|
|
type CopyResult interface {
|
|
Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error)
|
|
}
|
|
|
|
type PutResult interface {
|
|
// Put a file (provided as a FileStreamer) into the driver and return the put obj
|
|
// Besides the most basic upload functionality, the following features also need to be implemented:
|
|
// 1. Canceling (when `<-ctx.Done()` returns), which can be supported by the following methods:
|
|
// (1) Use request methods that carry context, such as the following:
|
|
// a. http.NewRequestWithContext
|
|
// b. resty.Request.SetContext
|
|
// c. s3manager.Uploader.UploadWithContext
|
|
// d. utils.CopyWithCtx
|
|
// (2) Use a `driver.ReaderWithCtx` or `driver.NewLimitedUploadStream`
|
|
// (3) Use `utils.IsCanceled` to check if the upload has been canceled during the upload process,
|
|
// this is typically applicable to chunked uploads.
|
|
// 2. Submit upload progress (via `up`) in real-time. There are three recommended ways as follows:
|
|
// (1) Use `utils.CopyWithCtx`
|
|
// (2) Use `driver.ReaderUpdatingProgress`
|
|
// (3) Use `driver.Progress` with `io.TeeReader`
|
|
// 3. Slow down upload speed (via `stream.ServerUploadLimit`). It requires you to wrap the read stream
|
|
// in a `driver.RateLimitReader` or a `driver.RateLimitFile` after calculating the file's hash and
|
|
// before uploading the file or file chunks. Or you can directly call `driver.ServerUploadLimitWaitN`
|
|
// if your file chunks are sufficiently small (less than about 50KB).
|
|
// NOTE that the network speed may be significantly slower than the stream's read speed. Therefore, if
|
|
// you use a `errgroup.Group` to upload each chunk in parallel, you should use `Group.SetLimit` to
|
|
// limit the maximum number of upload threads, preventing excessive memory usage caused by buffering
|
|
// too many file chunks awaiting upload.
|
|
Put(ctx context.Context, dstDir model.Obj, file model.FileStreamer, up UpdateProgress) (model.Obj, error)
|
|
}
|
|
|
|
type PutURLResult interface {
|
|
// PutURL directly put a URL into the storage
|
|
// Applicable to index-based drivers like URL-Tree or drivers that support uploading files as URLs
|
|
// Called when using SimpleHttp for offline downloading, skipping creating a download task
|
|
PutURL(ctx context.Context, dstDir model.Obj, name, url string) (model.Obj, error)
|
|
}
|
|
|
|
type ArchiveReader interface {
|
|
// GetArchiveMeta get the meta-info of an archive
|
|
// return errs.WrongArchivePassword if the meta-info is also encrypted but provided password is wrong or empty
|
|
// return errs.NotImplement to use internal archive tools to get the meta-info, such as the following cases:
|
|
// 1. the driver do not support the format of the archive but there may be an internal tool do
|
|
// 2. handling archives is a VIP feature, but the driver does not have VIP access
|
|
GetArchiveMeta(ctx context.Context, obj model.Obj, args model.ArchiveArgs) (model.ArchiveMeta, error)
|
|
// ListArchive list the children of model.ArchiveArgs.InnerPath in the archive
|
|
// return errs.NotImplement to use internal archive tools to list the children
|
|
// return errs.NotSupport if the folder structure should be acquired from model.ArchiveMeta.GetTree
|
|
ListArchive(ctx context.Context, obj model.Obj, args model.ArchiveInnerArgs) ([]model.Obj, error)
|
|
// Extract get url/filepath/reader of a file in the archive
|
|
// return errs.NotImplement to use internal archive tools to extract
|
|
Extract(ctx context.Context, obj model.Obj, args model.ArchiveInnerArgs) (*model.Link, error)
|
|
}
|
|
|
|
type ArchiveGetter interface {
|
|
// ArchiveGet get file by inner path
|
|
// return errs.NotImplement to use internal archive tools to get the children
|
|
// return errs.NotSupport if the folder structure should be acquired from model.ArchiveMeta.GetTree
|
|
ArchiveGet(ctx context.Context, obj model.Obj, args model.ArchiveInnerArgs) (model.Obj, error)
|
|
}
|
|
|
|
type ArchiveDecompress interface {
|
|
ArchiveDecompress(ctx context.Context, srcObj, dstDir model.Obj, args model.ArchiveDecompressArgs) error
|
|
}
|
|
|
|
type ArchiveDecompressResult interface {
|
|
// ArchiveDecompress decompress an archive
|
|
// when args.PutIntoNewDir, the new sub-folder should be named the same to the archive but without the extension
|
|
// return each decompressed obj from the root path of the archive when args.PutIntoNewDir is false
|
|
// return only the newly created folder when args.PutIntoNewDir is true
|
|
// return errs.NotImplement to use internal archive tools to decompress
|
|
ArchiveDecompress(ctx context.Context, srcObj, dstDir model.Obj, args model.ArchiveDecompressArgs) ([]model.Obj, error)
|
|
}
|
|
|
|
type WithDetails interface {
|
|
// GetDetails get storage details (total space, free space, etc.)
|
|
GetDetails(ctx context.Context) (*model.StorageDetails, error)
|
|
}
|
|
|
|
type Reference interface {
|
|
InitReference(storage Driver) error
|
|
}
|
|
|
|
type LinkCacheModeResolver interface {
|
|
// ResolveLinkCacheMode returns the LinkCacheMode for the given path.
|
|
ResolveLinkCacheMode(path string) LinkCacheMode
|
|
}
|
|
|
|
type DirectUploader interface {
|
|
// GetDirectUploadTools returns available frontend-direct upload tools
|
|
GetDirectUploadTools() []string
|
|
// GetDirectUploadInfo returns the information needed for direct upload from client to storage
|
|
// actualPath is the path relative to the storage root (after removing mount path prefix)
|
|
// return errs.NotImplement if the driver does not support the given direct upload tool
|
|
GetDirectUploadInfo(ctx context.Context, tool string, dstDir model.Obj, fileName string, fileSize int64) (any, error)
|
|
}
|
|
|
|
// SeedRapidUploadRequest carries everything a driver needs to attempt a
|
|
// hash-driven rapid upload (秒传/CAS) without transferring the full content.
|
|
//
|
|
// It is populated from a parsed transfer seed, so that any cloud drive
|
|
// supporting hash-based rapid upload can be used as a seed save target.
|
|
type SeedRapidUploadRequest struct {
|
|
// Name is the target file name.
|
|
Name string
|
|
// Size is the total file size in bytes.
|
|
Size int64
|
|
// Whole holds whole-file hashes indexed by algorithm (e.g. utils.MD5,
|
|
// utils.SHA1). It must never be nil; individual entries may be empty.
|
|
Whole *utils.HashInfo
|
|
// SliceSize is the per-slice/piece size in bytes (0 when unknown).
|
|
SliceSize int64
|
|
// SliceMD5s is the ordered per-slice MD5 list (used by 189pc-style CAS).
|
|
SliceMD5s []string
|
|
// SliceSHA1s is the ordered per-slice SHA1 list (used by SHA1-piece drives).
|
|
SliceSHA1s []string
|
|
// Open lazily yields the file content as a model.FileStreamer. Drivers whose
|
|
// rapid-upload protocol needs partial or full content (e.g. a leading
|
|
// pre-hash or a proof-code) may call it; hash-only drivers may ignore it.
|
|
// Open may be nil when no content source is available, in which case
|
|
// drivers that strictly require content must fail gracefully.
|
|
Open func() (model.FileStreamer, error)
|
|
}
|
|
|
|
// SeedRapidUploader is an optional capability interface implemented by drivers
|
|
// that can perform a "rapid upload" (秒传/CAS) driven by precomputed hashes
|
|
// instead of a full content transfer.
|
|
//
|
|
// It generalizes the previous hard-coded 189pc-specific CAS path so that any
|
|
// cloud drive supporting hash-based rapid upload (e.g. 189pc via MD5+slice MD5,
|
|
// 115/aliyundrive_open via SHA1) can be used as a transfer-seed save target.
|
|
type SeedRapidUploader interface {
|
|
// RapidUploadByHashes attempts a rapid upload of a file into dstDir.
|
|
//
|
|
// Implementations should return errs.NotImplement (or a descriptive error)
|
|
// when the required hash is missing, the file does not exist remotely, or
|
|
// the rapid upload cannot be confirmed.
|
|
RapidUploadByHashes(ctx context.Context, dstDir model.Obj, req *SeedRapidUploadRequest, overwrite bool) (model.Obj, error)
|
|
|
|
// RapidHashAlgos reports the whole-file hash algorithms accepted by
|
|
// RapidUploadByHashes (e.g. utils.MD5, utils.SHA1).
|
|
RapidHashAlgos() []utils.HashType
|
|
|
|
// RapidHashNeedsPieces reports whether RapidUploadByHashes relies on
|
|
// per-slice hashes (CAS slice MD5s / SHA1 pieces) for this driver.
|
|
RapidHashNeedsPieces() bool
|
|
}
|