<?xml version="1.0"?>
<?xml-stylesheet type='text/xsl' href='./rfc2629.xslt' ?>

<?rfc toc="yes"?>
<?rfc symrefs="no"?>
<?rfc compact="no" ?>
<?rfc sortrefs="yes" ?>
<?rfc strict="yes" ?>
<?rfc linkmailto="yes" ?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" >
    

<?xml-stylesheet type='text/xsl' href='./rfc2629.xslt' ?>

<?rfc toc="yes"?>
<?rfc symrefs="yes"?>
<?rfc compact="yes" ?>
<?rfc subcompact="yes" ?>
<?rfc sortrefs="yes" ?>
<rfc ipr="trust200902" docName="draft-nir-httpbis-che-01" category="info">
  <front>
    <title abbrev="compact-header">HTTP/2.0 Discussion: Compact Header Encoding</title>
    <author initials="Y." surname="Nir" fullname="Yoav Nir">
      <organization abbrev="Check Point">Check Point Software Technologies Ltd.</organization>
      <address>
        <postal>
          <street>5 Hasolelim st.</street>
          <city>Tel Aviv</city>
          <code>67897</code>
          <country>Israel</country>
        </postal>
        <email>ynir@checkpoint.com</email>
      </address>
    </author>
    <date year="2012"/>
    <area>Applications Area</area>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <t> This document proposes an alternative encoding for HTTP headers. This encoding is
        considerably more compact than the uncompressed textual encoding in HTTP/1.1 and current
        HTTP/2.0 draft.</t>
    </abstract>
  </front>
  <middle>
    <!-- ====================================================================== -->
    <section anchor="introduction" title="Introduction">
      <t> HTTP/1.x and the current draft of HTTP/2.0 encode headers using text labels and text 
        values. HTTP/2.0 attempts to make this more efficient by compressing the textual headers.
        This proposes a binary-only alternative.</t>
      <section anchor="mustshouldmay" title="Conventions Used in This Document">
        <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"/>.</t>
      </section>
    </section>
    <section anchor="encoding" title="The Binary Encoding">
      <figure><preamble>The header block is formatted as follows:</preamble><artwork>
+------------------------------------+
|1|   version     |          8       |
+------------------------------------+
| Flags (8)  |   Length (24 bits)    |
+------------------------------------+
|X|          Stream-ID (31bits)      |
+------------------------------------+
|      Sequence of headers           |
|                                    |
+------------------------------------+
        </artwork></figure>
      <t> The sequence of headers is just a list of the headers in one of 5 formats: <list 
        style="symbols">
        <t> Flags - These are headers with no associated data. The only information they convey is
          by their mere presence.</t>
        <t> Short Type-Value - where the header is associated with a 16-bit value.</t>
        <t> Long Type-Value - where the header is associated with a 32-bit value.</t>
        <t> Type-Length-Value - where the length is specified in the header.</t>
        </list></t>
      <t> All formats include a 16-bit header identifier (see below), and those identifiers will be
        allocated through a new IANA registry (see <xref target="iana" />). The header identifier
        specifies which format applies.</t>  
      <section anchor="format1" title="Flags">
        <figure><preamble>These headers are 16-bit numbers containing the header identifier.
          </preamble><artwork>
+-----------------+
|header identifier|
+-----------------+
        </artwork></figure>
      </section>    
      <section anchor="format2" title="Short Type-Value">
        <figure><preamble>These headers have the 16-bit identifier, and also the 16-bit value.
          </preamble><artwork>
+------------------------------------+
|header identifier|  Value           |
+------------------------------------+
        </artwork></figure>
      </section>    
      <section anchor="format3" title="Long Type-Value">
        <figure><preamble>These headers have the 16-bit identifier, and also a 32-bit value.
          </preamble><artwork>
+------------------------------------+
|header identifier|    Value         |
+-----------------+------------------+
|  Value (cont)   |
+-----------------+
        </artwork></figure>
      </section>    
      <section anchor="format4" title="Type-Length-Value">
        <figure><preamble>These headers have the 16-bit identifier, and also a 24-bit length 
          field, and a value of variable length.</preamble><artwork>
