<?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.7 (Ruby 3.2.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ietf-httpbis-resumable-upload-03" category="std" consensus="true" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.20.0 -->
  <front>
    <title abbrev="Resumable Uploads">Resumable Uploads for HTTP</title>
    <seriesInfo name="Internet-Draft" value="draft-ietf-httpbis-resumable-upload-03"/>
    <author initials="M." surname="Kleidl" fullname="Marius Kleidl" role="editor">
      <organization>Transloadit</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>lucas@lucaspardue.com</email>
      </address>
    </author>
    <date year="2024" month="March" day="04"/>
    <area>ART</area>
    <workgroup>HTTP</workgroup>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <?line 61?>

<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 65?>

<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 that 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 send the 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 512,144 L 512,176" 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="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 and while the request content is being uploaded, the target resource <bcp14>MAY</bcp14> send one or more informational responses with a <tt>104 (Upload Resumption Supported)</tt> status code to the client. In the first informational response, the <tt>Location</tt> header field <bcp14>MUST</bcp14> be set to the URL pointing to the upload resource. In subsequent informational responses, the <tt>Location</tt> header field <bcp14>MUST NOT</bcp14> be set. An informational response <bcp14>MAY</bcp14> contain the <tt>Upload-Offset</tt> header field with the current upload offset as the value to inform the client about the upload progress. In subsequent informational responses, the upload offset <bcp14>MUST NOT</bcp14> be smaller than in previous informational responses. In addition, later offset retrievals (<xref target="offset-retrieving"/>) <bcp14>MUST NOT</bcp14> receive an upload offset that is less than the offset reported in the latest informational response, allowing the client to free associated resources.</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>
      <t>The request content <bcp14>MAY</bcp14> be empty. If the <tt>Upload-Complete</tt> header field is then set to true, the client intends to upload an empty entity. An <tt>Upload-Complete</tt> header field is set to false is also valid. This can be used to create an upload resource URL before transferring data, which can save client or server resources. Since informational responses are optional, this technique provides another mechanism to learn the URL, at the cost of an additional round-trip before data upload can commence.</t>
      <t>The following example shows an upload creation. The client transfers the entire 100 bytes in the first request. The server generates two informational responses to transmit the upload resource's URL and progress information, and one final response to acknowledge the completed upload:</t>
      <sourcecode type="http-message"><![CDATA[
POST /upload HTTP/1.1
Host: example.com
Upload-Draft-Interop-Version: 5
Upload-Complete: ?1
Content-Length: 100

[content (100 bytes)]
]]></sourcecode>
      <sourcecode type="http-message"><![CDATA[
HTTP/1.1 104 Upload Resumption Supported
Upload-Draft-Interop-Version: 5
Location: https://example.com/upload/b530ce8ff

HTTP/1.1 104 Upload Resumption Supported
Upload-Draft-Interop-Version: 5
Upload-Offset: 50

HTTP/1.1 201 Created
Location: https://example.com/upload/b530ce8ff
Upload-Offset: 100
]]></sourcecode>
      <t>The next example shows an upload creation, where only the first 25 bytes are transferred. The server acknowledges the received data and that the upload is not complete yet:</t>
      <sourcecode type="http-message"><![CDATA[
POST /upload HTTP/1.1
Host: example.com
Upload-Draft-Interop-Version: 5
Upload-Complete: ?0
Content-Length: 25

[partial content (25 bytes)]
]]></sourcecode>
      <sourcecode type="http-message"><![CDATA[
HTTP/1.1 201 Created
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 5.</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> or <tt>200 (OK)</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>
      <t>The following example shows an offset retrieval request. The server indicates the new offset and that the upload is not complete yet:</t>
      <sourcecode type="http-message"><![CDATA[
HEAD /upload/b530ce8ff HTTP/1.1
Host: example.com
Upload-Draft-Interop-Version: 5
]]></sourcecode>
      <sourcecode type="http-message"><![CDATA[
HTTP/1.1 204 No Content
Upload-Offset: 100
Upload-Complete: ?0
Cache-Control: no-store
]]></sourcecode>
      <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>While the request content is being uploaded, the target resource <bcp14>MAY</bcp14> send one or more informational responses with a <tt>104 (Upload Resumption Supported)</tt> status code to the client. These informational responses <bcp14>MUST NOT</bcp14> contain the <tt>Location</tt> header field. They <bcp14>MAY</bcp14> include the <tt>Upload-Offset</tt> header field with the current upload offset as the value to inform the client about the upload progress. The same restrictions on the <tt>Upload-Offset</tt> header field in informational responses from the upload creation (<xref target="upload-creation"/>) apply.</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>
      <t>The request content <bcp14>MAY</bcp14> be empty. If the <tt>Upload-Complete</tt> field is then set to true, the client wants to complete the upload without appending additional data.</t>
      <t>The following example shows an upload append. The client transfers the next 100 bytes at an offset of 100 and does not indicate that the upload is then completed. The server acknowledges the new offset:</t>
      <sourcecode type="http-message"><![CDATA[
PATCH /upload/b530ce8ff HTTP/1.1
Host: example.com
Upload-Offset: 100
Upload-Draft-Interop-Version: 5
Content-Length: 100

[content (100 bytes)]
]]></sourcecode>
      <sourcecode type="http-message"><![CDATA[
HTTP/1.1 201 Created
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>
      <t>The following example shows an upload cancellation:</t>
      <sourcecode type="http-message"><![CDATA[
DELETE /upload/b530ce8ff HTTP/1.1
Host: example.com
Upload-Draft-Interop-Version: 5
]]></sourcecode>
      <sourcecode type="http-message"><![CDATA[
HTTP/1.1 204 No Content
]]></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 be 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. 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>
      <t>Some servers or intermediaries provide scanning of content uploaded by clients. Any scanning mechanism that relies on receiving a complete file in a single request message can be defeated by resumable uploads because content can be split across multiple messages. Servers or intermediaries wishing to perform content scanning <bcp14>SHOULD</bcp14> consider how resumable uploads can circumvent scanning and take appropriate measures. Possible strategies include waiting for the upload to complete before scanning a full file, or disabling resumable uploads.</t>
      <t>Resumable uploads are vulnerable to Slowloris-style attacks <xref target="SLOWLORIS"/>. A malicious client may create upload resources and keep them alive by regularly sending <tt>PATCH</tt> requests with no or small content to the upload resources. This could be abused to exhaust server resources by creating and holding open uploads indefinitely with minimal work.</t>
      <t>Servers <bcp14>SHOULD</bcp14> provide mitigations for Slowloris attacks, such as increasing the maximum number of clients the server will allow, limiting the number of uploads a single client is allowed to make, imposing restrictions on the minimum transfer speed an upload is allowed to have, and restricting the length of time an upload resource can exist.</t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>IANA is asked to register the following entries in the "Hypertext Transfer Protocol (HTTP) Field Name Registry":</t>
      <table>
        <thead>
          <tr>
            <th align="left">Field Name</th>
            <th align="left">Status</th>
            <th align="left">Reference</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td align="left">Upload-Complete</td>
            <td align="left">permanent</td>
            <td align="left">
              <xref target="upload-complete"/> of this document</td>
          </tr>
          <tr>
            <td align="left">Upload-Offset</td>
            <td align="left">permanent</td>
            <td align="left">
              <xref target="upload-offset"/> of this document</td>
          </tr>
        </tbody>
      </table>
      <t>IANA is asked to register the following entry in the "HTTP Status Codes" registry:</t>
      <dl>
        <dt>Value:</dt>
        <dd>
          <t>104 (suggested value)</t>
        </dd>
        <dt>Description:</dt>
        <dd>
          <t>Upload Resumption Supported</t>
        </dd>
        <dt>Specification:</dt>
        <dd>
          <t>This document</t>
        </dd>
      </dl>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <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>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="SLOWLORIS" target="https://web.archive.org/web/20150315054838/http://ha.ckers.org/slowloris/">
          <front>
            <title>Welcome to Slowloris - the low bandwidth, yet greedy and poisonous HTTP client!</title>
            <author initials="R." surname="&quot;RSnake&quot; Hansen">
              <organization/>
            </author>
            <date year="2009" month="June"/>
          </front>
        </reference>
      </references>
    </references>
    <?line 476?>

<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-02">
        <name>Since draft-ietf-httpbis-resumable-upload-02</name>
        <ul spacing="normal">
          <li>
            <t>Add upload progress notifications via informational responses.</t>
          </li>
          <li>
            <t>Add security consideration regarding request filtering.</t>
          </li>
          <li>
            <t>Explain the use of empty requests for creation uploads and appending.</t>
          </li>
          <li>
            <t>Extend security consideration to include resource exhaustion attacks.</t>
          </li>
          <li>
            <t>Allow 200 status codes for offset retrieval.</t>
          </li>
          <li>
            <t>Increase the draft interop version.</t>
          </li>
        </ul>
      </section>
      <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:
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
DCJmUzebUJTF5pKUPeKSPNrTZN3hk1kj1fOZdY6tYEaqLGCPIC4eRp4BcmBz
I2zxeCVd1lJRG8ni5eiii89pPgAyNo5hMr26+dTPGAABAIjn56ZRuGmWjzj2
sFug8aTvMrq624yydpSPBgLMpXl0wH2Pdh4J9TeRA4qrWG+PbXXkSV+Qyudd
0PGamxAin+i3p8LVjp/7czz4tzrfw+KmvnBIbwggZA3Yapip34dO7uyIdh1i
QC0vq968jMeSl/E4zsuIvN9B3rRkVbusac91B7KXoGw0s2EyKrAOaa5H9onP
Q+zT2Z1LjjOCxRtFK221rejN5tyWgeORmjHKuSHj9MEOr/PM9xPTej/TSzrp
pFwE5CK4gDydLZP+WIAPgTEvvEWHozaEYtgX69tHZbnqzn+DdnYvIRbk2m1q
7vNzSLZNuq+rp1Mn891UsbA9m2Zq5yvM1C1BKgCfJ5bMnnXLsXKCZI41fGVF
JoJ2DgiZom2nSNXpFYaSUnQ5cIcZmkEn7yz7aLum+bk6fR9Q3p++0gSNQO4J
oZAbnwVuB+Qe1gE4IyWUQmdWiuFFJLgsVPU4hAIyULcr0pY7Om1HSzbxqJuV
ZYfWnbTAlodqa1ogObzCYSQ/xY2SLZdmhgTh13T3/HQ5nm5KZs+ogTsmyO3T
Q+nmnXWpLkofbRHd93+HWern5NfZNIfjHVGGd3/SOI21lnDq3fwqv2g++LnS
LJbRV5l0UyvvkKWebQrx207bktuEzWqVr8f/r6RR/90mTIf0ca/k6Ptwwf+f
HH2n5Oi0k8Yb4j8C8r8kT3p7JvDn5kpvRqHbC+I/7bRuy42+8xrEubopNfpe
4/x8udG8Fu0Q9POkRoMojY2dr21ssPdkT8cCcYNNwHWdmkndniJYCDcZVxEj
LNIrg6Sl9iktNO6mQTenbfetV9bqJuXBpdlowPC9jtczp468hjG9Rti3cnKO
hYh15+DS+eUnZ5zfLdXcddGMutQL/uEyURPxhmKQZEStuO+aHs0jbEmOJnHo
U6PT0JkIuHQgfNdhW5DD0/Ew0YZdrvL2VFPvr+rNH6XWAZ/iiOpxHW30Tf18
ac1hDmk7ATRM6Q3Dvb9wnqYAfrNf64kc7ZMtfq37ZXX+/M60sI1Q0IggdLW2
s/8cYcXmqQu8KG3hh+kky7N67fPIfKsZycbhXlG3xtSTZyV34ZHEIKES6ovU
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
5EXisZXhI93zdiJRnjh2JdHBVv8vTMoYwk6nAAA=

-->

</rfc>
