ownCloud
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage
Edit page

Protocol changes

The spaces concept allows clients to look up the space endpoints a user has access to and then do individual sync discoveries. Technically, we introduce an indirection that allows clients to rely on server provided URLs instead of hardcoded /webdav or /dav/files/{username} paths, that may change over time.

Space discovery

%%{init: {"sequence": { "showSequenceNumbers":true, "messageFontFamily":"courier", "messageFontWeight":"normal", "messageFontSize":"11"}}}%%
%% font weight is a css bug: https://github.com/mermaid-js/mermaid/issues/1976
%% edit this diagram by pasting it into eg. https://mermaid.live
sequenceDiagram
    participant Client
    participant Graph
    participant SpaceA
    participant SpaceB
    links Client: {"web": "https://owncloud.dev/clients/web/", "RClone": "https://owncloud.dev/clients/rclone/"}
    link Graph: Documentation @ https://owncloud.dev/extensions/graph/

    Note left of Client:  First, a clients looks
up the spaces a user has access to opt space lookup Client->>+Graph: GET /me/drives Graph-->>-Client: 200 OK JSON list of spaces, say A, B and C,
each with a dedicated webDavURL, etag and quota end Note left of Client: Then it can do a parallel
sync discovery on spaces
whose etag changed par Client to Space A Client->>+SpaceA: PROPFIND {webDavURL for Space A} SpaceA-->>-Client: 207 Multistatus PROPFIND response and Client to Space B Client->>+SpaceB: PROPFIND {webDavURL for space B} SpaceB-->>-Client: 207 Multistatus PROPFIND response end

New /dav/spaces/{spaceid} endpoint with spaceid and a relative path

The ocDAV service is responsible for translating ownCloud flavoured WebDAV into CS3 API calls.

General view

A PROPFIND finds its way to a storage provider like this:

%%{init: {"sequence": { "showSequenceNumbers":true, "messageFontFamily":"courier", "messageFontWeight":"normal", "messageFontSize":"11"}}}%%
%% font weight is a css bug: https://github.com/mermaid-js/mermaid/issues/1976
%% edit this diagram by pasting it into eg. https://mermaid.live
sequenceDiagram
    participant Client
    participant ocDAV
    participant StorageProvider

    Note right of Client: {spaceid} identifies the space
{relative/path} is relative to the space root Client->>+ocDAV: PROPFIND /dav/space/{spaceid}/{relative/path} Note right of ocDAV: translate ownCloud flavoured webdav
into CS3 API requests ocDAV->>+StorageProvider: ListContainer({spaceid}, path: {relative/path}) StorageProvider-->>-ocDAV: []ResourceInfo ocDAV-->>-Client: 207 Multistatus

While the above is a simplification to get an understanding of what needs to go where, there are several places where sharding can happen.

Proxy can do user based routing

The ocis proxy authenticates requests and can forward requests to different backends, depending on the logged-in user or cookies. For example multiple ocdav services can be configured to shard users based on username or affiliation.

%%{init: {"sequence": { "showSequenceNumbers":true, "messageFontFamily":"courier", "messageFontWeight":"normal", "messageFontSize":"11"}}}%%
%% font weight is a css bug: https://github.com/mermaid-js/mermaid/issues/1976
%% edit this diagram by pasting it into eg. https://mermaid.live
sequenceDiagram
    participant Client
    participant proxy
    participant ocDAV1 as ocDAV [a-k]
    participant ocDAV2 as ocDAV [l-z]

    Note right of Client: {spaceid} identifies the space
{relative/path} is relative to the space root Client->>+proxy: PROPFIND /dav/space/{spaceid}/{relative/path} alt username starting with a-k proxy->>+ocDAV1: PROPFIND /dav/space/{spaceid}/{relative/path} Note right of ocDAV1: translate ownCloud flavoured webdav
into CS3 API requests ocDAV1-->>-Client: 207 Multistatus else username starting with l-z proxy->>+ocDAV2: PROPFIND /dav/space/{spaceid}/{relative/path} ocDAV2-->>-Client: 207 Multistatus end

Gateway can do path or storage provider id based routing

The reva gateway acts as a facade to multiple storage providers that can be configured with the storage registry:

%%{init: {"sequence": { "showSequenceNumbers":true, "messageFontFamily":"courier", "messageFontWeight":"normal", "messageFontSize":"11"}}}%%
%% font weight is a css bug: https://github.com/mermaid-js/mermaid/issues/1976
%% edit this diagram by pasting it into eg. https://mermaid.live
sequenceDiagram
    participant ocDAV
    participant Gateway
    participant StorageRegistry
    participant StorageProvider1 as StorageProvider [a-k]
    participant StorageProvider2 as StorageProvider [l-z]

    Note right of ocDAV: translate ownCloud flavoured webdav
