<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc2629 version 1.6.1 (Ruby 3.0.3) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-tus-httpbis-resumable-uploads-protocol-00" category="std" consensus="true" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.12.2 -->
  <front>
    <title abbrev="Resumable Uploads">tus - Resumable Uploads Protocol</title>
    <seriesInfo name="Internet-Draft" value="draft-tus-httpbis-resumable-uploads-protocol-00"/>
    <author initials="M." surname="Kleidl" fullname="Marius Kleidl">
      <organization>Transloadit Ltd</organization>
      <address>
        <email>marius@transloadit.com</email>
      </address>
    </author>
    <author initials="J." surname="Mehta" fullname="Jiten Mehta">
      <organization>Apple Inc.</organization>
      <address>
        <email>jmehta@apple.com</email>
      </address>
    </author>
    <author initials="G." surname="Zhang" fullname="Guoye Zhang">
      <organization>Apple Inc.</organization>
      <address>
        <email>guoye_zhang@apple.com</email>
      </address>
    </author>
    <author initials="L." surname="Pardue" fullname="Lucas Pardue">
      <organization>Cloudflare</organization>
      <address>
        <email>lucaspardue.24.7@gmail.com</email>
      </address>
    </author>
    <author initials="S." surname="Matsson" fullname="Stefan Matsson">
      <organization>JellyHive</organization>
      <address>
        <email>s.matsson@gmail.com</email>
      </address>
    </author>
    <date year="2022" month="February" day="24"/>
    <area>ART</area>
    <workgroup>HTTP</workgroup>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <t>HTTP clients often encounter interrupted data transfers as a result of canceled requests or dropped connections. Prior to interruption, part of a representation may have been exchanged. To complete the data transfer of the entire representation, it is often desirable to issue subsequent requests that transfer only the remainder of the representation. HTTP range requests support this concept of resumable downloads from server to client. This document describes a mechanism that supports resumable uploads from client to server using HTTP.</t>
    </abstract>
    <note removeInRFC="true">
      <name>Discussion Venues</name>
      <t>Discussion of this document takes place on the
  tus-v2 GitHub repository at
  <eref target="https://github.com/tus/tus-v2"/>.</t>
    </note>
  </front>
  <middle>
    <section anchor="introduction">
      <name>Introduction</name>
      <t>HTTP clients often encounter interrupted data transfers as a result of canceled requests or dropped connections. Prior to interruption, part of a representation (see <xref section="3.2" sectionFormat="of" target="HTTP"/>) might have been exchanged. To complete the data transfer of the entire representation, it is often desirable to issue subsequent requests that transfer only the remainder of the representation. HTTP range requests (see <xref section="14" sectionFormat="of" target="HTTP"/>) support this concept of resumable downloads from server to client.</t>
      <t>HTTP methods such as POST or PUT can be used by clients to request processing of representation data enclosed in the request message. The transfer of representation data from client to server is often referred to as an upload. Uploads are just as likely as downloads to suffer from the effects of data transfer interruption. Humans can play a role in upload interruptions through manual actions such as pausing an upload. Regardless of the cause of an interruption, servers may have received part of the representation before its occurrence and it is desirable if clients can complete the data transfer by sending only the remainder of the representation. The process of sending additional parts of a representation using subsequent HTTP requests from client to server is herein referred to as a resumable upload.</t>
      <t>Connection interruptions are common and the absence of a standard mechanism for resumable uploads has lead to a proliferation of custom solutions. Some of those use HTTP, while others rely on other transfer mechanisms entirely. An HTTP-based standard solution is desirable for such a common class of problem.</t>
      <t>This document defines the Resumable Uploads Protocol, an optional mechanism for resumable uploads using HTTP that is backwards-compatible with conventional HTTP uploads. When an upload is interrupted, clients can send subsequent requests to query the server state and use this information to the send remaining data. Alternatively, they can cancel the upload entirely.</t>
    </section>
    <section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
      <t>The terms byte sequence, Item, string, sf-binary, sf-boolean, sf-integer, sf-string, and sf-token are imported from
<xref target="STRUCTURED-FIELDS"/>.</t>
      <t>The terms client and server are imported from <xref target="HTTP"/>.</t>
      <t>Upload: A sequence of one or more procedures, uniquely identified by a token chosen by a client.</t>
      <t>Procedure: An HTTP message exchange for that can be used for resumable uploads.</t>
    </section>
    <section anchor="uploading-overview">
      <name>Uploading Overview</name>
      <t>The Resumable Uploads Protocol consists of several procedures that rely on HTTP message exchanges. The following procedures are defined:</t>
      <ul spacing="normal">
        <li>Upload Transfer Procedure (<xref target="upload-transfer"/>)</li>
        <li>Offset Retrieving Procedure (<xref target="offset-retrieving"/>)</li>
        <li>Upload Cancellation Procedure (<xref target="upload-cancellation"/>)</li>
      </ul>
      <t>A single upload is a sequence of one or more procedures. Each upload is uniquely
