<?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-rfc version 1.7.1 (Ruby 3.2.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ietf-httpbis-resumable-upload-02" category="std" consensus="true" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.18.2 -->
  <front>
    <title abbrev="Resumable Uploads">Resumable Uploads for HTTP</title>
    <seriesInfo name="Internet-Draft" value="draft-ietf-httpbis-resumable-upload-02"/>
    <author initials="M." surname="Kleidl" fullname="Marius Kleidl" role="editor">
      <organization>Transloadit Ltd</organization>
      <address>
        <email>marius@transloadit.com</email>
      </address>
    </author>
    <author initials="G." surname="Zhang" fullname="Guoye Zhang" role="editor">
      <organization>Apple Inc.</organization>
      <address>
        <email>guoye_zhang@apple.com</email>
      </address>
    </author>
    <author initials="L." surname="Pardue" fullname="Lucas Pardue" role="editor">
      <organization>Cloudflare</organization>
      <address>
        <email>lucaspardue.24.7@gmail.com</email>
      </address>
    </author>
    <date year="2023" month="October" day="19"/>
    <area>ART</area>
    <workgroup>HTTP</workgroup>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <?line 52?>

<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>About This Document</name>
      <t>
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-ietf-httpbis-resumable-upload/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        HTTP Working Group mailing list (<eref target="mailto:ietf-http-wg@w3.org"/>),
        which is archived at <eref target="https://lists.w3.org/Archives/Public/ietf-http-wg/"/>.
        Working Group information can be found at <eref target="https://httpwg.org/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/httpwg/http-extensions/labels/resumable-upload"/>.</t>
    </note>
  </front>
  <middle>
    <?line 56?>

<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 an optional mechanism for HTTP than enables resumable uploads in a way 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. Different from ranged downloads, this protocol does not support transferring different parts of the same representation in parallel.</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>
      <?line -18?>

<t>The terms Byte Sequence, Item, String, Token, Integer, and Boolean are imported from
<xref target="STRUCTURED-FIELDS"/>.</t>
      <t>The terms client and server are from <xref target="HTTP"/>.</t>
    </section>
    <section anchor="overview">
      <name>Overview</name>
      <t>Resumable uploads are supported in HTTP through use of a temporary resource, an <em>upload resource</em>, that is separate from the resource being uploaded to (hereafter, the <em>target resource</em>) and specific to that upload. By interacting with the upload resource, a client can retrieve the current offset of the upload (<xref target="offset-retrieving"/>), append to the upload (<xref target="upload-appending"/>), and cancel the upload (<xref target="upload-cancellation"/>).</t>
      <t>The remainder of this section uses an example of a file upload to illustrate different interactions with the upload resource. Note, however, that HTTP message exchanges use representation data (see <xref section="8.1" sectionFormat="of" target="HTTP"/>), which means that resumable uploads can be used with many forms of content -- not just static files.</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 to the target resource. An interruption occurs and the client then attempts to resume the upload using subsequent HTTP requests to the upload resource.</t>
        <t>1) The client notifies the server that it wants to begin an upload (<xref target="upload-creation"/>). The server reserves the required resources to accept the upload from the client, and the client begins transferring the entire file in the request content.</t>
        <t>An informational response can be sent to the client, which signals the server's support of resumable upload as well as the upload resource URL via the Location header field (<xref section="10.2.2" sectionFormat="of" target="HTTP"/>).</t>
        <figure anchor="fig-upload-creation">
          <name>Upload Creation</name>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="320" width="520" viewBox="0 0 520 320" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 8,48 L 8,304" fill="none" stroke="black"/>
                <path d="M 368,48 L 368,304" fill="none" stroke="black"/>
                <path d="M 16,80 L 360,80" fill="none" stroke="black"/>
                <path d="M 376,144 L 512,144" fill="none" stroke="black"/>
                <path d="M 376,176 L 512,176" fill="none" stroke="black"/>
                <path d="M 16,240 L 360,240" fill="none" stroke="black"/>
                <path d="M 16,288 L 360,288" fill="none" stroke="black"/>
                <polygon class="arrowhead" points="384,176 372,170.4 372,181.6" fill="black" transform="rotate(180,376,176)"/>
                <polygon class="arrowhead" points="368,288 356,282.4 356,293.6" fill="black" transform="rotate(0,360,288)"/>
                <polygon class="arrowhead" points="368,80 356,74.4 356,85.6" fill="black" transform="rotate(0,360,80)"/>
                <polygon class="arrowhead" points="24,240 12,234.4 12,245.6" fill="black" transform="rotate(180,16,240)"/>
                <g class="text">
                  <text x="28" y="36">Client</text>
                  <text x="348" y="36">Server</text>
                  <text x="36" y="68">POST</text>
                  <text x="408" y="116">Reserve</text>
                  <text x="480" y="116">resources</text>
                  <text x="392" y="132">for</text>
                  <text x="436" y="132">upload</text>
                  <text x="512" y="164">|</text>
                  <text x="120" y="212">104</text>
                  <text x="164" y="212">Upload</text>
                  <text x="236" y="212">Resumption</text>
                  <text x="320" y="212">Supported</text>
                  <text x="124" y="228">with</text>
                  <text x="172" y="228">upload</text>
                  <text x="232" y="228">resouce</text>
                  <text x="280" y="228">URL</text>
                  <text x="36" y="276">Flow</text>
                  <text x="104" y="276">Interrupted</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
