Skip to content

fix(qihoo360): correct token expiration handling to use absolute timestamp - #11

Merged
Wodlie merged 156 commits into
feat/qihoo360from
copilot/implement-qihoo360-driver
Feb 28, 2026
Merged

fix(qihoo360): correct token expiration handling to use absolute timestamp#11
Wodlie merged 156 commits into
feat/qihoo360from
copilot/implement-qihoo360-driver

Conversation

Copilot AI commented Nov 9, 2025

Copy link
Copy Markdown

The driver failed after ~1 hour because access_token_expire was misinterpreted as a duration instead of an absolute Unix timestamp.

Changes

Token Expiration Bug Fix (util.go:113)

// Before: treated API value as duration, set expiry to year 2082
d.authExpire = time.Now().Unix() + resp.Data.AccessTokenExpire

// After: use absolute timestamp directly
d.authExpire = resp.Data.AccessTokenExpire

API returns 1772190715 (Feb 27 2026, 11:11:55), not 3600 seconds. The buggy code calculated expiration as now + 1772190715, setting it 56 years in the future. Token actually expired after 1 hour, but code never refreshed it.

Retry Protection (util.go:127-132)

  • Added requestWithRetry() with max 2 retries to prevent infinite recursion when auth repeatedly fails

Type Corrections (driver.go:107-118)

  • Changed uint64int64 for model.DiskUsage compatibility
  • Changed FreeSpace field → UsedSpace (FreeSpace is a calculated method)

Verification

Tested with API key, confirmed token expires in ~1 hour and is now properly refreshed at 55 minutes (with 5-minute buffer).

Original prompt

请参考driver/template与https://github.com/Wodlie/ecs_mcp_server,实现qihoo360的驱动,如有需要创建的临时文件请不要提交,不需要创建文档。如果有部分功能需要超过Wodlie/ecs_mcp_server提供的代码(比如文件上传),请返回“未实现”


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

NewbieOrange and others added 30 commits October 4, 2025 00:41
* feat(pikpak): support disk usage

* fix(alias): cannot list with details

* refactor: rename `NewDiskUsageFromUsedAndTotal`

* fix(disk-usage): get details of storages that is not initialized
* feat(http3|quic): add http3|quic support

* revert(ai): fix ai error

* fix(shutdown): shutdown was using close

* feat(http3|quic): add config if needs h3

* feat(http3|quic): add Alt-Svc to expose h3
* 新增清真云Open驱动,支持最新的轻量SDK

* Change Go version in go.mod

Downgrade Go version from 1.24.2 to 1.23.4

Signed-off-by: zzzhr1990 <[email protected]>

* Apply suggestions from code review

* Removed unnecessary comments
* Downgraded the Go version to 1.23.4.
* Not sure whether FileStream supports concurrent read and write operations, so currently using single-threaded upload to ensure safety.

Co-authored-by: Copilot <[email protected]>
Signed-off-by: zzzhr1990 <[email protected]>

* feat(halalcloud_open): support disk usage

* Set useSingleUpload to true for upload safety

Not sure whether FileStream supports concurrent read and write operations, so currently using single-threaded upload to ensure safety.

Signed-off-by: zzzhr1990 <[email protected]>

* Update meta.go

Change required for RefreshToken, If using a personal API approach, the RefreshToken is not required.

Signed-off-by: zzzhr1990 <[email protected]>

* remove debug logs

* bump halalcloud SDK version

* fix unnecessary params

* Update drivers/halalcloud_open/driver_init.go

Co-authored-by: Copilot <[email protected]>
Signed-off-by: zzzhr1990 <[email protected]>

* Fixed spelling errors; changed hardcoded retry parameters to constants.

* remove pointer in get link function in utils.go

---------

Signed-off-by: zzzhr1990 <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: KirCute <[email protected]>
* fix retry task after restart

* fix: initialize SrcStorage and DstStorage in tasks to prevent nil pointer dereference

* feat: implement storage load signal mechanism for improved synchronization

* fix:  update StoragesLoaded logic

* refactor: reorganize storage loading logic and improve synchronization handling

---------

Co-authored-by: j2rong4cn <[email protected]>
* feat(cache): improve cache management

* feat(disk-usage): add cache

* feat(disk-usage): add refresh

* fix(disk-usage): cache with ttl

* feat(cache): implement KeyedCache and TypedCache for improved caching mechanism

* fix(copy): update object retrieval to use Get instead of GetUnwrap

* refactor(cache): simplify DirectoryCache structure and improve object management

* fix(cache): correct cache entry initialization and key deletion logic in TypedCache

* refactor(driver): remove GetObjInfo interface and simplify Link function logic
https://github.com/OpenListTeam/OpenList/pull/888/files#r2430925783

* fix(link): optimize link retrieval and caching logic

* refactor(cache): consolidate cache management and improve directory cache handling

* fix(cache): add cache control based on storage configuration in List function

* .

* refactor: replace fmt.Sprintf with strconv for integer conversions

* refactor(cache): enhance cache entry management with Expirable interface

* fix(cache): improve link reference acquisition logic to handle expiration

* refactor: replace OnlyLinkMFile with NoLinkSF in driver configurations and logic

* refactor(link): enhance link caching logic with dynamic type keys based on IP and User-Agent

* feat(drivers): add LinkCacheType to driver configurations for enhanced caching

* refactor(cache): streamline directory object management in cache operations

* refactor(cache): remove unnecessary 'dirty' field from CacheEntry structure

