Repository files navigation

S3 to webDAV Proxy

This project is still under development

πŸ’Έ PointCab GmbH is providing finances for this project

Purpose

Allow accessing WebDAV backends through the S3 protocol.

As a developer of an app that is able to talk to S3 backends

I want to access WebDAV servers through the S3 protocol

So that I don't have to implement and maintain two protocols in my code

How it works

This project is based on rclone (and the plan is to bring the changes back to rclone). Rclone is a powerful tool to manage files on cloud storages. One feature is to serve a particular storage over a given protocol.

One of the protocols rclone can serve is S3 (the feature did not make it yet into the release). The shortcoming of that feature is that only one WebDAV authentication can match one S3 authentication. E.g. a WebDAV username + password combination can be set and all S3 requests will be forwarded to that specific WebDAV user.

For our use-case we need to access data of different WebDAV users. The solution is to use the S3 access key and forward it as a Bearer token to WebDAV.

  1. The application that wants to talk to WebDAV using the S3 protocol has to obtain oauth tokens (or any other valid bearer tokens) for every user from the WebDAV server.
  2. It puts the acquired token as the S3 access key into the S3 request.
  3. rclone (acting as the S3 to WebDAV proxy) takes the S3 access key of every request and uses it as Bearer token to authenticate against the WebDAV server. (The S3 secrets will be ignored in the current solution.)

Through this solution the application at the very end only has to implement the S3 protocol, but can also access data that is stored on WebDAV servers on a user to user basis.

How to use it

1. Start a WebDAV server

So far we have tested it with ownCloud and Nextcloud.

2. Run the S3 to WebDAV proxy

docker run --rm \
-p 8080:8080 \
-e REMOTE_NAME=nc \
-e REMOTE_URL="https://<domain>/remote.php/webdav/" \
-e REMOTE_VENDOR=nextcloud \
--name s3-webdav-proxy ghcr.io/jankaritech/s3-webdav-proxy

If you want to use a WebDAV server running on localhost add --network=host

Configuration for Remote Server (WebDAV)

  • REMOTE_NAME: Identifier for the remote server.
  • REMOTE_URL: WebDAV URL of the remote server. Example: https://<domain>/remote.php/webdav/.
  • REMOTE_VENDOR: Vendor of the remote server. Tested vendors are nextcloud and owncloud.

Configuration for the S3 to WebDAV proxy

  • PROXY_ARGS: A space separated list of arguments to pass to rclone.

    Example: -e PROXY_ARGS="--vfs-cache-mode=full --vfs-read-chunk-size=100M".

    Some useful options are:

    • --vfs-cache-max-age: Max time since last access of objects in the cache (default 1h0m0s).
    • --vfs-cache-max-size: Max total size of objects in the cache (default off).
    • --vfs-cache-mode Cache mode off|minimal|writes|full (default off).
    • --vfs-cache-poll-interval: Interval to poll the cache for stale objects (default 1m0s).
    • --vfs-case-insensitive: If a file name not found, find a case insensitive match.
    • --vfs-disk-space-total-size: Specify the total space of disk (default off).
    • --vfs-fast-fingerprint: Use fast (less accurate) fingerprints for change detection.
    • --vfs-read-ahead: Extra read ahead over --buffer-size when using cache-mode full.
    • --vfs-read-chunk-size: Read the source objects in chunks (default 128Mi).
    • --vfs-read-chunk-size-limit: If greater than --vfs-read-chunk-size, double the chunk size after each chunk read, until the limit is reached ('off' is unlimited) (default off).
    • --vfs-read-wait: Time to wait for in-sequence read before seeking (default 20ms).
    • --vfs-used-is-size: rclone size Use the rclone size algorithm for Used size.
    • --vfs-write-back: Time to writeback files after last use when using cache (default 5s).
    • --vfs-write-wait: Time to wait for in-sequence write before giving error (default 1s).

3. Obtain a Bearer token from the WebDAV server

using oauth2 tokens

  • install the oauth2 app in ownCloud/Nextcloud
  • in ownCloud/Nextcloud create a new oauth2 client with the redirect URL http://localhost:9876/
  • create a json file called oauth.json and this content
 {
"installed": {
"client_id": "<client-id-copied-from-oauth2-app>",
"project_id": "focus-surfer-382910",
"auth_uri": "<owncloud-server-root>/index.php/apps/oauth2/authorize",
"token_uri": "<owncloud-server-root>/index.php/apps/oauth2/api/v1/token",
"client_secret": "<client-secret-copied-from-oauth2-app>",
"redirect_uris": [
"http://localhost:9876"
]
}
}

using app-passwords

In Nextcloud one can also use the app-passwords as Bearer tokens. For that navigate in the WebUI to Personal Settings -> Security and generate a new app password. This app password is simply your token. (This does not work with OwnCloud)

4. access WebDAV using S3:

every root folder becomes a bucket, every file below it is a key

curl

  • list all buckets (root folders): curl --location 'http://localhost:8080/' -H'Authorization: AWS4-HMAC-SHA256 Credential=<oauth-access-token-or-app-password>/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-date,Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024' replace <oauth-access-token-or-app-password> with your token, that you got with oauth2l or the app password, the rest of the header has to exist, but the content doesn't matter currently
  • list keys in a bucket (any file below the root folder): curl --location 'http://localhost:8080/<bucket>?list-type=2' -H'Authorization: AWS4-HMAC-SHA256 Credential=<oauth-access-token-or-app-password>/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-date,Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024'

MinIO client

  • install mc
  • add the proxy as alias: mc alias set mys3proxy http://localhost:8080 <oauth-access-token> anysecretkeyitdoesnotmatter replace <oauth-access-token-or-app-password> with your token, that you got with oauth2l
  • list buckets: mc ls mys3proxy
  • list items in a bucket mc ls mys3proxy/folder
  • upload a file: mc cp <localfile> mys3proxy/<bucket (root folder)>/<keyname>
  • find files mc find proxy/<bucket>/ --name "*.txt"
  • download all content of a bucket: mc cp --recursive mys3proxy/<bucket> /tmp/dst/ (items that have a space in their name seem to have an issue)

MinIO Go Client SDK

minioClient, err := minio.New(testURL.Host, &minio.Options{
Creds: credentials.NewStaticV4(
<oauth-access-token-or-app-password>,
"does-not-matter-will-be-ignored-by-server",
"",
),
Secure: false,
})
assert.NoError(t, err)
buckets, err := minioClient.ListBuckets(context.Background())

Any other S3 library or tool

They all should "just" work πŸ™

About

S3 to webDAV Proxy

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

