Skip to content

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。

成功:

json
{"success":true,"data":{"entry":{"path":"manuals/start.pdf"}}}

失敗:

json
{"success":false,"error":{"code":"conflict","message":"The destination already exists."}}

HTTP Status 是最終依據;429 包含 Retry-After: 2。批次請求可能返回 HTTP 200,但其中部分 Result 失敗。

公共物件

Entry

json
{
  "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 修改 alttitle、共享 tags,並透過 metadataVersion 樂觀並行控制。

Resource

GET /api/config 返回 namepublicUrl、副檔名/MIME、maxSizereadOnlyquotaBytesusedBytes、名稱/深度/圖片/批次/壓縮限制、deliveryModeanimatedImagePolicy,以及:

json
{"storageCapabilities":{
  "search":true,"sort":true,"cursorPagination":false,
  "atomicMove":true,"nativeCopy":true,"recoverableDelete":true,"publicUrl":true
}}

發現與列表

在已授權資源及子目錄中依檔名、資產標題、預設/多語言替代文字和共享標籤搜尋;可依資源、路徑範圍、類型、副檔名、大小及修改日期篩選。回應包含分頁、彙總、掃描數量和 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

引數預設含義
resourceFiles設定的資源名。
path要列出的資料夾。
search名稱關鍵詞;searchMode=tags 時為逗號分隔標籤。
searchModenamenametags
sortnamenamesizetype(MIME 類型)、modified
directionascascdesc
offset0支援 Offset 的 Adapter 使用。
limit100請求頁大小,伺服器限制為 10–500。
cursor上一頁返回的不透明 Cursor。

Response Data 包含 entriestotalpathoffsetlimitsortdirectionnextCursor、目錄 capabilitiesstorageCapabilities。Cursor Adapter 可返回 total: null;禁止自行構造或修改 Cursor。

資料夾與檔案寫操作

POST /api/folders

json
{"resource":"Files","path":"manuals","name":"2026"}

返回 {entry},HTTP 201。

PATCH /api/entries/rename

json
{"resource":"Files","path":"manuals/draft.pdf","name":"guide.pdf","overwrite":false}

name 是名稱,不是目標路徑;overwrite 需要獨立權限。

POST /api/entries/copyPOST /api/entries/move

json
{"resource":"Files","path":"manuals/guide.pdf","destination":"archive/2026","overwrite":false,"autoRename":true}

destination 是資料夾。autoRename=true 且不覆蓋時,SoFinder 自動產生安全名稱。

DELETE /api/entries

json
{"resource":"Files","path":"manuals/old.pdf"}

返回 trash;永久刪除 Adapter 為 null,可恢復資源則包含回收站項目和自動清理數量。

POST /api/entries/batch

json
{"operation":"copy","resource":"Files","paths":["a.pdf","folder"],"destination":"archive","overwrite":false,"autoRename":true}

operationcopymovedelete。Path 會去重,不能同時包含資料夾和其子項。返回 operationtotalsucceededfailedpurgedItemspurgedBytes 和逐項 results;每項包含 pathsuccess,以及 entryerror.code/message

POST /api/entries/batch-rename

json
{"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,欄位為 resourcepathupload,可選 overwrite=1autoRename=1。返回 {entry} 和 HTTP 201。autoRename=1 且不覆蓋時,同名檔案會以 photo(1).jpg 這類 CKFinder 風格的第一個可用名稱儲存。伺服器檢查真實位元組,不信任客戶端大小或 MIME Metadata。

分塊上傳

POST /api/uploads/chunks 使用 Multipart:

  • resourcepathname,可選 overwrite=1autoRename=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_pendingRetry-After
  • POST /api/preview/document/jobs:Body 為 {"resource":"Files","path":"manual.docx","retry":false},依使用者與檔案版本建立或重用轉換工作。
  • GET /api/preview/document/jobs/{id}:回傳 queuedrunningreadyfailedexpired;就緒時包含預覽 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、分頁以及 usedItemsusedBytesmaxItemsmaxBytes
  • POST /api/trash/{id}/restore Body:{"resource":"Files","conflict":"cancel"};策略為 cancelrenameoverwrite
  • 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 返回解碼後的 widthheight
  • 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,並回傳逐項成功/錯誤。
json
{
  "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 為 cropresizerotatepresetoptimizewatermarkTextwatermarkImage,完整界線見 image-actions.schema.json。格式轉換必須另存;舊 Transform/Crop Body 在公布的 Sunset 前相容並回傳棄用 Header。

ZIP 與 Metadata

POST /api/archive

json
{"resource":"Files","paths":["manual.pdf","screenshots"]}

返回名為 sofinder-download.zipapplication/zip,受資源選擇數量、遞迴項目數和容量限制。

GET /api/metadata?resource=Files 返回 favorites、最多 12 個檔案或資料夾的 quickAccess 路徑、相容新增的 quickAccessEntries 顯示資訊(namedirectorymimeTypeexists)、按 Path 組織的 tags,以及最多 50 條 recent {path,touchedAt}。失效快速項目以 exists: false 保留顯示,直到使用者開啟或移除。使用 PATCH /api/metadata 更新:

json
{"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 包括 typeselectioncurrentFolder_tokenCKEditorFuncNum,可選 responseType=json。除非明確啟用 ckeditor4.overwrite_on_upload,否則同名檔案會自動改名。回呼和 JSON 格式參見 CKEditor 指南

常見狀態和錯誤

完整 Code/Status/Category 目錄是 error-codes.json,CI 會自動與伺服器 Literal Exception 比對。

Status代表 Code客戶端處理
400invalid_jsoninvalid_pathinvalid_type修正語法或引數。
401/403access_deniedread_only登入或申請資源/操作權限。
404not_foundupload_session_not_foundtrash_disabled重新整理狀態,不要原樣重試。
409conflictupload_session_mismatchrestore_parent_missing詢問改名/覆蓋或重建父目錄。
413file_too_largequota_exceededbatch_limit_exceededarchive_limit_exceeded縮小操作或修改策略。
415invalid_extensioninvalid_mime_typeunsafe_file_contentunsupported_image選擇允許且有效的格式。
416invalid_range修正或移除 Range。
422invalid_tagsinvalid_cropstorage_search_unsupported修正語義輸入或按 Capability 降級。
429rate_limit_exceededconcurrency_limit_exceeded等待 Retry-After 並使用退避。
500/503/507儲存、配額、回收站、圖片或 Session 可用性錯誤保留 Machine Code,停止自動寫重試並通知運維。

不得向使用者顯示內部 Stack Trace,也不要記錄 Session Cookie、CSRF Token、簽名 URL、憑據或私有檔案內容。

Released under the MIT License.