* refactor(cache): replace 'dirty' field with bitwise flags

* refactor(io): 调高SyncClosers.AcquireReference的优先级

* refactor(link): 优化链接获取逻辑,增加重

* refactor(link): 添加RequireReference字段以增强链接管理

* refactor(link): 移除MFile字段,改用RangeReader

* refactor: 移除不必要的NoLinkSF字段

* refactor(cache): 修改目录缓存的脏标志定义和更新逻辑

* feat(cache): add expiration gc

---------

Co-authored-by: KirCute <[email protected]>
Co-authored-by: KirCute <[email protected]>
Co-authored-by: j2rong4cn <[email protected]>
* feat(onedrive): add ref support

* fix(onedrive): remove redundant token assignment from reference

---------

Co-authored-by: j2rong4cn <[email protected]>
* feat(drivers): add ProtonDrive driver

- Implement complete ProtonDrive storage driver with end-to-end encryption support
- Add authentication via username/password with credential caching and reusable login
- Support all core operations: List, Link, Put, Copy, Move, Remove, Rename, MakeDir
- Include encrypted file operations with PGP key management and node passphrase handling
- Add temporary HTTP server for secure file downloads with range request support
- Support media streaming using temp server range requests
- Implement progress tracking for uploads and downloads
- Support directory operations with circular move detection
- Add proper error handling and panic recovery for external library integration
- Support buffered upload for specific sequential and encrypted, but optimized transmission.

* Update drivers/proton_drive/util.go

Co-authored-by: Copilot <[email protected]>
Signed-off-by: D@' 3z K!7 <[email protected]>

* chore

* feat(drivers): enhance ProtonDrive temp server

- Implement separate listen and public port configuration for complex network deployments
- Add intelligent port detection with 8080 as preferred default, fallback to auto-assignment
- Support Container/NAT/VM environments through configurable external host and port mapping
- Add port availability validation with graceful fallback to listen port
- Enable users to specify external domain/IP for client connections (e.g., 192.168.1.5)
- Follow FTP server configuration patterns for network flexibility
- Maintain localhost development simplicity while supporting production deployments

* feat(proton_drive): refactor directory handling and improve link retrieval

* fix(proton_drive): add NoLinkURL configuration option

* fix(proton_drive): update file size retrieval and enforce TwoFACode requirement

* feat(proton_drive): add expiration to link response

* fix(proton_drive): handle empty RootFolderID in Init method

* fix(proton_drive): update credential handling to use email and reusable login

* fix(proton_drive): update credential handling to use reusableCredential variable

* fix(proton_drive): update DirectRename to use GetLink for source object retrieval

* fix(proton_drive): refactor uploadFile to return model.Obj and handle errors correctly

* fix(proton_drive): refactor DirectMove to use getLink for source retrieval and simplify destination handling

* fix(proton_drive): simplify Copy method by removing temporary file creation and directly using FileStream

* refactor(proton_drive): remove unused temporary server and related code

* chore

* fix(proton_drive): fix driver

- Handle fresh login if ProtonDrive rejects AccessToken or RefreshToken
- Update stored credentials

* fix(proton_drive): simplify reusable login handling in Init method

* fix(proton_drive): fix driver

- Update stored credentials, now is failing

* feat(proton_drive): improve authentication handling and remove unused variables

* fix(proton_drive): fix driver

- Update stored credentials, now is failing

* fix(proton_drive): improve authentication handling

* refactor(proton_drive): move client initialization to initClient method

* feat(proton_drive): move addrs and addrKRs

* feat(proton_drive): optimize upload threads

- Change ConcurrentBlockUploadCount to user configured upload threads number
- Comment ConcurrentFileCryptoCount, default is runtime.GOMAXPROCS(0)

---------

Signed-off-by: D@' 3z K!7 <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: KirCute <[email protected]>
Co-authored-by: j2rong4cn <[email protected]>
Co-authored-by: KirCute <[email protected]>
* fix(alias): Check the driver path during initialization

* fix(alias): Don't check the driver path during initialization anymore.
* feat(drivers/123): Allow modification of the platform field

* feat(drivers/123): Set login platfrom as web

* fix(drivers/123): update platform field help value
* feat(strm): strm local file

* feat: 代码优化

* feat: 访问被strm挂载路径时也更新

* fix: 路径最后带/判断缺失

* fix: 路径最后带/判断缺失

* refactor

* refactor

* fix: close seekable-stream in `generateStrm`

* refactor: lazy create local file

* 优化路径判断

---------

Co-authored-by: KirCute <[email protected]>
allows access to files on remote devices via Thunder's tunneling service.
…1359)

* support proxy

* debug

* debug2

* del debug

* add proxy configuration with env var fallback

* comments to en

* refactor(env): fallback env

---------

Co-authored-by: jyxjjj <[email protected]>
)

* fix file link display size

* fix performance and field

* cn to en notes

---------

Co-authored-by: ShenLin <[email protected]>
…eam#1528)

* feat(stream): enhance GetRangeReaderFromLink rate limiting

* refactor(stream): update GetRangeReaderFromMFile to return *model.FileRangeReader

* refactor(stream): simplify context error handling in RateLimitReader, RateLimitWriter, and RateLimitFile

* refactor(net): replace custom LimitedReadCloser with readers.NewLimitedReadCloser

* fix(model): update Link.ContentLength JSON tag for correct serialization

* docs(model): add clarification to FileRangeReader usage comment
OpenListTeam#1584)

