Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add merge extension #56

Merged
merged 5 commits into from
Feb 3, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 121 additions & 10 deletions protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,10 @@ Servers MUST accept `PATCH` requests against any tus resource and apply the
bytes contained in the message at the given `Offset`. All `PATCH` requests
MUST use `Content-Type: application/offset+octet-stream`.

The `Offset` value SHOULD be equal, but MAY also be smaller than the current
offset of the resource, and servers MUST handle `PATCH` operations containing
the same data at the same absolute offsets idempotently. The behavior of using
`Offset` values larger than the current upload offset is undefined, see the
[Parallel Chunks](#parallel-chunks) extension.
The `Offset` value MUST be equal to the current offset of the resource. In order
to achieve parallel upload the Merge extension MAY be used. If the offsets
do not match the server MUST return the `409 Conflict` status code without
modifying the upload resource.

Clients SHOULD send all remaining bytes of a resource in a single `PATCH`
request, but MAY also use multiple small requests for scenarios where this is
Expand Down Expand Up @@ -386,11 +385,6 @@ Die Würde des Menschen ist unantastbar.
TUS-Resumable: 1.0.0
```

### Parallel Chunks

This extension will define how to upload several chunks of a file in parallel in
order to overcome the throughput limitations of individual tcp connections.

### Streams

This extension defines how to upload finite streams of data that have an
Expand Down Expand Up @@ -512,6 +506,123 @@ HTTP/1.1 204 No Content
TUS-Resumable: 1.0.0
```

### Merge

This extension can be used to merge multiple uploads into a single one enabling
clients to perform parallel uploads and uploading non-contiguous chunks. If the
server supports this extension it MUST be announced by adding the `merge`
element to the values of the `TUS-Extension` header.

A partial upload is an upload which represents a chunk of a file. It is
constructed by including the `Merge: partial` header when creating a new
resource using the file creation extension. Multiple partial uploads are merged
into a final upload in a specific order. The server SHOULD NOT process these
partial uploads until they are merged to form a final upload. The length of the
final resource MUST be the sum of the length of all partial resources. A final
upload is considered finished if all of its partial uploads are finished.

In order to create a new final upload the client MUST omit the `Entity-Length`
header and add the `Merge` header to the file creation request. The headers
value is the string `final` followed by a semicolon and a space-separated list
of the URLs of the partial uploads which will be merged. The order of this list
MUST represent the order using which the partial uploads are concatenated
without adding, modifying or removing any bytes. This merge request MAY even
happen if all or some of the corresponding partial uploads are not finished.

The server MAY delete partial uploads once they are merged but they MAY be used
multiple times for forming a final resource.

Any `PATCH` request against a final upload MUST be denied and MUST neither
modify the final nor any of its partial resources. The response of a `HEAD`
request MUST NOT contain the `Offset` header. The `Entity-Length` header MUST be
included if the length of the final resource can be calculated at the time.
Responses to `HEAD` requests against partial or final uploads MUST include the
`Merge` header and its value as sent in the file creation request.

#### Headers

##### Merge

The `Merge` header indicates whether the upload created by the request is either
a partial or final upload. If a partial upload is to be built, the header value
MUST be `partial`. In the case of creating a final resource its value is the
string `final` followed by a semicolon and a space-separated list of the URLs of
the partial uploads which will be merged and form the file. All of the URLs MUST
NOT contain a space. The host and protocol scheme of the URLs MAY be omitted. In
this case the value of the `Host` header MUST be used as the host and the scheme
of the current request.

#### Example

In the following example the `Host` and `TUS-Resumable` headers are omitted for
readability although they are required by the specification.
In the beginning two partial uploads are created:

```
POST /files HTTP/1.1
Merge: partial
Entity-Length: 5

HTTP/1.1 204 No Content
Location: http://tus.example.org/files/a
```
```
POST /files HTTP/1.1
Merge: partial
Entity-Length: 6

HTTP/1.1 204 No Content
Location: http://tus.example.org/files/b
```

The next step is to create the final upload consisting of the two earlier
generated partial uploads. In following request no `Entity-Length` header is
presented.

```
POST /files HTTP/1.1
Merge: final; /files/a http://tus.example.org/files/b

HTTP/1.1 204 No Content
Location: http://tus.example.org/files/ab
```

The length of the final resource is now 11 bytes:

```
HEAD /files/ab HTTP/1.1

HTTP/1.1 204 No Content
Entity-Length: 11
Merge: final; /files/a /files/b
```

You are now able to upload data to the two partial resources using `PATCH`
requests:

```
PATCH /files/a HTTP/1.1
Offset: 0
Content-Length: 5

hello

HTTP/1.1 204 No Content
```
```
PATCH /files/b HTTP/1.1
Offset: 0
Content-Length: 6

world

HTTP/1.1 204 No Content
```

In the first request the string `hello` was uploaded while the second file now
contains ` world` with a leading space. The data stored for the final upload
`/files/ab` is `hello world`.

## FAQ

### Why is the protocol using custom headers?
Expand Down