<?xml version="1.0" encoding="UTF-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc2629 version 1.2.8 -->

<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
]>


<rfc ipr="trust200902" docName="draft-frindell-httpbis-partial-post-replay-00" category="info">

  <front>
    <title abbrev="HTTP-PPR">HTTP Partial POST Replay</title>

    <author initials="A." surname="Frindell" fullname="Alan Frindell">
      <organization>Facebook</organization>
      <address>
        <email>afrind@fb.com</email>
      </address>
    </author>

    <date year="2019" month="June" day="28"/>

    
    <workgroup>httpbis Working Group</workgroup>
    <keyword>Internet-Draft</keyword>

    <abstract>


<t>This memo introduces a method of exchanging HTTP <xref target="RFC7230"/> messages between a
web server and a cooperating intermediary – such as a reverse proxy load
balancer – that enables faster restarts for the web server with minimal
disruption for users.</t>



    </abstract>


  </front>

  <middle>


<section anchor="introduction" title="Introduction">

<t>Web servers need to drain traffic periodically for configuration changes,
software updates and maintenance.  As continuous deployment becomes more common,
the frequency of such events increases.  When a server shuts down, it chooses
whether to let all existing requests run to completion, or abort some or all
in-progress requests.  Aborted requests lead to poor user experiences including
error messages or additional latency while the request is resent.  Partial POST
Replay makes it possible to eliminate this class of errors by handing off
in-process requests to another server within a deployment.</t>

<section anchor="conventions-and-definitions" title="Conventions and Definitions">

<t>The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”,
“SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” 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>

</section>
</section>
<section anchor="partial-post-replay" title="Partial POST Replay">

<t>This section describes the Partial POST Replay mechanism for handing off a
request with a partially transferred entity body to another server instance.</t>

<section anchor="response-message" title="Response Message">

<t>When the server begins restarting, it responds to any unprocessed requests with
incomplete entity bodies with a new 3xx status code (TBD).  The HTTP/1.1 status
message is Partial POST Replay.  Once this status is sent the server MUST NOT
process this request other than is specified in this document.</t>

<t>The server MUST have prior knowledge that the intermediary supports Partial
POST Replay before sending the 3xx response.  If a server sends this response
to an intermediary that does not understand it, the response will likely be
forwarded back to the client.</t>

<section anchor="response-headers" title="Response Headers">