* perf(stream): optimize CacheFullAndWriter for better memory management

* fix(stream): ensure proper seek handling in CacheFullAndWriter for improved data integrity
* fix(baidu_netdisk): improve upload experience

* fix(typo): URL should be uppercase, apply suggestion from @Copilot

Co-authored-by: Copilot <[email protected]>
Signed-off-by: ShenLin <[email protected]>

* fix(typo): URL should be uppercase, apply suggestion from @Copilot

Co-authored-by: Copilot <[email protected]>
Signed-off-by: ShenLin <[email protected]>

* fix(baidu_netdisk): use "UploadAPI" as a fallback when using dynamic upload api

* fix(baidu_netdisk): all uploads share the same upload url cache

* fix(drivers/baidu_netdisk): defer uploadUrlMu unlock

* update driver.go to main

---------

Signed-off-by: ShenLin <[email protected]>
Signed-off-by: jenfonro <[email protected]>
Co-authored-by: ShenLin <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: jenfonro <[email protected]>
Khoray and others added 22 commits January 25, 2026 17:00
…enListTeam#2010)

* fix(driver/seafile): object not found when RootFolderPath != "/"

* refactor(seafile): restructure Seafile driver for improved library handling and error management

* add IsDir method to LibraryInfo type

* improve initialization

* add repoID to RepoItemResp and update List method to set repoID

---------

Co-authored-by: Khoray <[email protected]>
Co-authored-by: j2rong4cn <[email protected]>
* fix(drivers/alias): default sort & substitute link

* fix

* fix
…penListTeam#2035)

* fix(drivers/cloudreve_v4): add IsFolder attribute to Getter response

Signed-off-by: MadDogOwner <[email protected]>

* refactor(drivers/cloudreve_v4): implement File.fileToObject method

Signed-off-by: MadDogOwner <[email protected]>

* fix(drivers/cloudreve_v4): implement 404 not found for getter

Signed-off-by: MadDogOwner <[email protected]>

---------

Signed-off-by: MadDogOwner <[email protected]>
* fix(drivers/quark): apply html escaping in quark
…penListTeam#1617)

* fix(FsRemove): add validation for empty items in delete file list

If Req.Names contains an empty string item, the whole directory will be removed. As a result we need add a simple guard to prevent such cases.

Signed-off-by: huyuantao <[email protected]>

* fix(FsRemove): enhance validation to prevent unintended directory deletion

1. Use `utils.FixAndCleanPath` to correctly identify and block invalid names.
2. Change error handling from `return` to `continue`.

Signed-off-by: huyuantao <[email protected]>

---------

