Skip to content

Files

File routes act on one session's workspace over HTTP only, as the agent's Unix user; directories move as tar archives

The relay serves the file routes. opc push and opc pull are clients for upload and download.

OperationRelay routeAPI routeScope
ListGET /files/{id}/filesGET /sessions/{id}/workspace/filessessions:read
Read one fileGET /files/{id}/fileGET /sessions/{id}/workspace/filesessions:read
Download an archiveGET /files/{id}/archiveGET /sessions/{id}/workspace/archivesessions:read
Upload an archivePUT /files/{id}/archivePUT /sessions/{id}/workspace/archivesessions:write

Every path is relative to the workspace. Errors are JSON, {"error": {...}}.

ErrorCause
404 session_not_foundThe member has no access to the session
400 invalid_pathAn absolute path, a .. segment, or a path that resolves outside the workspace through a symlink
404 path_not_foundThe path does not exist

List

GET /files/cs_0123456789abcdef/files?path=myrepo/src&depth=2&limit=100

depth is 1 to 10 and limit 1 to 100. The result is path, entries and nextCursor; pass nextCursor back as cursor. Each entry has:

FieldMeaning
pathRelative to the workspace
typefile, dir or symlink
bytesSize, or null
modifiedAtModification time
pushedAt, pushedByOn an uploaded top-level directory: when and by whom

Read one file

GET /files/{id}/file?path=<file> returns the bytes with Content-Type, Content-Length and an ETag.

CaseResult
If-None-Match equals the ETag304
File over 100 MiB413 too_large. Download it in an archive

Download an archive

GET /files/{id}/archive?path=<directory or file> streams a tar archive (application/x-tar). With Accept-Encoding: zstd or gzip the stream is compressed and Content-Encoding says how; zstd is preferred when both are offered.

Upload an archive

PUT /files/{id}/archive?path=<name> with a tar stream as the body unpacks the archive as one directory named name at the top of the workspace, beside the repositories.

tar -cf - -C ./fixtures . | zstd | curl -X PUT \
  -H "Content-Encoding: zstd" -H "Idempotency-Key: fixtures-1" \
  --data-binary @- "$BASE/files/cs_0123456789abcdef/archive?path=fixtures"

The example leaves out authentication.

ItemRule
nameOne path level: letters, digits, ., - and _, up to 255 characters, not starting with .
Content-Encodingzstd, gzip or absent
name uploaded beforeReplaced
Idempotency-Key repeated by the same member to the same sessionThe first response, without reading the body. The relay keeps keys 24 hours in memory; a relay restart forgets them

The response is {"upload": {"path", "files", "bytes", "replaced"}, "seq"}.

FieldMeaning
replacedNull, or the pushedAt and pushedBy of the upload it replaced
seqThat of the files.pushed event the upload records. In the event, replaced is a boolean

A failed upload changes nothing.

ErrorCause
400 invalid_archiveAbsolute paths, .. segments, hard links, device files, FIFOs, a symlink that points outside the archive, an entry beneath a symlink the archive created, or a body that is not tar
413 too_largeMore than 1 GiB of file content or 100,000 entries
409 path_existsname exists and was not created by an upload