<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt'?>
<?xml-stylesheet type='text/css' href='XML/rfc2629.css'?>
<?rfc strict="yes"?>
<?rfc toc="yes"?>
<?rfc tocdepth="4"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<!DOCTYPE rfc SYSTEM "XML/rfc2629/rfc2629.dtd" [
<!-- One method to get references from the online citation libraries.
There has to be one entity for each item to be referenced. 
An alternate method (rfc include) is described in the references. -->

<!ENTITY RFC2119 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC2616 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2616.xml">

]>
<rfc category="info" docName="draft-lentczner-rhttp-00" ipr="trust200902">
   <front>
      <title>Reverse HTTP</title>
      <author fullname="Mark Lentczner" initials="M." surname="Lentczner">
         <organization>Linden Research, Inc.</organization>
         <address>
            <postal>
               <street>945 Battery St.</street>
               <city>San Francisco</city>
               <region>CA</region>
               <code>94111</code>
               <country>US</country>
            </postal>
            <phone>+1 415 243 9000</phone>
            <email>zero@lindenlab.com</email>
         </address>
      </author>
      <author fullname="Donovan Preston" initials="D." surname="Preston">
         <organization/>
         <address>
            <email>dsposx@mac.com</email>
         </address>
      </author>
      <date year="2009" month="March" day="4"/>
      <area>Applications</area>
      <workgroup>Internet Engineering Task Force</workgroup>
      <abstract>
         <t>This memo explains a method for making HTTP requests to a host that cannot be contacted
            directly. Typically, such a host is behind a firewall and/or a network address
            translation system.</t>
      </abstract>
   </front>
   <middle>
      <section title="Introduction">
         <t>HTTP has become widely used as an application layer transport. Systems such as XML-RPC
            and SOAP, as well as numerous "web APIs" such as the Flickr API, all use HTTP as a
            method for having a client make requests of a server.</t>
         <t>The design of HTTP is such that the entity that initiates the TCP connection over which
            HTTP flows is also the entity that issues the request. When building applications over
            HTTP where the hosts involved can both function as TCP servers, this is no problem: When
            either host wishes to invoke an function on the other, it can initiate a TCP connection
            to the other, and acting as the client in the HTTP protocol, issue the request.</t>
         <t>In many HTTP based applications, one of the hosts cannot function as an HTTP server.
            Typically, the host may be behind a firewall, or not have a publicly routable IP
            address. In this case, application layer interfaces can no longer be symmetric: If a
            host needs to invoke a function on a host that cannot function as an HTTP server, than
            that function cannot be easily layered on top of HTTP. Typical designs to work around
            this constraint involve different encodings and semantics for requests from the server
            host to the non-server host, and the use of the long-poll technique.</t>
         <t>Reverse HTTP is designed to enable the application layer encoding and semantics to be
            built upon HTTP uniformly for requests in either direction between a non-server host and
            server host. Since the non-server host cannot be contacted directly, the non-server host
            still needs to establish the TCP connection, but once the Reverse HTTP protocol is
            negotiated, the full HTTP protocol is used in the reverse of the normal direction: from
            the server to the client </t>
         <section title="Requirements Language">
            <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD
               NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as
               described in <xref target="RFC2119">RFC 2119</xref>.</t>
         </section>
      </section>
      <section title="Protocol">
         <section title="Overview">
            <t>A Reverse HTTP connection is established between hosts A and B as follows:<list
                  style="numbers">
                  <t>Host A establishes a TCP connection to host B.</t>
                  <t>Host A makes an HTTP request to host B. This request indicates A's willingness
                     to engage in Reverse HTTP, and supplies any identification, authentication and
                     authorization needed by B. The request is signaled by the Upgrade header in the
                     request. Typically, the request is also indicated by a particular URL, and the
                     other information encoded in the URL, body, or cookies, but applications are
                     free to use any methods they wish for these purposes.</t>
                  <t>Host B signals its agreement to enter into Reverse HTTP by use of a 101 status
                     code and the Upgrade header in its response. At the conclusion of this
                     response, the original HTTP connection is considered abandoned, and a new HTTP
                     connection is established where host B is in the role of client and host A in
                     the role of server. From then on, request messages can be sent from B, with
                     responses from A.</t>
               </list></t>
         </section>
         <section title="Upgrade">
            <t>The switch to Reverse HTTP is signaled via HTTP's Upgrade header and upgrade
               mechanism, as described in sections 14.42 and 10.1.2. of <xref target="RFC2616"
                  >RFC2616</xref>.</t>
            <t>The protocol token used in the Upgrade header is:<figure>
                  <artwork>PTTH/1.0</artwork>
               </figure></t>
            <t>Section 10.1.2 of <xref target="RFC2616">HTTP</xref> defines the precise point of the
               protocol switch: Directly after the empty line of the response message containing the
               Upgrade header. At this point, the new connection proceeds with the full HTTP
               protocol, as if the TCP connection had just been established, but with the parties in
               reverse: the original server acting as the HTTP client, sending request messages, and
               the original client acting as the HTTP server, sending response messages.</t>
         </section>
         <section title="Example">
            <t>In this example, host A will contact host B, and indicate it's willingness to enter
               into Reverse HTTP, and then process request messages from B:</t>
            <t><figure>
                  <artwork>A --> B: POST /message-queue?id=iamsam HTTP/1.1
         Host: b.example.com
         Upgrade: PTTH/1.0
         Connection: Upgrade
         