<t>Each request header is echoed in the response message with the prefix <spanx style="verb">Echo-</spanx>.
For example, the <spanx style="verb">User-Agent: Foo</spanx> request header would be included in the
response as <spanx style="verb">Echo-User-Agent: Foo</spanx>.  HTTP/2 <xref target="RFC7540"/> and HTTP/3 {{?HTTP3}
request pseudo-headers (beginning with ‘:’) are echoed in the response message
with the prefix <spanx style="verb">Pseudo-Echo-</spanx>, and with the ‘:’ removed.  For example, <spanx style="verb">:path:
/</spanx> is echoed as <spanx style="verb">pseudo-echo-path: /</spanx>.  The server MUST NOT insert any Echo- or
Pseudo-Echo headers in the response if the corresponding header was not present
in the request.</t>

<t>Because there might be request body bytes in flight to the server when the 3xx
response is generated, the length of the response body is unknown.  The response
SHOULD NOT include a <spanx style="verb">Content-Length</spanx> header (but will include a
<spanx style="verb">Echo-Content-Length</spanx> header, if the request contained <spanx style="verb">Content-Length</spanx>).  If
the request protocol is HTTP/1.1, the server SHOULD use chunked transfer
encoding for the response.</t>

<t>HTTP/1.1 server SHOULD include a <spanx style="verb">Connection: close</spanx> header in the response to
prevent the intermediary from reusing the connection for a new request.  HTTP/2
and HTTP/3 servers SHOULD emit a GOAWAY frame on each open connection when
shutdown is initiated.</t>

</section>
</section>
<section anchor="intermediary-processing" title="Intermediary Processing">

<t>Intermediaries MUST track the number of body bytes forwarded to the server for
any request that could be replayed by the server.  When an intermediary receives
a 3xx status code from the server, it stops forwarding any new HTTP data from
the client to this server.  The intermediary does not forward the 3xx response
to the client, but instead reconstructs the original HTTP request message from
headers in the response beginning with the <spanx style="verb">Echo-</spanx> or <spanx style="verb">Pseudo-Echo</spanx> prefixes.
Alternatively, if the intermediary retained a copy of the request it MAY use
that and discard the response headers.</t>

<t>The intermediary can choose to buffer the response before selecting a new
server, or can immediately select a new server and begin forwarding the request
there.  When the entire replayed request body has been sent to the new server,
the intermediary can begin forwarding new HTTP data from the client to the new
server.</t>

<t>If the intermediary receives more body bytes from the server than it forwarded,
or if the response is terminated before receiving all forwarded bytes, the
intermediary MUST fail the request with a 5xx status.</t>

</section>
<section anchor="original-request-termination" title="Original Request Termination">

<t>When the intermediary has received in the response body all of the request bytes
forwarded to the original server, it completes the request message to the
original server, according to the semantics of the transport protocol:</t>

<t><list style="symbols">
  <t>For HTTP/1.0, the intermediary half-closes the connection</t>
  <t>For HTTP/1.1, the intermediary sends the final chunk terminator, or
half-closes the connection if the request did not use chunked transfer encoding.</t>
  <t>For HTTP/2, the intermediary sends a DATA frame with the END_STREAM flag set
 on the request stream</t>
  <t>For HTTP/3, the intermediary sends a FIN on the request stream</t>
</list></t>

<t>When the server processes the end of the request, it completes the response
message according to the semantics of the transport protocol.</t>

<t>Note that some HTTP server implementations treat the termination of the request
with fewer bytes than specified in the Content-Length header as an error.
Because all required information has been transferred to the intermediary before
this error occurs, the server can abort the response and ignore the error
without impacting the final status of the request.</t>

<t>It is possible that the entire entity body was sent by the intermediary before
it received the Partial POST Replay status message.  In this case the
intermediary will receive the entire entity body in the response.</t>

</section>
<section anchor="preventing-loops" title="Preventing Loops">

<t>To prevent the intermediary from becoming stuck in an infinite redirect loop, it
SHOULD add a ‘Partial-Post-Replay: 1’ header whenever forwarding to a new
server.  An intermediary that receives a redirect response with more
<spanx style="verb">Echo-Partial-Post-Replay</spanx> headers than it supports SHOULD fail original request
with a 5xx response.</t>

</section>
</section>
<section anchor="existing-solutions" title="Existing Solutions">

<t>There are several existing solutions to handling requests while draining
traffic from a web server, but each has drawbacks that Partial POST Replay does
not.</t>

<section anchor="drain-timeout" title="Drain Timeout">

<t>When servers stop accepting new connections, they often set a timeout during
which existing requests can continue processing.  At the end of the timeout, the
server will abort any unfinished requests.  During this phase, the server is not
operating at full capacity, and requests that exceed the timeout are still
terminated with error.</t>

</section>
<section anchor="goaway" title="GOAWAY">

<t>HTTP/2 introduced the GOAWAY frame which a server can use to indicate which
requests will not be processed, and which can be safely retried by the client.
There are two problems with this mechanism.</t>

<t>First, the server cannot use this mechanism to refuse requests with stream IDs
lower than the highest stream ID it has already processed.  For example, if the
server has received a partial request on stream ID=3, but has already begun
processing a request on stream ID=5, it cannot send a GOAWAY with a
Last-Stream-ID lower than 5.  HTTP/2 does not have a status code that indicates
an individual request is retryable</t>

<t>Second, an intermediary cannot seamlessly retry a POST request unless it has
buffered the entire request body.  Buffering all request bodies presents an
enormous scalability challenge for intermediaries.</t>

</section>
<section anchor="state-handover" title="State Handover">

<t>Another possible technique is to pass state from a draining web server to a new
instance.  Such deployments start a new instance to handle new work in parallel
with the instance that is shutting down.  This requires that the system have
enough resources to run two instances of the server simultaneously, for a
potentially very long time.</t>

</section>
</section>
<section anchor="security-considerations" title="Security Considerations">

<t>An intermediary must trust the server to echo back the headers and body of the
original request.  A malicious server could replay a different request to the
intermediary, who would then send it to another server.  The response to this
forged request would be interpreted as a response to the original request.</t>

</section>
<section anchor="iana-considerations" title="IANA Considerations">

<t>This document has no IANA actions.</t>

</section>


  </middle>

  <back>

    <references title='Normative References'>





<reference  anchor="RFC2119" target='https://www.rfc-editor.org/info/rfc2119'>
<front>
<title>Key words for use in RFCs to Indicate Requirement Levels</title>
<author initials='S.' surname='Bradner' fullname='S. Bradner'><organization /></author>
<date year='1997' month='March' />
<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" target='https://www.rfc-editor.org/info/rfc8174'>
<front>
<title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
<author initials='B.' surname='Leiba' fullname='B. Leiba'><organization /></author>
<date year='2017' month='May' />
<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>




    </references>

    <references title='Informative References'>

<reference anchor="HTTP3" >
  <front>
    <title>Hypertext Transfer Protocol Version 3 (HTTP/3)</title>
    <author initials="M." surname="Bishop" fullname="Mike Bishop" role="editor">
      <organization>Akamai Technologies</organization>
    </author>
    <date />
  </front>
  <seriesInfo name="Internet-Draft" value="draft-ietf-quic-http-latest"/>
</reference>




<reference  anchor="RFC7230" target='https://www.rfc-editor.org/info/rfc7230'>
<front>
<title>Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing</title>
<author initials='R.' surname='Fielding' fullname='R. Fielding' role='editor'><organization /></author>
<author initials='J.' surname='Reschke' fullname='J. Reschke' role='editor'><organization /></author>
<date year='2014' month='June' />
<abstract><t>The Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems.  This document provides an overview of HTTP architecture and its associated terminology, defines the &quot;http&quot; and &quot;https&quot; Uniform Resource Identifier (URI) schemes, defines the HTTP/1.1 message syntax and parsing requirements, and describes related security concerns for implementations.</t></abstract>
</front>
<seriesInfo name='RFC' value='7230'/>
<seriesInfo name='DOI' value='10.17487/RFC7230'/>
</reference>



<reference  anchor="RFC7540" target='https://www.rfc-editor.org/info/rfc7540'>
<front>
<title>Hypertext Transfer Protocol Version 2 (HTTP/2)</title>
<author initials='M.' surname='Belshe' fullname='M. Belshe'><organization /></author>
<author initials='R.' surname='Peon' fullname='R. Peon'><organization /></author>
<author initials='M.' surname='Thomson' fullname='M. Thomson' role='editor'><organization /></author>
<date year='2015' month='May' />
<abstract><t>This specification describes an optimized expression of the semantics of the Hypertext Transfer Protocol (HTTP), referred to as HTTP version 2 (HTTP/2).  HTTP/2 enables a more efficient use of network resources and a reduced perception of latency by introducing header field compression and allowing multiple concurrent exchanges on the same connection.  It also introduces unsolicited push of representations from servers to clients.</t><t>This specification is an alternative to, but does not obsolete, the HTTP/1.1 message syntax.  HTTP's existing semantics remain unchanged.</t></abstract>
</front>
<seriesInfo name='RFC' value='7540'/>
<seriesInfo name='DOI' value='10.17487/RFC7540'/>
</reference>




    </references>


<section numbered="false" anchor="acknowledgments" title="Acknowledgments">

<t>This draft evolved from a feature developed at Facebook.  Thanks to Mohammad
Husain, Woo Xie and David Langevin who worked on the initial implementation and
deployment of this feature.</t>

</section>


  </back>

<!-- ##markdown-source:
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
B3vzvBShIwAA

-->

</rfc>