S3 to webDAV Proxy

This project is still under development

πŸ’Έ PointCab GmbH is providing finances for this project

Purpose

Allow accessing WebDAV backends through the S3 protocol.

As a developer of an app that is able to talk to S3 backends

I want to access WebDAV servers through the S3 protocol

So that I don't have to implement and maintain two protocols in my code

How it works

This project is based on rclone (and the plan is to bring the changes back to rclone). Rclone is a powerful tool to manage files on cloud storages. One feature is to serve a particular storage over a given protocol.

One of the protocols rclone can serve is S3 (the feature did not make it yet into the release). The shortcoming of that feature is that only one WebDAV authentication can match one S3 authentication. E.g. a WebDAV username + password combination can be set and all S3 requests will be forwarded to that specific WebDAV user.

For our use-case we need to access data of different WebDAV users. The solution is to use the S3 access key and forward it as a Bearer token to WebDAV.

  1. The application that wants to talk to WebDAV using the S3 protocol has to obtain oauth tokens (or any other valid bearer tokens) for every user from the WebDAV server.
  2. It puts the acquired token as the S3 access key into the S3 request.
  3. rclone (acting as the S3 to WebDAV proxy) takes the S3 access key of every request and uses it as Bearer token to authenticate against the WebDAV server. (The S3 secrets will be ignored in the current solution.)

Through this solution the application at the very end only has to implement the S3 protocol, but can also access data that is stored on WebDAV servers on a user to user basis.

How to use it

1. Start a WebDAV server

So far we have tested it with ownCloud and Nextcloud.

2. Run the S3 to WebDAV proxy

docker run --rm \
-p 8080:8080 \
-e REMOTE_NAME=nc \
-e REMOTE_URL="https://<domain>/remote.php/webdav/" \
-e REMOTE_VENDOR=nextcloud \
--name s3-webdav-proxy ghcr.io/jankaritech/s3-webdav-proxy

If you want to use a WebDAV server running on localhost add --network=host

Configuration for Remote Server (WebDAV)

  • REMOTE_NAME: Identifier for the remote server.
  • REMOTE_URL: WebDAV URL of the remote server. Example: https://<domain>/remote.php/webdav/.
  • REMOTE_VENDOR: Vendor of the remote server. Tested vendors are nextcloud and owncloud.

Configuration for the S3 to WebDAV proxy

  • PROXY_ARGS: A space separated list of arguments to pass to rclone.

    Example: -e PROXY_ARGS="--vfs-cache-mode=full --vfs-read-chunk-size=100M".

    Some useful options are:

    • --vfs-cache-max-age: Max time since last access of objects in the cache (default 1h0m0s).
    • --vfs-cache-max-size: Max total size of objects in the cache (default off).
    • --vfs-cache-mode Cache mode off|minimal|writes|full (default off).
    • --vfs-cache-poll-interval: Interval to poll the cache for stale objects (default 1m0s).
    • --vfs-case-insensitive: If a file name not found, find a case insensitive match.
    • --vfs-disk-space-total-size: Specify the total space of disk (default off).
    • --vfs-fast-fingerprint: Use fast (less accurate) fingerprints for change detection.
    • --vfs-read-ahead: Extra read ahead over --buffer-size when using cache-mode full.
    • --vfs-read-chunk-size: Read the source objects in chunks (default 128Mi).
    • --vfs-read-chunk-size-limit: If greater than --vfs-read-chunk-size, double the chunk size after each chunk read, until the limit is reached ('off' is unlimited) (default off).
    • --vfs-read-wait: Time to wait for in-sequence read before seeking (default 20ms).
    • --vfs-used-is-size: rclone size Use the rclone size algorithm for Used size.
    • --vfs-write-back: Time to writeback files after last use when using cache (default 5s).
    • --vfs-write-wait: Time to wait for in-sequence write before giving error (default 1s).

3. Obtain a Bearer token from the WebDAV server

using oauth2 tokens

  • install the oauth2 app in ownCloud/Nextcloud
  • in ownCloud/Nextcloud create a new oauth2 client with the redirect URL http://localhost:9876/
  • create a json file called oauth.json and this content
 {
"installed": {
"client_id": "<client-id-copied-from-oauth2-app>",
"project_id": "focus-surfer-382910",
"auth_uri": "<owncloud-server-root>/index.php/apps/oauth2/authorize",
"token_uri": "<owncloud-server-root>/index.php/apps/oauth2/api/v1/token",
"client_secret": "<client-secret-copied-from-oauth2-app>",
"redirect_uris": [
"http://localhost:9876"
]
}
}

using app-passwords

In Nextcloud one can also use the app-passwords as Bearer tokens. For that navigate in the WebUI to Personal Settings -> Security and generate a new app password. This app password is simply your token. (This does not work with OwnCloud)

4. access WebDAV using S3:

every root folder becomes a bucket, every file below it is a key

curl

  • list all buckets (root folders): curl --location 'http://localhost:8080/' -H'Authorization: AWS4-HMAC-SHA256 Credential=<oauth-access-token-or-app-password>/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-date,Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024' replace <oauth-access-token-or-app-password> with your token, that you got with oauth2l or the app password, the rest of the header has to exist, but the content doesn't matter currently
  • list keys in a bucket (any file below the root folder): curl --location 'http://localhost:8080/<bucket>?list-type=2' -H'Authorization: AWS4-HMAC-SHA256 Credential=<oauth-access-token-or-app-password>/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-date,Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024'

MinIO client

  • install mc
  • add the proxy as alias: mc alias set mys3proxy http://localhost:8080 <oauth-access-token> anysecretkeyitdoesnotmatter replace <oauth-access-token-or-app-password> with your token, that you got with oauth2l
  • list buckets: mc ls mys3proxy
  • list items in a bucket mc ls mys3proxy/folder
  • upload a file: mc cp <localfile> mys3proxy/<bucket (root folder)>/<keyname>
  • find files mc find proxy/<bucket>/ --name "*.txt"
  • download all content of a bucket: mc cp --recursive mys3proxy/<bucket> /tmp/dst/ (items that have a space in their name seem to have an issue)

MinIO Go Client SDK

minioClient, err := minio.New(testURL.Host, &minio.Options{
Creds: credentials.NewStaticV4(
<oauth-access-token-or-app-password>,
"does-not-matter-will-be-ignored-by-server",
"",
),
Secure: false,
})
assert.NoError(t, err)
buckets, err := minioClient.ListBuckets(context.Background())

Any other S3 library or tool

They all should "just" work πŸ™

About

S3 to webDAV Proxy

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

