mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-25 22:42:16 -05:00
194 lines
7.1 KiB
Markdown
194 lines
7.1 KiB
Markdown
---
|
|
title: "Resumable Upload"
|
|
date: 2023-10-10T00:00:00+00:00
|
|
weight: 21
|
|
geekdocRepo: https://github.com/owncloud/ocis
|
|
geekdocEditPath: edit/master/docs/apis/http
|
|
geekdocFilePath: tus_upload.md
|
|
geekdocCollapseSection: true
|
|
---
|
|
|
|
Infinite Scale supports the tus resumable-upload protocol, which is a robust, modular, and open protocol designed to resume large file uploads reliably over HTTP.
|
|
In situations where file uploads might be interrupted due to network issues, browser crashes, or other unforeseen interruptions,
|
|
tus ensures that uploads can be resumed from the point of failure without losing data.
|
|
This documentation shows some basic examples, refer [tus official site](https://tus.io/protocols/resumable-upload) for more details.
|
|
|
|
## Upload in Chunks
|
|
|
|
### Create an Upload URL
|
|
|
|
The client must send a POST request against a known upload creation URL to request a new upload resource.
|
|
The filename has to be provided in base64-encoded format.
|
|
|
|
Example:
|
|
```shell
|
|
# base64 encoded filename 'tustest.txt' is 'dHVzdGVzdC50eHQ='
|
|
echo -n 'tustest.txt' | base64
|
|
```
|
|
|
|
{{< tabs "create-upload-url" >}}
|
|
{{< tab "Request" >}}
|
|
```shell
|
|
curl -ks -XPOST https://ocis.test/remote.php/dav/spaces/8d72036d-14a5-490f-889e-414064156402$196ac304-7b88-44ce-a4db-c4becef0d2e0 \
|
|
-H "Authorization: Bearer eyJhbGciOiJQUzI..."\
|
|
-H "Tus-Resumable: 1.0.0" \
|
|
-H "Upload-Length: 10" \
|
|
-H "Upload-Metadata: filename dHVzdGVzdC50eHQ="
|
|
```
|
|
{{< /tab >}}
|
|
|
|
{{< tab "Response - 201 Created" >}}
|
|
```
|
|
< HTTP/1.1 201 Created
|
|
< Access-Control-Allow-Headers: Tus-Resumable, Upload-Length, Upload-Metadata, If-Match
|
|
< Access-Control-Allow-Origin: *
|
|
< Access-Control-Expose-Headers: Tus-Resumable, Upload-Offset, Location
|
|
< Content-Length: 0
|
|
< Content-Security-Policy: default-src 'none';
|
|
< Date: Mon, 16 Oct 2023 08:49:39 GMT
|
|
< Location: https://ocis.test/data/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJyZXZhIiwiZXhwIjoxNjk3NTMyNTc5LCJpYXQiOjE2OTc0NDYxNzksInRhcmdldCI6Imh0dHA6Ly9sb2NhbGhvc3Q6OTE1OC9kYXRhL3R1cy8zYTU3ZWZlMS04MzE0LTQ4MGEtOWY5Ny04N2Q1YzBjYTJhMTgifQ.FbrlY7mdOfsbFgMrP8OtcHlCEq72a2ZVnPD2iBo9MfM
|
|
< Tus-Extension: creation,creation-with-upload,checksum,expiration
|
|
< Tus-Resumable: 1.0.0
|
|
< Vary: Origin
|
|
< X-Content-Type-Options: nosniff
|
|
< X-Download-Options: noopen
|
|
< X-Frame-Options: SAMEORIGIN
|
|
< X-Permitted-Cross-Domain-Policies: none
|
|
< X-Request-Id: xxxxxxxxxxxxxxxxxxxxxx
|
|
< X-Robots-Tag: none
|
|
< X-Xss-Protection: 1; mode=block
|
|
<
|
|
* Connection #0 to host localhost left intact
|
|
```
|
|
{{< /tab >}}
|
|
{{< /tabs >}}
|
|
|
|
The server will return a temporary upload URL in the location header of the response:
|
|
```
|
|
< Location: https://ocis.test/data/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJyZXZhIiwiZXhwIjoxNjk3NTMyNTc5LCJpYXQiOjE2OTc0NDYxNzksInRhcmdldCI6Imh0dHA6Ly9sb2NhbGhvc3Q6OTE1OC9kYXRhL3R1cy8zYTU3ZWZlMS04MzE0LTQ4MGEtOWY5Ny04N2Q1YzBjYTJhMTgifQ.FbrlY7mdOfsbFgMrP8OtcHlCEq72a2ZVnPD2iBo9MfM
|
|
```
|
|
|
|
### Upload the First Chunk
|
|
|
|
Once a temporary upload URL has been created, a client can send a PATCH request to upload a file. The file content should be sent in the body of the request:
|
|
{{< tabs "upload-the-first-chunk" >}}
|
|
{{< tab "Request" >}}
|
|
```shell
|
|
curl -ks -XPATCH https://temporary-upload-url \
|
|
-H "Authorization: Bearer eyJhbGciOiJQUzI..." \
|
|
-H "Tus-Resumable: 1.0.0" \
|
|
-H "Upload-Offset: 0" \
|
|
-H "Content-Type: application/offset+octet-stream" -d "01234"
|
|
```
|
|
{{< /tab >}}
|
|
|
|
{{< tab "Response - 204 No Content" >}}
|
|
```
|
|
< HTTP/1.1 204 No Content
|
|
< Date: Tue, 17 Oct 2023 04:10:52 GMT
|
|
< Oc-Fileid: 8d72036d-14a5-490f-889e-414064156402$73bb5450-816b-4cae-90aa-1f96adc95bd4!84e319e4-de1d-4dd8-bbd0-e51d933cdbcd
|
|
< Tus-Resumable: 1.0.0
|
|
< Upload-Expires: 1697602157
|
|
< Upload-Offset: 5
|
|
< Vary: Origin
|
|
< X-Content-Type-Options: nosniff
|
|
< X-Request-Id: xxxxxxxxxxxxxxxxxxxxxx
|
|
<
|
|
* Connection #0 to host localhost left intact
|
|
```
|
|
{{< /tab >}}
|
|
{{< /tabs >}}
|
|
|
|
### Upload Further Chunks
|
|
|
|
After the first chunk is uploaded, the second chunk can be uploaded by pointing `Upload-Offset` to exact position that was returned in the first response.
|
|
Upload process will not be marked as complete until the total uploaded content size matches the `Upload-Length` specified during the creation of the temporary URL.
|
|
|
|
{{< tabs "upload-the-second-chunk" >}}
|
|
{{< tab "Request" >}}
|
|
```shell
|
|
curl -ks -XPATCH https://temporary-upload-url \
|
|
-H "Authorization: Bearer eyJhbGciOiJQUzI..." \
|
|
-H "Tus-Resumable: 1.0.0" \
|
|
-H "Upload-Offset: 5" \
|
|
-H "Content-Type: application/offset+octet-stream" -d "56789"
|
|
```
|
|
{{< /tab >}}
|
|
|
|
{{< tab "Response - 204 No Content" >}}
|
|
```
|
|
< HTTP/1.1 204 No Content
|
|
< Date: Tue, 17 Oct 2023 04:11:00 GMT
|
|
< Oc-Fileid: 8d72036d-14a5-490f-889e-414064156402$73bb5450-816b-4cae-90aa-1f96adc95bd4!84e319e4-de1d-4dd8-bbd0-e51d933cdbcd
|
|
< Tus-Resumable: 1.0.0
|
|
< Upload-Expires: 1697602157
|
|
< Upload-Offset: 10
|
|
< Vary: Origin
|
|
< X-Content-Type-Options: nosniff
|
|
< X-Request-Id: xxxxxxxxxxxxxxxxxxxxxx
|
|
<
|
|
* Connection #0 to host localhost left intact
|
|
```
|
|
{{< /tab >}}
|
|
{{< /tabs >}}
|
|
{{< hint type=warning title="Important Warning" >}}
|
|
`Upload-Offset` header indicates the byte position in the target file where the server should start writing the upload content.
|
|
It ensures data integrity and order during the upload process.
|
|
{{< /hint >}}
|
|
|
|
## Creation with Upload
|
|
|
|
{{< tabs "creation-with-upload" >}}
|
|
{{< tab "Request" >}}
|
|
```shell
|
|
curl -ks -XPOST https://ocis.test/remote.php/dav/spaces/{space-id} \
|
|
-H "Authorization: Bearer eyJhbGciOiJQUzI..." \
|
|
-H "Tus-Resumable: 1.0.0" \
|
|
-H "Upload-Length: 14" \
|
|
-H "Content-Type: application/offset+octet-stream" \
|
|
-H "Upload-Metadata: filename dGVzdC50eHQ=" \
|
|
-H "Tus-Extension: creation-with-upload" \
|
|
-d "upload content"
|
|
```
|
|
{{< /tab >}}
|
|
|
|
{{< tab "Response - 201 Created" >}}
|
|
```shell
|
|
< HTTP/1.1 201 Created
|
|
< Access-Control-Allow-Headers: Tus-Resumable, Upload-Length, Upload-Metadata, If-Match
|
|
< Access-Control-Allow-Origin: *
|
|
< Access-Control-Expose-Headers: Tus-Resumable, Upload-Offset, Location
|
|
< Content-Length: 0
|
|
< Content-Security-Policy: default-src 'none';
|
|
< Content-Type: text/plain
|
|
< Date: Mon, 16 Oct 2023 04:18:25 GMT
|
|
< Etag: "372c96743f68bc40e789124d30567371"
|
|
< Last-Modified: Mon, 16 Oct 2023 04:18:25 +0000
|
|
< Location: https://ocis.test/data/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJyZXZhIiwiZXhwIjoxNjk3NTE2MzA1LCJpYXQiOjE2OTc0Mjk5MDUsInRhcmdldCI6Imh0dHA6Ly9sb2NhbGhvc3Q6OTE1OC9kYXRhL3R1cy82NjlhODBlZi1hN2VjLTQwYTAtOGNmOS05MTgwNTVhYzlkZjAifQ.yq-ofJYnJ9FLML7Z_jki1FJQ7Ulbt9O_cmLe6V411A4
|
|
< Oc-Etag: "372c96743f68bc40e789124d30567371"
|
|
< Oc-Fileid: 44d3e1e0-6c01-4b94-9145-9d0068239fcd$446bdad4-4b27-41f1-afce-0881f202a214!d7c292a6-c395-4e92-bf07-2c1663aec8dd
|
|
< Oc-Perm: RDNVWZP
|
|
< Tus-Extension: creation,creation-with-upload,checksum,expiration
|
|
< Tus-Resumable: 1.0.0
|
|
< Upload-Expires: 1697516305
|
|
< Upload-Offset: 14
|
|
< Vary: Origin
|
|
< X-Content-Type-Options: nosniff
|
|
< X-Download-Options: noopen
|
|
< X-Frame-Options: SAMEORIGIN
|
|
* TLSv1.2 (IN), TLS header, Supplemental data (23):
|
|
{ [5 bytes data]
|
|
< X-Permitted-Cross-Domain-Policies: none
|
|
< X-Request-Id: xxxxxxxxxxxxxxxxxxxxxx
|
|
< X-Robots-Tag: none
|
|
< X-Xss-Protection: 1; mode=block
|
|
<
|
|
* Connection #0 to host localhost left intact
|
|
```
|
|
{{< /tab >}}
|
|
{{< /tabs >}}
|
|
|
|
{{< hint type=warning title="Important Warning" >}}
|
|
`Upload-Length` header should contain the exact byte as upload content.
|
|
{{< /hint >}}
|