Client                                  Server
|                                            |
| POST                                       |
|------------------------------------------->|
|                                            |
|                                            | Reserve resources
|                                            | for upload
|                                            |------------------
|                                            |                 |
|                                            |<-----------------
|                                            |
|            104 Upload Resumption Supported |
|            with upload resouce URL         |
|<-------------------------------------------|
|                                            |
| Flow Interrupted                           |
|------------------------------------------->|
|                                            |
]]></artwork>
          </artset>
        </figure>
        <t>2) If the connection to the server is interrupted, the client might want to resume the upload. However, before this is possible the client needs to know the amount of data that the server received before the interruption. It does so by retrieving the offset (<xref target="offset-retrieving"/>) from the upload resource.</t>
        <figure anchor="fig-offset-retrieving">
          <name>Offset Retrieval</name>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="160" width="416" viewBox="0 0 416 160" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 8,48 L 8,144" fill="none" stroke="black"/>
                <path d="M 408,48 L 408,144" fill="none" stroke="black"/>
                <path d="M 16,80 L 400,80" fill="none" stroke="black"/>
                <path d="M 16,128 L 400,128" fill="none" stroke="black"/>
                <polygon class="arrowhead" points="408,80 396,74.4 396,85.6" fill="black" transform="rotate(0,400,80)"/>
                <polygon class="arrowhead" points="24,128 12,122.4 12,133.6" fill="black" transform="rotate(180,16,128)"/>
                <g class="text">
                  <text x="28" y="36">Client</text>
                  <text x="388" y="36">Server</text>
                  <text x="36" y="68">HEAD</text>
                  <text x="68" y="68">to</text>
                  <text x="108" y="68">upload</text>
                  <text x="172" y="68">resource</text>
                  <text x="224" y="68">URL</text>
                  <text x="144" y="116">204</text>
                  <text x="172" y="116">No</text>
                  <text x="216" y="116">Content</text>
                  <text x="268" y="116">with</text>
                  <text x="344" y="116">Upload-Offset</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
Client                                       Server
|                                                 |
| HEAD to upload resource URL                     |
|------------------------------------------------>|
|                                                 |
|               204 No Content with Upload-Offset |
|<------------------------------------------------|
|                                                 |
]]></artwork>
          </artset>
        </figure>
        <t>3) The client can resume the upload by sending the remaining file content to the upload resource (<xref target="upload-appending"/>), 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-upload-appending">
          <name>Upload Append</name>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="160" width="416" viewBox="0 0 416 160" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 8,48 L 8,144" fill="none" stroke="black"/>
                <path d="M 408,48 L 408,144" fill="none" stroke="black"/>
                <path d="M 16,80 L 400,80" fill="none" stroke="black"/>
                <path d="M 16,128 L 400,128" fill="none" stroke="black"/>
                <polygon class="arrowhead" points="408,80 396,74.4 396,85.6" fill="black" transform="rotate(0,400,80)"/>
                <polygon class="arrowhead" points="24,128 12,122.4 12,133.6" fill="black" transform="rotate(180,16,128)"/>
                <g class="text">
                  <text x="28" y="36">Client</text>
                  <text x="388" y="36">Server</text>
                  <text x="40" y="68">PATCH</text>
                  <text x="76" y="68">to</text>
                  <text x="116" y="68">upload</text>
                  <text x="180" y="68">resource</text>
                  <text x="232" y="68">URL</text>
                  <text x="268" y="68">with</text>
                  <text x="344" y="68">Upload-Offset</text>
                  <text x="200" y="116">201</text>
                  <text x="248" y="116">Created</text>
                  <text x="292" y="116">on</text>
                  <text x="348" y="116">completion</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
Client                                       Server
|                                                 |
| PATCH to upload resource URL with Upload-Offset |
|------------------------------------------------>|
|                                                 |
|                      201 Created on completion  |
|<------------------------------------------------|
|                                                 |
]]></artwork>
          </artset>
        </figure>
        <t>4) If the client is not interested in completing the upload, it can instruct the upload resource to delete the upload and free all related resources (<xref target="upload-cancellation"/>).</t>
        <figure anchor="fig-upload-cancellation">
          <name>Upload Cancellation</name>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="160" width="416" viewBox="0 0 416 160" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 8,48 L 8,144" fill="none" stroke="black"/>
                <path d="M 408,48 L 408,144" fill="none" stroke="black"/>
                <path d="M 16,80 L 400,80" fill="none" stroke="black"/>
                <path d="M 16,128 L 400,128" fill="none" stroke="black"/>
                <polygon class="arrowhead" points="408,80 396,74.4 396,85.6" fill="black" transform="rotate(0,400,80)"/>
                <polygon class="arrowhead" points="24,128 12,122.4 12,133.6" fill="black" transform="rotate(180,16,128)"/>
                <g class="text">
                  <text x="28" y="36">Client</text>
                  <text x="388" y="36">Server</text>
                  <text x="44" y="68">DELETE</text>
                  <text x="84" y="68">to</text>
                  <text x="124" y="68">upload</text>
                  <text x="188" y="68">resource</text>
                  <text x="240" y="68">URL</text>
                  <text x="184" y="116">204</text>
                  <text x="212" y="116">No</text>
                  <text x="256" y="116">Content</text>
                  <text x="300" y="116">on</text>
                  <text x="356" y="116">completion</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