S3 to webDAV Proxy

This project is still under development

πŸ’Έ PointCab GmbH is providing finances for this project

Purpose

Allow accessing WebDAV backends through the S3 protocol.

As a developer of an app that is able to talk to S3 backends

I want to access WebDAV servers through the S3 protocol

So that I don't have to implement and maintain two protocols in my code

How it works

This project is based on rclone (and the plan is to bring the changes back to rclone). Rclone is a powerful tool to manage files on cloud storages. One feature is to serve a particular storage over a given protocol.

One of the protocols rclone can serve is S3 (the feature did not make it yet into the release). The shortcoming of that feature is that only one WebDAV authentication can match one S3 authentication. E.g. a WebDAV username + password combination can be set and all S3 requests will be forwarded to that specific WebDAV user.

For our use-case we need to access data of different WebDAV users. The solution is to use the S3 access key and forward it as a Bearer token to WebDAV.

  1. The application that wants to talk to WebDAV using the S3 protocol has to obtain oauth tokens (or any other valid bearer tokens) for every user from the WebDAV server.
  2. It puts the acquired token as the S3 access key into the S3 request.
  3. rclone (acting as the S3 to WebDAV proxy) takes the S3 access key of every request and uses it as Bearer token to authenticate against the WebDAV server. (The S3 secrets will be ignored in the current solution.)

Through this solution the application at the very end only has to implement the S3 protocol, but can also access data that is stored on WebDAV servers on a user to user basis.

How to use it

1. Start a WebDAV server

So far we have tested it with ownCloud and Nextcloud.

2. Run the S3 to WebDAV proxy

docker run --rm \
-p 8080:8080 \
-e REMOTE_NAME=nc \
-e REMOTE_URL="https://<domain>/remote.php/webdav/" \
-e REMOTE_VENDOR=nextcloud \
--name s3-webdav-proxy ghcr.io/jankaritech/s3-webdav-proxy

If you want to use a WebDAV server running on localhost add --network=host

Configuration for Remote Server (WebDAV)

  • REMOTE_NAME: Identifier for the remote server.
  • REMOTE_URL: WebDAV URL of the remote server. Example: https://<domain>/remote.php/webdav/.
  • REMOTE_VENDOR: Vendor of the remote server. Tested vendors are nextcloud and owncloud.

Configuration for the S3 to WebDAV proxy

  • PROXY_ARGS: A space separated list of arguments to pass to rclone.

    Example: -e PROXY_ARGS="--vfs-cache-mode=full --vfs-read-chunk-size=100M".

    Some useful options are:

    • --vfs-cache-max-age: Max time since last access of objects in the cache (default 1h0m0s).
    • --vfs-cache-max-size: Max total size of objects in the cache (default off).
    • --vfs-cache-mode Cache mode off|minimal|writes|full (default off).
    • --vfs-cache-poll-interval: Interval to poll the cache for stale objects (default 1m0s).
    • --vfs-case-insensitive: If a file name not found, find a case insensitive match.
    • --vfs-disk-space-total-size: Specify the total space of disk (default off).
    • --vfs-fast-fingerprint: Use fast (less accurate) fingerprints for change detection.
    • --vfs-read-ahead: Extra read ahead over --buffer-size when using cache-mode full.
    • --vfs-read-chunk-size: Read the source objects in chunks (default 128Mi).
    • --vfs-read-chunk-size-limit: If greater than --vfs-read-chunk-size, double the chunk size after each chunk read, until the limit is reached ('off' is unlimited) (default off).
    • --vfs-read-wait: Time to wait for in-sequence read before seeking (default 20ms).
    • --vfs-used-is-size: rclone size Use the rclone size algorithm for Used size.
    • --vfs-write-back: Time to writeback files after last use when using cache (default 5s).
    • --vfs-write-wait: Time to wait for in-sequence write before giving error (default 1s).

3. Obtain a Bearer token from the WebDAV server

using oauth2 tokens

  • install the oauth2 app in ownCloud/Nextcloud
  • in ownCloud/Nextcloud create a new oauth2 client with the redirect URL http://localhost:9876/
  • create a json file called oauth.json and this content
 {
"installed": {
"client_id": "<client-id-copied-from-oauth2-app>",
"project_id": "focus-surfer-382910",
"auth_uri": "<owncloud-server-root>/index.php/apps/oauth2/authorize",
"token_uri": "<owncloud-server-root>/index.php/apps/oauth2/api/v1/token",
"client_secret": "<client-secret-copied-from-oauth2-app>",
"redirect_uris": [
"http://localhost:9876"
]
}
}

using app-passwords

In Nextcloud one can also use the app-passwords as Bearer tokens. For that navigate in the WebUI to Personal Settings -> Security and generate a new app password. This app password is simply your token. (This does not work with OwnCloud)

4. access WebDAV using S3:

every root folder becomes a bucket, every file below it is a key

curl

  • list all buckets (root folders): curl --location 'http://localhost:8080/' -H'Authorization: AWS4-HMAC-SHA256 Credential=<oauth-access-token-or-app-password>/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-date,Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024' replace <oauth-access-token-or-app-password> with your token, that you got with oauth2l or the app password, the rest of the header has to exist, but the content doesn't matter currently
  • list keys in a bucket (any file below the root folder): curl --location 'http://localhost:8080/<bucket>?list-type=2' -H'Authorization: AWS4-HMAC-SHA256 Credential=<oauth-access-token-or-app-password>/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-date,Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024'

MinIO client

  • install mc
  • add the proxy as alias: mc alias set mys3proxy http://localhost:8080 <oauth-access-token> anysecretkeyitdoesnotmatter replace <oauth-access-token-or-app-password> with your token, that you got with oauth2l
  • list buckets: mc ls mys3proxy
  • list items in a bucket mc ls mys3proxy/folder
  • upload a file: mc cp <localfile> mys3proxy/<bucket (root folder)>/<keyname>
  • find files mc find proxy/<bucket>/ --name "*.txt"
  • download all content of a bucket: mc cp --recursive mys3proxy/<bucket> /tmp/dst/ (items that have a space in their name seem to have an issue)

MinIO Go Client SDK

minioClient, err := minio.New(testURL.Host, &minio.Options{
Creds: credentials.NewStaticV4(
<oauth-access-token-or-app-password>,
"does-not-matter-will-be-ignored-by-server",
"",
),
Secure: false,
})
assert.NoError(t, err)
buckets, err := minioClient.ListBuckets(context.Background())

Any other S3 library or tool

They all should "just" work πŸ™

About

S3 to webDAV Proxy

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

