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
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 MultistatusWhile 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
/webdavendpoint. 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