+------------------------------------+
|header identifier|    Length        |
+---------+-------+------------------+
| Length  | Value...                 |
+---------+--------------------------+
        </artwork></figure>
      </section>    
    </section>
    <section anchor="headerenc" title="Header Encoding">
      <t> The encoding of each header is specified in the specification that describes it. For 
        convenience, this document describes some common encodings. Specification writers SHOULD
        use these formats whenever they are appropriate.</t>
      <t> Unsigned integer numbers can be represented by either the short or long type-value, 
        depending on their range. Cache ages measured in seconds, such as in HSTS should use the 
        long type-value, whereas a header specifying an age in days should probably use a short 
        type-value. Either way, the encoding can be called "INT".</t>
      <t> Headers that hold an enumeration (such as Method) SHOULD use a short type-value, and 
        SHOULD reserve one value (0xffff) for custom values.</t>
      <t> Time values should be encoded as strings using the RFC3339 format.</t>  
      <t> Strings such as names should use the TLV format, and SHOULD be encoded as UTF-8. String
        headers should be specified by their encoding, so "UTF8", or "ASCII".</t> 
      <t> For headers with multiple values, the general format is always TLV, and the specification 
        should list their type as either of three things: <list style="symbols">
        <t> Short values - a list of 16-bit values</t>
        <t> Short strings - a sequence of strings, each prefixed by a 1-octet length field.</t>
        <t> Long strings - a sequence of strings, each prefixed by 1 2-octet length field.</t></list></t>
    </section>
    <section anchor="custom" title="Custom Headers and Custom Enumerations">
      <t> For each type of header, a range will be allocated for experimental and custom headers. 
        To avoid collisions, we define here a special header to denote what kind of header this is.
        The header is has identifier 49160 (0xC008), so it is TLV-formatted, and its value is 
        formatted as follows:</t>
        <figure><preamble>Custom header format</preamble><artwork>