S3 to webDAV Proxy

This project is still under development

πŸ’Έ PointCab GmbH is providing finances for this project

Purpose

Allow accessing WebDAV backends through the S3 protocol.

As a developer of an app that is able to talk to S3 backends

I want to access WebDAV servers through the S3 protocol

So that I don't have to implement and maintain two protocols in my code

How it works

This project is based on rclone (and the plan is to bring the changes back to rclone). Rclone is a powerful tool to manage files on cloud storages. One feature is to serve a particular storage over a given protocol.

One of the protocols rclone can serve is S3 (the feature did not make it yet into the release). The shortcoming of that feature is that only one WebDAV authentication can match one S3 authentication. E.g. a WebDAV username + password combination can be set and all S3 requests will be forwarded to that specific WebDAV user.

For our use-case we need to access data of different WebDAV users. The solution is to use the S3 access key and forward it as a Bearer token to WebDAV.

  1. The application that wants to talk to WebDAV using the S3 protocol has to obtain oauth tokens (or any other valid bearer tokens) for every user from the WebDAV server.
  2. It puts the acquired token as the S3 access key into the S3 request.
  3. rclone (acting as the S3 to WebDAV proxy) takes the S3 access key of every request and uses it as Bearer token to authenticate against the WebDAV server. (The S3 secrets will be ignored in the current solution.)

Through this solution the application at the very end only has to implement the S3 protocol, but can also access data that is stored on WebDAV servers on a user to user basis.

How to use it

1. Start a WebDAV server

So far we have tested it with ownCloud and Nextcloud.

2. Run the S3 to WebDAV proxy

docker run --rm \
-p 8080:8080 \
-e REMOTE_NAME=nc \
-e REMOTE_URL="https://<domain>/remote.php/webdav/" \
-e REMOTE_VENDOR=nextcloud \
--name s3-webdav-proxy ghcr.io/jankaritech/s3-webdav-proxy

If you want to use a WebDAV server running on localhost add --network=host

Configuration for Remote Server (WebDAV)

  • REMOTE_NAME: Identifier for the remote server.
  • REMOTE_URL: WebDAV URL of the remote server. Example: https://<domain>/remote.php/webdav/.
  • REMOTE_VENDOR: Vendor of the remote server. Tested vendors are nextcloud and owncloud.

Configuration for the S3 to WebDAV proxy

  • PROXY_ARGS: A space separated list of arguments to pass to rclone.

    Example: -e PROXY_ARGS="--vfs-cache-mode=full --vfs-read-chunk-size=100M".

    Some useful options are:

    • --vfs-cache-max-age: Max time since last access of objects in the cache (default 1h0m0s).
    • --vfs-cache-max-size: Max total size of objects in the cache (default off).
    • --vfs-cache-mode Cache mode off|minimal|writes|full (default off).
    • --vfs-cache-poll-interval: Interval to poll the cache for stale objects (default 1m0s).
    • --vfs-case-insensitive: If a file name not found, find a case insensitive match.
    • --vfs-disk-space-total-size: Specify the total space of disk (default off).
    • --vfs-fast-fingerprint: Use fast (less accurate) fingerprints for change detection.
    • --vfs-read-ahead: Extra read ahead over --buffer-size when using cache-mode full.
    • --vfs-read-chunk-size: Read the source objects in chunks (default 128Mi).
    • --vfs-read-chunk-size-limit: If greater than --vfs-read-chunk-size, double the chunk size after each chunk read, until the limit is reached ('off' is unlimited) (default off).
    • --vfs-read-wait: Time to wait for in-sequence read before seeking (default 20ms).
    • --vfs-used-is-size: rclone size Use the rclone size algorithm for Used size.
    • --vfs-write-back: Time to writeback files after last use when using cache (default 5s).
    • --vfs-write-wait: Time to wait for in-sequence write before giving error (default 1s).

3. Obtain a Bearer token from the WebDAV server

using oauth2 tokens

  • install the oauth2 app in ownCloud/Nextcloud
  • in ownCloud/Nextcloud create a new oauth2 client with the redirect URL http://localhost:9876/
  • create a json file called oauth.json and this content
 {
"installed": {
"client_id": "<client-id-copied-from-oauth2-app>",
"project_id": "focus-surfer-382910",
"auth_uri": "<owncloud-server-root>/index.php/apps/oauth2/authorize",
"token_uri": "<owncloud-server-root>/index.php/apps/oauth2/api/v1/token",
"client_secret": "<client-secret-copied-from-oauth2-app>",
"redirect_uris": [
"http://localhost:9876"
]
}
}

using app-passwords

In Nextcloud one can also use the app-passwords as Bearer tokens. For that navigate in the WebUI to Personal Settings -> Security and generate a new app password. This app password is simply your token. (This does not work with OwnCloud)

4. access WebDAV using S3:

every root folder becomes a bucket, every file below it is a key

curl

  • list all buckets (root folders): curl --location 'http://localhost:8080/' -H'Authorization: AWS4-HMAC-SHA256 Credential=<oauth-access-token-or-app-password>/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-date,Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024' replace <oauth-access-token-or-app-password> with your token, that you got with oauth2l or the app password, the rest of the header has to exist, but the content doesn't matter currently
  • list keys in a bucket (any file below the root folder): curl --location 'http://localhost:8080/<bucket>?list-type=2' -H'Authorization: AWS4-HMAC-SHA256 Credential=<oauth-access-token-or-app-password>/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-date,Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024'

MinIO client

  • install mc
  • add the proxy as alias: mc alias set mys3proxy http://localhost:8080 <oauth-access-token> anysecretkeyitdoesnotmatter replace <oauth-access-token-or-app-password> with your token, that you got with oauth2l
  • list buckets: mc ls mys3proxy
  • list items in a bucket mc ls mys3proxy/folder
  • upload a file: mc cp <localfile> mys3proxy/<bucket (root folder)>/<keyname>
  • find files mc find proxy/<bucket>/ --name "*.txt"
  • download all content of a bucket: mc cp --recursive mys3proxy/<bucket> /tmp/dst/ (items that have a space in their name seem to have an issue)

MinIO Go Client SDK

minioClient, err := minio.New(testURL.Host, &minio.Options{
Creds: credentials.NewStaticV4(
<oauth-access-token-or-app-password>,
"does-not-matter-will-be-ignored-by-server",
"",
),
Secure: false,
})
assert.NoError(t, err)
buckets, err := minioClient.ListBuckets(context.Background())

Any other S3 library or tool

They all should "just" work πŸ™

About

S3 to webDAV Proxy

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

