Skip to content

Commit

Permalink
Merge pull request #56 from tus/merge
Browse files Browse the repository at this point in the history
add merge extension
  • Loading branch information
Acconut committed Feb 3, 2015
2 parents 416de03 + 5e0ccb3 commit ba6d03f
Showing 1 changed file with 121 additions and 10 deletions.
131 changes: 121 additions & 10 deletions protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,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 @@ -384,11 +383,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 @@ -510,6 +504,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

0 comments on commit ba6d03f

Please sign in to comment.