+------------------------------------+
|header identifier| Flags  | Name... |
+---------+-------+------------------+
        </artwork></figure>
      <t> For example, suppose draft-nir-httpbis-copyright-notice defines a header that contains a
        copyright notice for the content. I will use 65530 (0xFFFA). Note that the two headers 
        don't have to be consecutive. If the sender knows that the receiver recognizes this header 
        with this identifier, the Custom header MAY be omitted.</t>
      <figure><preamble>Custom and Copyright Headers</preamble><artwork>
  C0 08 00 00 0C FF FA 00 4C 4F 50 59 52 49 47 48 |........COPYRIGH|
  54 FF FA 00 00 43 6f 70 79 72 69 67 68 74 20 28 |T....Copyright (|
  63 29 20 32 30 31 32 20 49 45 54 46 20 54 72 75 |c) 2012 IETF Tru|
  73 74 20 61 6e 64 20 74 68 65 20 70 65 72 73 6f |st and the perso|
  6e 73 20 69 64 65 6e 74 69 66 69 65 64 20 61 73 |ns identified as|
  20 74 68 65 20 64 6f 63 75 6d 65 6e 74 20 61 75 | the document au|
  74 68 6f 72 73 2e 20 41 6c 6c 20 72 69 67 68 74 |thors. All right|
  73 20 72 65 73 65 72 76 65 64 2e                |s reserved.     |
        </artwork></figure>
      <t> For custom values in enumerations we define the Custom-Value header with identifier 
        49161 (0vC009), where the content is the string name of the custom value. This header
        MUST follow the enumeration header.</t>
    </section>
    <section anchor="default" title="Default Headers">
      <t> Many requests share a lot of their headers. For example, the Cookie, User-Agents, Host,
        Connection, and Accept* headers pretty much remain constant between consecutive requests.</t>
      <t> To make the per-stream Headers block even smaller, we allow a default Headers block. This
        block is distinguished by having Stream-ID fixed to all zeros. Additionally a new flag is
        defined:</t><figure><artwork>    
  0x02 = FLAG_UPD - marks that this frame updates the default headers
        </artwork></figure>
      <t> Every subsequent request is deemed to include all the default headers, except where such
        headers are overridden by that request. The default headers are persistent for the
        connection.</t>
      <t> A default HEADERS with the FLAG_UPD flag cleared replaces the default headers for this 
        connection. A default HEADERS block with the FLAG_UPD set updates the default headers for
        this connection by replacing those that had already been set, and adding those that had not
        been set. This is useful for example, if a cookie had been set by the server. The only way
        to delete a header from the default headers is by replacement - a default HEADERS block 
        with FLAG_UPD cleared.</t>
    </section>
    <!-- ====================================================================== -->
    <section anchor="iana" title="IANA Considerations">
      <t> IANA is requested to set up a new registry of header identifiers. The value is 16-bit, 
        and the range is partitioned as follows:<list style="symbols">
        <t> 0-16383 - these values are allocated to flag headers, where the format is as in 
          <xref target="format1" /></t>
        <t> 16384-32767 - these values are allocated to short type-value headers, where the 
          format is as in <xref target="format2" /></t>
        <t> 32768-49151 - these values are allocated to long type-value headers, where the format 
          is as in <xref target="format3" /></t>
        <t> 49152-65535 - these values are allocated to type-length-value headers, where the format 
          is as in <xref target="format4" /></t></list></t>
      <t> The ending quarter of each range shall be reserved for experimental and custom usage, and 
        shall not be allocated by standards action. For example, the range 45056-49151 will be 
        reserved for experimental and custom long type-value headers.</t>
    </section>
    <section anchor="security" title="Security Considerations">
      <t> There are no security considerations for this draft. </t>
    </section>
    <section anchor="delta" title="Changes from Previous Versions">
      <t> First version </t>
    </section>
  </middle>
  <!-- ====================================================================== -->
  <back>
    <references title="Normative References"> 
      <reference anchor='RFC2119'>
        <front>
          <title abbrev='RFC Key Words'>Key words for use in RFCs to Indicate Requirement Levels</title>
          <author initials='S.' surname='Bradner' fullname='Scott Bradner'>
            <organization>Harvard University</organization>
            <address>
              <postal>
                <street>1350 Mass. Ave.</street>
                <street>Cambridge</street>
                <street>MA 02138</street>
              </postal>
              <phone>- +1 617 495 3864</phone>
              <email>sob@harvard.edu</email>
            </address>
          </author>
          <date year='1997' month='March' />
          <area>General</area>
          <keyword>keyword</keyword>
        </front>
        <seriesInfo name='BCP' value='14' />
        <seriesInfo name='RFC' value='2119' />
        <format type='TXT' octets='4723' target='ftp://ftp.isi.edu/in-notes/rfc2119.txt' />
        <format type='HTML' octets='16553' target='http://xml.resource.org/public/rfc/html/rfc2119.html' />
        <format type='XML' octets='5703' target='http://xml.resource.org/public/rfc/xml/rfc2119.xml' />
      </reference>
    </references>
    <!-- ====================================================================== -->
    <section title="Additional Examples">
        <t> NOTE: Most of the below examples were shamelessly copied from draft-snell-httpbis-bohe-01.</t>
        <t>Assuming the following (intentionally incomplete) header registrations:</t>
        <texttable>
          <ttcol>HTTP Header</ttcol>
          <ttcol>ID</ttcol>
          <ttcol>Hex</ttcol>
          <ttcol>Format</ttcol>
          <c>Version            </c> <c>16384</c> <c>4000</c> <c>Major.Minor in 16-bit</c>
          <c>Method             </c> <c>16385</c> <c>4001</c> <c>Enumeration</c>
          <c>Host               </c> <c>49152</c> <c>c000</c> <c>UTF8</c>
          <c>Path (Request URI) </c> <c>49153</c> <c>c001</c> <c>UTF8</c>
          <c>Status             </c> <c>16386</c> <c>4002</c> <c>uint16</c>
          <c>Status-Text        </c> <c>49386</c> <c>c0ea</c> <c>UTF8</c>
          <c>Content-Length     </c> <c>32768</c> <c>8000</c> <c>uint32</c>
          <c>Content-Type       </c> <c>49154</c> <c>c002</c> <c>ASCII</c>
          <c>Expect             </c> <c>16387</c> <c>4003</c> <c>uint16</c>
          <c>Last-Modified      </c> <c>49155</c> <c>c003</c> <c>RFC3339</c>
          <c>ETag               </c> <c>49156</c> <c>c004</c> <c>sequence of short strings</c>
          <c>If-None-Match      </c> <c>49157</c> <c>c005</c> <c>sequence of short strings</c>
          <c>Allow              </c> <c>49158</c> <c>c006</c> <c>sequence of uint16</c>
          <c>Do-Not-Track       </c> <c>   58</c> <c>003a</c> <c>flag</c>
        </texttable>
      
        <t>And the following values representing known HTTP Methods:</t>
      
        <texttable>
          <ttcol>Method</ttcol>
          <ttcol>Value</ttcol>
          <c>GET    </c> <c>1</c>
          <c>POST   </c> <c>2</c>
          <c>PUT    </c> <c>3</c>
          <c>DELETE </c> <c>4</c>
          <c>PATCH  </c> <c>5</c>
          <c>HEAD   </c> <c>6</c>
          <c>OPTIONS</c> <c>7</c>
          <c>CONNECT</c> <c>8</c>
        </texttable>
      
        <t>Here is what the encoding looks like:</t>
        
