drivers

Driver Guide

This guide summarizes the built-in CloudFS drivers, their registration names, options, examples, and notable behavior.

Overview

Driver Name Typical Use
Local local Local filesystem
FTP ftp Traditional FTP servers
SFTP sftp SSH-based file transfer
S3 s3 AWS S3 or S3-compatible object storage
SMB smb Windows shares and NAS devices
WebDAV webdav WebDAV services
Foxel foxel Foxel file service
OpenList openlist OpenList/Alist-compatible API
UpYun upyun UpYun object storage
Google Drive gdrive Google Drive and Shared Drives
OneDrive onedrive Microsoft OneDrive
115 Drive pan115 115 drive, primarily read/download
Quark Drive quark Quark drive, primarily read/download
GitHub github GitHub repository browsing
GitHub Release github-release GitHub release asset browsing
Mirror mirror HTTP directory mirror sites

Local

Registration name: local

Purpose: access a directory on the local machine.

Parameters:

Field Type Required Description
path string yes Local root directory. Must be absolute and already normalized

Unexported runtime fields:

  • Bookmark: only for special macOS scenarios
  • DirPerm: internal directory permission, currently defaults to 0755

Example:

1fs, err := driver.New("local", map[string]any{
2	"path": "/data/files",
3})

Notes:

  • path must be absolute
  • filepath.Clean(path) must match the original input or the driver returns fs.ErrInvalid
  • Windows path separators are normalized automatically

FTP

Registration name: ftp

Parameters:

Field Type Required Default Description
host string yes none FTP host
port int no 21 Port
username string yes none Username
password string yes none Password

Example:

1fs, err := driver.New("ftp", map[string]any{
2	"host": "127.0.0.1",
3	"username": "demo",
4	"password": "secret",
5})

Notes:

  • Connection setup uses a 10 second dial timeout
  • Copy() uses the library-level generic copy flow, which effectively downloads and re-uploads

SFTP

Registration name: sftp

Parameters:

Field Type Required Default Description
host string yes none SFTP host
port int no 22 Port
username string yes none Username
password string conditionally required none Required when private_key is not set
private_key string conditionally required none Required when password is not set; contains the private key text

Example:

1fs, err := driver.New("sftp", map[string]any{
2	"host": "sftp.example.com",
3	"username": "demo",
4	"private_key": privateKeyPEM,
5})

Notes:

  • Host key verification currently uses ssh.InsecureIgnoreHostKey()
  • private_key must be PEM text accepted by ssh.ParsePrivateKey()

S3

Registration name: s3

Parameters:

Field Type Required Default Description
endpoint string yes none S3 or S3-compatible endpoint
bucket string yes none Bucket name
region string no empty Region
access_key string no empty Access key
secret_key string conditionally required empty Required when access_key is set
session_token string no empty Temporary session token
list_version string no empty v1 or v2 list API
force_path_style bool no false Force path-style addressing

Example:

1fs, err := driver.New("s3", map[string]any{
2	"endpoint": "https://s3.example.com",
3	"bucket": "files",
4	"region": "us-east-1",
5	"access_key": "key",
6	"secret_key": "secret",
7	"force_path_style": true,
8	"list_version": "v2",
9})

Notes:

  • Directories are modeled as empty objects with a trailing slash
  • Copy() uses server-side copy for files and recursive copy for directories
  • Stat() first checks for a file and then falls back to prefix-based directory detection

SMB

Registration name: smb

Parameters:

Field Type Required Default Description
host string yes none SMB host
port int no 445 Port
username string yes none Username
password string yes none Password
domain string no empty Domain
share_name string yes none Share name

Example:

1fs, err := driver.New("smb", map[string]any{
2	"host": "192.168.1.10",
3	"username": "demo",
4	"password": "secret",
5	"share_name": "public",
6})

Notes:

  • The driver internally applies TrimPrefixFS(..., "/") because the backend API does not accept leading /
  • MakeDir() uses permission 0700

WebDAV

Registration name: webdav

Parameters:

Field Type Required Default Description
endpoint string yes none WebDAV endpoint
username string yes none Username
password string yes none Password
dir_perm os.FileMode no 0755 Permission used for mkdir and stream writes

Example:

1fs, err := driver.New("webdav", map[string]any{
2	"endpoint": "https://example.com/dav",
3	"username": "demo",
4	"password": "secret",
5})

Notes:

  • The current implementation forces DirPerm to 0755
  • Stat() maps WebDAV 403/404 errors to os.ErrPermission and os.ErrNotExist

Foxel

Registration name: foxel

Parameters:

Field Type Required Description
endpoint string yes Foxel service endpoint
username string yes Username
password string yes Password

Example:

1fs, err := driver.New("foxel", map[string]any{
2	"endpoint": "https://foxel.example.com",
3	"username": "demo",
4	"password": "secret",
5})

Notes:

  • The driver logs in during construction and stores a bearer token
  • It retries once after a 401 by logging in again
  • List() uses a built-in page size of 500

OpenList

Registration name: openlist

Parameters:

Field Type Required Description
endpoint string yes OpenList service endpoint
username string yes Username
password string yes Password

Example:

1fs, err := driver.New("openlist", map[string]any{
2	"endpoint": "https://openlist.example.com",
3	"username": "demo",
4	"password": "secret",
5})

Additional List() options:

Option Type Description
password string Directory password passed to /api/fs/list

Example:

1files, err := fs.List(ctx, "/secret", cloudfs.ListOption{
2	"password": "dir-pass",
3})

