<?xml version="1.0"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">

<rfc category="std" ipr="full3978" docName="hessian.txt">

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

<?rfc toc="yes" ?>
<?rfc symrefs="yes" ?>
<?rfc sortrefs="yes"?>
<?rfc iprnotified="no" ?>

  <front>
    <title>Hessian 2.0 Security</title>
    <author initials="S." surname="Ferguson" fullname="Scott Ferguson">
      <organization>Caucho Technology Inc.</organization>
      <address>
        <postal>
          <street>P.O. Box 9001</street>
          <city>La Jolla</city>
          <region>CA</region>
          <code>92038</code>
          <country>USA</country>
        </postal>
        <email>ferg@caucho.com</email>
      </address>
    </author>
    <author initials="E." surname="Ong" fullname="Emil Ong">
      <organization>Caucho Technology Inc.</organization>
      <address>
        <postal>
          <street>P.O. Box 9001</street>
          <city>La Jolla</city>
          <region>CA</region>
          <code>92038</code>
          <country>USA</country>
        </postal>
        <email>emil@caucho.com</email>
      </address>
    </author>
    <date month="August" year="2007" />
  </front>
  
  <middle>
    <section title="Design Goals">
      <t>
        Unlike older binary protocols, Hessian is both self-describing,
        compact, and portable across languages.  The wire protocol for web
        services should be invisible to application writers, it should not 
        require external schema or IDL.
      </t>
      <t>
      The Hessian protocol has the following design goals:
      </t>
      <list style="symbols">
        <t>
          It must not require external IDL or schema definitions, i.e. the 
          protocol should be invisible to application code.
        </t>
        <t>It must be language-independent.</t>
        <t>
          It must be simple so it can be effectively tested and implemented.
        </t>
        <t>It must be as fast as possible.</t>
        <t>It must be as compact as possible.</t>
        <t>It must support Unicode strings.</t>
        <t>
          It must support 8-bit binary data (i.e. without encoding or using 
          attachments.)
        </t>
        <t>
          It must support encryption, compression, signature, and
          transaction context envelopes.
        </t>
      </list>
    </section>

    <section title="Hessian Grammar">
      <figure anchor="messaging_grammar">
        <preamble>Envelope/Messaging/RPC Grammar</preamble>
        <artwork>
          # Envelope for encryption/headers
envelope  ::= 'E' x02 x00 env-chunk* 'z'

          # header, body, footer
env-chunk ::= int (string object)* binary int (string object)*
        </artwork>
      </figure>
    </section>

    <section title="Envelope">

      <figure anchor="envelope_grammar">
        <preamble>Envelope Grammar</preamble>
        <artwork>
envelope ::= E x02 x00 m b1 b0 &lt;method-string> env-chunk* z

env-chunk ::= int (string object)* binary int (string object)*
        </artwork>
      </figure>

      <t>
        A Hessian envelope wraps a Hessian message, adding headers and 
        footers and possibly compressing or encrypting the wrapped message.  
        The envelope type is identified by a method string, e.g.
        "com.caucho.hessian.io.Deflation" or
        "com.caucho.hessian.security.X509Encryption".
      </t>

      <t>
        Some envelopes may chunk the data, providing multiple header/footer
        chunks.  For example, a signature envelope might chunk a large
        streaming message to reduce the amount of buffering required to 
        validate the signatures.
      </t>

      <section title="Envelope examples">
        <figure anchor="identity_envelope_example">
          <preamble>Identity Envelope</preamble>
          <artwork>
E x02 x00
m x00 x08 Identity   # "Identity" envelope does nothing to the body
x90                  # no headers
B x00 x0a            # binary wrapped body (12 bytes)
  p x02 x00          # wrapped message
  x05 hello          # "hello"
  z                  # end of wrapped message
x90                  # no footers
z                    # end of envelope
          </artwork>
        </figure>

        <figure anchor="chunked_identity_envelope_example">
          <preamble>Chunked Identity Envelope</preamble>
          <artwork>