identified by a token chosen by a client. The token is carried in the Upload-Token header field; see <xref target="upload-token"/>.</t>
      <t>The remainder of this section uses examples of a file upload to illustrate permutations of procedure sequence. Note, however, that HTTP message exchanges use representation data (see <xref section="8.1" sectionFormat="of" target="HTTP"/>), which means that procedures can apply to many forms of content.</t>
      <section anchor="example-1-complete-upload-of-file-with-known-size">
        <name>Example 1: Complete upload of file with known size</name>
        <t>In this example, the client first attempts to upload a file with a known size in a single HTTP request. An interruption occurs and the client then attempts to resume the upload using subsequent HTTP requests.</t>
        <t>1) The Upload Transfer Procedure (<xref target="upload-transfer"/>) can be used to notify the server that the client wants to begin an upload. The server should then reserve the required resources to accept the upload from the client. The client also begins transferring the entire file in the request body. The request includes the Upload-Token header, which is used for identifying future requests related to this upload. An informational response can be sent to the client to signal the support of resumable upload on the server.</t>
        <figure anchor="fig-upload-transfer-procedure-init">
          <name>Upload Transfer Procedure Initiation</name>
          <artwork><![CDATA[
Client                                  Server
|                                            |
| POST with Upload-Token                     |
|------------------------------------------->|
|                                            |
|                                            | Reserve resources
|                                            | for Upload-Token
|                                            |------------------
|                                            |                 |
|                                            |<-----------------
|                                            |
|            104 Upload Resumption Supported |
|<-------------------------------------------|
|                                            |
| Flow Interrupted                           |
|------------------------------------------->|
|                                            |
]]></artwork>
        </figure>
        <t>2) If the connection to the server gets interrupted during the Upload Transfer Procedure, the client may want to resume the upload. Before this is possible, the client must know the amount of data that the server was able to receive before the connection got interrupted. To achieve this, the client uses the Offset Retrieving Procedure (<xref target="offset-retrieving"/>) to obtain the upload's offset.</t>
        <figure anchor="fig-offset-retrieving-procedure">
          <name>Offset Retrieving Procedure</name>
          <artwork><![CDATA[
Client                                      Server
|                                                |
| HEAD with Upload-Token                         |
|----------------------------------------------->|
|                                                |
|              204 No Content with Upload-Offset |
|<-----------------------------------------------|
|                                                |
]]></artwork>
        </figure>
        <t>3) After the Offset Retrieving Procedure (<xref target="offset-retrieving"/>) completes, the client can resume the upload by sending the remaining file content to the server, appending to the already stored data in the upload. The <tt>Upload-Offset</tt> value is included to ensure that the client and server agree on the offset that the upload resumes from.</t>
        <figure anchor="fig-resuming-upload">
          <name>Resuming Upload</name>
          <artwork><![CDATA[
Client                                      Server
|                                                |
| POST with Upload-Token and Upload-Offset       |
|----------------------------------------------->|
|                                                |
|                      201 Created on completion |
|<-----------------------------------------------|
|                                                |
]]></artwork>
        </figure>
        <t>4) If the client is not interesting in completing the upload anymore, it can instruct the server to delete the upload and free all related resources using the Upload Cancellation Procedure (<xref target="upload-cancellation"/>).</t>
        <figure anchor="fig-upload-cancellation-procedure">
          <name>Upload Cancellation Procedure</name>
          <artwork><![CDATA[
Client                                      Server
|                                                |
| DELETE with Upload-Token                       |
|----------------------------------------------->|
|                                                |
|                   204 No Content on completion |
|<-----------------------------------------------|
|                                                |
]]></artwork>
        </figure>
      </section>
      <section anchor="example-2-upload-as-a-series-of-parts">
        <name>Example 2: Upload as a series of parts</name>
        <t>In some cases clients might prefer to upload a file as a series of parts sent across multiple HTTP messages. One use case is to overcome server limits on HTTP message content size. Another use case is where the client does not know the final size, such as when file data originates from a streaming source.</t>
        <t>This example shows how the client, with prior knowledge about the server's resumable upload support, can upload parts of a file over a sequence of procedures.</t>
        <t>1) If the client is aware that the server supports resumable upload, it can use the Upload Transfer Procedure with the <tt>Upload-Incomplete</tt> header to start an upload.</t>
        <figure anchor="fig-upload-cancellation-procedure-usage">
          <name>Upload Transfer Procedure Usage</name>
          <artwork><![CDATA[
Client                                      Server
|                                                |
| POST with Upload-Token, Upload-Offset,         |
| and Upload-Incomplete                          |
|----------------------------------------------->|
|                                                |
|             201 Created with Upload-Incomplete |
|              on completion                     |
|<-----------------------------------------------|
|                                                |
]]></artwork>
        </figure>
        <t>2) The last part of the upload does not have the <tt>Upload-Incomplete</tt> header.</t>
        <figure anchor="fig-upload-cancellation-procedure-last-chunk">
          <name>Upload Transfer Procedure Last Chunk</name>
          <artwork><![CDATA[
Client                                      Server
|                                                |
| POST with Upload-Token and Upload-Offset       |
|----------------------------------------------->|
|                                                |
|                      201 Created on completion |
|<-----------------------------------------------|
|                                                |
]]></artwork>
        </figure>
      </section>
    </section>
    <section anchor="upload-transfer">
      <name>Upload Transfer Procedure</name>
      <t>The Upload Transfer Procedure is intended for transferring the data chunk. As such, it can be used for either resuming an existing upload, or starting a new upload. A limited form of this procedure <bcp14>MAY</bcp14> be used by the client to start a new upload without the knowledge of server support.</t>
      <t>This procedure is designed to be compatible with a regular upload. Therefore all methods are allowed with the exception of <tt>GET</tt>, <tt>HEAD</tt>, <tt>DELETE</tt>, and <tt>OPTIONS</tt>. All response status codes are allowed. The client is <bcp14>RECOMMENDED</bcp14> to use the <tt>POST</tt> method if not otherwise intended. The server <bcp14>MAY</bcp14> only support a limited number of methods.</t>
      <t>The client <bcp14>MUST</bcp14> use the same method throughout an entire upload. The server <bcp14>SHOULD</bcp14> reject the attempt to resume an upload with a different method with <tt>400 (Bad Request)</tt> response.</t>
      <t>The request <bcp14>MUST</bcp14> include the <tt>Upload-Token</tt> header field (<xref target="upload-token"/>) which uniquely identifies an upload. The client <bcp14>MUST NOT</bcp14> reuse the token for a different upload.</t>
      <t>When resuming an upload, the <tt>Upload-Offset</tt> header field (<xref target="upload-offset"/>) <bcp14>MUST</bcp14> be set to the resumption offset. The resumption offset 0 indicates a new upload. The absence of the <tt>Upload-Offset</tt> header field implies the resumption offset of 0.</t>
      <t>If the end of the request body is not the end of the upload, the <tt>Upload-Incomplete</tt> header field (<xref target="upload-incomplete"/>) <bcp14>MUST</bcp14> be set to true.</t>
      <t>If the server does not consider the upload associated with the token in the <tt>Upload-Token</tt> header field active, but the resumption offset is non-zero, it <bcp14>MUST</bcp14> respond with <tt>404 (Not Found)</tt> status code.</t>
      <t>The client <bcp14>MUST NOT</bcp14> perform multiple Upload Transfer Procedures (<xref target="upload-transfer"/>) for the same token in parallel to avoid race conditions and data loss or corruption. The server is <bcp14>RECOMMENDED</bcp14> to take measures to avoid parallel Upload Transfer Procedures: The server <bcp14>MAY</bcp14> terminate any ongoing Upload Transfer Procedure (<xref target="upload-transfer"/>) for the same token. Since the client is not allowed to perform multiple transfers in parallel, the server can assume that the previous attempt has already failed. Therefore, the server <bcp14>MAY</bcp14> abruptly terminate the previous HTTP connection or stream.</t>
      <t>If the offset in the <tt>Upload-Offset</tt> header field does not match the value 0, the offset provided by the immediate previous Offset Retrieving Procedure (<xref target="offset-retrieving"/>), or the end offset of the immediate previous incomplete transfer, the server <bcp14>MUST</bcp14> respond with <tt>409 (Conflict)</tt> status code.</t>
      <t>The server <bcp14>MUST</bcp14> send the <tt>Upload-Offset</tt> header in the response if it considers the upload active, either when the response is a success (e.g. <tt>201 (Created)</tt>), or when the response is a failure (e.g. <tt>409 (Conflict)</tt>). The value <bcp14>MUST</bcp14> be equal to the end offset of the entire upload, or the begin offset of the next chunk if the upload is still incomplete. The client <bcp14>SHOULD</bcp14> consider the upload failed if the response status code indicates a success but the offset in the <tt>Upload-Offset</tt> header field in the response does not equal to the begin offset plus the number of bytes uploaded in the request.</t>
      <t>If the request completes successfully and the entire upload is complete, the server <bcp14>MUST</bcp14> acknowledge it by responding with a successful status code between 200 and 299 (inclusive). Server is <bcp14>RECOMMENDED</bcp14> to use <tt>201 (Created)</tt> response if not otherwise specified. The response <bcp14>MUST NOT</bcp14> include the <tt>Upload-Incomplete</tt> header with the value of true.</t>
      <t>If the request completes successfully but the entire upload is not yet complete indicated by the <tt>Upload-Incomplete</tt> header, the server <bcp14>MUST</bcp14> acknowledge it by responding with the <tt>201 (Created)</tt> status code, the <tt>Upload-Incomplete</tt> header set to true.</t>
      <sourcecode type="example"><![CDATA[
:method: POST
:scheme: https
:authority: example.com
:path: /upload
upload-token: :SGVs…SGU=:
upload-draft-interop-version: 1
content-length: 100
[content (100 bytes)]

:status: 104
upload-draft-interop-version: 1

:status: 201
upload-offset: 100
]]></sourcecode>
      <sourcecode type="example"><![CDATA[
:method: POST
:scheme: https
:authority: example.com
:path: /upload
upload-token: :SGVs…SGU=:
upload-draft-interop-version: 1
upload-offset: 0
upload-incomplete: ?1
content-length: 25
[partial content (25 bytes)]

:status: 201
upload-incomplete: ?1
upload-offset: 25
]]></sourcecode>
      <t>The client <bcp14>MAY</bcp14> automatically attempt upload resumption when the connection is terminated unexpectedly, or if a server error status code between 500 and 599 (inclusive) is received. The client <bcp14>SHOULD NOT</bcp14> automatically retry if a client error status code between 400 and 499 (inclusive) is received.</t>
      <t>File metadata can affect how servers might act on the uploaded file. Clients can send Representation Metadata (see <xref section="8.3" sectionFormat="of" target="HTTP"/>) in the Upload Transfer Procedure request that starts an upload. Servers <bcp14>MAY</bcp14> interpret this metadata or <bcp14>MAY</bcp14> ignore it. Clients <bcp14>SHOULD NOT</bcp14> send representation metadata in subsequent Upload Transfer Procedure requests and servers <bcp14>SHOULD</bcp14> ignore representation received in subsequent requests. The <tt>Content-Type</tt> header can be used to indicate the MIME type of the file. The <tt>Content-Disposition</tt> header can be used to transmit a filename. If included, the parameters <bcp14>SHOULD</bcp14> be either <tt>filename</tt>, <tt>filename*</tt> or <tt>boundary</tt>.</t>
      <section anchor="feature-detection">
        <name>Feature Detection</name>
        <t>If the client has no knowledge of whether the server supports resumable upload, the Upload Transfer Procedure <bcp14>MAY</bcp14> be used with some additional constraints. In particular, the <tt>Upload-Offset</tt> header field (<xref target="upload-offset"/>) and the <tt>Upload-Incomplete</tt> header field (<xref target="upload-incomplete"/>) <bcp14>MUST NOT</bcp14> be sent in the request if the server support is unclear. This allows the upload to function as if it is a regular upload.</t>
        <t>If the server detects the Upload Transfer Procedure with neither the <tt>Upload-Offset</tt> header nor the <tt>Upload-Incomplete</tt> header, and it supports resumable upload, an informational response with <tt>104 (Upload Resumption Supported)</tt> status <bcp14>MAY</bcp14> be sent to the client while the request body is being uploaded.</t>
        <t>The client <bcp14>MUST NOT</bcp14> attempt to resume an upload if it did not receive the <tt>104 (Upload Resumption Supported)</tt> informational response, and it does not have other signals of whether the server supporting resumable upload.</t>
        <t>If the client is aware of the server support, it <bcp14>SHOULD</bcp14> start an upload with the <tt>Upload-Offset</tt> header set to 0 in order to prevent the unnecessary informational response.</t>
      </section>
      <section anchor="draft-version-identification">
        <name>Draft Version Identification</name>
        <ul empty="true">
          <li>
            <t><strong>RFC Editor's Note:</strong>  Please remove this section and <tt>Upload-Draft-Interop-Version</tt> from all examples prior to publication of a final version of this document.</t>
          </li>
        </ul>
        <t>The current interop version is 1.</t>
        <t>Client implementations of draft versions of the protocol <bcp14>MUST</bcp14> send a header field <tt>Upload-Draft-Interop-Version</tt> with the interop version as its value to its requests. Its ABNF is</t>
        <sourcecode type="abnf"><![CDATA[
Upload-Draft-Interop-Version = sf-integer
]]></sourcecode>
        <t>Server implementations of draft versions of the protocol <bcp14>MUST NOT</bcp14> send a <tt>104 (Upload Resumption Supported)</tt> informational response when the interop version indicated by the <tt>Upload-Draft-Interop-Version</tt> header field in the request is missing or mismatching.</t>
        <t>Server implementations of draft versions of the protocol <bcp14>MUST</bcp14> also send a header field <tt>Upload-Draft-Interop-Version</tt> with the interop version as its value to the <tt>104 (Upload Resumption Supported)</tt> informational response.</t>
        <t>Client implementations of draft versions of the protocol <bcp14>MUST</bcp14> ignore a <tt>104 (Upload Resumption Supported)</tt> informational response with missing or mismatching interop version indicated by the <tt>Upload-Draft-Interop-Version</tt> header field.</t>
        <t>The reason both the client and the server are sending and checking the draft version is to ensure that implementations of the final RFC will not accidentally interop with draft implementations, as they will not check the existence of the <tt>Upload-Draft-Interop-Version</tt> header field.</t>
      </section>
    </section>
    <section anchor="offset-retrieving">
      <name>Offset Retrieving Procedure</name>
      <t>If an upload is interrupted, the client <bcp14>MAY</bcp14> attempt to fetch the offset of the incomplete upload by sending a <tt>HEAD</tt> request to the server with the same <tt>Upload-Token</tt> header field (<xref target="upload-token"/>). The client <bcp14>MUST NOT</bcp14> initiate this procedure without the knowledge of server support.</t>
      <t>The request <bcp14>MUST</bcp14> use the <tt>HEAD</tt> method and include the <tt>Upload-Token</tt> header. The request <bcp14>MUST NOT</bcp14> include the <tt>Upload-Offset</tt> header or the <tt>Upload-Incomplete</tt> header. The server <bcp14>MUST</bcp14> reject the request with the <tt>Upload-Offset</tt> header or the <tt>Upload-Incomplete</tt> header by sending a <tt>400 (Bad Request)</tt> response.</t>
      <t>If the server considers the upload associated with this token active, it <bcp14>MUST</bcp14> send back a <tt>204 (No Content)</tt> response. The response <bcp14>MUST</bcp14> include the <tt>Upload-Offset</tt> header set to the current resumption offset for the client. The response <bcp14>MUST</bcp14> include the <tt>Upload-Incomplete</tt> header which is set to true if and only if the upload is incomplete. An upload is considered complete if and only if the server completely and successfully received a corresponding Upload Transfer Procedure (<xref target="upload-transfer"/>) request with the <tt>Upload-Incomplete</tt> header being omitted or set to false.</t>
      <t>The client <bcp14>MUST NOT</bcp14> perform the Offset Retrieving Procedure (<xref target="offset-retrieving"/>) while the Upload Transfer Procedures (<xref target="upload-transfer"/>) is in progress.</t>
      <t>The offset <bcp14>MUST</bcp14> be accepted by a subsequent Upload Transfer Procedure (<xref target="upload-transfer"/>). Due to network delay and reordering, the server might still be receiving data from an ongoing transfer for the same token, which in the client perspective has failed. The server <bcp14>MAY</bcp14> terminate any transfers for the same token before sending the response by abruptly terminating the HTTP connection or stream. Alternatively, the server <bcp14>MAY</bcp14> keep the ongoing transfer alive but ignore further bytes received past the offset.</t>
      <t>The client <bcp14>MUST NOT</bcp14> start more than one Upload Transfer Procedures (<xref target="upload-transfer"/>) based on the resumption offset from a single Offset Retrieving Procedure (<xref target="offset-retrieving"/>).</t>
      <t>The response <bcp14>SHOULD</bcp14> include <tt>Cache-Control: no-store</tt> header to prevent HTTP caching.</t>
      <t>If the server does not consider the upload associated with this token active, it <bcp14>MUST</bcp14> respond with <tt>404 (Not Found)</tt> status code.</t>
      <artwork><![CDATA[
:method: HEAD
:scheme: https
:authority: example.com
:path: /upload
upload-token: :SGVs…SGU=:
upload-draft-interop-version: 1

:status: 204
upload-offset: 100
cache-control: no-store
]]></artwork>
      <t>The client <bcp14>MAY</bcp14> automatically start uploading from the beginning using Upload Transfer Procedure (<xref target="upload-transfer"/>) if <tt>404 (Not Found)</tt> status code is received. The client <bcp14>SHOULD NOT</bcp14> automatically retry if a status code other than 204 and 404 is received.</t>
    </section>
    <section anchor="upload-cancellation">
      <name>Upload Cancellation Procedure</name>
      <t>If the client wants to terminate the transfer without the ability to resume, it <bcp14>MAY</bcp14> send a <tt>DELETE</tt> request to the server along with the <tt>Upload-Token</tt> which is an indication that the client is no longer interested in uploading this body and the server can release resources associated with this token. The client <bcp14>MUST NOT</bcp14> initiate this procedure without the knowledge of server support.</t>
      <t>The request <bcp14>MUST</bcp14> use the <tt>DELETE</tt> method and include the <tt>Upload-Token</tt> header. The request <bcp14>MUST NOT</bcp14> include the <tt>Upload-Offset</tt> header or the <tt>Upload-Incomplete</tt> header. The server <bcp14>MUST</bcp14> reject the request with the <tt>Upload-Offset</tt> header or the <tt>Upload-Incomplete</tt> header by sending a <tt>400 (Bad Request)</tt> response.</t>
      <t>If the server has successfully deactivated this token, it <bcp14>MUST</bcp14> send back a <tt>204 (No Content)</tt> response.</t>
      <t>The server <bcp14>MAY</bcp14> terminate any ongoing Upload Transfer Procedure (<xref target="upload-transfer"/>) for the same token before sending the response by abruptly terminating the HTTP connection or stream.</t>
      <t>If the server does not consider the upload associated with this token active, it <bcp14>MUST</bcp14> respond with <tt>404 (Not Found)</tt> status code.</t>
      <t>If the server does not support cancellation, it <bcp14>MUST</bcp14> respond with <tt>405 (Method Not Allowed)</tt> status code.</t>
      <sourcecode type="example"><![CDATA[
:method: DELETE
:scheme: https
:authority: example.com
:path: /upload
upload-token: :SGVs…SGU=:
upload-draft-interop-version: 1

:status: 204
]]></sourcecode>
    </section>
    <section anchor="header-fields">
      <name>Header Fields</name>
      <section anchor="upload-token">
        <name>Upload-Token</name>
        <t>The <tt>Upload-Token</tt> request header field is an Item Structured Header (see <xref section="3.3" sectionFormat="of" target="STRUCTURED-FIELDS"/>) carrying the token used for identification of a specific upload. Its value <bcp14>MUST</bcp14> be a byte sequence. Its ABNF is</t>
        <sourcecode type="abnf"><![CDATA[
Upload-Token = sf-binary
]]></sourcecode>
        <t>If not otherwise specified by the server, the client is <bcp14>RECOMMENDED</bcp14> to use 256-bit (32 bytes) cryptographically-secure random binary data as the value of the <tt>Upload-Token</tt>, in order to ensure that it is globally unique and non-guessable.</t>
        <t>A conforming implementation <bcp14>MUST</bcp14> be able to handle a <tt>Upload-Token</tt> field value of at least 128 octets.</t>
      </section>
      <section anchor="upload-offset">
        <name>Upload-Offset</name>
        <t>The <tt>Upload-Offset</tt> request and response header field is an Item Structured Header indicating the resumption offset of corresponding upload, counted in bytes. Its value <bcp14>MUST</bcp14> be an integer. Its ABNF is</t>
        <sourcecode type="abnf"><![CDATA[
Upload-Offset = sf-integer
]]></sourcecode>
      </section>
      <section anchor="upload-incomplete">
        <name>Upload-Incomplete</name>
        <t>The <tt>Upload-Incomplete</tt> request and response header field is an Item Structured Header indicating whether the corresponding upload is considered complete. Its value <bcp14>MUST</bcp14> be a boolean. Its ABNF is</t>
        <sourcecode type="abnf"><![CDATA[
Upload-Incomplete = sf-boolean
]]></sourcecode>
      </section>
    </section>
    <section anchor="redirection">
      <name>Redirection</name>
      <t>The <tt>301 (Moved Permanently)</tt> status code and the <tt>302 (Found)</tt> status code <bcp14>MUST NOT</bcp14> be used in Offset Retrieving Procedure (<xref target="offset-retrieving"/>) and Upload Cancellation Procedure (<xref target="upload-cancellation"/>) responses. A <tt>308 (Permanent Redirect)</tt> response <bcp14>MAY</bcp14> be persisted for all subsequent procedures. If client receives a <tt>307 (Temporary Redirect)</tt> response in the Offset Retrieving Procedure (<xref target="offset-retrieving"/>), it <bcp14>MAY</bcp14> apply the redirection directly in the immediate subsequent Upload Transfer Procedure (<xref target="upload-transfer"/>).</t>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>The tokens inside the <tt>Upload-Token</tt> header field can be selected by the client which has no knowledge of tokens picked by other client, so uniqueness cannot be guaranteed. If the token is guessable, an attacker can append malicious data to ongoing uploads. To mitigate these issues, 256-bit cryptographically-secure random binary data is recommended for the token.</t>
      <t>It is <bcp14>OPTIONAL</bcp14> for the server to partition upload tokens based on client identity established through other channels, such as Cookie or TLS client authentication. The client <bcp14>MAY</bcp14> relax the token strength if it is aware of server-side partitioning.</t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This specification registers the following entry in the Permanent Message Header Field Names registry established by <xref target="RFC3864"/>:</t>
      <t>Header field name: Upload-Token, Upload-Offset, Upload-Incomplete</t>
      <t>Applicable protocol: http</t>
      <t>Status: standard</t>
      <t>Author/change controller: IETF</t>
      <t>Specification: This document</t>
      <t>Related information: n/a</t>
      <t>This specification registers the following entry in the "HTTP Status Codes" registry:</t>
      <t>Code: 104</t>
      <t>Description: Upload Resumption Supported</t>
      <t>Specification: This document</t>
    </section>
  </middle>
  <back>
    <references>
      <name>Normative References</name>
      <reference anchor="RFC2119">
        <front>
          <title>Key words for use in RFCs to Indicate Requirement Levels</title>
          <author fullname="S. Bradner" initials="S." surname="Bradner">
            <organization/>
          </author>
          <date month="March" year="1997"/>
          <abstract>
            <t>In many standards track documents several words are used to signify the requirements in the specification.  These words are often capitalized. This document defines these words as they should be interpreted in IETF documents.  This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
          </abstract>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="2119"/>
        <seriesInfo name="DOI" value="10.17487/RFC2119"/>
      </reference>
      <reference anchor="HTTP">
        <front>
          <title>HTTP Semantics</title>
          <author fullname="Roy T. Fielding">
            <organization>Adobe</organization>
          </author>
          <author fullname="Mark Nottingham">
            <organization>Fastly</organization>
          </author>
          <author fullname="Julian Reschke">
            <organization>greenbytes GmbH</organization>
          </author>
          <date day="12" month="September" year="2021"/>
          <abstract>
            <t>   The Hypertext Transfer Protocol (HTTP) is a stateless application-
   level protocol for distributed, collaborative, hypertext information
   systems.  This document describes the overall architecture of HTTP,
   establishes common terminology, and defines aspects of the protocol
   that are shared by all versions.  In this definition are core
   protocol elements, extensibility mechanisms, and the "http" and
   "https" Uniform Resource Identifier (URI) schemes.

   This document updates RFC 3864 and obsoletes RFC 2818, RFC 7231, RFC
   7232, RFC 7233, RFC 7235, RFC 7538, RFC 7615, RFC 7694, and portions
   of RFC 7230.

            </t>
          </abstract>
        </front>
        <seriesInfo name="Internet-Draft" value="draft-ietf-httpbis-semantics-19"/>
      </reference>
      <reference anchor="RFC8174">
        <front>
          <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
          <author fullname="B. Leiba" initials="B." surname="Leiba">
            <organization/>
          </author>
          <date month="May" year="2017"/>
          <abstract>
            <t>RFC 2119 specifies common key words that may be used in protocol  specifications.  This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the  defined special meanings.</t>
          </abstract>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="8174"/>
        <seriesInfo name="DOI" value="10.17487/RFC8174"/>
      </reference>
      <reference anchor="STRUCTURED-FIELDS">
        <front>
          <title>Structured Field Values for HTTP</title>
          <author fullname="M. Nottingham" initials="M." surname="Nottingham">
            <organization/>
          </author>
          <author fullname="P-H. Kamp" initials="P-H." surname="Kamp">
            <organization/>
          </author>
          <date month="February" year="2021"/>
          <abstract>
            <t>This document describes a set of data types and associated algorithms that are intended to make it easier and safer to define and handle HTTP header and trailer fields, known as "Structured Fields", "Structured Headers", or "Structured Trailers". It is intended for use by specifications of new HTTP fields that wish to use a common syntax that is more restrictive than traditional HTTP field values.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="8941"/>
        <seriesInfo name="DOI" value="10.17487/RFC8941"/>
      </reference>
      <reference anchor="RFC3864">
        <front>
          <title>Registration Procedures for Message Header Fields</title>
          <author fullname="G. Klyne" initials="G." surname="Klyne">
            <organization/>
          </author>
          <author fullname="M. Nottingham" initials="M." surname="Nottingham">
            <organization/>
          </author>
          <author fullname="J. Mogul" initials="J." surname="Mogul">
            <organization/>
          </author>
          <date month="September" year="2004"/>
          <abstract>
            <t>This specification defines registration procedures for the message header fields used by Internet mail, HTTP, Netnews and other applications.  This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
          </abstract>
        </front>
        <seriesInfo name="BCP" value="90"/>
        <seriesInfo name="RFC" value="3864"/>
        <seriesInfo name="DOI" value="10.17487/RFC3864"/>
      </reference>
    </references>
    <section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>TODO acknowledge.</t>
    </section>
    <section numbered="false" anchor="appendix">
      <name>Appendix</name>
      <section numbered="false" anchor="informational-response">
        <name>Informational Response</name>
        <t>The server is allowed to respond to Upload Transfer Procedure (<xref target="upload-transfer"/>) requests with a <tt>104 (Upload Resumption Supported)</tt> intermediate response as soon as the server has validated the request. This way, the client knows that the server supports resumable uploads before the complete response for the Upload Transfer Procedure is received. The benefit is the clients can defer starting the actual data transfer until the server indicates full support of the incoming Upload Transfer Procedure (i.e. resumable are supported, the provided upload token is active etc).</t>
        <t>On the contrary, support for intermediate responses (the <tt>1XX</tt> range) in existing software is limited or not at all present. Such software includes proxies, firewalls, browsers, and HTTP libraries for clients and server. Therefore, the <tt>104 (Upload Resumption Supported)</tt> status code is optional and not mandatory for the successful completion of an upload. Otherwise, it might be impossible in some cases to implement resumable upload servers using existing software packages. Furthermore, as parts of the current internet infrastructure currently have limited support for intermediate responses, a successful delivery of a <tt>104 (Upload Resumption Supported)</tt> from the server to the client should be assumed.</t>
        <t>We hope that support for intermediate responses increases in the near future, to allow a wider usage of <tt>104 (Upload Resumption Supported)</tt>.</t>
      </section>
      <section numbered="false" anchor="feature-detection-1">
        <name>Feature Detection</name>
        <t>This specification includes a section about feature detection (it was called service discovery in earlier discussions, but this name is probably ill-suited). The idea is to allow resumable uploads to be transparently implemented by HTTP clients. This means that application developers just keep using the same API of their HTTP library as they have done in the past with traditional, non-resumable uploads. Once the HTTP library gets updated (e.g. because mobile OS or browsers start implementing resumable uploads), the HTTP library can transparently decide to use resumable uploads without explicit configuration by the application developer. Of course, in order to use resumable uploads, the HTTP library needs to know whether the server supports resumable uploads. If no support is detected, the HTTP library should use the traditional, non-resumable upload technique. We call this process feature detection.</t>
        <t>Ideally, the technique used for feature detection meets following <strong>criteria</strong> (there might not be one approach which fits all requirements, so we have to prioritize them):</t>
        <ol spacing="normal" type="1"><li>Avoid additional roundtrips by the client, if possible (i.e. an additional HTTP request by the client should be avoided).</li>
          <li>Be backwards compatible to HTTP/1.1 and existing network infrastructure: This means to avoid using new features in HTTP/2, or features which might require changes to existing network infrastructure (e.g. nginx or HTTP libraries)</li>
          <li>Conserve the user's privacy (i.e. the feature detection should not leak information to other third-parties about which URLs have been connected to)</li>
        </ol>
        <t>Following <strong>approaches</strong> have already been considered in the past. All except the last approaches have not been deemed acceptable and are therefore not included in the specification. This follow list is a reference for the advantages and disadvantages of some approaches:</t>
        <t><strong>Include a support statement in the SETTINGS frame.</strong> The SETTINGS frame is a HTTP/2 feature and is sent by the server to the client to exchange information about the current connection. The idea was to include an additional statement in this frame, so the client can detect support for resumable uploads without an additional roundtrip. The problem is that this is not compatible with HTTP/1.1. Furthermore, the SETTINGS frame is intended for information about the current connection (not bound to a request/response) and might not be persisted when transmitted through a proxy.</t>
        <t><strong>Include a support statement in the DNS record.</strong> The client can detect support when resolving a domain name. Of course, DNS is not semantically the correct layer. Also, DNS might not be involved if the record is cached or retrieved from a hosts files.</t>
        <t><strong>Send a HTTP request to ask for support.</strong> This is the easiest approach where the client sends an OPTIONS request and uses the response to determine if the server indicates support for resumable uploads. An alternative is that the client sends the request to a well-known URL to obtain this response, e.g. <tt>/.well-known/resumable-uploads</tt>. Of course, while being fully backwards-compatible, it requires an additional roundtrip.</t>
        <t><strong>Include a support statement in previous responses.</strong> In many cases, the file upload is not the first time that the client connects to the server. Often additional requests are sent beforehand for authentication, data retrieval etc. The responses for those requests can also include a header which indicates support for resumable uploads. There are two options:
- Use the standardized <tt>Alt-Svc</tt> response header. However, it has been indicated to us that this header might be reworked in the future and could also be semantically different from our intended usage.
- Use a new response header <tt>Resumable-Uploads: https://example.org/files/*</tt> to indicate under which endpoints support for resumable uploads is available.</t>
        <t><strong>Send a 104 intermediate response to indicate support.</strong> The clients normally starts a traditional upload and includes a header indicate that it supports resumable uploads (e.g. <tt>Upload-Offset: 0</tt>). If the server also supports resumable uploads, it will immediately respond with a 104 intermediate response to indicate its support, before further processing the request. This way the client is informed during the upload whether it can resume from possible connection errors or not. While an additional roundtrip is avoided, the problem with that solution is that many HTTP server libraries do not support sending custom 1XX responses and that some proxies may not be able to handle new 1XX status codes correctly.</t>
        <t><strong>Send a 103 Early Hint response to indicate support.</strong> This approach is the similar to the above one, with one exception: Instead of a new <tt>104 (Upload Resumption Supported)</tt> status code, the existing <tt>103 (Early Hint)</tt> status code is used in the intermediate response. The 103 code would then be accompanied by a header indicating support for resumable uploads (e.g. <tt>Resumable-Uploads: 1</tt>). It is unclear whether the Early Hints code is appropriate for that, as it is currently only used to indicate resources for prefetching them.</t>
      </section>
      <section numbered="false" anchor="upload-metadata">
        <name>Upload Metadata</name>
        <t>The Upload Transfer Procedure (<xref target="upload-transfer"/>) allows the <tt>Content-Type</tt> and <tt>Content-Disposition</tt> header to be included. They are intended to be a standardized way of communicating the file name and file type, if available. However, this is not without controversy. Some argue that since these headers are already defined in other specifications, it is not necessary to include them here again. Furthermore, the <tt>Content-Disposition</tt> header field's format is not clearly enough defined. For example, it is left open which disposition value should be used in the header. There needs to be more discussion whether this approach is suited or not.</t>
        <t>However, from experience with the tus project, users are often asking for a way to communicate the file name and file type. Therefore, we believe it is help to explicitly include an approach for doing so.</t>
      </section>
      <section numbered="false" anchor="faq">
        <name>FAQ</name>
        <ul spacing="normal">
          <li>
            <strong>Are multipart requests supported?</strong> Yes, requests whose body is encoded using the <tt>multipart/form-data</tt> are implicitly supported. The entire encoded body can be considered as a single file, which is then uploaded using the resumable protocol. The server, of course, must store the delimiter ("boundary") separating each part and must be able to parse the multipart format once the upload is completed.</li>
        </ul>
      </section>
    </section>
  </back>
  <!-- ##markdown-source:
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
wru8E4l7kgpxVRgzLt261CnWEfFX6n5xFJnd4S6Qa2e8SpG4cpbOWV4e5o2V
4WFfeS9OR4RImS/iRrfhNWLA2PsAJ97n6JrN4AznHXA8XgO+QTjWag/9sJ+N
LYUFfVfPNOTetCV5gX+P3Bq2lr/nXA/d6gdF5C5msFITIuvU7I/kDoEfEQd0
5DR15rem8J/3ZN40BLcV24bwiQyCEuxqSiVyB7EAoXtVnBSHvk1JgzdPbhxg
zTgcWJVLeMYmYAh22GALV4Laqupr+UoGJ5uqx6weFKbBNn+YQa753CpDaj61
IQhOl/1UHIeZ2/44tuGGqNmFi6y6Zin9kKkrGi1CAQBwR/8+kiX5H4J45vY4
ro+jDgSnpU4qLhoRekLodcOh9qHtcdCBriLh2t4Zs2aZ1QWCzqlwC0SCqEOL
tiJrj8M9Qa+hOow7bUFRtuBWXARGML8FsnGfmtIFrbrcSBKVuWT7FoTghJtA
3DrnhIedHmrQSybIYqsyxxaREyrJCbN7rZHJB6Ktvv1JmRpbJcCNEizQ+HGR
AZTUP0JkIHThPxqKZSQE4aQL4Wt48RnBeEiqsLLF5hS9pKIrrh+5KfMGeXEp
aD/JaR+OIx2bkDpQmpOrHv4bu+ddBuaW2heXhRmVvnQ9L67cP06rcLQfKoN6
nuWAE975xPgHB2DtYEkd3KLCYofVZV/0iRroBL92ZhDVwHbq0yhSqXAk25IN
JmLHuD9yohRyrHXMHi7Osy4ZW060ndD+8ZqzBeE/defr6c4obSNdLTXEHLlT
gzvImyvLcSLMD5iE9QOI+p+EmNmyBBtdCNnS9hk+UzsvmBJwogPOShuSaP2Y
N1PSjy7bSGDdVc8Y0Z+iiV6TRzmkZEa2DnFb8opde8QgsTmXOqZayhbtGxm9
1y6Vgqi9XlvcGKaqNhaT+LS7TVAi77KkryQupHrk3HROu49biF3hpeUiji99
ZzGG1NHWvBnrErPV0bFQGMjN2f/s5zB0o3Ye7kvqgEqqzboBC0Wvz1gET2qT
UEgWGC2oCbwSNgrYFRWk2fROaBxFFSIPGa1pmZdzkvOcg03MHJNjly0GHOY5
ou4B0iTabOQOjNxhHrDSQwEUgjQnb2SMKIwZbqEwP0q4Ru3tf67KpDHUQMhj
HHPnGOUsx7Y4x6aUMKHrI6AV3J6N9fOnYwvaBt+46zDJcTqrQQTjbktLFEuX
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

-->

</rfc>