Signed-off-by: huyuantao <[email protected]>
Co-authored-by: Pikachu Ren <[email protected]>
…with pagination and random chunk naming (OpenListTeam#2034)

* fix(drivers/teldrive): enhance file listing and upload functionality with pagination and random chunk naming

* fix(drivers/teldrive): optimize file listing by removing unnecessary mutex and restructuring data handling

* Update drivers/teldrive/meta.go

Co-authored-by: Copilot <[email protected]>
Signed-off-by: Chaloemchai <[email protected]>

---------

Signed-off-by: Chaloemchai <[email protected]>
Co-authored-by: Copilot <[email protected]>
…ListTeam#2068)

* fix(115_share): add user agent support and update driver dependency

* fix(115): fix download error

* feat: add thumbnail support for 115 driver and 115 share

- Add Thumb() method to FileObj in 115 driver to return thumbnail URL
- Add ThumbURL field to FileObj struct in 115 share utility
- Update 115driver dependency from v1.2.2 to v1.2.3 to support thumbnail functionality
- Implement Thumb() method for 115 share FileObj to return thumbnail URL
…eam#2087)

* feat(ci): add PR title validation for breaking changes

Updated regex to allow '!' for breaking changes in PR titles.

Signed-off-by: MadDogOwner <[email protected]>

* chore(pr): Update PR template

Add bilingual instructions for PR title formatting.

Signed-off-by: MadDogOwner <[email protected]>

---------

Signed-off-by: MadDogOwner <[email protected]>
* feat(drivers/123open): support sha1 reuse api

* fix(drivers/123open): fix typos
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
[skip ci]

Add SECURITY.md

Signed-off-by: MadDogOwner <[email protected]>
* chore(handles/auth): improve error response

Signed-off-by: MadDogOwner <[email protected]>

* Apply suggestion from @xrgzs

Signed-off-by: MadDogOwner <[email protected]>

---------

Signed-off-by: MadDogOwner <[email protected]>
The API returns access_token_expire as an absolute Unix timestamp, not a duration. The old code was adding it to current time, causing tokens to "expire" in year 2082. This meant tokens appeared valid even after actual expiration (1 hour), causing all API calls to fail after the program ran for some time.

Also added retry limit protection to prevent infinite recursion in error handling.

Co-authored-by: Wodlie <[email protected]>
Copilot AI changed the title feat(drivers): add qihoo360 driver for 360 AI云盘 fix(qihoo360): correct token expiration handling to use absolute timestamp Feb 27, 2026
@Wodlie
Wodlie requested a review from Copilot February 28, 2026 02:36

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes token-expiration handling for the Qihoo360 driver (treat API access_token_expire as an absolute Unix timestamp), and introduces broader infrastructure updates around request retries, link caching behavior, proxy config, and storage details reporting across multiple drivers.

Changes:

  • Correct token-expiration semantics and add bounded retry logic to prevent infinite auth recursion.
  • Add/adjust driver capabilities (disk usage fields, link cache modes, direct-upload info), and propagate Path on listed objects.
  • Introduce new drivers / patches / settings plus CLI and workflow template refinements.

Reviewed changes

Copilot reviewed 260 out of 337 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
internal/fs/other.go Adjust FS helpers to remove lazyCache and optionally skip hooks via context key.
internal/fs/list.go Update virtual-file listing call signature to pass refresh/name filtering parameters.
internal/fs/get.go Improve virtual-file lookup and mark root as read-only/virtual.
internal/fs/fs.go Update public FS APIs (skipHook, merge, direct-upload info plumbing).
internal/errs/unwrap.go Re-implement unwrap helper without stdlib errors.Unwrap.
internal/errs/object.go Add new object-related sentinel errors.
internal/errs/errors.go Add StorageNotInit and remove MoveBetweenTwoStorages.
internal/driver/utils.go Make Progress.Write explicitly return (n, err).
internal/driver/driver.go Add new driver interfaces (LinkCacheModeResolver, DirectUploader); remove legacy interface/comment blocks.
internal/driver/config.go Introduce LinkCacheMode and proxy preference flags; adjust proxy decision logic.
internal/db/tasks.go Block task persistence until storages load signal is fired.
internal/db/sharing.go Support caller-supplied sharing IDs and add delete-by-creator helper.
internal/conf/var.go Add config path global + storages-load signaling channel with reset/send helpers.
internal/conf/const.go Add new setting keys + SkipHookKey; change ContextKey underlying type.
internal/conf/config.go Add H3 flag + proxy address; tighten TLS default.
internal/cache/utils.go Add global cache GC cron + GC function registry.
internal/cache/type.go Add expirable cache entry abstractions.
internal/cache/keyed_cache.go Add generic keyed cache with TTL and GC integration.
internal/bootstrap/storage.go Emit storages-loaded signal after loading.
internal/bootstrap/patch/v4_1_9/webdav.go Migration patch to enable WebDav proxy settings.
internal/bootstrap/patch/v4_1_9/skip_tls.go Migration patch to reset insecure TLS skip setting.
internal/bootstrap/patch/v4_1_8/alias.go Migration patch to upgrade Alias driver config.
internal/bootstrap/patch/v3_all/rename.go Remove legacy v3 driver renaming patch.
internal/bootstrap/patch/v3_32_0/update_authn.go Avoid fatal exit during authn migration; log + return instead.
internal/bootstrap/patch/v3_24_0/hash_password.go Avoid fatal exit during password-hash migration; log + return instead.
internal/bootstrap/patch/all.go Register new v4 patches; remove v3-all rename patch.
internal/bootstrap/patch.go Minor import formatting cleanup.
internal/bootstrap/data/setting.go Add multiple new settings (preview defaults, hooks, LDAP, zip encoding).
internal/bootstrap/config.go Allow custom config path; add proxy config validation logging.
internal/archive/tool/base.go Switch multipart filename format to regex-based matching.
internal/archive/sevenzip/sevenzip.go Update 7z multipart matching regex.
internal/archive/rardecode/rardecode.go Update rar multipart matching regex.
drivers/yandex_disk/util.go Remove hard-coded User-Agent header usage.
drivers/yandex_disk/types.go Narrow return type of fileToObj to *model.Object.
drivers/yandex_disk/driver.go Ensure listed objects carry full Path.
drivers/wps/types.go Introduce WPS driver types + Obj implementation.
drivers/wps/meta.go Register WPS driver and config schema.
drivers/wps/driver.go Implement WPS driver interfaces incl. GetDetails.
drivers/wopan/driver.go Add GetDetails implementation.
drivers/weiyun/driver.go Improve login-type check; add GetDetails and WithDetails assertion.
drivers/webdav/meta.go Prefer proxy rather than forcing only-proxy.
drivers/webdav/driver.go Populate object Path; add redirect-resolution option to Link.
drivers/virtual/meta.go Replace OnlyLinkMFile with OnlyProxy semantics.
drivers/virtual/driver.go Switch to range-reader based link with dummy reader.
drivers/uss/driver.go Populate object Path in list results.
drivers/url_tree/meta.go Mark driver as OnlyIndices.
drivers/url_tree/driver.go Provide root path implementation on Addition.
drivers/thunderx/types.go Add AboutResponse for quota fetching.
drivers/thunderx/driver.go Add GetDetails implementation.
drivers/thunder_browser/types.go Add AboutResponse for quota fetching.
drivers/thunder_browser/driver.go Add GetDetails; minor formatting tweaks using strconv.
drivers/thunder/util.go Add Space field to common struct.
drivers/thunder/types.go Add AboutResponse for quota fetching.
drivers/thunder/meta.go Add Space fields; adjust proxy behavior config.
drivers/terabox/util.go Adjust errno handling for jsToken refresh.
drivers/terabox/driver.go Avoid float math for chunk count; populate object Path.
drivers/template/meta.go Remove OnlyLinkMFile from template config.
drivers/teldrive/meta.go Add random chunk name option.
drivers/teldrive/driver.go Add concurrent pagination via errgroup; fix single upload arg list; populate Path.
drivers/strm/util.go Refactor list conversion + link building (signing, prefix, suffix logic).
drivers/strm/types.go Remove hardcoded suffix maps (moved elsewhere).
drivers/strm/meta.go Expand Strm driver options; enforce proxy-only + no link URL.
drivers/smb/meta.go Switch SMB to proxy-only semantics.
drivers/smb/driver.go Populate Path; simplify Link to always use range reader; adjust disk usage to used-space.
drivers/sftp/types.go Populate Path for listed objects (including symlink-error case).
drivers/sftp/meta.go Switch SFTP to proxy-only semantics.
drivers/sftp/driver.go Simplify Link to range-reader only; adjust disk usage to used-space and int64 math.
drivers/seafile/util.go Remove old repo/path logic; add getLibraryInfo.
drivers/seafile/types.go Make repo/library items implement model.Obj.
drivers/s3/meta.go Add direct-upload toggles/host.
drivers/s3/driver.go Add direct-upload client + direct-upload tool/info endpoints.
drivers/quark_uc_tv/util.go Improve token invalidation detection via errno/message matching.
drivers/quark_uc/util.go Unescape HTML in filenames; expand query flags; switch part upload to net/http.
drivers/quark_uc/types.go Change quota fields to int64.
drivers/quark_open/util.go Use shared HTTP client; remove hard-coded UA from refresh call.
drivers/quark_open/driver.go Improve multipart upload retry/progress; avoid redundant boolean compare.
drivers/qihoo360/meta.go Register Qihoo360 driver with API key schema.
drivers/proton_drive/types.go Add ProtonDrive request/response types (new driver).
drivers/proton_drive/meta.go Register ProtonDrive driver and defaults (new driver).
drivers/pikpak/types.go Add AboutResponse for quota fetching.
drivers/pikpak/driver.go Add GetDetails; minor formatting cleanup.
drivers/openlist_share/driver.go Populate Path for listed objects.
drivers/openlist/types.go Add archive-decompress overwrite flag.
drivers/openlist/meta.go Add upstream IP pass-through + link cache auto mode.
drivers/openlist/driver.go Pass UA/IP headers upstream; propagate Overwrite; implement link cache resolver.
drivers/onedrive_app/util.go Add retry guard; add direct-upload upload-session helper.
drivers/onedrive_app/types.go Use int64 for quota fields.
drivers/onedrive_app/meta.go Add direct-upload enable flag.
drivers/onedrive_app/driver.go Populate Path; switch disk usage to used-space; add direct-upload endpoints.
drivers/onedrive/util.go Add retry guard + reference forwarding; add direct-upload helper and context-aware retries.
drivers/onedrive/types.go Use int64 for quota fields.
drivers/onedrive/meta.go Add direct-upload flag; minor formatting in TenantID field.
drivers/onedrive/driver.go Add reference wiring; populate Path; switch disk usage to used-space; add direct-upload endpoints.
drivers/netease_music/driver.go Provide root path via Addition rather than special-casing Get.
drivers/mopan/driver.go Fix upload progress math; add GetDetails.
drivers/misskey/util.go Clarify root-folder handling; build multipart form data safely.
drivers/mega/meta.go Add move-to-trash toggle.
drivers/mega/driver.go Respect move-to-trash toggle; add GetDetails.
drivers/mediafire/types.go Minor formatting (trailing newline).
drivers/mediafire/meta.go Make session token optional; standardize UA; remove OnlyLinkMFile from config.
drivers/mediafire/driver.go Auto-acquire session token; ensure progress reaches 100; switch disk usage to used-space and int64 parsing.
drivers/local/util_windows.go Switch disk usage to used-space; add cross-device error helper.
drivers/local/util_unix.go Switch disk usage to used-space; add cross-device error helper.
drivers/local/util.go Add reflink copy support helpers; use errs.NotImplement on unsupported.
drivers/local/meta.go Switch Local driver to proxy-only semantics.
drivers/local/copy_namedpipes_x.go Stub for named pipe copy on some OSes.
drivers/local/copy_namedpipes.go Implement FIFO creation during copy on Unix-like systems.
drivers/lenovonas_share/driver.go Simplify path normalization; ensure files have Path.
drivers/lanzou/meta.go Update default UA version string.
drivers/lanzou/driver.go Use shared Windows UA constant.
drivers/ilanzou/util.go Reduce headers; simplify accept-encoding/language.
drivers/ilanzou/driver.go Remove hard-coded UA; fix disk usage computation and used-space reporting.
drivers/halalcloud_open/obj_file.go Add Obj wrapper around SDK file type.
drivers/halalcloud_open/meta.go Register HalalCloudOpen driver schema.
drivers/halalcloud_open/driver_interface.go Implement driver interfaces and GetDetails.
drivers/halalcloud_open/driver_init.go Add SDK initialization + token persistence.
drivers/halalcloud_open/driver.go Define HalalCloudOpen driver struct.
drivers/google_drive/driver.go Switch disk usage reporting to used-space + int64 parsing.
drivers/github_releases/meta.go Change root model + add source-code listing toggle.
drivers/github_releases/driver.go Add source-code items + safer path joining.
drivers/github/types.go Populate Path on GitHub objects using FixAndCleanPath.
drivers/ftp/meta.go Switch FTP to proxy-only semantics.
drivers/ftp/driver.go Decode names once; populate Path; simplify RangeReader wrapper.
drivers/febbox/meta.go Set link cache mode to include IP.
drivers/dropbox/util.go Remove hard-coded User-Agent header usage.
drivers/doubao_share/util.go Use shared Windows UA constant.
drivers/doubao_share/types.go Rename response struct + update fields for new download-info API.
drivers/doubao_share/driver.go Switch to new download info endpoint.
drivers/doubao/meta.go Add API rate limit option + set default in init.
drivers/degoo/util.go Add user-info query for quota retrieval.
drivers/degoo/types.go Add user-info types for quota retrieval.
drivers/degoo/driver.go Add GetDetails implementation.
drivers/crypt/util.go Simplify path guessing; refactor encryption path routine.
drivers/crypt/meta.go Add CheckStatus to config.
drivers/cnb_releases/meta.go Switch root model to RootID; adjust defaults.
drivers/cnb_releases/driver.go Use ID-based root detection; improve upload progress reporting.
drivers/cloudreve_v4/types.go Add fileToObject; use int64 for capacity fields.
drivers/cloudreve_v4/driver.go Use fileToObject; implement Get; support ks3; switch disk usage to used-space.
drivers/cloudreve/util.go Add retry context propagation for multipart uploads.
drivers/cloudreve/types.go Populate Path; add storage details type.
drivers/cloudreve/driver.go Populate Path; add GetDetails.
drivers/chunk/driver.go Add root path via Addition; fix missing chunk detection; skip hooks during internal puts.
drivers/chaoxing/util.go Use strconv for Content-Length.
drivers/chaoxing/types.go Use strconv for folder ID formatting.
drivers/chaoxing/driver.go Stream multipart upload without buffering whole file; set ContentLength directly.
drivers/base/client.go Standardize UA constants; add proxy configuration hooks.
drivers/baidu_photo/meta.go Set link cache mode to include UA.
drivers/baidu_photo/driver.go Fix upload progress math; ensure final 100% progress update.
drivers/baidu_netdisk/types.go Add dynamic upload server response; prefer not using unreliable MD5; use int64 quota types.
drivers/baidu_netdisk/meta.go Add upload timeout + dynamic upload API options; set proxy preference.
drivers/azure_blob/meta.go Embed RootPath; simplify init; remove custom root id implementation.
drivers/azure_blob/driver.go Return global config rather than per-instance field.
drivers/autoindex/util_test.go Add parseSize unit tests.
drivers/autoindex/types.go Add internal helper types/errors for autoindex parsing.
drivers/autoindex/meta.go Register AutoIndex driver schema.
drivers/all.go Register new drivers (alist_v3, autoindex, halalcloud_open, proton_drive, qihoo360, wps).
drivers/aliyundrive_open/util.go Remove hard-coded User-Agent header usage.
drivers/aliyundrive_open/upload.go Ensure retry uses ctx; apply rate limit wrapper per attempt.
drivers/aliyundrive_open/driver.go Minor root object cleanup; switch disk usage to used-space (int64).
drivers/aliyundrive/driver.go Switch disk usage to used-space (int64).
drivers/alist_v3/util.go Add AList V3 login + request wrapper with relogin.
drivers/alist_v3/meta.go Register AList V3 driver schema and cache mode.
drivers/alias/types.go Add conflict policy constants/types and balanced obj wrapper.
drivers/alias/meta.go Replace legacy conflict toggles with explicit policy settings.
drivers/189pc/utils.go Add early login-failed guard; improve progress math + ensure 100% final update.
drivers/189pc/types.go Use int64 for capacity fields.
drivers/189pc/driver.go Switch disk usage to used-space.
drivers/189_tv/utils.go Add early login-failed guard.
drivers/189_tv/types.go Use int64 for capacity fields.
drivers/189_tv/driver.go Switch disk usage to used-space.
drivers/189/util.go Standardize UA usage in comments.
drivers/189/types.go Use int64 for capacity fields.
drivers/189/driver.go Switch disk usage to used-space.
drivers/139/types.go Add request/response structs for new operations.
drivers/139/meta.go Add username/password/mail cookie fields.
drivers/123_share/meta.go Prefer proxy downloads.
drivers/123_open/types.go Add SHA1 reuse/offline download types; use int64 quota types.
drivers/123_open/meta.go Prefer proxy downloads; clarify access token note.
drivers/123_open/driver.go Add token manager + SHA1 reuse + offline download APIs; switch disk usage to used-space.
drivers/123_link/driver.go Provide root path via Addition.
drivers/123/upload.go Simplify upload stream handling + progress math; handle singleflight return properly.
drivers/123/types.go Use int64 quota types; add offline task response types.
drivers/123/meta.go Add platform header config; prefer proxy downloads; set defaults.
drivers/123/driver.go Set platform header in Init; switch disk usage to used-space.
drivers/115_share/utils.go Add thumbnail support + standard UA usage.
drivers/115_share/driver.go Add UA selection; use SDK methods that accept UA.
drivers/115_open/util.go Add tolerant json.Number -> int64 parsing helper.
drivers/115_open/upload.go Ensure retry uses ctx; apply rate limit wrapper per attempt.
drivers/115_open/meta.go Add page size; set link cache mode to include UA.
drivers/115_open/driver.go Clamp page size; remove legacy GetObjInfo; fix rename field name; switch disk usage to used-space.
drivers/115/util.go Remove custom DownloadWithUA implementation; minor formatting.
drivers/115/types.go Add thumbnail support.
drivers/115/meta.go Set link cache mode to include UA.
drivers/115/driver.go Use SDK DownloadWithUA; switch disk usage to used-space.
cmd/storage.go Use bootstrap Init/Release rather than cmd wrapper.
cmd/root.go Add --config flag and clarify --data semantics.
cmd/lang.go Change language JSON generation to merge into existing files.
cmd/flags/config.go Add ConfigPath flag storage.
cmd/crypt.go Import ordering cleanup.
cmd/common.go Simplify Init/Release to bootstrap.Init/Release.
cmd/cancel2FA.go Use bootstrap Init/Release.
cmd/admin.go Use bootstrap Init/Release.
SECURITY.md Add security policy + reporting guidance (EN/ZH).
README_nl.md Add ProtonDrive + demo links + sponsor section.
README_ja.md Add ProtonDrive + demo links + sponsor section.
README_cn.md Add ProtonDrive + demo links + sponsor section.
README.md Add ProtonDrive + demo links + sponsor section.
.github/workflows/issue_pr_comment.yml Improve checkbox detection + allow breaking-change titles with !.
.github/PULL_REQUEST_TEMPLATE.md Document breaking-change ! convention.
.github/ISSUE_TEMPLATE/01-bug_report_en.yml Reorder required logs/config fields; add “I didn’t read” checkbox.
.github/ISSUE_TEMPLATE/00-bug_report_zh.yml Reorder required logs/config fields; add “I didn’t read” checkbox.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/errs/unwrap.go
return err
}
return unwrapped
return u.Unwrap()

