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 scenariosDirPerm: internal directory permission, currently defaults to0755
Example:
1fs, err := driver.New("local", map[string]any{ 2 "path": "/data/files", 3})
Notes:
pathmust be absolutefilepath.Clean(path)must match the original input or the driver returnsfs.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_keymust be PEM text accepted byssh.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 directoriesStat()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 permission0700
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
DirPermto0755 Stat()maps WebDAV 403/404 errors toos.ErrPermissionandos.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_idis set androot_idis empty, the root becomesshared_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_idtakes precedence overuser_idCopy()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 containsidandpick_codeCreate()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 returnsWrapFS(d, 60)so callers can use path-like accessCopy()andCreate()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
repoandref:/README.md - With fixed
repobut 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
repoandrelease:/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 HTTPHEADheaders such asContent-Type,Content-Length, andLast-Modified- Custom mirror HTML layouts may require parser extensions
Choosing a Driver
- Use
localfor local directories or mounted filesystems - Use
sftp,smb, orwebdavfor standard NAS/server file sharing - Use
s3for object storage - Use
gdriveoronedrivefor SaaS drive integration - Use
github,github-release,mirror,pan115, orquarkfor read-heavy scenarios