Client                                       Server
|                                                 |
| DELETE to upload resource URL                   |
|------------------------------------------------>|
|                                                 |
|                    204 No Content on completion |
|<------------------------------------------------|
|                                                 |
]]></artwork>
          </artset>
        </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 serially 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 incrementally.</t>
        <t>1) If the client is aware that the server supports resumable upload, it can start an upload with the <tt>Upload-Complete</tt> field value set to false and the first part of the file.</t>
        <figure anchor="fig-upload-creation-incomplete">
          <name>Incomplete Upload Creation</name>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="176" width="416" viewBox="0 0 416 176" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 8,48 L 8,160" fill="none" stroke="black"/>
                <path d="M 408,48 L 408,160" fill="none" stroke="black"/>
                <path d="M 16,80 L 400,80" fill="none" stroke="black"/>
                <path d="M 16,144 L 400,144" fill="none" stroke="black"/>
                <polygon class="arrowhead" points="408,80 396,74.4 396,85.6" fill="black" transform="rotate(0,400,80)"/>
                <polygon class="arrowhead" points="24,144 12,138.4 12,149.6" fill="black" transform="rotate(180,16,144)"/>
                <g class="text">
                  <text x="28" y="36">Client</text>
                  <text x="388" y="36">Server</text>
                  <text x="36" y="68">POST</text>
                  <text x="76" y="68">with</text>
                  <text x="164" y="68">Upload-Complete:</text>
                  <text x="244" y="68">?0</text>
                  <text x="120" y="116">201</text>
                  <text x="168" y="116">Created</text>
                  <text x="220" y="116">with</text>
                  <text x="308" y="116">Upload-Complete:</text>
                  <text x="388" y="116">?0</text>
                  <text x="120" y="132">and</text>
                  <text x="172" y="132">Location</text>
                  <text x="220" y="132">on</text>
                  <text x="276" y="132">completion</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
Client                                       Server
|                                                 |
| POST with Upload-Complete: ?0                   |
|------------------------------------------------>|
|                                                 |
|            201 Created with Upload-Complete: ?0 |
|            and Location on completion           |
|<------------------------------------------------|
|                                                 |
]]></artwork>
          </artset>
        </figure>
        <t>2) Subsequently, parts are appended (<xref target="upload-appending"/>). The last part of the upload has a <tt>Upload-Complete</tt> field value set to true to indicate the complete transfer.</t>
        <figure anchor="fig-upload-appending-last-chunk">
          <name>Upload Append Last Chunk</name>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="176" width="416" viewBox="0 0 416 176" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 8,48 L 8,160" fill="none" stroke="black"/>
                <path d="M 408,48 L 408,160" fill="none" stroke="black"/>
                <path d="M 16,96 L 400,96" fill="none" stroke="black"/>
                <path d="M 16,144 L 400,144" fill="none" stroke="black"/>
                <polygon class="arrowhead" points="408,96 396,90.4 396,101.6" fill="black" transform="rotate(0,400,96)"/>
                <polygon class="arrowhead" points="24,144 12,138.4 12,149.6" fill="black" transform="rotate(180,16,144)"/>
                <g class="text">
                  <text x="28" y="36">Client</text>
                  <text x="388" y="36">Server</text>
                  <text x="40" y="68">PATCH</text>
                  <text x="76" y="68">to</text>
                  <text x="116" y="68">upload</text>
                  <text x="180" y="68">resource</text>
                  <text x="232" y="68">URL</text>
                  <text x="268" y="68">with</text>
                  <text x="72" y="84">Upload-Offset</text>
                  <text x="144" y="84">and</text>
                  <text x="228" y="84">Upload-Complete:</text>
                  <text x="308" y="84">?1</text>
                  <text x="208" y="132">201</text>
                  <text x="256" y="132">Created</text>
                  <text x="300" y="132">on</text>
                  <text x="356" y="132">completion</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