Copilot AI Feb 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UnwrapOrSelf no longer provides the 'or self' fallback when Unwrap() returns nil; it will return nil instead of the original error. Keep the custom type-assert approach if desired, but add a nil check (if u.Unwrap() is nil, return err).

Suggested change
return u.Unwrap()
unwrapped := u.Unwrap()
if unwrapped == nil {
return err
}
return unwrapped

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +21
func NewKeyedCache[T any](ttl time.Duration) *KeyedCache[T] {
c := &KeyedCache[T]{
entries: make(map[string]*CacheEntry[T]),
ttl: ttl,
}
gcFuncs = append(gcFuncs, c.GC)
return c
}

Copilot AI Feb 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gcFuncs is a shared package-level slice (iterated by the GC cron) but is appended to without synchronization. This can race with the cron loop and cause panics or data races. Protect gcFuncs with a mutex (or use an atomic copy-on-write pattern) and iterate over a snapshot in the cron job.

Copilot uses AI. Check for mistakes.
Comment thread internal/db/tasks.go
Comment on lines +34 to 35
<-conf.StoragesLoadSignal()
return []byte(task.PersistData), nil

Copilot AI Feb 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This unconditionally blocks until SendStoragesLoadedSignal() closes the channel. If storage loading fails or the signal is never sent, task persistence can deadlock/hang. Consider using a select with a timeout (or plumb a context) and fall back to returning PersistData rather than blocking forever.