S3 to webDAV Proxy

This project is still under development

πŸ’Έ PointCab GmbH is providing finances for this project

Purpose

Allow accessing WebDAV backends through the S3 protocol.

As a developer of an app that is able to talk to S3 backends

I want to access WebDAV servers through the S3 protocol

So that I don't have to implement and maintain two protocols in my code

How it works

This project is based on rclone (and the plan is to bring the changes back to rclone). Rclone is a powerful tool to manage files on cloud storages. One feature is to serve a particular storage over a given protocol.

One of the protocols rclone can serve is S3 (the feature did not make it yet into the release). The shortcoming of that feature is that only one WebDAV authentication can match one S3 authentication. E.g. a WebDAV username + password combination can be set and all S3 requests will be forwarded to that specific WebDAV user.

For our use-case we need to access data of different WebDAV users. The solution is to use the S3 access key and forward it as a Bearer token to WebDAV.

  1. The application that wants to talk to WebDAV using the S3 protocol has to obtain oauth tokens (or any other valid bearer tokens) for every user from the WebDAV server.
  2. It puts the acquired token as the S3 access key into the S3 request.
  3. rclone (acting as the S3 to WebDAV proxy) takes the S3 access key of every request and uses it as Bearer token to authenticate against the WebDAV server. (The S3 secrets will be ignored in the current solution.)

Through this solution the application at the very end only has to implement the S3 protocol, but can also access data that is stored on WebDAV servers on a user to user basis.

How to use it

1. Start a WebDAV server

So far we have tested it with ownCloud and Nextcloud.

2. Run the S3 to WebDAV proxy

docker run --rm \
-p 8080:8080 \
-e REMOTE_NAME=nc \
-e REMOTE_URL="https://<domain>/remote.php/webdav/" \
-e REMOTE_VENDOR=nextcloud \
--name s3-webdav-proxy ghcr.io/jankaritech/s3-webdav-proxy

If you want to use a WebDAV server running on localhost add --network=host

Configuration for Remote Server (WebDAV)

  • REMOTE_NAME: Identifier for the remote server.
  • REMOTE_URL: WebDAV URL of the remote server. Example: https://<domain>/remote.php/webdav/.
  • REMOTE_VENDOR: Vendor of the remote server. Tested vendors are nextcloud and owncloud.

Configuration for the S3 to WebDAV proxy

  • PROXY_ARGS: A space separated list of arguments to pass to rclone.

    Example: -e PROXY_ARGS="--vfs-cache-mode=full --vfs-read-chunk-size=100M".

    Some useful options are:

    • --vfs-cache-max-age: Max time since last access of objects in the cache (default 1h0m0s).
    • --vfs-cache-max-size: Max total size of objects in the cache (default off).
    • --vfs-cache-mode Cache mode off|minimal|writes|full (default off).
    • --vfs-cache-poll-interval: Interval to poll the cache for stale objects (default 1m0s).
    • --vfs-case-insensitive: If a file name not found, find a case insensitive match.
    • --vfs-disk-space-total-size: Specify the total space of disk (default off).
    • --vfs-fast-fingerprint: Use fast (less accurate) fingerprints for change detection.
    • --vfs-read-ahead: Extra read ahead over --buffer-size when using cache-mode full.
    • --vfs-read-chunk-size: Read the source objects in chunks (default 128Mi).
    • --vfs-read-chunk-size-limit: If greater than --vfs-read-chunk-size, double the chunk size after each chunk read, until the limit is reached ('off' is unlimited) (default off).
    • --vfs-read-wait: Time to wait for in-sequence read before seeking (default 20ms).
    • --vfs-used-is-size: rclone size Use the rclone size algorithm for Used size.
    • --vfs-write-back: Time to writeback files after last use when using cache (default 5s).
    • --vfs-write-wait: Time to wait for in-sequence write before giving error (default 1s).

3. Obtain a Bearer token from the WebDAV server

using oauth2 tokens

  • install the oauth2 app in ownCloud/Nextcloud
  • in ownCloud/Nextcloud create a new oauth2 client with the redirect URL http://localhost:9876/
  • create a json file called oauth.json and this content
 {
"installed": {
"client_id": "<client-id-copied-from-oauth2-app>",
"project_id": "focus-surfer-382910",
"auth_uri": "<owncloud-server-root>/index.php/apps/oauth2/authorize",
"token_uri": "<owncloud-server-root>/index.php/apps/oauth2/api/v1/token",
"client_secret": "<client-secret-copied-from-oauth2-app>",
"redirect_uris": [
"http://localhost:9876"
]
}
}

using app-passwords

In Nextcloud one can also use the app-passwords as Bearer tokens. For that navigate in the WebUI to Personal Settings -> Security and generate a new app password. This app password is simply your token. (This does not work with OwnCloud)

4. access WebDAV using S3:

every root folder becomes a bucket, every file below it is a key

curl

  • list all buckets (root folders): curl --location 'http://localhost:8080/' -H'Authorization: AWS4-HMAC-SHA256 Credential=<oauth-access-token-or-app-password>/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-date,Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024' replace <oauth-access-token-or-app-password> with your token, that you got with oauth2l or the app password, the rest of the header has to exist, but the content doesn't matter currently
  • list keys in a bucket (any file below the root folder): curl --location 'http://localhost:8080/<bucket>?list-type=2' -H'Authorization: AWS4-HMAC-SHA256 Credential=<oauth-access-token-or-app-password>/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-date,Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024'

MinIO client

  • install mc
  • add the proxy as alias: mc alias set mys3proxy http://localhost:8080 <oauth-access-token> anysecretkeyitdoesnotmatter replace <oauth-access-token-or-app-password> with your token, that you got with oauth2l
  • list buckets: mc ls mys3proxy
  • list items in a bucket mc ls mys3proxy/folder
  • upload a file: mc cp <localfile> mys3proxy/<bucket (root folder)>/<keyname>
  • find files mc find proxy/<bucket>/ --name "*.txt"
  • download all content of a bucket: mc cp --recursive mys3proxy/<bucket> /tmp/dst/ (items that have a space in their name seem to have an issue)

MinIO Go Client SDK

minioClient, err := minio.New(testURL.Host, &minio.Options{
Creds: credentials.NewStaticV4(
<oauth-access-token-or-app-password>,
"does-not-matter-will-be-ignored-by-server",
"",
),
Secure: false,
})
assert.NoError(t, err)
buckets, err := minioClient.ListBuckets(context.Background())

Any other S3 library or tool

They all should "just" work πŸ™

About

S3 to webDAV Proxy

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