A &lt;-- B: HTTP/1.1 101 Switching Protocols
         Upgrade: PTTH/1.0
         Connection: Upgrade

A &lt;-- B: GET /status HTTP/1.1
         Host: 

A --> B: HTTP/1.1 200 OK
         Content-type: text/plain
         Content-Length: 4

         Good</artwork>
               </figure></t>
         </section>
      </section>
      <section title="Considerations">
         <section title="Host Header">
            <t>Section 14.23 of <xref target="RFC2616">HTTP</xref> requires that all HTTP/1.1
               requests have a Host header. However, if the URI requested doesn't include an
               internet host, then the Host field is empty. In the case of Reverse HTTP, the URI
               requested refers to a resource on Host A, which does not have an  host name or IP
               accessible to Host B. As such, the Host field in request messages from B SHOULD
               contain an empty Host field.</t>
         </section>
         <section title="Connection">
            <t>The Upgrade mechanism is defined to be a hop-by-hop level in HTTP. As such, the
               Upgrade header is required to be listed in a Connection header in both the request
               message and the response message. Reverse HTTP, however, is establishing an
               end-to-end establishment of an HTTP connection in the reverse direction. Thus,
               Reverse HTTP upgrade can only be used with a proxy if the proxy is willing to
               establish Reverse HTTP on the next hop, or the CONNECT verb is used with the proxy to
               first establish a tunnel. Where Reverse HTTP is used over HTTPS connections, there is
               no problem, even in the face of proxies, because those proxies establish an
               end-to-end tunnel that constitutes a single HTTP hop.</t>
         </section>
         <section title="Persistent Connections">
            <t>Once established, the HTTP connection operating in reverse is just like any other
               HTTP connection. In particular, the persistent connection mechanisms of both HTTP 1.0
               and 1.1 are available. In this way, a host can establish a bi-directional HTTP based
               communication to another host using two TCP connections: One running a persistent
               HTTP connection to the remote host, and another, after negotiating Reverse HTTP,
               running a persistent HTTP connection from the remote host back to itself.</t>
         </section>
         <section title="Fall Back">
            <t>Applications can be developed where not all hosts have to understand Reverse HTTP. If
               the non-server host doesn't understand Reverse HTTP, then the server will not see an
               Upgrade token of PTTH/1.0 and so will know to fall back to some other application
               method of routing requests to the non-server host.  If the server doesn't understand
               Reverse HTTP, then it will respond to the HTTP request, ignoring the Upgrade token.
               In such cases, the non-server host will see a response that corresponds to the fall
               back method.</t>
            <t>The actual method of fall back is beyond the scope of this memo.  The authors have
               experimented with various forms including JSON and XML encoding of application level
               requests, and more generic encoding of HTTP messages into HTTP message bodies. In
               general, existing applications can migrate to Reverse HTTP and keep their existing
               techniques as fall back.</t>
         </section>
      </section>
      <section anchor="Security" title="Security Considerations">
         <t>Reverse HTTP introduces no new security concerns beyond those known with HTTP. However,
            as it applies HTTP in a novel way, the common security concerns need to be applied to
            the parties in reverse. In particular, client software that initiates Reverse HTTP must
            realize that it will act as a server once the upgrade is complete, and so prepare it
            self for almost all the same issues any HTTP server must be concerned with. The security
            concerns can be lessened somewhat in that the client need not be prepared for arbitrary
            requests from the Internet. HTTP requests can only come from the host the client chooses
            to connect and establish Reverse HTTP to. Standard precautions, such as negotiating TLS
            or using HTTPS, should be use so that the client can rule out man-in-the-middle and
            impersonation attacks.</t>
      </section>
      <section title="IANA Considerations">
         <t>This document asks IANA to register the token PTTH in the HTTP Upgrade Token
         registry.</t>
      </section>
   </middle>
   <back>
      <references title="Normative References"> &RFC2119; &RFC2616;
      </references>
   </back>
</rfc>