Client                                       Server
|                                                 |
| PATCH to upload resource URL with               |
| Upload-Offset and Upload-Complete: ?1           |
|------------------------------------------------>|
|                                                 |
|                       201 Created on completion |
|<------------------------------------------------|
|                                                 |
]]></artwork>
          </artset>
        </figure>
      </section>
    </section>
    <section anchor="upload-creation">
      <name>Upload Creation</name>
      <t>When a resource supports resumable uploads, the first step is creating the upload resource. To be compatible with the widest range of resources, this is accomplished by including the <tt>Upload-Complete</tt> header field in the request that initiates the upload.</t>
      <t>As a consequence, resumable uploads support all HTTP request methods that can carry content, such as <tt>POST</tt>, <tt>PUT</tt>, and <tt>PATCH</tt>. Similarly, the response to the upload request can have any status code. Both the method(s) and status code(s) supported are determined by the resource.</t>
      <t><tt>Upload-Complete</tt> <bcp14>MUST</bcp14> be set to false if the end of the request content is not the end of the upload. Otherwise, it <bcp14>MUST</bcp14> be set to true. This header field can be used for request identification by a server. The request <bcp14>MUST NOT</bcp14> include the <tt>Upload-Offset</tt> header field.</t>
      <t>If the request is valid, the server <bcp14>SHOULD</bcp14> create an upload resource. Then, the server <bcp14>MUST</bcp14> include the <tt>Location</tt> header field in the response and set its value to the URL of the upload resource. The client <bcp14>MAY</bcp14> use this URL for offset retrieval (<xref target="offset-retrieving"/>), upload append (<xref target="upload-appending"/>), and upload cancellation (<xref target="upload-cancellation"/>).</t>
      <t>Once the upload resource is available, the target resource <bcp14>MAY</bcp14> send an informational response with a <tt>104 (Upload Resumption Supported)</tt> status code to the client while the request content is being uploaded. In this informational response, the <tt>Location</tt> header field <bcp14>MUST</bcp14> be set to the upload resource.</t>
      <t>The server <bcp14>MUST</bcp14> send the <tt>Upload-Offset</tt> header field 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 <tt>Upload-Offset</tt> field 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 has a status code that indicates a success but the offset indicated in the <tt>Upload-Offset</tt> field value does not equal the total of 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). Servers are <bcp14>RECOMMENDED</bcp14> to use <tt>201 (Created)</tt> unless otherwise specified. The response <bcp14>MUST NOT</bcp14> include the <tt>Upload-Complete</tt> header field with the value of false.</t>
      <t>If the request completes successfully but the entire upload is not yet complete, as indicated by an <tt>Upload-Complete</tt> field value of false in the request, the server <bcp14>MUST</bcp14> acknowledge it by responding with the <tt>201 (Created)</tt> status code and an <tt>Upload-Complete</tt> header value set to false.</t>
      <t>If the request includes an <tt>Upload-Complete</tt> field value set to true and a valid <tt>Content-Length</tt> header field, the client attempts to upload a fixed-length resource in one request. In this case, the upload's final size is the <tt>Content-Length</tt> field value and the server <bcp14>MUST</bcp14> record it to ensure its consistency.</t>
      <sourcecode type="example"><![CDATA[
:method: POST
:scheme: https
:authority: example.com
:path: /upload
upload-draft-interop-version: 4
upload-complete: ?1
content-length: 100
[content (100 bytes)]

:status: 104
upload-draft-interop-version: 4
location: https://example.com/upload/b530ce8ff

:status: 201
location: https://example.com/upload/b530ce8ff
upload-offset: 100
]]></sourcecode>
      <sourcecode type="example"><![CDATA[
:method: POST
:scheme: https
:authority: example.com
:path: /upload
upload-draft-interop-version: 4
upload-complete: ?0
content-length: 25
[partial content (25 bytes)]

:status: 201
location: https://example.com/upload/b530ce8ff
upload-complete: ?0
upload-offset: 25
]]></sourcecode>
      <t>If the client received an informational response with the upload URL in the Location field value, it <bcp14>MAY</bcp14> automatically attempt upload resumption when the connection is terminated unexpectedly, or if a 5xx status is received. The client <bcp14>SHOULD NOT</bcp14> automatically retry if it receives a 4xx status code.</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 request that starts an upload. Servers <bcp14>MAY</bcp14> interpret this metadata or <bcp14>MAY</bcp14> ignore it. The <tt>Content-Type</tt> header field (<xref section="8.3" sectionFormat="of" target="HTTP"/>) can be used to indicate the MIME type of the file. The <tt>Content-Disposition</tt> header field (<xref target="RFC6266"/>) 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 resource supports resumable uploads, a resumable request can be used with some additional constraints. In particular, the <tt>Upload-Complete</tt> field value (<xref target="upload-complete"/>) <bcp14>MUST NOT</bcp14> be false if the server support is unclear. This allows the upload to function as if it is a regular upload.</t>
        <t>Servers <bcp14>SHOULD</bcp14> use the <tt>104 (Upload Resumption Supported)</tt> informational response to indicate their support for a resumable upload request.</t>
        <t>Clients <bcp14>MUST NOT</bcp14> attempt to resume an upload unless they receive <tt>104 (Upload Resumption Supported)</tt> informational response, or have other out-of-band methods to determine server support for resumable uploads.</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 4.</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. The <tt>Upload-Draft-Interop-Version</tt> field value is an Integer.</t>
        <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 Retrieval</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 upload resource.</t>
      <t>The request <bcp14>MUST NOT</bcp14> include an <tt>Upload-Offset</tt> or <tt>Upload-Complete</tt> header field. The server <bcp14>MUST</bcp14> reject requests with either of these fields by responding with a <tt>400 (Bad Request)</tt> status code.</t>
      <t>If the server considers the upload resource to be active, it <bcp14>MUST</bcp14> respond with a <tt>204 (No Content)</tt> status code. The response <bcp14>MUST</bcp14> include the <tt>Upload-Offset</tt> header field, with the value set to the current resumption offset for the target resource. The response <bcp14>MUST</bcp14> include the <tt>Upload-Complete</tt> header field; the value is set to true only if the upload is complete.</t>
      <t>An upload is considered complete only if the server completely and successfully received a corresponding creation request (<xref target="upload-creation"/>) or append request (<xref target="upload-appending"/>) with the <tt>Upload-Complete</tt> header value set to true.</t>
      <t>The client <bcp14>MUST NOT</bcp14> perform offset retrieval while creation (<xref target="upload-creation"/>) or append (<xref target="upload-appending"/>) is in progress.</t>
      <t>The offset <bcp14>MUST</bcp14> be accepted by a subsequent append (<xref target="upload-appending"/>). Due to network delay and reordering, the server might still be receiving data from an ongoing transfer for the same upload resource, which in the client perspective has failed. The server <bcp14>MAY</bcp14> terminate any transfers for the same upload resource 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 append (<xref target="upload-appending"/>) based on the resumption offset from a single offset retrieving (<xref target="offset-retrieving"/>) request.</t>
      <t>In order to prevent HTTP caching, the response <bcp14>SHOULD</bcp14> include a <tt>Cache-Control</tt> header field with the value <tt>no-store</tt>.</t>
      <t>If the server does not consider the upload resource to be active, it <bcp14>MUST</bcp14> respond with a <tt>404 (Not Found)</tt> status code.</t>
      <t>The resumption offset can be less than or equal to the number of bytes the client has already sent. The client <bcp14>MAY</bcp14> reject an offset which is greater than the number of bytes it has already sent during this upload. The client is expected to handle backtracking of a reasonable length. If the offset is invalid for this upload, or if the client cannot backtrack to the offset and reproduce the same content it has already sent, the upload <bcp14>MUST</bcp14> be considered a failure. The client <bcp14>MAY</bcp14> cancel the upload (<xref target="upload-cancellation"/>) after rejecting the offset.</t>
      <artwork><![CDATA[
:method: HEAD
:scheme: https
:authority: example.com
:path: /upload/b530ce8ff
upload-draft-interop-version: 4

:status: 204
upload-offset: 100
upload-complete: ?0
cache-control: no-store
]]></artwork>
      <t>The client <bcp14>SHOULD NOT</bcp14> automatically retry if a client error status code between 400 and 499 (inclusive) is received.</t>
    </section>
    <section anchor="upload-appending">
      <name>Upload Append</name>
      <t>Upload appending is used for resuming an existing upload.</t>
      <t>The request <bcp14>MUST</bcp14> use the <tt>PATCH</tt> method and be sent to the upload resource. The <tt>Upload-Offset</tt> field value (<xref target="upload-offset"/>) <bcp14>MUST</bcp14> be set to the resumption offset.</t>
      <t>If the end of the request content is not the end of the upload, the <tt>Upload-Complete</tt> field value (<xref target="upload-complete"/>) <bcp14>MUST</bcp14> be set to false.</t>
      <t>The server <bcp14>SHOULD</bcp14> respect representation metadata received during creation (<xref target="upload-creation"/>) and ignore any representation metadata received from appending (<xref target="upload-appending"/>).</t>
      <t>If the server does not consider the upload associated with the upload resource active, it <bcp14>MUST</bcp14> respond with a <tt>404 (Not Found)</tt> status code.</t>
      <t>The client <bcp14>MUST NOT</bcp14> perform multiple upload transfers for the same upload resource in parallel. This helps avoid race conditions, and data loss or corruption. The server is <bcp14>RECOMMENDED</bcp14> to take measures to avoid parallel upload transfers: The server <bcp14>MAY</bcp14> terminate any creation (<xref target="upload-creation"/>) or append (<xref target="upload-appending"/>) for the same upload URL. 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 indicated by the <tt>Upload-Offset</tt> field value does not match the offset provided by the immediate previous offset retrieval (<xref target="offset-retrieving"/>), or the end offset of the immediate previous incomplete successful transfer, the server <bcp14>MUST</bcp14> respond with a <tt>409 (Conflict)</tt> status code.</t>
      <t>The server <bcp14>MUST</bcp14> send the <tt>Upload-Offset</tt> header field 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 status code indicates a success but the offset indicated by the <tt>Upload-Offset</tt> field value does not equal the total of 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). Servers are <bcp14>RECOMMENDED</bcp14> to use a <tt>201 (Created)</tt> response if not otherwise specified. The response <bcp14>MUST NOT</bcp14> include the <tt>Upload-Complete</tt> header field with the value set to false.</t>
      <t>If the request completes successfully but the entire upload is not yet complete indicated by the <tt>Upload-Complete</tt> field value set to false, the server <bcp14>MUST</bcp14> acknowledge it by responding with a <tt>201 (Created)</tt> status code and the <tt>Upload-Complete</tt> field value set to true.</t>
      <t>If the request includes the <tt>Upload-Complete</tt> field value set to true  and a valid <tt>Content-Length</tt> header field, the client attempts to upload the remaining resource in one request. In this case, the upload's final size is the sum of the upload's offset and the <tt>Content-Length</tt> header field. If the server does not have a record of the upload's final size from creation or the previous append, the server <bcp14>MUST</bcp14> record the upload's final size to ensure its consistency. If the server does have a previous record, that value <bcp14>MUST</bcp14> match the upload's final size. If they do not match, the server <bcp14>MUST</bcp14> reject the request with a <tt>400 (Bad Request)</tt> status code.</t>
      <sourcecode type="example"><![CDATA[
:method: PATCH
:scheme: https
:authority: example.com
:path: /upload/b530ce8ff
upload-offset: 100
upload-draft-interop-version: 4
content-length: 100
[content (100 bytes)]

:status: 201
upload-offset: 200
]]></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>
    </section>
    <section anchor="upload-cancellation">
      <name>Upload Cancellation</name>
      <t>If the client wants to terminate the transfer without the ability to resume, it can send a <tt>DELETE</tt> request to the upload resource. Doing so is an indication that the client is no longer interested in continuing the upload, and that the server can release any resources associated with it.</t>
      <t>The client <bcp14>MUST NOT</bcp14> initiate cancellation without the knowledge of server support.</t>
      <t>The request <bcp14>MUST</bcp14> use the <tt>DELETE</tt> method. The request <bcp14>MUST NOT</bcp14> include an <tt>Upload-Offset</tt> or <tt>Upload-Complete</tt> header field. The server <bcp14>MUST</bcp14> reject the request with a <tt>Upload-Offset</tt> or <tt>Upload-Complete</tt> header field with a <tt>400 (Bad Request)</tt> status code.</t>
      <t>If the server successfully deactivates the upload resource, it <bcp14>MUST</bcp14> respond with a <tt>204 (No Content)</tt> status code.</t>
      <t>The server <bcp14>MAY</bcp14> terminate any in-flight requests to the upload resource before sending the response by abruptly terminating their HTTP connection(s) or stream(s).</t>
      <t>If the server does not consider the upload resource to be active, it <bcp14>MUST</bcp14> respond with a <tt>404 (Not Found)</tt> status code.</t>
      <t>If the server does not support cancellation, it <bcp14>MUST</bcp14> respond with a <tt>405 (Method Not Allowed)</tt> status code.</t>
      <sourcecode type="example"><![CDATA[
:method: DELETE
:scheme: https
:authority: example.com
:path: /upload/b530ce8ff
upload-draft-interop-version: 4

:status: 204
]]></sourcecode>
    </section>
    <section anchor="header-fields">
      <name>Header Fields</name>
      <section anchor="upload-offset">
        <name>Upload-Offset</name>
        <t>The <tt>Upload-Offset</tt> request and response header field indicates the resumption offset of corresponding upload, counted in bytes. The <tt>Upload-Offset</tt> field value is an Integer.</t>
      </section>
      <section anchor="upload-complete">
        <name>Upload-Complete</name>
        <t>The <tt>Upload-Complete</tt> request and response header field indicates whether the corresponding upload is considered complete. The <tt>Upload-Complete</tt> field value is a Boolean.</t>
        <t>The <tt>Upload-Complete</tt> header field <bcp14>MUST</bcp14> only by used if support by the resource is known to the client (<xref target="feature-detection"/>).</t>
      </section>
    </section>
    <section anchor="redirection">
      <name>Redirection</name>
      <t>The <tt>301 (Moved Permanently)</tt> and <tt>302 (Found)</tt> status codes <bcp14>MUST NOT</bcp14> be used in offset retrieval (<xref target="offset-retrieving"/>) and upload cancellation (<xref target="upload-cancellation"/>) responses. For other responses, the upload resource <bcp14>MAY</bcp14> return a <tt>308 (Permanent Redirect)</tt> status code and clients <bcp14>SHOULD</bcp14> use new permanent URI for subsequent requests. If the client receives a <tt>307 (Temporary Redirect)</tt> response to an offset retrieval (<xref target="offset-retrieving"/>) request, it <bcp14>MAY</bcp14> apply the redirection directly in an immediate subsequent upload append (<xref target="upload-appending"/>).</t>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>The upload resource URL is the identifier used for modifying the upload. Without further protection of this URL, an attacker may obtain information about an upload, append data to it, or cancel it.</t>
      <t>To prevent this, the server <bcp14>SHOULD</bcp14> ensure that only authorized clients can access the upload resource. In addition, the upload resource URL <bcp14>SHOULD</bcp14> be generated in such a way that makes it hard to be guessed by unauthorized clients.</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-Offset, Upload-Complete</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 (suggested value)</t>
      <t>Description: Upload Resumption Supported</t>
      <t>Specification: This document</t>
    </section>
  </middle>
  <back>
    <references anchor="sec-normative-references">
      <name>Normative References</name>
      <reference anchor="HTTP">
        <front>
          <title>HTTP Semantics</title>
          <author fullname="R. Fielding" initials="R." role="editor" surname="Fielding"/>
          <author fullname="M. Nottingham" initials="M." role="editor" surname="Nottingham"/>
          <author fullname="J. Reschke" initials="J." role="editor" surname="Reschke"/>
          <date month="June" year="2022"/>
          <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.</t>
            <t>This document updates RFC 3864 and obsoletes RFCs 2818, 7231, 7232, 7233, 7235, 7538, 7615, 7694, and portions of 7230.</t>
          </abstract>
        </front>
        <seriesInfo name="STD" value="97"/>
        <seriesInfo name="RFC" value="9110"/>
        <seriesInfo name="DOI" value="10.17487/RFC9110"/>
      </reference>
      <reference anchor="RFC2119">
        <front>
          <title>Key words for use in RFCs to Indicate Requirement Levels</title>
          <author fullname="S. Bradner" initials="S." surname="Bradner"/>
          <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="RFC8174">
        <front>
          <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
          <author fullname="B. Leiba" initials="B." surname="Leiba"/>
          <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"/>
          <author fullname="P-H. Kamp" surname="P-H. Kamp"/>
          <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="RFC6266">
        <front>
          <title>Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)</title>
          <author fullname="J. Reschke" initials="J." surname="Reschke"/>
          <date month="June" year="2011"/>
          <abstract>
            <t>RFC 2616 defines the Content-Disposition response header field, but points out that it is not part of the HTTP/1.1 Standard. This specification takes over the definition and registration of Content-Disposition, as used in HTTP, and clarifies internationalization aspects. [STANDARDS-TRACK]</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="6266"/>
        <seriesInfo name="DOI" value="10.17487/RFC6266"/>
      </reference>
      <reference anchor="RFC3864">
        <front>
          <title>Registration Procedures for Message Header Fields</title>
          <author fullname="G. Klyne" initials="G." surname="Klyne"/>
          <author fullname="M. Nottingham" initials="M." surname="Nottingham"/>
          <author fullname="J. Mogul" initials="J." surname="Mogul"/>
          <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>
    <?line 443?>

