You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by jf...@apache.org on 2002/08/29 13:04:34 UTC

cvs commit: jakarta-tomcat-connectors/jk/xdocs/jk2 configtc.xml configweb.xml

jfclere     2002/08/29 04:04:34

  Modified:    jk       build.xml
               jk/xdocs menu.idx style.xsl.in
  Added:       jk/xdocs/common AJPv13.xml
               jk/xdocs/jk2 configtc.xml configweb.xml
  Removed:     jk/xdocs AJPv13.xml configtc.xml configweb.xml
  Log:
  Arrange structure to allow jk and jk2 documentation togother.
  Note:
   - The index.xml is still the jk2 one.
   - The links to sessions are not working.
  
  Revision  Changes    Path
  1.48      +11 -1     jakarta-tomcat-connectors/jk/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jk/build.xml,v
  retrieving revision 1.47
  retrieving revision 1.48
  diff -u -r1.47 -r1.48
  --- build.xml	13 Aug 2002 16:26:37 -0000	1.47
  +++ build.xml	29 Aug 2002 11:04:34 -0000	1.48
  @@ -394,7 +394,17 @@
           basedir="${source.docs}"
           destdir="${build.docs}"
           style="${source.docs}/style.xsl"
  -        includes="**.xml"/>
  +        includes="*/**.xml"
  +        excludes="index.xml">
  +    </style>
  +    <style
  +        basedir="${source.docs}"
  +        destdir="${build.docs}"
  +        style="${source.docs}/style.xsl"
  +        includes="index.xml">
  +        <param name="images" expression="images"/>
  +        <param name="homedoc" expression=""/>
  +    </style>
    
       <!-- Copy all relevant (non processed) files from the sources -->
       <copy
  
  
  
  1.3       +3 -3      jakarta-tomcat-connectors/jk/xdocs/menu.idx
  
  Index: menu.idx
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jk/xdocs/menu.idx,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- menu.idx	20 Jun 2002 19:33:10 -0000	1.2
  +++ menu.idx	29 Aug 2002 11:04:34 -0000	1.3
  @@ -2,7 +2,7 @@
   
   <index>
     <document href="index.xml"/>
  -  <document href="AJPv13.xml"/>
  -  <document href="configtc.xml"/>
  -  <document href="configweb.xml"/>
  +  <document href="common/AJPv13.xml"/>
  +  <document href="jk2/configtc.xml"/>
  +  <document href="jk2/configweb.xml"/>
   </index>
  
  
  
  1.4       +15 -10    jakarta-tomcat-connectors/jk/xdocs/style.xsl.in
  
  Index: style.xsl.in
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jk/xdocs/style.xsl.in,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- style.xsl.in	30 Jun 2002 03:32:01 -0000	1.3
  +++ style.xsl.in	29 Aug 2002 11:04:34 -0000	1.4
  @@ -7,10 +7,14 @@
     <!--
       Let's start by declaring HOW this stylesheet must behave.
     -->
  -  <xsl:output method="html" indent="no"
  +  <xsl:output method="html" indent="yes"
       doctype-public="-//W3C//DTD HTML 4.01//EN"
       doctype-system="http://www.w3.org/TR/html4/strict.dtd"/>
   
  +  <!-- Define default values for parameters -->
  +  <xsl:param name="images" select="'../images'"/>
  +  <xsl:param name="homedoc" select="'../'"/>
  +
     <!-- Defined variables (non-overrideable) -->
     <xsl:variable name="body-bg"       select="'@body-bg@'"/>
     <xsl:variable name="body-fg"       select="'@body-fg@'"/>
  @@ -56,7 +60,7 @@
             <meta name="email" content="{$email}"/>
           </xsl:for-each>
           <link rel="stylesheet" type="text/css" href="style.css"/>
  -        <link rel="shortcut icon" href="images/tomcat.ico"/>
  +        <link rel="shortcut icon" href="{$images}/tomcat.ico"/>
         </head>
   
         <!--
  @@ -72,10 +76,10 @@
             -->
             <tr height="1">
               <td width="150" bgcolor="{$body-bg}" height="1" class="nil">
  -              <img src="images/pixel.gif" border="0" width="150" height="1" vspace="0" hspace="0"/>
  +              <img src="{$images}/pixel.gif" border="0" width="150" height="1" vspace="0" hspace="0"/>
               </td>
               <td width="*" bgcolor="{$body-bg}" height="1" class="nil">
  -              <img src="images/pixel.gif" border="0" width="370" height="1" vspace="0" hspace="0"/>
  +              <img src="{$images}/pixel.gif" border="0" width="370" height="1" vspace="0" hspace="0"/>
               </td>
             </tr>
   
  @@ -87,10 +91,10 @@
                 <table border="0" cellspacing="0" cellpadding="0" width="100%">
                   <tr>
                     <td align="left">
  -                    <img src="images/jakarta.gif" border="0" width="270" height="75" align="left"/>
  +                    <img src="{$images}/jakarta.gif" border="0" width="270" height="75" align="left"/>
                     </td>
                     <td align="right">
  -                    <img src="images/mod_jk.jpeg" border="0" width="400" height="75" align="right"/>
  +                    <img src="{$images}/mod_jk.jpeg" border="0" width="400" height="75" align="right"/>
                     </td>
                   </tr>
                 </table>
  @@ -131,10 +135,10 @@
                   <!-- Empty row, thanks IE -->
                   <tr height="1">
                     <td width="10" bgcolor="#cccccc" height="1" class="nil">
  -                    <img src="images/pixel.gif" border="0" width="10" height="1" vspace="0" hspace="0"/>
  +                    <img src="{$images}/pixel.gif" border="0" width="10" height="1" vspace="0" hspace="0"/>
                     </td>
                     <td width="140" bgcolor="#cccccc" height="1" class="nil">
  -                    <img src="images/pixel.gif" border="0" width="140" height="1" vspace="0" hspace="0"/>
  +                    <img src="{$images}/pixel.gif" border="0" width="140" height="1" vspace="0" hspace="0"/>
                     </td>
                   </tr>
   
  @@ -231,7 +235,7 @@
         <table border="0" cellspacing="0" cellpadding="0" width="100%">
           <tr>
             <td bgcolor="{$banner-bg}" class="section" valign="top" align="left">
  -            <img src="images/corner.gif" valign="top" align="left" hspace="0" vspace="0" border="0"/>
  +            <img src="{$images}/corner.gif" valign="top" align="left" hspace="0" vspace="0" border="0"/>
                 <xsl:if test="string-length(description/text()) = 0">
                   <xsl:value-of select="@name"/>
                 </xsl:if>
  @@ -249,7 +253,7 @@
         <table border="0" cellspacing="0" cellpadding="0" width="100%">
           <tr>
             <td bgcolor="{$sub-banner-bg}" class="subsection" valign="top" align="left">
  -            <img src="images/corner.gif" valign="top" align="left" hspace="0" vspace="0" border="0"/>
  +            <img src="{$images}/corner.gif" valign="top" align="left" hspace="0" vspace="0" border="0"/>
                 <xsl:if test="string-length(description/text()) = 0">
                   <xsl:value-of select="@name"/>
                 </xsl:if>
  @@ -483,6 +487,7 @@
             anchor we gathered before. We call this "target".
           -->
           <xsl:variable name="target">
  +          <xsl:value-of select="$homedoc"/>
             <xsl:if test="string-length($file) > 0">
               <xsl:choose>
                 <xsl:when test="substring($file,string-length($file)-3) = '.xml'">
  
  
  
  1.1                  jakarta-tomcat-connectors/jk/xdocs/common/AJPv13.xml
  
  Index: AJPv13.xml
  ===================================================================
  <?xml version="1.0"?> 
  <document>
    <properties>
      <title>Apache JServ Protocol version 1.3</title>
      <author email="danmil@shore.net">danmil@shore.net</author>
      <author email="jfrederic.clere@fujitsu-siemens.com">Jean-Frederic Clere</author>
    </properties>
  
  <section name="Intro">
  
  <p>
  The original document was written by
  Dan Milstein, <author email="danmil@shore.net">danmil@shore.net</author>
  on December 2000. The present document is generated out of an xml file
  to allow a more easy integration in the Tomcat documentation.
  
  </p>
  
  <p>
  This describes the Apache JServ Protocol version 1.3 (hereafter
  <b>ajp13</b>).  There is, apparently, no current documentation of how the
  protocol works.  This document is an attempt to remedy that, in order to
  make life easier for maintainers of mod_jk, and for anyone who wants to
  port the protocol somewhere (into jakarta 4.x, for example).
  </p>
  
  </section>
  
  <section name="author">
  
  <p>
  I am not one of the designers of this protocol -- I believe that Gal
  Shachor was the original designer.  Everything in this document is derived
  from the actual implementation I found in the tomcat 3.x code.  I hope it
  is useful, but I can't make any grand claims to perfect accuracy.  I also
  don't know why certain design decisions were made.  Where I was able, I've
  offered some possible justifications for certain choices, but those are
  only my guesses.  In general, the C code which Shachor wrote is very clean
  and comprehensible (if almost totally undocumented).  I've cleaned up the
  Java code, and I think it's reasonably readable.
  </p>
  </section>
  
  <section name="Design Goals">
  
  <p>
  According to email from Gal Shachor to the jakarta-dev mailing list,
  the original goals of <b>mod_jk</b> (and thus <b>ajp13</b>) were to extend
  <b>mod_jserv</b> and <b>ajp12</b> by (I am only including the goals which
  relate to communication between the web server and the servlet container):
  
  <ul>
    <li> Increasing performance (speed, specifically). </li>
  
    <li> Adding support for SSL, so that <code>isSecure()</code> and
         <code>geScheme()</code> will function correctly within the servlet
         container.  The client certificates and cipher suite will be
         available to servlets as request attributes. </li>
  
  </ul>
  </p>
  </section>
  
  <section name="Overview of the protocol">
  
  <p>
  The <b>ajp13</b> protocol is packet-oriented.  A binary format was
  presumably chosen over the more readable plain text for reasons of
  performance.  The web server communicates with the servlet container over
  TCP connections.  To cut down on the expensive process of socket creation,
  the web server will attempt to maintain persistent TCP connections to the
  servlet container, and to reuse a connection for multiple request/response
  cycles.
  </p><p>
  Once a connection is assigned to a particular request, it will not be
  used for any others until the request-handling cycle has terminated.  In
  other words, requests are not multiplexed over connections.  This makes
  for much simpler code at either end of the connection, although it does
  cause more connections to be open at once.
  </p><p>
  Once the web server has opened a connection to the servlet container,
  the connection can be in one of the following states:
  </p><p>
  <ul>
    <li> Idle <br/> No request is being handled over this connection. </li>
    <li> Assigned <br/> The connecton is handling a specific request.</li>
  </ul>
  
  </p><p>
  Once a connection is assigned to handle a particular request, the basic
  request informaton (e.g. HTTP headers, etc) is sent over the connection in
  a highly condensed form (e.g. common strings are encoded as integers).
  Details of that format are below in Request Packet Structure. If there is a
  body to the request (content-length > 0), that is sent in a separate
  packet immediately after.
  </p><p>
  At this point, the servlet container is presumably ready to start
  processing the request.  As it does so, it can send the
  following messages back to the web server:
  
  <ul>
    <li>SEND_HEADERS <br/>Send a set of headers back to the browser.</li>
  
    <li>SEND_BODY_CHUNK <br/>Send a chunk of body data back to the browser.</li>
  
    <li>GET_BODY_CHUNK <br/>Get further data from the request if it hasn't all
    been transferred yet.  This is necessary because the packets have a fixed
    maximum size and arbitrary amounts of data can be included the body of a
    request (for uploaded files, for example).  (Note: this is unrelated to
    HTTP chunked tranfer).</li>
  
    <li>END_RESPONSE <br/> Finish the request-handling cycle.</li>
  </ul>
  </p><p>
  
  Each message is accompanied by a differently formatted packet of data.  See
  Response Packet Structures below for details.
  </p>
  </section>
  
  <section name="Basic Packet Structure">
  
  <p>
  There is a bit of an XDR heritage to this protocol, but it differs in
  lots of ways (no 4 byte alignment, for example).
  </p><p>
  Byte order: I am not clear about the endian-ness of the individual
  bytes.  I'm guessing the bytes are little-endian, because that's what XDR
  specifies, and I'm guessing that sys/socket library is magically making
  that so (on the C side).  If anyone with a better knowledge of socket calls
  can step in, that would be great.
  </p><p>
  There are four data types in the protocol: bytes, booleans, integers and
  strings.
  
  <dl>
    <dt><b>Byte</b></dt>
    <dd>A single byte.</dd>
  
    <dt><b>Boolean</b></dt>
    <dd>A single byte, 1 = true, 0 = false.  Using other non-zero values as
    true (i.e. C-style) may work in some places, but it won't in
    others.</dd>
    
    <dt><b>Integer</b></dt>
    <dd>A number in the range of 0 to 2^16 (32768).  Stored in 2 bytes with
    the high-order byte first.</dd>
  
    <dt><b>String</b></dt>
    <dd>A variable-sized string (length bounded by 2^16). Encoded with the
    length packed into two bytes first, followed by the string (including the
    terminating '\0').  Note that the encoded length does <b>not</b> include
    the trailing '\0' -- it is like <code>strlen</code>.  This is a touch
    confusing on the Java side, which is littered with odd autoincrement
    statements to skip over these terminators.  I believe the reason this was
    done was to allow the C code to be extra efficient when reading strings
    which the servlet container is sending back -- with the terminating \0
    character, the C code can pass around references into a single buffer,
    without copying.  If the \0 was missing, the C code would have to copy
    things out in order to get its notion of a string.</dd>
  </dl>
  </p>
  
  <subsection name="Packet Size">
  <p>
  According to much of the code, the max packet
  size is 8 * 1024 bytes (8K).  The actual length of the packet is encoded in the
  header.
  </p>
  </subsection>
  
  <subsection name="Packet Headers">
  <p>
  Packets sent from the server to the container begin with
  <code>0x1234</code>.  Packets sent from the container to the server begin
  with <code>AB</code> (that's the ASCII code for A followed by the ASCII
  code for B).  After those first two bytes, there is an integer (encoded as
  above) with the length of the payload.  Although this might suggest that
  the maximum payload could be as large as 2^16, in fact, the code sets the
  maximum to be 8K.
  
  
  <table>
    <tr>
      <th colspan="6">Packet Format (Server->Container)</th>
    </tr>
  
    <tr>
      <th>Byte</th>
      <td>0</td>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4...(n+3)</td>
    </tr>
  
    <tr>
      <th>Contents</th>
      <td>0x12</td>
      <td>0x34</td>
      <td colspan="2">Data Length (n)</td>
      <td>Data</td>
    </tr>
  </table>
  
  <table>
    <tr>
      <th colspan="6"><b>Packet Format (Container->Server)</b></th>
    </tr>
  
    <tr>
      <th>Byte</th>
      <td>0</td>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4...(n+3)</td>
    </tr>
  
    <tr>
      <th>Contents</th>
      <td>A</td>
      <td>B</td>
      <td colspan="2">Data Length (n)</td>
      <td>Data</td>
    </tr>
  </table>
  
  
  <A NAME="prefix-codes"></A> For most packets, the first byte of the
  payload encodes the type of message.  The exception is for request body
  packets sent from the server to the container -- they are sent with a
  standard packet header (0x1234 and then length of the packet), but without
  any prefix code after that (this seems like a mistake to me).
  </p><p>
  The web server can send the following messages to the servlet container:
  
  <table>
    <tr>
      <th>Code</th>
      <th>Type of Packet</th>
      <th>Meaning</th>
    </tr>
    <tr>
      <td>2</td>
      <td>Forward Request</td>
      <td>Begin the request-processing cycle with the following data</td>
    </tr>
    <tr>
      <td>7</td>
      <td>Shutdown</td>
      <td>The web server asks the container to shut itself down.</td>
    </tr>
  </table>
  
  </p>
  <p>The servlet container can send the following types of messages to the web
  server:
  <table>
    <tr>
      <th>Code</th>
      <th>Type of Packet</th>
      <th>Meaning</th>
    </tr>
    <tr>
      <td>3</td>
      <td>Send Body Chunk</td>
      <td>Send a chunk of the body from the servlet container to the web
      server (and presumably, onto the browser). </td>
    </tr>
    <tr>
      <td>4</td>
      <td>Send Headers</td>
      <td>Send the response headers from the servlet container to the web
      server (and presumably, onto the browser).</td>
    </tr>
    <tr>
      <td>5</td>
      <td>End Response</td>
      <td>Marks the end of the response (and thus the request-handling cycle).</td>
    </tr>
    <tr>
      <td>6</td>
      <td>Get Body Chunk</td>
      <td>Get further data from the request if it hasn't all been transferred
      yet.</td>
    </tr>
  </table>
  </p>
  <p>
  Each of the above messages has a different internal structure, detailed below.
  </p>
  </subsection>
  </section>
  
  <section name="Request Packet Structure">
  
  <p>
  For messages from the server to the container of type "Forward Request":
  </p><p>
  <source>
  AJP13_FORWARD_REQUEST :=
      prefix_code      (byte) 0x02 = JK_AJP13_FORWARD_REQUEST
      method           (byte)
      protocol         (string)
      req_uri          (string)
      remote_addr      (string)
      remote_host      (string)
      server_name      (string)
      server_port      (integer)
      is_ssl           (boolean)
      num_headers      (integer)
      request_headers *(req_header_name req_header_value)
      attributes      *(attribut_name attribute_value)
      request_terminator (byte) OxFF
  </source>
  </p><p>
  The <code>request_headers</code> have the following structure:
  </p><p>
  <source>
  req_header_name := 
      sc_req_header_name | (string)  [see below for how this is parsed]
  
  sc_req_header_name := 0xA0xx (integer)
  
  req_header_value := (string)
  </source>
  </p><p>
  
  The <code>attributes</code> are optional and have the following structure:
  </p><p>
  <source>
  attribute_name := (string)
  
  attribute_value := (string)
  
  </source>
  </p><p>
  Not that the all-important header is "content-length', because it
  determines whether or not the container looks for another packet
  immediately.
  </p><p>
  Detailed description of the elements of Forward Request.
  </p>
  <subsection name="request_prefix">
  <p>
  For all requests, this will be 2.
  See above for details on other <A HREF="#prefix-codes">prefix codes</A>.
  </p>
  </subsection>
  
  <subsection name="method">
  <p>
  The HTTP method, encoded as a single byte:
  
  <source>
  OPTIONS      1
  GET          2
  HEAD         3
  POST         4
  PUT          5
  DELETE       6
  TRACE        7
  PROPFIND     8
  PROPPATCH    9
  MKCOL       10
  COPY        11
  MOVE        12
  LOCK        13
  UNLOCK      14
  ACL         15
  REPORT      16
  VERSION-CONTROL 17
  CHECKIN     18
  CHECKOUT    19
  UNCHECKOUT  20
  SEARCH      21
  </source>
  </p>
  </subsection>
  
  <subsection  name="protocol, req_uri, remote_addr, remote_host, server_name, server_port, is_ssl">
  <p>
    These are all fairly self-explanatory.  Each of these is required, and
    will be sent for every request.
  </p>
  </subsection>
  
  <subsection name="Headers">
  <p>
    The structure of <code>request_headers</code> is the following:
    First, the number of headers <code>num_headers</code> is encoded.
    Then, a series of header name <code>req_header_name</code> / value
    <code>req_header_value</code> pairs follows.
    Common header names are encoded as integers,
    to save space.  If the header name is not in the list of basic headers,
    it is encoded normally (as a string, with prefixed length).  The list of
    common headers <code>sc_req_header_name</code>and their codes
    is as follows (all are case-sensitive):
  </p><p>
  <table>
    <tr><th>
      Name</th><th>Code value</th><th>Code name</th>
    </tr><tr><td>
      accept</td><td>0xA001</td><td>SC_REQ_ACCEPT</td>
    </tr><tr><td>
      accept-charset</td><td>0xA002</td><td>SC_REQ_ACCEPT_CHARSET</td>
    </tr><tr><td>
      accept-encoding</td><td>0xA003</td><td>SC_REQ_ACCEPT_ENCODING</td>
    </tr><tr><td>
      accept-language</td><td>0xA004</td><td>SC_REQ_ACCEPT_LANGUAGE</td>
    </tr><tr><td>
      authorization</td><td>0xA005</td><td>SC_REQ_AUTHORIZATION</td>
    </tr><tr><td>
      connection</td><td>0xA006</td><td>SC_REQ_CONNECTION</td>
    </tr><tr><td>
      content-type</td><td>0xA007</td><td>SC_REQ_CONTENT_TYPE</td>
    </tr><tr><td>
      content-length</td><td>0xA008</td><td>SC_REQ_CONTENT_LENGTH</td>
    </tr><tr><td>
      cookie</td><td>0xA009</td><td>SC_REQ_COOKIE</td>
    </tr><tr><td>
      cookie2</td><td>0xA00A</td><td>SC_REQ_COOKIE2</td>
    </tr><tr><td>
      host</td><td>0xA00B</td><td>SC_REQ_HOST</td>
    </tr><tr><td>
      pragma</td><td>0xA00C</td><td>SC_REQ_PRAGMA</td>
    </tr><tr><td>
      referer</td><td>0xA00D</td><td>SC_REQ_REFERER</td>
    </tr><tr><td>
      user-agent</td><td>0xA00E</td><td>SC_REQ_USER_AGENT</td>
    </tr>
  </table>
  </p><p>
    The Java code that reads this grabs the first two-byte integer and if
    it sees an <code>'0xA0'</code> in the most significant
    byte, it uses the integer in the second byte as an index into an array of
    header names.  If the first byte is not '0xA0', it assumes that the
    two-byte integer is the length of a string, which is then read in.
  </p><p>
    This works on the assumption that no header names will have length
    greater than 0x9999 (==0xA000 - 1), which is perfectly reasonable, though
    somewhat arbitrary. (If you, like me, started to think about the cookie
    spec here, and about how long headers can get, fear not -- this limit is
    on header <b>names</b> not header <b>values</b>.  It seems unlikely that
    unmanageably huge header names will be showing up in the HTTP spec any time
    soon).
  </p><p>
    <b>Note:</b> The <code>content-length</code> header is extremely
    important.  If it is present and non-zero, the container assumes that
    the request has a body (a POST request, for example), and immediately
    reads a separate packet off the input stream to get that body.
  </p>
  </subsection>
  
  <subsection name="Optional Information">
  <p>
  
    The list of attributes prefixed with a <code>?</code>
    (e.g. <code>?context</code>) are all optional.  For each, there is a
    single byte code to indicate the type of attribute, and then a string to
    give its value.  They can be sent in any order (thogh the C code always
    sends them in the order listed below).  A special terminating code is
    sent to signal the end of the list of optional attributes. The list of
    byte codes is:
  </p><p>
  <source>
  context            1 [Not currently implemented]
  servlet_path       2 [Not currently implemented]
  remote_user        3
  auth_type          4
  query_string       5
  jvm_route          6
  ssl_cert           7
  ssl_cipher         8
  ssl_session        9
  
  req_attribute      10 
  
  terminator         0xFF
  </source>
  </p><p>
  
    The <code>context</code> and <code>servlet_path</code> are not currently
    set by the C code, and most of the Java code completely ignores whatever
    is sent over for those fields (and some of it will actually break if a
    string is sent along after one of those codes).  I don't know if this is
    a bug or an unimplemented feature or just vestigial code, but it's
    missing from both sides of the connection.
  </p><p>
    The <code>remote_user</code> and <code>auth_type</code> presumably refer
    to HTTP-level authentication, and communicate the remote user's username
    and the type of authentication used to establish their identity (e.g. Basic,
    Digest).  I'm not clear on why the password isn't also sent, but I don't
    know HTTP authentication inside and out.
  </p><p>
    The <code>query_string</code>, <code>ssl_cert</code>,
    <code>ssl_cipher</code>, and <code>ssl_session</code> refer to the
    corresponding pieces of HTTP and HTTPS.
  </p><p>
    The <code>jvm_route</code>, as I understand it, is used to support sticky
    sessions -- associating a user's sesson with a particular Tomcat instance
    in the presence of multiple, load-balancing servers.  I don't know the
    details.
  </p><p>
    Beyond this list of basic attributes, any number of other attributes can
    be sent via the <code>req_attribute</code> code (10).  A pair of strings
    to represent the attribute name and value are sent immediately after each
    instance of that code.  Environment values are passed in via this method.
  </p><p>
    Finally, after all the attributes have been sent, the attribute terminator,
    0xFF, is sent.  This signals both the end of the list of attributes, and
    also then end of the Request Packets as a whole.
  </p><p>
  
  The server can also send a <code>shutdown</code> packet.  To ensure some
  basic security, the container will only actually do the shutdown if the
  request comes from the same machine on which it's hosted.
  </p>
  </subsection>
  
  </section>
  
  <section name="Response Packet Structure">
  
  <p>
  For messages which the container can send back to the server.
  
  <source>
  AJP13_SEND_BODY_CHUNK := 
    prefix_code   3
    chunk_length  (integer)
    chunk        *(byte)
  
  
  AJP13_SEND_HEADERS :=
    prefix_code       4
    http_status_code  (integer)
    http_status_msg   (string)
    num_headers       (integer)
    response_headers *(res_header_name header_value)
  
  res_header_name := 
      sc_res_header_name | (string)   [see below for how this is parsed]
  
  sc_res_header_name := 0xA0 (byte)
  
  header_value := (string)
  
  AJP13_END_RESPONSE :=
    prefix_code       5
    reuse             (boolean)
  
  
  AJP13_GET_BODY_CHUNK :=
    prefix_code       6
    requested_length  (integer)
  </source>
  
  </p>
  <p>
  Details:
  </p>
  
  <subsection name="Send Body Chunk">
  <p>
    The chunk is basically binary data, and is sent directly back to the browser.
  </p>
  </subsection>
  
  <subsection name="Send Headers">
  <p>
    The status code and message are the usual HTTP things (e.g. "200" and "OK").
    The response header names are encoded the same way the request header names are.
    See <A HREF="#header_encoding">above</A> for details about how the the
    codes are distinguished from the strings.  The codes for common headers are:
  </p><p>
  <source>
  Content-Type         0xA001
  Content-Language     0xA002
  Content-Length       0xA003 
  Date                 0xA004
  Last-Modified        0xA005
  Location             0xA006
  Set-Cookie           0xA007
  Set-Cookie2          0xA008
  Servlet-Engine       0xA009
  Status               0xA00A
  WWW-Authenticate     0xA00B
  </source>
  </p><p> 
    After the code or the string header name, the header value is immediately
    encoded.
  </p>
  </subsection>
  
  <subsection name="End Response">
  <p>
    Signals the end of this request-handling cycle.  If the
    <code>reuse</code> flag is true (==1), this TCP connection can now be used to
    handle new incoming requests.  If <code>reuse</code> is false (anything
    other than 1 in the actual C code), the connection should be closed.
  </p>
  </subsection>
  
  <subsection name="Get Body Chunk">
  <p>
    The container asks for more data from the request (if the body was
    too large to fit in the first packet sent over).  The server will send a
    body packet back with an amount of data which is the minimum of the
    <code>request_length</code>, the maximum send body size (XXX), and the
    number of bytes actually left to send from the request body.
  <br/>
    If there is no more data in the body (i.e. the servlet container is
    trying to read past the end of the body), the server will send back an
    "empty" packet, whch is a body packet with a payload length of 0.
  </p>
  </subsection>
  </section>
  
  <section name="Questions I Have">
  
  <p> What happens if the request headers > max packet size?  There is no
  provision to send a second packet of request headers in case there are more
  than 8K (I think this is correctly handled for response headers, though I'm
  not certain).  I don't know if there is a way to get more than 8K worth of
  data into that initial set of request headers, but I'll bet there is
  (combine long cookies with long ssl information and a lot of environment
  variables, and you should hit 8K easily).  I think the connector would just
  fail before trying to send any headers in this case, but I'm not certain.</p>
  
  <p> What about authentication?  There doesn't seem to be any authentication
  of the connection between the web server and the container.  This strikes
  me as potentially dangerous.</p>
  
  </section>
  
  
  </document>
  
  
  
  1.1                  jakarta-tomcat-connectors/jk/xdocs/jk2/configtc.xml
  
  Index: configtc.xml
  ===================================================================
  <?xml version="1.0"?>
  <document>
    <properties>
      <title>Configuration in the Tomcat</title>
      <author email="jfrederic.clere@fujitsu-siemens.com">Jean-Frederic Clere</author>
    </properties>
  
  <section name="Intro">
  <p>
    This document describes the configuration file used by mod_jk2 on the
    Tomcat site. Its default name is ${jkHome}/conf/jk2.properties,
    where ${jkHome} is the well known ${catalina.base} property.
  </p>
  </section>
  
  <section name="Config options">
  <p>
  <table>
  
    <tr>
    <th>Property name</th>
    <th>Default</th>
    <th>Description</th>
    </tr>
  
    <tr>
    <td>handler.list</td>
    <td>apr,shm,request,container,channelSocket,channelJni,channelUnix</td>
    <td>Handlers to load.</td>
    </tr>
  
    <tr>
    <td>class.myhandler</td>
    <td>No default value</td>
    <td>Define the class of the handler myhandler.</td>
    </tr>
  
    <tr>
    <th colspan="2">apr</th>
    <td>APR descriptor</td>
    </tr>
  
    <tr>
    <td>NativeSo</td>
    <td>jkjni</td>
    <td>
      Location of the jkjni dynamic library.
      It is searched in java.library.path but a absolut path can be specified.
    </td>
    </tr>
  
    <tr>
    <th colspan="2">channelSocket</th>
    <td>A communication transport from a remote Web Server.</td>
    </tr>
  
    <tr>
    <td>port</td>
    <td>8009</td>
    <td>First port where Tomcat is listening</td>
    </tr>
  
    <tr>
    <td>address</td>
    <td>127.0.0.1</td>
    <td>Local address where Tomcat is listening.</td>
    </tr>
  
    <tr>
    <td>maxPort</td>
    <td>port+10</td>
    <td>Max port used to listen.</td>
    </tr>
  
    <tr>
    <th colspan="2">channelUnix</th>
    <td>A AF_UNIX socket communication transport from a local Web Server.</td>
    </tr>
  
    <tr>
    <td>file</td>
    <td>No default value</td>
    <td>
      Name of the "file" associate with the socket.
      That must be absolut path name.
    </td>
    </tr>
  
    <tr>
    <th colspan="2">channelJni</th>
    <td>A in Web Server process communication.</td>
    </tr>
  
    <tr>
    <th colspan="2">mx</th>
    <td>mx4j adapter.</td>
    </tr>
  
    <tr>
    <td>port</td>
    <td>-1 (Disabled)</td>
    <td>Port Number.</td>
    </tr>
  
    <tr>
    <th colspan="2">shm</th>
    <td>shared memory objects handler.</td>
    </tr>
  
    <tr>
    <td>file</td>
    <td>/tmp/shm.file</td>
    <td>Shared memory file.</td>
    </tr>
  
    <tr>
    <td>host</td>
    <td>localhost</td>
    <td>Host name.</td>
    </tr>
  
    <tr>
    <td>port</td>
    <td>8009</td>
    <td>Port number.</td>
    </tr>
  
    <tr>
    <td>unixSocket</td>
    <td>No default value</td>
    <td>Unix socket where tomcat is listening.</td>
    </tr>
  
  </table>
  </p>
  </section>
    
  <section name="Examples">
  <p>
  The examples below are working when the Web Server is configured according the 
  examples described in the configweb file.
  </p>
  <subsection name="using normal socket">
  <p>
  There is no need to use the jkjni logic to use normal socket, so that just for
  Fun.
  </p>
  
  <p>
  <source>
  # list of needed handlers.
  handler.list=apr,channelSocket,request
  
  # Override the default port for the channelSocket
  channelSocket.port=8019
  
  # Dynamic library
  apr.NativeSo=/home1/jakarta/jakarta-tomcat-connectors/jk/build/jk2/apache2/jkjni.so
  </source>
  </p>
  </subsection>
  
  <subsection name="using AF_UNIX socket">
  <p>
  Create and listen on a AF_UNIX socket. The location of the socket must be the
  same in the Web Server configuration file.
  </p>
  
  <p>
  <source>
  # list of needed handlers.
  handler.list=apr,channelUnix,request
  
  # Location of the socket.
  channelUnix.file=${jkHome}/work/jk2.socket
  
  # Dynamic library
  jtc=/home1/jakarta/jakarta-tomcat-connectors
  apr.NativeSo=${jtc}/jk/build/jk2/apache2/jkjni.so
  </source>
  </p>
  </subsection>
  
  <subsection name="using user defined class for communication">
  <p>
  It is possible to have a user defined class for the communication.
  Here we have used the ChannelUn as example.
  </p>
  
  <p>
  <source>
  # Define our own handler.
  class.mychannel=org.apache.jk.common.ChannelUn
  # list of needed handlers.
  handler.list=apr,mychannel,request
  
  # Location of the socket.
  channelUnix.file=${jkHome}/work/jk2.socket
  
  # Dynamic library
  jtc=/home1/jakarta/jakarta-tomcat-connectors
  apr.NativeSo=${jtc}/jk/build/jk2/apache2/jkjni.so
  </source>
  </p>
  </subsection>
  </section>
  </document>
  
  
  
  1.1                  jakarta-tomcat-connectors/jk/xdocs/jk2/configweb.xml
  
  Index: configweb.xml
  ===================================================================
  <?xml version="1.0"?>
  <document>
      <properties>
          <title>Configuration in the Web Server</title>
          <author email="cmanolache@yahoo.com">Costin Manolache</author>
          <author email="jfrederic.clere@fujitsu-siemens.com">Jean-Frederic Clere</author>
      </properties>
      <section name="Intro">
          <p>Jk2 uses a config file ( workers2.properties ) in the style of a .properties or ini
   file. It can be configured to use any other backend that provides similar
   capabilities.
    </p>
          <p>
    This document describes the format of this configuration file. Its default name is ${serverRoot}/conf/workers2.properties,
    where ${serverRoot} is something like /opt/apache.
  </p>
      </section>
      <section name="Installation">
          <subsection name="Apache 1"/>
          <subsection name="Apache 2"/>
          <subsection name="IIS"/>
      </section>
      <section name="Config file">
          <p> The default config file is user editable, but mod_jk will persist the 
  changes requested by protocol( not implemented). If you manually change the file while jk2 is 
  working, your changes will be lost. 
    </p>
          <p>The default configuration format . .  Each setting consists of an object 
  name and a property, with the associated value. The property name is a simple
   string, with no '.' in it. The name can be anything, but it must have a
  known  'type' as prefix.  
    </p>
          <p>2 formats are supported:   
              <source>
                  TYPE:NAME.PROPERTY=VALUE 
              </source>
          </p>
          <p>and
              <source>
                  [TYPE:NAME]
                  PROPERTY=VALUE
              </source>
          </p>
      </section>
      <section name="Components"><p>Each component instance has a name, that is used for configuration and at runtime. Each component has a number of configurable properties. The following rules are used:
  <ul><li>The name is composed from the type and a local part, separated with a ':' ( example: channel.unixsocket:/tmp/jk.socket ) </li>
  <li>The 'type' consist of '.' and ascii characters.  It is mapped to a JMX 'domain'.  </li>
  <li>The local part consists of ascii characters and .:/; 
  <p>Note that '=,' are not currently allowed - a future version may support the jmx syntax by using quotes to separate the local part from the property and value ( in .properties mode we must use '=' to separate the value from type, local name and property name ). </p></li>
  <li>The property is a simple name, with no dots. </li>
  <li>A simple form of substitution is used in values, where $(property) will be replaced with a previously defined setting. If the property has ':' in it, it'll take the value from the object, if not it'll take the value from a global map.</li></ul></p>
          <subsection name="Common properties">
              <p>Common properties for all components</p>
              <p>
                  <table>
                      <tr>
                          <th>Property name</th>
                          <th>Default</th>
                          <th>Description</th>
                      </tr>
                      <tr>
                          <td>disabled</td>
                          <td>0 (false)</td>
                          <td>"disabled" state for the component, 1=true 0=false</td>
                      </tr>
                      <tr>
                          <td>debug</td>
                          <td>0 (false)</td>
                          <td>"debug" state for the component, 1=true 0=false</td>
                      </tr>
                  </table>
              </p>
          </subsection>
          <subsection name="workerEnv">
              <p>This component represent the core jk2, it has the default logger for all other components. Is the central controller, it controls global properties
  and  provides access to all other objects</p>
              <p>
                  <table>
                      <tr>
                          <th>Property name</th>
                          <th>Default</th>
                          <th>Description</th>
                      </tr>
                      <tr>
                          <td>logger</td>
                          <td>logger</td>
                          <td>Default loger used by jk2 components, can be changed in the config file, normally it defaults to "logger" the Alias for the default logger for the Server/platform.</td>
                      </tr>
                      <tr>
                          <td>timing</td>
                          <td>0</td>
                          <td>Will jk2 get request timing (needs APR?)</td>
                      </tr>
                  </table>
              </p>
          </subsection>
          <subsection name="config">
              <p>The config component, hold the detail of the conifg system, such config file name, create global defines</p>
              <p>
                  <table>
                      <tr>
                          <th>Property name</th>
                          <th>Default</th>
                          <th>Description</th>
                      </tr>
                      <tr>
                          <td>debugEnv</td>
                          <td>0</td>
                          <td>Set the debug level of the hidden env component </td>
                      </tr>
                  </table>
              </p>
          </subsection>
          <subsection name="uriMap"/>
          <subsection name="shm">
              <p>Shared memory descriptor</p>
              <p>
                  <table>
                      <tr>
                          <th>Property name</th>
                          <th>Default</th>
                          <th>Description</th>
                      </tr>
                      <tr>
                          <td>file</td>
                          <td>No default value</td>
                          <td>Name of the file that will be mmapped to use as shared memory.</td>
                      </tr>
                      <tr>
                          <td>size</td>
                          <td>No default value</td>
                          <td>Size of the file.</td>
                      </tr>
                  </table>
              </p>
          </subsection>
          <subsection name="uri">
              <p>A uri stores a pattern that is used
   to match requests to workers, and asociated properties</p>
              <p>
                  <table>
                      <tr>
                          <th>Property name</th>
                          <th>Default</th>
                          <th>Description</th>
                      </tr>
                      <tr>
                          <td>worker</td>
                          <td>lb:0 (The default loadbalancer)</td>
                          <td>Name of the worker that process the request corresponding to the uri</td>
                      </tr>
                      <tr>
                          <td>context</td>
                          <td/>
                          <td>the context that will be served by this uri component (webapp style)</td>
                      </tr>
                  </table>
              </p>
          </subsection>
          <subsection name="vm">
              <p>Represents the JVM when used as inprocess container
              </p>
              <p>
                  <table>
                      <tr>
                          <th>Property name</th>
                          <th>Default</th>
                          <th>Description</th>
                      </tr>
                      <tr>
                          <td>JVM</td>
                          <td>(Autoguess)</td>
                          <td>JVM to use for this vm</td>
                      </tr>
                      <tr>
                          <td>OPT</td>
                          <td/>
                          <td>Option to pass to this vm, this is a multivalued property</td>
                      </tr>
                  </table>
              </p>
          </subsection>
          <subsection name="channels">
              <p>A channel represents a transport protocol, connecting 2
  sides  for RPC communication. The most common and standard is the tcp socket.
  Other  important  channels are unix socket and jni</p>
              <subsection name="channel.un">
                  <p>
      AF_UNIX socket. Only on UNIX like platform. These sockets are faster
      than "normal" sockets but they are limited to the machine. 
  </p>
                  <p>
                      <table>
                          <tr>
                              <th>Property name</th>
                              <th>Default</th>
                              <th>Description</th>
                          </tr>
                          <tr>
                              <td>file</td>
                              <td>Name of socket</td>
                              <td>Name of the socket file (It is created by the Tomcat ChannelUn)</td>
                          </tr>
                      </table>
                  </p>
              </subsection>
              <subsection name="channel.socket">
                  <p>
      A communication transport to a remote Engine
      <b>Magic:</b> The local part of the name will be the Engine name,
      to use when defining the uri mappings. For example
      channel.socket.local_9009 will automatically define an engine named
      local_9009, and if no other setting is set ajp13 will be used for
      communication.
      <b>Magic:</b> If no channel is defined in the config, a default channel
      will be constructed with port=8009, engine=DEFAULT, worker=ajp13 -
      named 'channel.socket.DEFAULT'
  </p>
                  <p>
                      <table>
                          <tr>
                              <th>Property name</th>
                              <th>Default</th>
                              <th>Description</th>
                          </tr>
                          <tr>
                              <td>port</td>
                              <td>8009</td>
                              <td>Port where Tomcat is listening</td>
                          </tr>
                          <tr>
                              <td>host</td>
                              <td>localhost</td>
                              <td>Remote host</td>
                          </tr>
                          <tr>
                              <td>keepalive</td>
                              <td>0</td>
                              <td>? </td>
                          </tr>
                          <tr>
                              <td>lbfactor</td>
                              <td>1</td>
                              <td>
      Load balancing factor to use. At this moment, it'll be set on the worker,
      but in future it should be possible to use lb on a channel level.
    </td>
                          </tr>
                          <tr>
                              <td>group</td>
                              <td>lb:0</td>
                              <td>loadbalanced groups to which this channel and the associated worker will be added, multivalued</td>
                          </tr>
                          <tr>
                              <td>tomcatId</td>
                              <td>?</td>
                              <td>?</td>
                          </tr>
                      </table>
                  </p>
              </subsection>
              <subsection name="channel.jni">
                  <p>The jni channel, used if tomcat is started inprocess</p>
              </subsection>
          </subsection>
          <subsection name="workers">
              <subsection name="jni">
                  <p>worker used in inprocess, holds the details of the Tomcat class to startup, and paramters to pass</p>
                  <p>
                      <table>
                          <tr>
                              <th>Property name</th>
                              <th>Default</th>
                              <th>Description</th>
                          </tr>
                          <tr>
                              <td>class</td>
                              <td>org/apache/jk/apr/TomcatStarter</td>
                              <td>class that holds the main method called to start tomcat</td>
                          </tr>
                          <tr>
                              <td>ARG</td>
                              <td/>
                              <td>Arguments to pass to main method when called</td>
                          </tr>
                          <tr>
                              <td>stdout</td>
                              <td>NULL</td>
                              <td>file to redirect Standard output from the java process</td>
                          </tr>
                          <tr>
                              <td>stderr</td>
                              <td>NULL</td>
                              <td>file to redirect Standard output from the java process </td>
                          </tr>
                      </table>
                  </p>
              </subsection>
              <subsection name="ajp13">
                  <p>Default worker</p>
                  <p>
                      <table>
                          <tr>
                              <th>Property name</th>
                              <th>Default</th>
                              <th>Description</th>
                          </tr>
                          <tr>
                              <td>secretkey</td>
                              <td>NULL</td>
                              <td>
                                  <b>Magic:</b> The secret key will be set automatically on the associated
      worker.
    </td>
                          </tr>
                          <tr>
                              <td>tomcatId</td>
                              <td/>
                              <td/>
                          </tr>
                          <tr>
                              <td>route</td>
                              <td/>
                              <td/>
                          </tr>
                          <tr>
                              <td>group</td>
                              <td/>
                              <td/>
                          </tr>
                          <tr>
                              <td>level</td>
                              <td/>
                              <td/>
                          </tr>
                          <tr>
                              <td>channel</td>
                              <td/>
                              <td/>
                          </tr>
                      </table>
                  </p>
              </subsection>
              <subsection name="status">
                  <p>Worker that outputs a page with usefull information to monitor JK2</p>
                  <p>To use it add a uri component assigned to this worker</p>
              </subsection>
              <subsection name="lb">
                  <p>Loadbalanced worker</p>
                  <p>
                      <table>
                          <tr>
                              <th>Property name</th>
                              <th>Default</th>
                              <th>Description</th>
                          </tr>
                          <tr>
                              <td>worker</td>
                              <td/>
                              <td/>
                          </tr>
                          <tr>
                              <td>noWorkerMsg</td>
                              <td/>
                              <td/>
                          </tr>
                          <tr>
                              <td>noWorkerCode</td>
                              <td>503</td>
                              <td/>
                          </tr>
                          <tr>
                              <td>hwBalanceErr</td>
                              <td/>
                              <td/>
                          </tr>
                      </table>
                  </p>
              </subsection>
          </subsection>
          <subsection name="loggers">
              <p>Any connector based on jk2, at least has a default logger, that can be reached using the "logger" alias, the logger used is the more appropiate for the plataform/server combination, Apache2 under in any platform has logger.apache2 as default, IIS on his only platform uses logger.win32, and Any apache 1 install uses logger.file as default.., the config file lets you change that defaults, you can end using logger.file in IIs i.e</p>
              <p>The properties shared by all loggers are:
  <table>
                      <tr>
                          <th>Property name</th>
                          <th>Default</th>
                          <th>Description</th>
                      </tr>
                      <tr>
                          <td>level</td>
                          <td>INFO</td>
                          <td>Log level. Supported: EMERG, ERROR, INFO, DEBUG</td>
                      </tr>
                  </table>
              </p>
              <subsection name="logger.file">
                  <p>
                      <table>
                          <tr>
                              <th>Property name</th>
                              <th>Default</th>
                              <th>Description</th>
                          </tr>
                          <tr>
                              <td>file</td>
                              <td>${serverRoot}/logs/jk2.log</td>
                              <td>
      Log file.  XXX you may be able to change this at runtime,
                 to implement rolling.
    </td>
                          </tr>
                      </table>
                  </p>
              </subsection>
              <subsection name="logger.win32">
                  <p>logger used in the IIS server by default, it ends at native Application Event Log.</p>
              </subsection>
              <subsection name="logger.apache2">
                  <p>Logger used in Apache2 servers, it normally in ends in error.log </p>
              </subsection>
          </subsection>
      </section>
      <section name="Examples">
          <p>
  The examples below are working when the Tomcat is configured according the 
  examples described in the configtc file.
  </p>
          <subsection name="/example using normal socket">
              <p> 
  Map /examples to the Tomcat /examples context using a normal socket. Note the 
  IP instead localhost (The JVM listens on the IPV4 address not no the IPV6).
  </p>
              <p>
                  <source>
  [shm]
  file=${serverRoot}/logs/shm.file
  size=1048576
  
  # Example socket channel, override port and host.
  [channel.socket:localhost:8019]
  port=8019
  host=127.0.0.1
  
  # define the worker
  [ajp13:localhost:8019]
  channel=channel.socket:localhost:8019
  
  # Uri mapping
  [uri:/examples/*]
  worker=ajp13:localhost:8019
  </source>
              </p>
          </subsection>
          <subsection name="/jkstatus">
              <p>
  Map /jkstatus to the status worker.
  </p>
              <p>
                  <source>
  [shm]
  file=${serverRoot}/logs/shm.file
  size=1048576
  
  # define the worker
  [status:status]
  
  # Uri mapping
  [uri:/jkstatus/*]
  worker=status:status
  </source>
              </p>
          </subsection>
          <subsection name="/example using AF_UNIX socket">
              <p>
  Map /examples to the Tomcat /examples context using a AF_UNIX socket.
  Socket file is create by the Tomcat becarefull when the Web Server runs in
  a different user than the Tomcat with the permission of the socket file:
  <source>
  apache20@jfcexpert:~/apache> ls -l /home1/jakarta/jakarta-tomcat-4.1/dist/work/jk2.socket
  srw-rw----    1 jakarta  jakarta         0 Jun 20 08:27 /home1/jakarta/jakarta-tomcat-4.1/dist/work/jk2.socket
  </source>
  Here the Tomcat user and the Web Server user must be in the same group.
  </p>
              <p>
                  <source>
  [shm]
  file=${serverRoot}/logs/shm.file
  size=1048576
  
  # Example unixsocket channel.
  [channel.un:unixsocket]
  file=/home1/jakarta/jakarta-tomcat-4.1/dist/work/jk2.socket
  
  # define the worker
  [ajp13:unixsocket]
  channel=channel.un:unixsocket
  
  # Uri mapping
  [uri:/examples/*]
  worker=ajp13:unixsocket
  </source>
              </p>
          </subsection>
      </section>
  </document>
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>