Copilot uses AI. Check for mistakes.
Comment on lines +21 to +26
confBody, err := utils.Json.MarshalIndent(conf.Conf, "", " ")
if err != nil {
utils.Log.Errorf("[ResetSkipTlsVerify] failed to rewrite config: marshal config error: %+v", err)
return
}
err = os.WriteFile(conf.ConfigPath, confBody, 0o777)

Copilot AI Feb 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Writing config files with mode 0777 makes them world-writable. Use a safer permission (commonly 0600 for secrets or 0644 if intended to be readable) and ideally preserve the existing file mode when rewriting.

Suggested change
confBody, err := utils.Json.MarshalIndent(conf.Conf, "", " ")
if err != nil {
utils.Log.Errorf("[ResetSkipTlsVerify] failed to rewrite config: marshal config error: %+v", err)
return
}
err = os.WriteFile(conf.ConfigPath, confBody, 0o777)
mode := os.FileMode(0o600)
if info, statErr := os.Stat(conf.ConfigPath); statErr == nil {
mode = info.Mode().Perm()
}
confBody, err := utils.Json.MarshalIndent(conf.Conf, "", " ")
if err != nil {
utils.Log.Errorf("[ResetSkipTlsVerify] failed to rewrite config: marshal config error: %+v", err)
return
}
err = os.WriteFile(conf.ConfigPath, confBody, mode)