S3 to webDAV Proxy

This project is still under development

πŸ’Έ PointCab GmbH is providing finances for this project

Purpose

Allow accessing WebDAV backends through the S3 protocol.

As a developer of an app that is able to talk to S3 backends

I want to access WebDAV servers through the S3 protocol

So that I don't have to implement and maintain two protocols in my code

How it works

This project is based on rclone (and the plan is to bring the changes back to rclone). Rclone is a powerful tool to manage files on cloud storages. One feature is to serve a particular storage over a given protocol.

One of the protocols rclone can serve is S3 (the feature did not make it yet into the release). The shortcoming of that feature is that only one WebDAV authentication can match one S3 authentication. E.g. a WebDAV username + password combination can be set and all S3 requests will be forwarded to that specific WebDAV user.

For our use-case we need to access data of different WebDAV users. The solution is to use the S3 access key and forward it as a Bearer token to WebDAV.

  1. The application that wants to talk to WebDAV using the S3 protocol has to obtain oauth tokens (or any other valid bearer tokens) for every user from the WebDAV server.
  2. It puts the acquired token as the S3 access key into the S3 request.
  3. rclone (acting as the S3 to WebDAV proxy) takes the S3 access key of every request and uses it as Bearer token to authenticate against the WebDAV server. (The S3 secrets will be ignored in the current solution.)

Through this solution the application at the very end only has to implement the S3 protocol, but can also access data that is stored on WebDAV servers on a user to user basis.

How to use it

1. Start a WebDAV server

So far we have tested it with ownCloud and Nextcloud.

2. Run the S3 to WebDAV proxy

docker run --rm \
-p 8080:8080 \
-e REMOTE_NAME=nc \
-e REMOTE_URL="https://<domain>/remote.php/webdav/" \
-e REMOTE_VENDOR=nextcloud \
--name s3-webdav-proxy ghcr.io/jankaritech/s3-webdav-proxy

If you want to use a WebDAV server running on localhost add --network=host

Configuration for Remote Server (WebDAV)

  • REMOTE_NAME: Identifier for the remote server.
  • REMOTE_URL: WebDAV URL of the remote server. Example: https://<domain>/remote.php/webdav/.
  • REMOTE_VENDOR: Vendor of the remote server. Tested vendors are nextcloud and owncloud.

Configuration for the S3 to WebDAV proxy

  • PROXY_ARGS: A space separated list of arguments to pass to rclone.

    Example: -e PROXY_ARGS="--vfs-cache-mode=full --vfs-read-chunk-size=100M".

    Some useful options are:

    • --vfs-cache-max-age: Max time since last access of objects in the cache (default 1h0m0s).
    • --vfs-cache-max-size: Max total size of objects in the cache (default off).
    • --vfs-cache-mode Cache mode off|minimal|writes|full (default off).
    • --vfs-cache-poll-interval: Interval to poll the cache for stale objects (default 1m0s).
    • --vfs-case-insensitive: If a file name not found, find a case insensitive match.
    • --vfs-disk-space-total-size: Specify the total space of disk (default off).
    • --vfs-fast-fingerprint: Use fast (less accurate) fingerprints for change detection.
    • --vfs-read-ahead: Extra read ahead over --buffer-size when using cache-mode full.
    • --vfs-read-chunk-size: Read the source objects in chunks (default 128Mi).
    • --vfs-read-chunk-size-limit: If greater than --vfs-read-chunk-size, double the chunk size after each chunk read, until the limit is reached ('off' is unlimited) (default off).
    • --vfs-read-wait: Time to wait for in-sequence read before seeking (default 20ms).
    • --vfs-used-is-size: rclone size Use the rclone size algorithm for Used size.
    • --vfs-write-back: Time to writeback files after last use when using cache (default 5s).
    • --vfs-write-wait: Time to wait for in-sequence write before giving error (default 1s).

3. Obtain a Bearer token from the WebDAV server

using oauth2 tokens

  • install the oauth2 app in ownCloud/Nextcloud
  • in ownCloud/Nextcloud create a new oauth2 client with the redirect URL http://localhost:9876/
  • create a json file called oauth.json and this content
 {
"installed": {
"client_id": "<client-id-copied-from-oauth2-app>",
"project_id": "focus-surfer-382910",
"auth_uri": "<owncloud-server-root>/index.php/apps/oauth2/authorize",
"token_uri": "<owncloud-server-root>/index.php/apps/oauth2/api/v1/token",
"client_secret": "<client-secret-copied-from-oauth2-app>",
"redirect_uris": [
"http://localhost:9876"
]
}
}

using app-passwords

In Nextcloud one can also use the app-passwords as Bearer tokens. For that navigate in the WebUI to Personal Settings -> Security and generate a new app password. This app password is simply your token. (This does not work with OwnCloud)

4. access WebDAV using S3:

every root folder becomes a bucket, every file below it is a key

curl

  • list all buckets (root folders): curl --location 'http://localhost:8080/' -H'Authorization: AWS4-HMAC-SHA256 Credential=<oauth-access-token-or-app-password>/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-date,Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024' replace <oauth-access-token-or-app-password> with your token, that you got with oauth2l or the app password, the rest of the header has to exist, but the content doesn't matter currently
  • list keys in a bucket (any file below the root folder): curl --location 'http://localhost:8080/<bucket>?list-type=2' -H'Authorization: AWS4-HMAC-SHA256 Credential=<oauth-access-token-or-app-password>/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-date,Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024'

MinIO client

  • install mc
  • add the proxy as alias: mc alias set mys3proxy http://localhost:8080 <oauth-access-token> anysecretkeyitdoesnotmatter replace <oauth-access-token-or-app-password> with your token, that you got with oauth2l
  • list buckets: mc ls mys3proxy
  • list items in a bucket mc ls mys3proxy/folder
  • upload a file: mc cp <localfile> mys3proxy/<bucket (root folder)>/<keyname>
  • find files mc find proxy/<bucket>/ --name "*.txt"
  • download all content of a bucket: mc cp --recursive mys3proxy/<bucket> /tmp/dst/ (items that have a space in their name seem to have an issue)

MinIO Go Client SDK

minioClient, err := minio.New(testURL.Host, &minio.Options{
Creds: credentials.NewStaticV4(
<oauth-access-token-or-app-password>,
"does-not-matter-will-be-ignored-by-server",
"",
),
Secure: false,
})
assert.NoError(t, err)
buckets, err := minioClient.ListBuckets(context.Background())

Any other S3 library or tool

They all should "just" work πŸ™

About

S3 to webDAV Proxy

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