<section anchor="informational-response">
      <name>Informational Response</name>
      <t>The server is allowed to respond to upload creation (<xref target="upload-creation"/>) 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 is received. The benefit is the clients can defer starting the actual data transfer until the server indicates full support (i.e. resumable are supported, the provided upload URL 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 anchor="changes-feature-detection">
      <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>
          <t>Avoid additional roundtrips by the client, if possible (i.e. an additional HTTP request by the client should be avoided).</t>
        </li>
        <li>
          <t>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)</t>
        </li>
        <li>
          <t>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)</t>
        </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 field which indicates support for resumable uploads. There are two options:
- Use the standardized <tt>Alt-Svc</tt> response header field. However, it has been indicated to us that this header field might be reworked in the future and could also be semantically different from our intended usage.
- Use a new response header field <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 field 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 field 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 anchor="upload-metadata">
      <name>Upload Metadata</name>
      <t>When an upload is created (<xref target="upload-creation"/>), the <tt>Content-Type</tt> and <tt>Content-Disposition</tt> header fields are allowed 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 header fields 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 field. 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 anchor="faq">
      <name>FAQ</name>
      <ul spacing="normal">
        <li>
          <t><strong>Are multipart requests supported?</strong> Yes, requests whose content is encoded using the <tt>multipart/form-data</tt> are implicitly supported. The entire encoded content 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.</t>
        </li>
      </ul>
    </section>
    <section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>This document is based on an Internet-Draft specification written by Jiten Mehta, Stefan Matsson, and the authors of this document.</t>
      <t>The <eref target="https://tus.io/">tus v1 protocol</eref> is a specification for a resumable file upload protocol over HTTP. It inspired the early design of this protocol. Members of the tus community helped significantly in the process of bringing this work to the IETF.</t>
      <t>The authors would like to thank Mark Nottingham for substantive contributions to the text.</t>
    </section>
    <section numbered="false" removeInRFC="true" anchor="changes">
      <name>Changes</name>
      <section numbered="false" anchor="since-draft-ietf-httpbis-resumable-upload-01">
        <name>Since draft-ietf-httpbis-resumable-upload-01</name>
        <ul spacing="normal">
          <li>
            <t>Replace Upload-Incomplete header with Upload-Complete.</t>
          </li>
          <li>
            <t>Replace terminology about procedures with HTTP resources.</t>
          </li>
          <li>
            <t>Increase the draft interop version.</t>
          </li>
        </ul>
      </section>
      <section numbered="false" anchor="since-draft-ietf-httpbis-resumable-upload-00">
        <name>Since draft-ietf-httpbis-resumable-upload-00</name>
        <ul spacing="normal">
          <li>
            <t>Remove Upload-Token and instead use Server-generated upload URL for upload identification.</t>
          </li>
          <li>
            <t>Require the Upload-Incomplete header field in Upload Creation Procedure.</t>
          </li>
          <li>
            <t>Increase the draft interop version.</t>
          </li>
        </ul>
      </section>
      <section numbered="false" anchor="since-draft-tus-httpbis-resumable-uploads-protocol-02">
        <name>Since draft-tus-httpbis-resumable-uploads-protocol-02</name>
        <t>None</t>
      </section>
      <section numbered="false" anchor="since-draft-tus-httpbis-resumable-uploads-protocol-01">
        <name>Since draft-tus-httpbis-resumable-uploads-protocol-01</name>
        <ul spacing="normal">
          <li>
            <t>Clarifying backtracking and preventing skipping ahead during the Offset Receiving Procedure.</t>
          </li>
          <li>
            <t>Clients auto-retry 404 is no longer allowed.</t>
          </li>
        </ul>
      </section>
      <section numbered="false" anchor="since-draft-tus-httpbis-resumable-uploads-protocol-00">
        <name>Since draft-tus-httpbis-resumable-uploads-protocol-00</name>
        <ul spacing="normal">
          <li>
            <t>Split the Upload Transfer Procedure into the Upload Creation Procedure and the Upload Appending Procedure.</t>
          </li>
        </ul>
      </section>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAAAAAAAAA+096XLbyJn/+RS9nh8jq0TqsCaZYU6Nj1i7vmLJO8lOpUYg