E x02 x00
m x00 x08 Identity   # "Identity" envelope does nothing to the body
x90                  # no headers
B x00 x0c            # binary header for wrapped body (10 bytes)
  p x02 x00          # wrapped message
  x07 hello,         # "hello, "
  z                  # end of wrapped message
x90                  # no footers

x90                  # no headers
B x00 x08            # binary wrapped body (10 bytes)
  p x02 x00          # wrapped message
  x05 world          # world
  z
x90                  # no footers
z                    # end of envelope
          </artwork>
        </figure>

        <figure anchor="compression_envelope_example">
          <preamble>Compression Envelope</preamble>
          <artwork>
E x02 x00
m x00 x09 Deflation  # "Deflation" envelope compresses the body
x90                  # no headers
B x00 x0a            # binary wrapped body (32 bytes)
  x78 x9c x4b...     # compressed message
x90                  # no footers
z                    # end of envelope
          </artwork>
        </figure>
      </section>
    </section>
      
    <section title="Bytecode map">
      <t>
        Hessian is organized as a bytecode protocol.  A Hessian implementation 
        is essentially a big switch statement on the initial bytecode.
      </t>

      <figure anchor="bytecode_encoding">
        <preamble>Bytecode Encoding</preamble>
        <artwork>
x00 - x1f    # utf-8 string length 0-32
x20 - x2f    # binary data length 0-16
x30 - x37    # reserved
x38 - x3f    # long from -x40000 to x3ffff
x40 - x41    # reserved
x42          # 8-bit binary data final chunk ('B')
x43          # reserved ('C' streaming call)
x44          # 64-bit IEEE encoded double ('D')
x45          # reserved ('E' envelope)
x46          # boolean false ('F')
x47          # reserved
x48          # reserved ('H' header)
x49          # 32-bit signed integer ('I')
x4a          # reference to 1-256th map/list
x4b          # reference to 1-65536th map/list
x4c          # 64-bit signed long integer ('L')
x4d          # map with optional type ('M')
x4e          # null ('N')
x4f          # object definition ('O')
x50          # reserved ('P' streaming message/post)
x51          # reserved
x52          # reference to map/list - integer ('R')
x53          # utf-8 string final chunk ('S')
x54          # boolean true ('T')
x55          # reserved
x56          # list/vector ('V')
x57          # reserved
x58          # utf-8 xml final chunk ('X')
x59 - x62    # reserved
x62          # 8-bit binary data non-final chunk ('b')
x63          # reserved ('c' call for RPC)
x64          # UTC time encoded as 64-bit long milliseconds since 
             #  epoch ('d')
x65          # reserved
x66          # reserved ('f' for fault for RPC)
x67          # double 0.0
x68          # double 1.0
x69          # double represented as byte (-128.0 to 127.0)
x6a          # double represented as short (-32768.0 to 327676.0)
x6b          # double represented as float
x6c          # list/vector length ('l')
x6d          # reserved ('m' method for RPC call)
x6e          # list/vector compact length
x6f          # object instance ('o')
x70          # reserved ('p' - message/post)
x71          # reserved
x72          # reserved ('r' reply for message/RPC)
x73          # utf-8 string non-final chunk ('s')
x74          # map/list type ('t')
x75          # type-ref
x76          # compact vector ('v')
x77          # long encoded as 32-bit int
x78          # utf-8 XML non-final chunk ('x')
x79          # reserved
x7a          # list/map terminator ('z')
x7b - x7f    # reserved
x80 - xbf    # one-byte compact int (-x10 to x3f, x90 is 0)
xc0 - xcf    # two-byte compact int (-x800 to x3ff)
xd0 - xd7    # three-byte compact int (-x40000 to x3ffff)
        </artwork>
      </figure>

    </section>
  </middle>

  <back>
  </back>
 
</rfc>