Notes:

  • The implementation expects an OpenList/Alist-style API
  • Construction performs login immediately

UpYun

Registration name: upyun

Parameters:

Field Type Required Description
bucket string yes Service bucket
operator string yes Operator account
password string yes Operator password

Example:

1fs, err := driver.New("upyun", map[string]any{
2	"bucket": "demo-space",
3	"operator": "demo",
4	"password": "secret",
5})

Notes:

  • Close() is intentionally a no-op to avoid an SDK panic path

Google Drive

Registration name: gdrive

Parameters:

Field Type Required Default Description
credentials string no empty Credentials JSON content
credentials_file string no empty Path to credentials JSON
access_token string no empty OAuth access token
root_id string no root Root folder ID
shared_drive_id string no empty Shared Drive ID
export_mime_type string no empty Export format for Google Workspace docs
page_size int64 no 1000 Page size
acknowledge_abuse bool no false Auto-acknowledge abusive file downloads
supports_all_drives bool no false Enable All Drives support

Example:

1fs, err := driver.New("gdrive", map[string]any{
2	"credentials_file": "/path/to/service-account.json",
3	"root_id": "root",
4	"supports_all_drives": true,
5})

Notes:

  • Auth sources are selected in this order: credentials, credentials_file, access_token
  • If shared_drive_id is set and root_id is empty, the root becomes shared_drive_id
  • Reading native Google Docs/Sheets/Slides requires export_mime_type
  • Create() overwrites an existing file with the same name

OneDrive

Registration name: onedrive

Parameters:

Field Type Required Default Description
access_token string yes none Microsoft Graph access token
endpoint string no https://graph.microsoft.com/v1.0 Graph API endpoint
drive_id string no empty Target drive
user_id string no empty Target user drive
root_id string no root Root item ID
page_size int64 no 200 Child page size
copy_timeout time.Duration no 10m Max wait for async copy completion

Example:

1fs, err := driver.New("onedrive", map[string]any{
2	"access_token": token,
3	"drive_id": "b!xxxx",
4})

Notes:

  • drive_id takes precedence over user_id
  • Copy() uses the Graph async copy API and may return 202 before polling for completion

115 Drive

Registration name: pan115

Parameters:

Field Type Required Description
cookie string yes Logged-in 115 cookie

Example:

1fs, err := driver.New("pan115", map[string]any{
2	"cookie": cookie,
3})

Additional List() options:

Option Type Default Description
offset int64 0 Pagination offset
page_size int64 50 Page size

Notes:

  • The driver validates the cookie and performs a login check
  • ExtraInfo() commonly contains id and pick_code
  • Create() is not implemented, so this is effectively a read/download-oriented driver
  • The returned FS is additionally wrapped through quark.WrapFS(d, 180) to expose a path-like interface on top of upstream IDs

Quark

Registration name: quark

Parameters:

Field Type Required Description
cookie string yes Logged-in Quark cookie

Example:

1fs, err := driver.New("quark", map[string]any{
2	"cookie": cookie,
3})

Notes:

  • The raw backend API is mostly ID-based rather than path-based
  • New() automatically returns WrapFS(d, 60) so callers can use path-like access
  • Copy() and Create() are not implemented, so it is best used for read/download scenarios

GitHub

Registration name: github

Parameters:

Field Type Required Description
ref string no Fixed branch or tag
repo string no Fixed repository
owner string yes Repository owner or organization
token string no GitHub token
show_tag bool no Expose tags as a top-level layer when ref is not fixed
show_branch bool no Expose branches as a top-level layer when ref is not fixed

Example:

1fs, err := driver.New("github", map[string]any{
2	"owner": "honmaple",
3	"repo": "cloudfs",
4	"ref": "main",
5})

Path model:

  • With fixed repo and ref: /README.md
  • With fixed repo but dynamic refs: /main/README.md
  • With both dynamic: /cloudfs/main/README.md

Notes:

  • Read-only browsing and download driver
  • Branch and tag names containing / are exposed through URL escaping

GitHub Release

Registration name: github-release

Parameters:

Field Type Required Description
repo string no Fixed repository
owner string yes Repository owner or organization
release string no Fixed release name
token string no GitHub token

Example:

1fs, err := driver.New("github-release", map[string]any{
2	"owner": "cli",
3	"repo": "cli",
4	"release": "GitHub CLI 2.0.0",
5})

Path model:

  • With fixed repo and release: /gh_2.0.0_checksums.txt
  • With dynamic release selection: /GitHub%20CLI%202.0.0/gh_2.0.0_checksums.txt

Notes:

  • The directory layer uses the release name, not the tag
  • Read-only release asset browser

Mirror

Registration name: mirror

Parameters:

Field Type Required Description
endpoint string yes Base URL of the mirror site
format string no Parser format: tuna, aliyun, or default nginx-style parsing

Example:

1fs, err := driver.New("mirror", map[string]any{
2	"endpoint": "https://mirrors.example.com",
3	"format": "tuna",
4})

Notes:

  • Read-only driver
  • Stat() depends on HTTP HEAD headers such as Content-Type, Content-Length, and Last-Modified
  • Custom mirror HTML layouts may require parser extensions

Choosing a Driver

  • Use local for local directories or mounted filesystems
  • Use sftp, smb, or webdav for standard NAS/server file sharing
  • Use s3 for object storage
  • Use gdrive or onedrive for SaaS drive integration
  • Use github, github-release, mirror, pan115, or quark for read-heavy scenarios

©2026 · 红枫文档