Copilot uses AI. Check for mistakes.
Comment on lines +5 to +8
import "os"

func copyNamedPipe(_ string, _, _ os.FileMode) error {
return nil

Copilot AI Feb 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning nil here reports success but does not actually create/copy the named pipe on these platforms, which can lead to silent data loss/inconsistent results during copy. Prefer returning a defined error (e.g., errs.NotImplement) so callers can fall back to a different copy strategy or report unsupported behavior.

Suggested change
import "os"
func copyNamedPipe(_ string, _, _ os.FileMode) error {
return nil
import (
"errors"
"os"
)
func copyNamedPipe(_ string, _, _ os.FileMode) error {
return errors.New("copyNamedPipe not supported on this platform")

Copilot uses AI. Check for mistakes.
Comment thread cmd/lang.go
Comment on lines +71 to +96
if mergeJson(newData, oldData) {
log.Infof("%s.json no changed, skip", name)
} else {
log.Infof("%s.json changed, update file", name)
//log.Infof("old: %+v\nnew:%+v", oldData, data)
utils.WriteJsonToFile(fmt.Sprintf("lang/%s.json", name), newData, true)
utils.WriteJsonToFile(fmt.Sprintf("lang/%s.json", name), oldData, true)
}
}

func mergeJson(source, target map[string]interface{}) bool {
equal := true
for k, v := range source {
tgtV, tgtOk := target[k]
if !tgtOk {
equal = false
target[k] = v
} else {
srcMap, srcIsMap := v.(map[string]interface{})
tgtMap, tgtIsMap := tgtV.(map[string]interface{})
if srcIsMap && tgtIsMap {
equal = mergeJson(srcMap, tgtMap) && equal
}
}
}
return equal
}

Copilot AI Feb 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mergeJson only adds missing keys and never updates existing non-map values, so changed translations in newData won’t propagate to the generated files (and equal may remain true even when values differ). If the intent is a true merge, compare/overwrite leaf values when they differ; if the intent is strictly 'fill missing keys', the log message and function name should reflect that and you likely still want to write out when values differ.

Copilot uses AI. Check for mistakes.
Comment thread drivers/123/driver.go
func (d *Pan123) Init(ctx context.Context) error {
_, err := d.Request(UserInfo, http.MethodGet, nil, nil)
_, err := d.Request(UserInfo, http.MethodGet, func(req *resty.Request) {
req.SetHeader("platform", "web")

Copilot AI Feb 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The driver addition adds Platform, but Init still hard-codes platform=web. Use the configured d.Platform (defaulting to web when empty) so the new config field actually takes effect.

Suggested change
req.SetHeader("platform", "web")
platform := d.Platform
if platform == "" {
platform = "web"
}
req.SetHeader("platform", platform)

Copilot uses AI. Check for mistakes.
Comment thread drivers/strm/meta.go
Comment on lines 15 to +25
Paths string `json:"paths" required:"true" type:"text"`
SiteUrl string `json:"siteUrl" type:"text" required:"false" help:"The prefix URL of the strm file"`
FilterFileTypes string `json:"filterFileTypes" type:"text" default:"strm" required:"false" help:"Supports suffix name of strm file"`
DownloadFileTypes string `json:"downloadFileTypes" type:"text" default:"ass" required:"false" help:"Files need to download with strm (usally subtitles)"`
PathPrefix string `json:"PathPrefix" type:"text" required:"false" default:"/d" help:"Path prefix"`
DownloadFileTypes string `json:"downloadFileTypes" type:"text" default:"ass,srt,vtt,sub,strm" required:"false" help:"Files need to download with strm (usally subtitles)"`
FilterFileTypes string `json:"filterFileTypes" type:"text" default:"mp4,mkv,flv,avi,wmv,ts,rmvb,webm,mp3,flac,aac,wav,ogg,m4a,wma,alac" required:"false" help:"Supports suffix name of strm file"`
EncodePath bool `json:"encodePath" default:"true" required:"true" help:"encode the path in the strm file"`
LocalModel bool `json:"localModel" default:"false" help:"enable local mode"`
WithoutUrl bool `json:"withoutUrl" default:"false" help:"strm file content without URL prefix"`
WithSign bool `json:"withSign" default:"false"`
SaveStrmToLocal bool `json:"SaveStrmToLocal" default:"false" help:"save strm file locally"`
SaveStrmLocalPath string `json:"SaveStrmLocalPath" type:"text" help:"save strm file local path"`
SaveLocalMode string `json:"SaveLocalMode" type:"select" help:"save strm file locally mode" options:"insert,update,sync" default:"insert"`

Copilot AI Feb 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSON tags are inconsistent (PathPrefix, SaveStrmToLocal, SaveStrmLocalPath, SaveLocalMode are PascalCase while others are lower-camel). This is a breaking config API for users and makes configuration inconsistent. Normalize tags to a single convention (typically snake_case or lowerCamel) and consider supporting the old keys for backward compatibility if these keys already shipped.

Copilot uses AI. Check for mistakes.
Comment thread drivers/terabox/util.go
}
errno := utils.Json.Get(res.Body(), "errno").ToInt()
if errno == 4000023 || errno == 4500016 {
if errno == 4000023 || errno == 450016 {

Copilot AI Feb 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The errno constant change from 4500016 to 450016 looks like a dropped 00 and will stop triggering the jsToken refresh for the previous error code. If the API really returns 4500016, revert or handle both values to avoid breaking token refresh.

Suggested change
if errno == 4000023 || errno == 450016 {
if errno == 4000023 || errno == 4500016 || errno == 450016 {

Copilot uses AI. Check for mistakes.
Comment thread internal/db/sharing.go
Comment on lines +53 to +57
return "", errors.New("failed find valid id")
} else {
query := model.SharingDB{ID: s.ID}
if err := db.Where(query).First(&query).Error; err == nil {
return "", errors.New("sharing already exist")

Copilot AI Feb 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New error messages have grammar issues (failed find valid id, sharing already exist). Consider updating them to clearer phrasing like failed to find a valid id and sharing already exists for better UX and easier searching in logs.

Suggested change
return "", errors.New("failed find valid id")
} else {
query := model.SharingDB{ID: s.ID}
if err := db.Where(query).First(&query).Error; err == nil {
return "", errors.New("sharing already exist")
return "", errors.New("failed to find a valid id")
} else {
query := model.SharingDB{ID: s.ID}
if err := db.Where(query).First(&query).Error; err == nil {
return "", errors.New("sharing already exists")

Copilot uses AI. Check for mistakes.
@Wodlie
Wodlie merged commit 23c9150 into feat/qihoo360 Feb 28, 2026
8 checks passed
@Wodlie
Wodlie deleted the copilot/implement-qihoo360-driver branch February 28, 2026 16:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.