into CS3 API requests ocDAV->>+Gateway: ListContainer({spaceid}, path: {relative/path}) Note right of Gateway: find address of the storage provider
that is responsible for the space Gateway->>+StorageRegistry: ListStorageProviders({spaceid}) StorageRegistry-->>-Gateway: []ProviderInfo Note right of Gateway: forward request to
correct storage provider alt username starting with a-k Gateway->>+StorageProvider1: ListContainer({spaceid}, path: {relative/path}) StorageProvider1-->>-Gateway: []ResourceInfo else username starting with l-z Gateway->>+StorageProvider2: ListContainer({spaceid}, path: {relative/path}) StorageProvider2-->>-Gateway: []ResourceInfo end Gateway-->>-ocDAV: []ResourceInfo

Old /dav/files/{username} endpoint with username and a path relative to the users home

PROPFIND request against old webdav endpoints

To route a PROPFIND request against the old webdav endpoints like /dav/files/username, ocdav first has to build a CS3 namespace prefix, e.g. /users/{{.Id.OpaqueId}} to the users home.

%%{init: {"sequence": { "showSequenceNumbers":true, "messageFontFamily":"courier", "messageFontWeight":"normal", "messageFontSize":"11"}}}%%
%% font weight is a css bug: https://github.com/mermaid-js/mermaid/issues/1976
%% edit this diagram by pasting it into eg. https://mermaid.live
sequenceDiagram
    participant Client
    participant ocDAV
    participant Gateway

    opt old /dav/files/{username} endpoint with username and a path relative to the users home
    Note right of Client: translate ownCloud flavoured webdav
into CS3 API requests Client->>+ocDAV: PROPFIND /dav/files/{username}/{relative/path} Note right of ocDAV: translate ownCloud flavoured webdav
into CS3 API requests ocDAV->>+Gateway: GetUser({username}) Gateway-->>-ocDAV: User Note right of ocDAV: build path prefix to user home ocDAV->>+ocDAV: {namespace/prefix} = ApplyLayout({path layout}, User), eg. /users/e/einstein Note right of ocDAV: look up the space responsible for a path ocDAV->>+Gateway: ListStorageSpaces(path: {namespace/prefix}/{relative/path}) Gateway-->>-ocDAV: []StorageSpace Note right of ocDAV: make actual request with space and relative path ocDAV->>+Gateway: ListContainer({spaceid}, path: {relative/path}) Gateway-->>-ocDAV: []ResourceInfo ocDAV-->>-Client: 207 Multistatus end

Handling legacy global namespace webdav endpoints

The reason ocis uses a path based lookup instead of looking up the current users home using the user id and a space type filter is, because there are deployments that use a global namespace at the legacy /webdav endpoint. To support these use cases, the gateway allows looking up spaces using their mount path.

%%{init: {"sequence": { "showSequenceNumbers":true, "messageFontFamily":"courier", "messageFontWeight":"normal", "messageFontSize":"11"}}}%%
%% font weight is a css bug: https://github.com/mermaid-js/mermaid/issues/1976
%% edit this diagram by pasting it into eg. https://mermaid.live
sequenceDiagram
    participant Client
    participant ocDAV
    participant Gateway

    Note right of Client: translate ownCloud flavoured webdav
into CS3 API requests alt old /dav/files/{username} endpoint with username and a path relative to the users home Client->>+ocDAV: PROPFIND /dav/files/{username}/{relative/path} Note right of ocDAV: look up {username} in URL path ocDAV->>+Gateway: GetUser({username}) Gateway-->>-ocDAV: User Note right of ocDAV:build namespace prefix to user home ocDAV->>+ocDAV: {namespace/prefix} = ApplyLayout({namespace layout}, User), eg. /users/e/einstein else legacy /webdav/ endpoint with a path relative to the users home Client->>+ocDAV: PROPFIND /webdav/{relative/path} Note right of ocDAV: use currently logged in user ocDAV->>+ocDAV: ContextGetUser() Note right of ocDAV: build namespace prefix to user home ocDAV->>+ocDAV: {namespace/prefix} = ApplyLayout({namespace layout}, User), eg. /users/e/einstein else legacy /webdav/ endpoint with a path relative to a global namespace Client->>+ocDAV: PROPFIND /webdav/{relative/path} Note right of ocDAV: omit namespace prefix by using empty layout template ocDAV->>+ocDAV: {namespace/prefix} = ApplyLayout("/", u), always returns "/" end Note right of ocDAV: look up the space responsible for a path ocDAV->>+Gateway: ListStorageSpaces(path: {namespace/prefix}/{relative/path}) Gateway-->>-ocDAV: []StorageSpace Note right of ocDAV: make actual request with space and relative path ocDAV->>+Gateway: ListContainer({spaceid}, path: {relative/path}) Gateway-->>-ocDAV: []ResourceInfo ocDAV-->>-Client: 207 Multistatus