S3 to webDAV Proxy

This project is still under development

πŸ’Έ PointCab GmbH is providing finances for this project

Purpose

Allow accessing WebDAV backends through the S3 protocol.

As a developer of an app that is able to talk to S3 backends

I want to access WebDAV servers through the S3 protocol

So that I don't have to implement and maintain two protocols in my code

How it works

This project is based on rclone (and the plan is to bring the changes back to rclone). Rclone is a powerful tool to manage files on cloud storages. One feature is to serve a particular storage over a given protocol.

One of the protocols rclone can serve is S3 (the feature did not make it yet into the release). The shortcoming of that feature is that only one WebDAV authentication can match one S3 authentication. E.g. a WebDAV username + password combination can be set and all S3 requests will be forwarded to that specific WebDAV user.

For our use-case we need to access data of different WebDAV users. The solution is to use the S3 access key and forward it as a Bearer token to WebDAV.

  1. The application that wants to talk to WebDAV using the S3 protocol has to obtain oauth tokens (or any other valid bearer tokens) for every user from the WebDAV server.
  2. It puts the acquired token as the S3 access key into the S3 request.
  3. rclone (acting as the S3 to WebDAV proxy) takes the S3 access key of every request and uses it as Bearer token to authenticate against the WebDAV server. (The S3 secrets will be ignored in the current solution.)

Through this solution the application at the very end only has to implement the S3 protocol, but can also access data that is stored on WebDAV servers on a user to user basis.

How to use it

1. Start a WebDAV server

So far we have tested it with ownCloud and Nextcloud.

2. Run the S3 to WebDAV proxy

docker run --rm \
-p 8080:8080 \
-e REMOTE_NAME=nc \
-e REMOTE_URL="https://<domain>/remote.php/webdav/" \
-e REMOTE_VENDOR=nextcloud \
--name s3-webdav-proxy ghcr.io/jankaritech/s3-webdav-proxy

If you want to use a WebDAV server running on localhost add --network=host

Configuration for Remote Server (WebDAV)

  • REMOTE_NAME: Identifier for the remote server.
  • REMOTE_URL: WebDAV URL of the remote server. Example: https://<domain>/remote.php/webdav/.
  • REMOTE_VENDOR: Vendor of the remote server. Tested vendors are nextcloud and owncloud.

Configuration for the S3 to WebDAV proxy

  • PROXY_ARGS: A space separated list of arguments to pass to rclone.

    Example: -e PROXY_ARGS="--vfs-cache-mode=full --vfs-read-chunk-size=100M".

    Some useful options are:

    • --vfs-cache-max-age: Max time since last access of objects in the cache (default 1h0m0s).
    • --vfs-cache-max-size: Max total size of objects in the cache (default off).
    • --vfs-cache-mode Cache mode off|minimal|writes|full (default off).
    • --vfs-cache-poll-interval: Interval to poll the cache for stale objects (default 1m0s).
    • --vfs-case-insensitive: If a file name not found, find a case insensitive match.
    • --vfs-disk-space-total-size: Specify the total space of disk (default off).
    • --vfs-fast-fingerprint: Use fast (less accurate) fingerprints for change detection.
    • --vfs-read-ahead: Extra read ahead over --buffer-size when using cache-mode full.
    • --vfs-read-chunk-size: Read the source objects in chunks (default 128Mi).
    • --vfs-read-chunk-size-limit: If greater than --vfs-read-chunk-size, double the chunk size after each chunk read, until the limit is reached ('off' is unlimited) (default off).
    • --vfs-read-wait: Time to wait for in-sequence read before seeking (default 20ms).
    • --vfs-used-is-size: rclone size Use the rclone size algorithm for Used size.
    • --vfs-write-back: Time to writeback files after last use when using cache (default 5s).
    • --vfs-write-wait: Time to wait for in-sequence write before giving error (default 1s).

3. Obtain a Bearer token from the WebDAV server

using oauth2 tokens

  • install the oauth2 app in ownCloud/Nextcloud
  • in ownCloud/Nextcloud create a new oauth2 client with the redirect URL http://localhost:9876/
  • create a json file called oauth.json and this content
 {
"installed": {
"client_id": "<client-id-copied-from-oauth2-app>",
"project_id": "focus-surfer-382910",
"auth_uri": "<owncloud-server-root>/index.php/apps/oauth2/authorize",
"token_uri": "<owncloud-server-root>/index.php/apps/oauth2/api/v1/token",
"client_secret": "<client-secret-copied-from-oauth2-app>",
"redirect_uris": [
"http://localhost:9876"
]
}
}

using app-passwords

In Nextcloud one can also use the app-passwords as Bearer tokens. For that navigate in the WebUI to Personal Settings -> Security and generate a new app password. This app password is simply your token. (This does not work with OwnCloud)

4. access WebDAV using S3:

every root folder becomes a bucket, every file below it is a key

curl

  • list all buckets (root folders): curl --location 'http://localhost:8080/' -H'Authorization: AWS4-HMAC-SHA256 Credential=<oauth-access-token-or-app-password>/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-date,Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024' replace <oauth-access-token-or-app-password> with your token, that you got with oauth2l or the app password, the rest of the header has to exist, but the content doesn't matter currently
  • list keys in a bucket (any file below the root folder): curl --location 'http://localhost:8080/<bucket>?list-type=2' -H'Authorization: AWS4-HMAC-SHA256 Credential=<oauth-access-token-or-app-password>/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-date,Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024'

MinIO client

  • install mc
  • add the proxy as alias: mc alias set mys3proxy http://localhost:8080 <oauth-access-token> anysecretkeyitdoesnotmatter replace <oauth-access-token-or-app-password> with your token, that you got with oauth2l
  • list buckets: mc ls mys3proxy
  • list items in a bucket mc ls mys3proxy/folder
  • upload a file: mc cp <localfile> mys3proxy/<bucket (root folder)>/<keyname>
  • find files mc find proxy/<bucket>/ --name "*.txt"
  • download all content of a bucket: mc cp --recursive mys3proxy/<bucket> /tmp/dst/ (items that have a space in their name seem to have an issue)

MinIO Go Client SDK

minioClient, err := minio.New(testURL.Host, &minio.Options{
Creds: credentials.NewStaticV4(
<oauth-access-token-or-app-password>,
"does-not-matter-will-be-ignored-by-server",
"",
),
Secure: false,
})
assert.NoError(t, err)
buckets, err := minioClient.ListBuckets(context.Background())

Any other S3 library or tool

They all should "just" work πŸ™

About

S3 to webDAV Proxy

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