<figure><preamble>Version Header:</preamble><artwork>
  40 00 02 00             |@...|
</artwork></figure>

<figure><preamble>Method Header (GET Request)</preamble><artwork>
  40 01 00 01             |@...|
</artwork></figure>

<figure><preamble>Method Header (PATCH Request)</preamble><artwork>
  40 01 00 05             |@...|
</artwork></figure>

<figure><preamble>Method Header (Custom "FOO" Method)</preamble><artwork>
  40 01 FF FF C0 09 00 03 46 4F 4F                |@.......FOO     |
</artwork></figure>

<figure><preamble>Do Not Track</preamble><artwork>
  00 3A                   |.:|
</artwork></figure>

<figure><preamble>Host Header:</preamble><artwork>
  C0 00 00 00 0F 77 77 77 2e 65 78 61 6d 70 6c 65 |.....www.example|
  2e 6f 72 67                                     |.org            |
</artwork></figure>

<figure><preamble>HTTP Response Status ("200 OK") as two separate headers, one containing the 
  status code, the other containing the status text:</preamble><artwork>
  40 02 00 C8 C0 EA 00 00 02 4F 4B                |@........OK     |
</artwork></figure>

<figure><preamble>Content-Length Header (value encoded as uint32):</preamble><artwork>
  80 00 00 00 00 C8       |......|
</artwork></figure>

<figure><preamble>Content-Type Header (although maybe it should become an enum:</preamble><artwork>
  C0 02 00 00 0A 69 6d 61 67 65 2f 6a 70 65 67    |.....image/jpeg |
</artwork></figure>

<figure><preamble>Expect Header (Expect: 100):</preamble><artwork>
  40 03 00 64             |...d|
</artwork></figure>

<figure><preamble>Last-Modified (Using RFC3339 Format):</preamble><artwork>
  C0 03 00 00 19 32 30 31 32 2d 30 38 2d 30 31 54 |.....2012-08-01T|
  30 34 3a 32 33 3a 31 32 2e 31 32 33 34 5a       |04:23:12.1234Z  |
</artwork></figure>

<figure><preamble>ETag (Strong Entity-Tag, String-format):</preamble><artwork>
  C0 04 00 00 06 05 61 62 63 64 65                |......abcde     |
</artwork></figure>

<figure><preamble>If-None-Match (Multiple values)</preamble><artwork>
  C0 05 00 00 0C 05 61 62 63 64 65 05 61 62 63 64 |......abcde.abcd|
  66                                              |f               |
</artwork></figure>

<figure><preamble>Allow (GET, POST, FOO):</preamble><artwork>
  C0 06 00 00 06 00 01 00 02 FF FF C0 09 00 00 04 |................|
  03 46 4f 4f                                     |.FOO             |
</artwork></figure>

    </section>
  </back>
</rfc>