2CQRgQCDBiRzHOdZ9ln2yfa7+gJA6vAkTrZWVTOWSKCP7z67h8PhoM7qXI/V
W22aZTLJtXq3ystkatSsrNTz8/M3g2QyqfRVzyODaZkWyRLenlbJrB5mup4N
F3W9mmRmWNmnhw09PTw4GqRJredltR4rU08Hg2xVjVVdNaY+Ojj4Br5PKp2M
1cnb88F1WV3Oq7JZjXkNl3oNH03H6rSodVXoevgEpxwMTJ0U0x+SvCxgGWtt
BmaZVPUPf2nKWpuxKsrBKhur7+sy3VOmrOpKzwz8tl7iL38aDK500ejxQKlw
NqXq9QrG+w5WkRVz9Tv8Dj5dlLhZ3KEZ7+/jv9fzUVnN9+G7ZZLlY+VAMLye
//b6EX4J3yVVuvDv5ZmpzYi/3D+Br7IrbfbfNJM8S/fDAXDYSq9K/+o8qxfN
ZJSWS5md/hnq97UuTFYWZj9PJjo3+23oD/jNYWZMo4f00Fh1HhokTb0oKwTH
EP5TKisAhi9H6j9ynU1z+ogR/jKpssaEn1clkpGeZnVZ0Qewu6TIfkxqWNdY
nVdJYXCSrFYvAPn4hGaYLWms39b+CdxgvIbfjdR/LZJiHizhd0251sGnNyzg
ZLUCyj0t0lE49xwH+eFHHOS3CT7RnfrFSL1Jqmmjg7lfNGliwo9vmPxxXjbT
WQ70HU6e4ygrGmR0dDz6+W/n+DmtYDAoymoJb18RcSJVAgM+e/zN4eEBME4x
898OBsPhUCUTAwBMgSPwWZXmmS5qo8oZUIbSRVo2yDiwI/h/1axqPVXTpE4U
QX2mK6NgQwmRRF7DaypNilTn8Fil/9Jog2NVwOflagWfpWVR6BT3ZgA6VQZf
1aUfHD7fU7AxGggHXcG4sB6CBuB7rRbJlVYTjWt7nyL09XSkzksYeAlIqLWq
FzpeIA6FH8IwWaVbY+4pIKvMbneqTVaRoMJFIcUr00wM7qOo/X7qRVIHwxf5
miaoEDvF1M8YTzUiZKgK1+zHMs1qBdIFnodVAHRSvaLNOxZT0/K6EMFalUtl
dHWlCWqMKtg9vgoStVniKmEPaZVNNCJlqRFEmVnykmUuEwzerIKheUAcWiZp
DAoxXPaIiWWZTae5Hgy+QHFaldOGUPkvQDo7Rmv14cMZD6AejY7wMVz2x48P
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
v10fjgpqkwAA

-->

</rfc>