S3 to webDAV Proxy

This project is still under development

πŸ’Έ PointCab GmbH is providing finances for this project

Purpose

Allow accessing WebDAV backends through the S3 protocol.

As a developer of an app that is able to talk to S3 backends

I want to access WebDAV servers through the S3 protocol

So that I don't have to implement and maintain two protocols in my code

How it works

This project is based on rclone (and the plan is to bring the changes back to rclone). Rclone is a powerful tool to manage files on cloud storages. One feature is to serve a particular storage over a given protocol.

One of the protocols rclone can serve is S3 (the feature did not make it yet into the release). The shortcoming of that feature is that only one WebDAV authentication can match one S3 authentication. E.g. a WebDAV username + password combination can be set and all S3 requests will be forwarded to that specific WebDAV user.

For our use-case we need to access data of different WebDAV users. The solution is to use the S3 access key and forward it as a Bearer token to WebDAV.

  1. The application that wants to talk to WebDAV using the S3 protocol has to obtain oauth tokens (or any other valid bearer tokens) for every user from the WebDAV server.
  2. It puts the acquired token as the S3 access key into the S3 request.
  3. rclone (acting as the S3 to WebDAV proxy) takes the S3 access key of every request and uses it as Bearer token to authenticate against the WebDAV server. (The S3 secrets will be ignored in the current solution.)

Through this solution the application at the very end only has to implement the S3 protocol, but can also access data that is stored on WebDAV servers on a user to user basis.

How to use it

1. Start a WebDAV server

So far we have tested it with ownCloud and Nextcloud.

2. Run the S3 to WebDAV proxy

docker run --rm \
-p 8080:8080 \
-e REMOTE_NAME=nc \
-e REMOTE_URL="https://<domain>/remote.php/webdav/" \
-e REMOTE_VENDOR=nextcloud \
--name s3-webdav-proxy ghcr.io/jankaritech/s3-webdav-proxy

If you want to use a WebDAV server running on localhost add --network=host

Configuration for Remote Server (WebDAV)

  • REMOTE_NAME: Identifier for the remote server.
  • REMOTE_URL: WebDAV URL of the remote server. Example: https://<domain>/remote.php/webdav/.
  • REMOTE_VENDOR: Vendor of the remote server. Tested vendors are nextcloud and owncloud.

Configuration for the S3 to WebDAV proxy

  • PROXY_ARGS: A space separated list of arguments to pass to rclone.

    Example: -e PROXY_ARGS="--vfs-cache-mode=full --vfs-read-chunk-size=100M".

    Some useful options are:

    • --vfs-cache-max-age: Max time since last access of objects in the cache (default 1h0m0s).
    • --vfs-cache-max-size: Max total size of objects in the cache (default off).
    • --vfs-cache-mode Cache mode off|minimal|writes|full (default off).
    • --vfs-cache-poll-interval: Interval to poll the cache for stale objects (default 1m0s).
    • --vfs-case-insensitive: If a file name not found, find a case insensitive match.
    • --vfs-disk-space-total-size: Specify the total space of disk (default off).
    • --vfs-fast-fingerprint: Use fast (less accurate) fingerprints for change detection.
    • --vfs-read-ahead: Extra read ahead over --buffer-size when using cache-mode full.
    • --vfs-read-chunk-size: Read the source objects in chunks (default 128Mi).
    • --vfs-read-chunk-size-limit: If greater than --vfs-read-chunk-size, double the chunk size after each chunk read, until the limit is reached ('off' is unlimited) (default off).
    • --vfs-read-wait: Time to wait for in-sequence read before seeking (default 20ms).
    • --vfs-used-is-size: rclone size Use the rclone size algorithm for Used size.
    • --vfs-write-back: Time to writeback files after last use when using cache (default 5s).
    • --vfs-write-wait: Time to wait for in-sequence write before giving error (default 1s).

3. Obtain a Bearer token from the WebDAV server

using oauth2 tokens

  • install the oauth2 app in ownCloud/Nextcloud
  • in ownCloud/Nextcloud create a new oauth2 client with the redirect URL http://localhost:9876/
  • create a json file called oauth.json and this content
 {
"installed": {
"client_id": "<client-id-copied-from-oauth2-app>",
"project_id": "focus-surfer-382910",
"auth_uri": "<owncloud-server-root>/index.php/apps/oauth2/authorize",
"token_uri": "<owncloud-server-root>/index.php/apps/oauth2/api/v1/token",
"client_secret": "<client-secret-copied-from-oauth2-app>",
"redirect_uris": [
"http://localhost:9876"
]
}
}

using app-passwords

In Nextcloud one can also use the app-passwords as Bearer tokens. For that navigate in the WebUI to Personal Settings -> Security and generate a new app password. This app password is simply your token. (This does not work with OwnCloud)

4. access WebDAV using S3:

every root folder becomes a bucket, every file below it is a key

curl

  • list all buckets (root folders): curl --location 'http://localhost:8080/' -H'Authorization: AWS4-HMAC-SHA256 Credential=<oauth-access-token-or-app-password>/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-date,Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024' replace <oauth-access-token-or-app-password> with your token, that you got with oauth2l or the app password, the rest of the header has to exist, but the content doesn't matter currently
  • list keys in a bucket (any file below the root folder): curl --location 'http://localhost:8080/<bucket>?list-type=2' -H'Authorization: AWS4-HMAC-SHA256 Credential=<oauth-access-token-or-app-password>/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-date,Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024'

MinIO client

  • install mc
  • add the proxy as alias: mc alias set mys3proxy http://localhost:8080 <oauth-access-token> anysecretkeyitdoesnotmatter replace <oauth-access-token-or-app-password> with your token, that you got with oauth2l
  • list buckets: mc ls mys3proxy
  • list items in a bucket mc ls mys3proxy/folder
  • upload a file: mc cp <localfile> mys3proxy/<bucket (root folder)>/<keyname>
  • find files mc find proxy/<bucket>/ --name "*.txt"
  • download all content of a bucket: mc cp --recursive mys3proxy/<bucket> /tmp/dst/ (items that have a space in their name seem to have an issue)

MinIO Go Client SDK

minioClient, err := minio.New(testURL.Host, &minio.Options{
Creds: credentials.NewStaticV4(
<oauth-access-token-or-app-password>,
"does-not-matter-will-be-ignored-by-server",
"",
),
Secure: false,
})
assert.NoError(t, err)
buckets, err := minioClient.ListBuckets(context.Background())

Any other S3 library or tool

They all should "just" work πŸ™

About

S3 to webDAV Proxy

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages