HTTP API 參考
機器可讀的 OpenAPI 3.1 文件會在 PHP 測試中逐項核對全部公開 API Route。
以下路徑都相對於 SoFinder 路由匯入前綴,例如 /sofinder。API 面向同源、已登入的應用客戶端,不是匿名物件儲存 API。
協議約定
- JSON Endpoint 傳送
Accept: application/json。 - 所有請求攜帶 Symfony Session Cookie。
- 所有寫操作需要
X-CSRF-TOKEN: <token>;JSON 寫操作還要使用Content-Type: application/json。 - Path 是資源根目錄下、以
/分隔的邏輯路徑,不能傳送絕對路徑、..或儲存 URL。 - 時間戳是 Unix 秒,容量是整數 Byte。
- 客戶端必須忽略未知 Response Field 和 Capability Flag。
成功:
{"success":true,"data":{"entry":{"path":"manuals/start.pdf"}}}失敗:
{"success":false,"error":{"code":"conflict","message":"The destination already exists."}}HTTP Status 是最終依據;429 包含 Retry-After: 2。批次請求可能返回 HTTP 200,但其中部分 Result 失敗。
公共物件
Entry
{
"path": "images/photo.jpg",
"name": "photo.jpg",
"directory": false,
"size": 184231,
"modifiedAt": 1787529600,
"mimeType": "image/jpeg",
"url": "https://cdn.example.com/images/photo.jpg",
"capabilities": {"read": true, "rename": true, "delete": false}
}url 可以為 null;非空值可能是公開地址、認證 proxy 或宿主 Route。Capability 只是提示,伺服器會重新授權。
Asset Reference 1.0
上傳與 Picker 回應可以新增 asset,格式請見 Schema,原有 entry 保留。啟用資產目錄後,GET /api/assets/resolve 依資源/路徑解析或懶註冊;GET /api/assets/{id} 讀取目前 Workspace 記錄;PATCH /api/assets/{id}/metadata 修改 alt、title、共享 tags,並透過 metadataVersion 樂觀並行控制。
Resource
GET /api/config 返回 name、publicUrl、副檔名/MIME、maxSize、readOnly、quotaBytes、usedBytes、名稱/深度/圖片/批次/壓縮限制、deliveryMode、animatedImagePolicy,以及:
{"storageCapabilities":{
"search":true,"sort":true,"cursorPagination":false,
"atomicMove":true,"nativeCopy":true,"recoverableDelete":true,"publicUrl":true
}}發現與列表
GET /api/assets/search
在已授權資源及子目錄中依檔名、資產標題、預設/多語言替代文字和共享標籤搜尋;可依資源、路徑範圍、類型、副檔名、大小及修改日期篩選。回應包含分頁、彙總、掃描數量和 truncated,避免將受限掃描誤認為完整索引。
資產使用與刪除預檢
GET /api/assets/{id}/usages列出授權範圍內的 Host 引用。PUT /api/assets/{id}/usages/{referenceId}冪等登記{label,url,context}。DELETE /api/assets/{id}/usages/{referenceId}移除已登記的引用。POST /api/assets/delete-check接受{resource,paths},回傳safe、引用總數和受影響資產。它只提示風險,不會繞過使用者明確的刪除決定。
私有資產存取工作階段
POST /api/assets/access-sessions 接受私有 Proxy 資產 ID 和可選 ttl,回傳綁定檔案版本的內聯 URL 與到期時間;DELETE /api/assets/access-sessions/{id} 撤銷整組工作階段。檔案變更、到期、撤銷或未列入工作階段的資產均無法讀取。
GET /api/config
返回 apiVersion、目前使用者可見的 resources、Plugin Descriptor、圖片預設、有效圖片 Capability 和 UI Default。目前 API Version 為 1.0。
GET /api/capabilities
回傳版本化且機器可讀的 Entry Operation、Storage Capability、Host 可控選用功能、 Plugin Slot/Selection 和 Picker Kind。
GET /api/security/status
回傳病毒掃描就緒狀態、待掃描/通過/隔離/失敗計數與有界最近記錄;存取角色由 malware_scanning.status_roles 限制。
GET /api/entries
| 引數 | 預設 | 含義 |
|---|---|---|
resource | Files | 設定的資源名。 |
path | 空 | 要列出的資料夾。 |
search | 空 | 名稱關鍵詞;searchMode=tags 時為逗號分隔標籤。 |
searchMode | name | name 或 tags。 |
sort | name | name、size、type(MIME 類型)、modified。 |
direction | asc | asc 或 desc。 |
offset | 0 | 支援 Offset 的 Adapter 使用。 |
limit | 100 | 請求頁大小,伺服器限制為 10–500。 |
cursor | 無 | 上一頁返回的不透明 Cursor。 |
Response Data 包含 entries、total、path、offset、limit、sort、direction、nextCursor、目錄 capabilities 和 storageCapabilities。Cursor Adapter 可返回 total: null;禁止自行構造或修改 Cursor。
資料夾與檔案寫操作
POST /api/folders
{"resource":"Files","path":"manuals","name":"2026"}返回 {entry},HTTP 201。
PATCH /api/entries/rename
{"resource":"Files","path":"manuals/draft.pdf","name":"guide.pdf","overwrite":false}name 是名稱,不是目標路徑;overwrite 需要獨立權限。
POST /api/entries/copy、POST /api/entries/move
{"resource":"Files","path":"manuals/guide.pdf","destination":"archive/2026","overwrite":false,"autoRename":true}destination 是資料夾。autoRename=true 且不覆蓋時,SoFinder 自動產生安全名稱。
DELETE /api/entries
{"resource":"Files","path":"manuals/old.pdf"}返回 trash;永久刪除 Adapter 為 null,可恢復資源則包含回收站項目和自動清理數量。
POST /api/entries/batch
{"operation":"copy","resource":"Files","paths":["a.pdf","folder"],"destination":"archive","overwrite":false,"autoRename":true}operation 為 copy、move、delete。Path 會去重,不能同時包含資料夾和其子項。返回 operation、total、succeeded、failed、purgedItems、purgedBytes 和逐項 results;每項包含 path、success,以及 entry 或 error.code/message。
POST /api/entries/batch-rename
{"resource":"Files","renames":[{"path":"draft-a.pdf","name":"report-1.pdf"},{"path":"draft-b.pdf","name":"report-2.pdf"}]}來源路徑與目標名稱必須唯一,副檔名不可修改;伺服器會分別驗證並授權每個項目,回應使用與其他批次操作相同的逐項結果格式。
上傳
POST /api/uploads
使用 multipart/form-data,欄位為 resource、path、upload,可選 overwrite=1 或 autoRename=1。返回 {entry} 和 HTTP 201。autoRename=1 且不覆蓋時,同名檔案會以 photo(1).jpg 這類 CKFinder 風格的第一個可用名稱儲存。伺服器檢查真實位元組,不信任客戶端大小或 MIME Metadata。
分塊上傳
POST /api/uploads/chunks 使用 Multipart:
resource、path、name,可選overwrite=1或autoRename=1;- 16–80 字元 URL-safe
uploadId; - 從 0 開始的
index、固定total、檔案欄位chunk。
未完成返回 {"complete":false};最後一塊返回 {"complete":true,"entry":{...}} 和 HTTP 201。Session Metadata 不可變化,重試必須沿用 Resource、Path、Name、Overwrite、Auto-Rename、Total。
GET /api/uploads/chunks/{id}返回目前 Actor 的 Session、已接收 Index 和 Metadata。DELETE /api/uploads/chunks/{id}取消並丟棄 Session,需要 CSRF。
Session 24 小時後過期。客戶端可以補傳缺失 Index,但不能超過檔案大小和最大 Chunk 數限制。
內容傳遞
GET /api/download?resource=Files&path=manual.pdf:授權後以 Attachment 下載,資料夾返回invalid_type。GET /api/content?resource=Images&path=photo.jpg&disposition=inline:返回私有內容,支援 ETag、Last-Modified、條件請求和單段 Byte Range。只有安全 Raster MIME 能 Inline,其餘強制 Attachment。無效 Range 返回 416。GET /api/signed-url?resource=Private&path=manual.pdf&ttl=300:先重新授權目前使用者,再回傳{url,expiresAt}。臨時網址指向/signed/{token};只有宿主 Firewall 明確允許該路由匿名存取時才不需要 Session。Token 使用 HMAC、僅適用於delivery_mode: proxy,並綁定檔案大小與修改時間;過期或檔案已替換回傳 410,竄改回傳 403。GET /api/preview/text?resource=Files&path=readme.txt:回傳已授權 UTF-8 文字、JSON、XML 或 YAML 檔案的前 256 KiB,格式為{content,truncated,mimeType,size};內建 UI 一律按純文字顯示。GET /api/preview/document?resource=Files&path=manual.pdf:直接回傳已授權 PDF 或已快取的 Office 轉換結果;非同步模式下未快取的 Office 檔案回傳 HTTP 202、document_preview_pending與Retry-After。POST /api/preview/document/jobs:Body 為{"resource":"Files","path":"manual.docx","retry":false},依使用者與檔案版本建立或重用轉換工作。GET /api/preview/document/jobs/{id}:回傳queued、running、ready、failed或expired;就緒時包含預覽 URL,等待時包含retryAfter。部署需求請參考 PDF 與 Office 預覽。GET /api/checksum?resource=Files&path=manual.pdf:為不超過 512 MiB 的已授權檔案回傳{algorithm:"sha256",checksum,size},不會暴露 Adapter 路徑。
回收站
GET /api/trash?resource=Files&offset=0&limit=50&search=term返回items、分頁以及usedItems、usedBytes、maxItems、maxBytes。POST /api/trash/{id}/restoreBody:{"resource":"Files","conflict":"cancel"};策略為cancel、rename、overwrite。DELETE /api/trash/{id}Body:{"resource":"Files"},永久刪除。
Trash ID 是按 Actor 隔離的 32 位十六進位制字串。覆蓋恢復需要 overwrite 權限;父資料夾不存在返回 restore_parent_missing。
圖片
GET /api/images/thumbnail?resource=Images&path=photo.jpg&width=240&height=180返回私有快取縮圖和 ETag。GET /api/images/info?resource=Images&path=photo.jpg返回解碼後的width、height。GET /api/images/variant?resource=Images&path=photo.jpg&width=640&format=webp&v=...啟用後回傳繼承授權且受白名單限制的響應式變體。PATCH /api/images/edit執行 1–10 個有序 Action。PATCH /api/images/batch對 1–100 個路徑執行同一組 Action,並回傳逐項成功/錯誤。
{
"resource":"Images",
"path":"photo.jpg",
"actions":[
{"type":"crop","x":10,"y":20,"width":800,"height":600},
{"type":"resize","width":400,"height":300,"quality":88},
{"type":"rotate","degrees":90}
],
"save":{"mode":"copy","name":"photo-card.jpg"}
}Action 為 crop、resize、rotate、preset、optimize、watermarkText、watermarkImage,完整界線見 image-actions.schema.json。格式轉換必須另存;舊 Transform/Crop Body 在公布的 Sunset 前相容並回傳棄用 Header。
ZIP 與 Metadata
POST /api/archive:
{"resource":"Files","paths":["manual.pdf","screenshots"]}返回名為 sofinder-download.zip 的 application/zip,受資源選擇數量、遞迴項目數和容量限制。
GET /api/metadata?resource=Files 返回 favorites、最多 12 個檔案或資料夾的 quickAccess 路徑、相容新增的 quickAccessEntries 顯示資訊(name、directory、mimeType、exists)、按 Path 組織的 tags,以及最多 50 條 recent {path,touchedAt}。失效快速項目以 exists: false 保留顯示,直到使用者開啟或移除。使用 PATCH /api/metadata 更新:
{"resource":"Files","path":"manual.pdf","action":"favorite","favorite":true}
{"resource":"Files","path":"manuals","action":"quick_access","pinned":true}
{"resource":"Files","path":"manual.pdf","action":"tags","tags":["docs","approved"]}
{"resource":"Files","path":"manual.pdf","action":"touch"}Host 設定關閉 features.quick_access_files 後,新增檔案快速項目會返回 422 quick_access_file_disabled;資料夾仍可使用,既有檔案快速項目仍可移除。
Client 確認最近路徑已在 SoFinder 外部消失後,可傳送 action: "forget",從收藏、標籤和 最近狀態中清理該路徑。Host 關閉某項功能後,其專用操作回傳 feature_disabled 及 HTTP 404,Config Response 的 featureAvailability 也會標記為 false。
每個項目最多 10 個不重複標籤,每個 1–30 個可見字元。
CKEditor 相容上傳
POST /compat/ckeditor4/upload 使用 Multipart upload 欄位;Query 包括 type、selection、currentFolder、_token、CKEditorFuncNum,可選 responseType=json。除非明確啟用 ckeditor4.overwrite_on_upload,否則同名檔案會自動改名。回呼和 JSON 格式參見 CKEditor 指南。
常見狀態和錯誤
完整 Code/Status/Category 目錄是 error-codes.json,CI 會自動與伺服器 Literal Exception 比對。
| Status | 代表 Code | 客戶端處理 |
|---|---|---|
| 400 | invalid_json、invalid_path、invalid_type | 修正語法或引數。 |
| 401/403 | access_denied、read_only | 登入或申請資源/操作權限。 |
| 404 | not_found、upload_session_not_found、trash_disabled | 重新整理狀態,不要原樣重試。 |
| 409 | conflict、upload_session_mismatch、restore_parent_missing | 詢問改名/覆蓋或重建父目錄。 |
| 413 | file_too_large、quota_exceeded、batch_limit_exceeded、archive_limit_exceeded | 縮小操作或修改策略。 |
| 415 | invalid_extension、invalid_mime_type、unsafe_file_content、unsupported_image | 選擇允許且有效的格式。 |
| 416 | invalid_range | 修正或移除 Range。 |
| 422 | invalid_tags、invalid_crop、storage_search_unsupported | 修正語義輸入或按 Capability 降級。 |
| 429 | rate_limit_exceeded、concurrency_limit_exceeded | 等待 Retry-After 並使用退避。 |
| 500/503/507 | 儲存、配額、回收站、圖片或 Session 可用性錯誤 | 保留 Machine Code,停止自動寫重試並通知運維。 |
不得向使用者顯示內部 Stack Trace,也不要記錄 Session Cookie、CSRF Token、簽名 URL、憑據或私有檔案內容。