Index: extras/ajp/src/main/java/org/mortbay/jetty/ajp/Ajp13Parser.java
===================================================================
--- extras/ajp/src/main/java/org/mortbay/jetty/ajp/Ajp13Parser.java	(revision 2039)
+++ extras/ajp/src/main/java/org/mortbay/jetty/ajp/Ajp13Parser.java	(working copy)
@@ -57,8 +57,8 @@
     private View _tok1; // Saved token: header value, request URI orresponse code
     protected int _length;
     protected int _packetLength;
-    
 
+
     /* ------------------------------------------------------------------------------- */
     public Ajp13Parser(Buffers buffers, EndPoint endPoint, EventHandler handler, Ajp13Generator generator)
     {
@@ -163,7 +163,7 @@
             // mod_jk implementations may have some partial data from header
             // check if there are partial contents in the header
             // copy it to the body if there are any
-            if(_header.length() > 0)
+            if (_header.length() > 0)
             {
                 // copy the patial data from the header to the body
                 _body.put(_header);
@@ -198,7 +198,7 @@
                 throw (e instanceof EofException) ? e : new EofException(e);
             }
         }
-        
+
         if (filled < 0)
         {
             if (_state > STATE_END)
@@ -210,10 +210,10 @@
             reset(true);
             throw new EofException();
         }
-    
+
         return filled;
     }
-    
+
     /* ------------------------------------------------------------------------------- */
     public long parseNext() throws IOException
     {
@@ -241,21 +241,21 @@
             _handler.messageComplete(_contentPosition);
             return total_filled;
         }
-        
+
         if (_state < 0)
         {
             // have we seen a packet?
-            if (_packetLength<=0)
+            if (_packetLength <= 0)
             {
-                if (_buffer.length()<4)
+                if (_buffer.length() < 4)
                 {
-                    if (total_filled<0) 
-                        total_filled=0;
-                    total_filled+=fill();
-                    if (_buffer.length()<4)
+                    if (total_filled < 0)
+                        total_filled = 0;
+                    total_filled += fill();
+                    if (_buffer.length() < 4)
                         return total_filled;
                 }
-                
+
                 _contentLength = HttpTokens.UNKNOWN_CONTENT;
                 int _magic = Ajp13RequestPacket.getInt(_buffer);
                 if (_magic != Ajp13RequestHeaders.MAGIC)
@@ -265,14 +265,14 @@
                 _packetLength = Ajp13RequestPacket.getInt(_buffer);
                 if (_packetLength > Ajp13Packet.MAX_PACKET_SIZE)
                     throw new IOException("AJP13 packet (" + _packetLength + "bytes) too large for buffer");
-                
+
             }
-            
+
             if (_buffer.length() < _packetLength)
             {
-                if (total_filled<0) 
-                    total_filled=0;
-                total_filled+=fill();
+                if (total_filled < 0)
+                    total_filled = 0;
+                total_filled += fill();
                 if (_buffer.length() < _packetLength)
                     return total_filled;
             }
@@ -291,20 +291,20 @@
                     break;
                 case Ajp13Packet.CPING_REQUEST_ORDINAL:
                     ((Ajp13Generator) _generator).sendCPong();
-                    
-                    if(_header != null)
+
+                    if (_header != null)
                     {
                         _buffers.returnBuffer(_header);
                         _header = null;
                     }
 
-                    if(_body != null)
+                    if (_body != null)
                     {
                         _buffers.returnBuffer(_body);
                         _body = null;
                     }
 
-                    _buffer= null;
+                    _buffer = null;
 
                     reset(true);
 
@@ -317,8 +317,8 @@
                 default:
                     // XXX Throw an Exception here?? Close
                     // connection!
-                    Log.warn("AJP13 message type ({PING}: "+packetType+" ) not supported/recognized as an AJP request");
-                throw new IllegalStateException("PING is not implemented");
+                    Log.warn("AJP13 message type ({PING}: " + packetType + " ) not supported/recognized as an AJP request");
+                    throw new IllegalStateException("PING is not implemented");
             }
 
 
@@ -334,7 +334,7 @@
 
             _headers = Ajp13RequestPacket.getInt(_buffer);
 
-            for (int h=0;h<_headers;h++)
+            for (int h = 0; h < _headers; h++)
             {
                 bufHeaderName = Ajp13RequestPacket.getHeaderName(_buffer, _tok0);
                 bufHeaderValue = Ajp13RequestPacket.getString(_buffer, _tok1);
@@ -342,7 +342,9 @@
                 if (bufHeaderName != null && bufHeaderName.toString().equals(Ajp13RequestHeaders.CONTENT_LENGTH))
                 {
                     _contentLength = BufferUtil.toLong(bufHeaderValue);
-                    if (_contentLength <= 0)
+
+
+                    if (_contentLength == 0)
                         _contentLength = HttpTokens.NO_CONTENT;
                 }
 
@@ -350,7 +352,6 @@
             }
 
 
-
             attr_type = Ajp13RequestPacket.getByte(_buffer) & 0xff;
             while (attr_type != 0xFF)
             {
@@ -401,30 +402,29 @@
                         // Check if experimental or can they
                         // assumed to be
                         // supported
-                        
+
                     case Ajp13RequestHeaders.SSL_KEYSIZE_ATTR:
-                        
+
                         // This has been implemented as either a string or a integer.
-                        
+
                         // Does it look like a string containing digits?
                         int length = Ajp13RequestPacket.getInt(_buffer);
-                        
-                        if (length>0 && length<16)
+
+                        if (length > 0 && length < 16)
                         {
                             // this must be a string length rather than a key length
                             _buffer.skip(-2);
                             _handler.parsedRequestAttribute("javax.servlet.request.key_size", Ajp13RequestPacket.getString(_buffer, _tok1));
                         }
                         else
-                            _handler.parsedRequestAttribute("javax.servlet.request.key_size",length);
-                        
+                            _handler.parsedRequestAttribute("javax.servlet.request.key_size", length);
+
                         break;
 
-                        
                         // Used to lock down jk requests with a
                         // secreate
                         // key.
-                        
+
                     case Ajp13RequestHeaders.SECRET_ATTR:
                         // XXX Investigate safest way to
                         // deal with
@@ -450,21 +450,17 @@
                         break;
                     default:
                         Log.warn("Unsupported Ajp13 Request Attribute {}", new Integer(attr_type));
-                    break;
+                        break;
                 }
 
                 attr_type = Ajp13RequestPacket.getByte(_buffer) & 0xff;
             }
 
 
-
-
-
-
             _contentPosition = 0;
             switch ((int) _contentLength)
             {
-                case HttpTokens.UNKNOWN_CONTENT:
+
                 case HttpTokens.NO_CONTENT:
                     _state = STATE_END;
                     _handler.headerComplete();
@@ -472,6 +468,29 @@
 
                     break;
 
+                case HttpTokens.UNKNOWN_CONTENT:
+
+                    if (_buffers != null && _body == null && _buffer == _header && _header.length() <= 0)
+                    {
+                        _body = _buffers.getBuffer(Ajp13Packet.MAX_PACKET_SIZE);
+                        _body.clear();
+
+                    }
+
+                    _state = STATE_AJP13CHUNK_START;
+
+                    _generator.getBodyChunk();
+
+                    total_filled += fill();
+                    _generator.gotBody();
+
+
+                    _handler.headerComplete(); // May recurse here!
+
+
+                    return total_filled;
+
+
                 default:
 
                     if (_buffers != null && _body == null && _buffer == _header && _contentLength > (_header.capacity() - _header.getIndex()))
@@ -480,61 +499,70 @@
                         _body.clear();
 
                     }
-                _state = STATE_AJP13CHUNK_START;
-                _handler.headerComplete(); // May recurse here!
-                return total_filled;
+                    _state = STATE_AJP13CHUNK_START;
+                    _handler.headerComplete(); // May recurse here!
+                    return total_filled;
             }
         }
 
 
         Buffer chunk;
 
-        while (_state>STATE_END)
+        while (_state > STATE_END)
         {
             switch (_state)
             {
                 case STATE_AJP13CHUNK_START:
-                    if (_buffer.length()<6)
+
+
+                    if (_buffer.length() < 6)
                     {
-                        if (total_filled<0) 
-                            total_filled=0;
-                        total_filled+=fill();
-                        if (_buffer.length()<6)
+                        if (total_filled < 0)
+                            total_filled = 0;
+                        total_filled += fill();
+                        if (_buffer.length() < 6)
                             return total_filled;
                     }
-                    int _magic=Ajp13RequestPacket.getInt(_buffer);
-                    if (_magic!=Ajp13RequestHeaders.MAGIC)
+                    int _magic = Ajp13RequestPacket.getInt(_buffer);
+                    if (_magic != Ajp13RequestHeaders.MAGIC)
                     {
-                        throw new IOException("Bad AJP13 rcv packet: "+"0x"+Integer.toHexString(_magic)+" expected "+"0x"
-                                +Integer.toHexString(Ajp13RequestHeaders.MAGIC)+" "+this);
+                        throw new IOException("Bad AJP13 rcv packet: " + "0x" + Integer.toHexString(_magic) + " expected " + "0x"
+                                + Integer.toHexString(Ajp13RequestHeaders.MAGIC) + " " + this);
                     }
-                    _chunkPosition=0;
-                    _chunkLength=Ajp13RequestPacket.getInt(_buffer)-2;
+
+
+                    _chunkPosition = 0;
+                    _chunkLength = Ajp13RequestPacket.getInt(_buffer) - 2;
+
+
+
                     Ajp13RequestPacket.getInt(_buffer);
-                    if (_chunkLength==0)
+                    if (_chunkLength == 0)
                     {
-                        _state=STATE_END;
+                        _state = STATE_END;
+                         _generator.gotBody();
                         _handler.messageComplete(_contentPosition);
                         return total_filled;
                     }
-                    _state=STATE_AJP13CHUNK;
+                    _state = STATE_AJP13CHUNK;
 
                 case STATE_AJP13CHUNK:
-                    if (_buffer.length()<_chunkLength)
+
+                    if (_buffer.length() < _chunkLength)
                     {
-                        if (total_filled<0) 
-                            total_filled=0;
-                        total_filled+=fill();
-                        if (_buffer.length()<_chunkLength)
+                        if (total_filled < 0)
+                            total_filled = 0;
+                        total_filled += fill();
+                        if (_buffer.length() < _chunkLength)
                             return total_filled;
                     }
 
-                    int remaining=_chunkLength-_chunkPosition;
+                    int remaining = _chunkLength - _chunkPosition;
 
-                    if (remaining==0)
+                    if (remaining == 0)
                     {
-                        _state=STATE_AJP13CHUNK_START;
-                        if (_contentPosition<_contentLength)
+                        _state = STATE_AJP13CHUNK_START;
+                        if (_contentPosition < _contentLength || _contentLength == HttpTokens.UNKNOWN_CONTENT)
                         {
                             _generator.getBodyChunk();
                         }
@@ -546,22 +574,22 @@
                         return total_filled;
                     }
 
-                    if (_buffer.length()<remaining)
+                    if (_buffer.length() < remaining)
                     {
-                        remaining=_buffer.length();
+                        remaining = _buffer.length();
                     }
 
-                    chunk=Ajp13RequestPacket.get(_buffer,(int)remaining);
-                    _contentPosition+=chunk.length();
-                    _chunkPosition+=chunk.length();
+                    chunk = Ajp13RequestPacket.get(_buffer, (int) remaining);
+                    _contentPosition += chunk.length();
+                    _chunkPosition += chunk.length();
                     _contentView.update(chunk);
 
-                    remaining=_chunkLength-_chunkPosition;
+                    remaining = _chunkLength - _chunkPosition;
 
-                    if (remaining==0)
+                    if (remaining == 0)
                     {
-                        _state=STATE_AJP13CHUNK_START;
-                        if (_contentPosition<_contentLength)
+                        _state = STATE_AJP13CHUNK_START;
+                        if (_contentPosition < _contentLength || _contentLength == HttpTokens.UNKNOWN_CONTENT)
                         {
                             _generator.getBodyChunk();
                         }
@@ -573,10 +601,10 @@
 
                     _handler.content(chunk);
 
-                return total_filled;
+                    return total_filled;
 
-            default:
-                throw new IllegalStateException("Invalid Content State");
+                default:
+                    throw new IllegalStateException("Invalid Content State");
 
             }
 
@@ -651,20 +679,20 @@
     {
         _state = STATE_END;
 
-        if(!Ajp13SocketConnector.__allowShutdown)
+        if (!Ajp13SocketConnector.__allowShutdown)
         {
             Log.warn("AJP13: Shutdown Request is Denied, allowShutdown is set to false!!!");
             return;
         }
 
-        if(Ajp13SocketConnector.__secretWord != null)
+        if (Ajp13SocketConnector.__secretWord != null)
         {
             Log.warn("AJP13: Validating Secret Word");
             try
             {
                 String secretWord = Ajp13RequestPacket.getString(_buffer, _tok1).toString();
 
-                if(!Ajp13SocketConnector.__secretWord.equals(secretWord))
+                if (!Ajp13SocketConnector.__secretWord.equals(secretWord))
                 {
                     Log.warn("AJP13: Shutdown Request Denied, Invalid Sercret word!!!");
                     throw new IllegalStateException("AJP13: Secret Word is Invalid: Peer has requested shutdown but, Secret Word did not match");
@@ -713,7 +741,7 @@
         public void parsedRemoteHost(Buffer host) throws IOException;
 
         public void parsedRequestAttribute(String key, Buffer value) throws IOException;
-        
+
         public void parsedRequestAttribute(String key, int value) throws IOException;
 
         public void parsedServerName(Buffer name) throws IOException;
@@ -727,11 +755,11 @@
         public void startForwardRequest() throws IOException;
 
         public void parsedAuthorizationType(Buffer authType) throws IOException;
-        
+
         public void parsedRemoteUser(Buffer remoteUser) throws IOException;
 
         public void parsedServletPath(Buffer servletPath) throws IOException;
-        
+
         public void parsedContextPath(Buffer context) throws IOException;
 
         public void parsedSslCert(Buffer sslCert) throws IOException;
@@ -741,17 +769,11 @@
         public void parsedSslSession(Buffer sslSession) throws IOException;
 
 
-
-
-
-
-
     }
 
     /* ------------------------------------------------------------ */
     /**
      * TODO Make this common with HttpParser
-     * 
      */
     public static class Input extends ServletInputStream
     {
@@ -802,11 +824,11 @@
             if (_endp == null)
                 _parser.parseNext();
 
-            // Handle blocking end points
+                // Handle blocking end points
             else if (_endp.isBlocking())
             {
                 _parser.parseNext();
-                
+
                 // parse until some progress is made (or IOException thrown for timeout)
                 while (_content.length() == 0 && !_parser.isState(Ajp13Parser.STATE_END))
                 {
Index: extras/ajp/src/test/java/org/mortbay/jetty/ajp/HttpClientPostChunked.java
===================================================================
--- extras/ajp/src/test/java/org/mortbay/jetty/ajp/HttpClientPostChunked.java	(revision 0)
+++ extras/ajp/src/test/java/org/mortbay/jetty/ajp/HttpClientPostChunked.java	(revision 0)
@@ -0,0 +1,72 @@
+package org.mortbay.jetty.ajp;
+
+import java.io.PrintWriter;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.net.UnknownHostException;
+import java.net.URL;
+
+
+public class HttpClientPostChunked
+{
+    public static void main(String args[])
+    {
+
+        try
+        {
+
+            String urlAddress = "http://192.168.245.149/bong/SamplePost.htm";
+            System.out.println("Address: " + urlAddress);
+            URL url = new URL(urlAddress);
+            HttpURLConnection con = (HttpURLConnection)url.openConnection();
+            con.setDoOutput(true);
+            con.setRequestMethod("POST");
+
+            con.setChunkedStreamingMode(8);
+            PrintWriter pw = new PrintWriter(new OutputStreamWriter(con.getOutputStream()));
+
+
+
+            pw.write("thename=the quick brown fox jumps over to the lazy dog THE QUICK BROWN FOX JUMPS OVER TO THE LAZY DOG ");
+            pw.write("the quick brown fox jumps over to the lazy dog THE QUICK BROWN FOX JUMPS OVER TO THE LAZY DOG ");
+            pw.write("the quick brown fox jumps over to the lazy dog THE QUICK BROWN FOX JUMPS OVER TO THE LAZY DOG ");
+            pw.write("the quick brown fox jumps over to the lazy dog THE QUICK BROWN FOX JUMPS OVER TO THE LAZY DOG ");
+            pw.write("the quick brown fox jumps over to the lazy dog THE QUICK BROWN FOX JUMPS OVER TO THE LAZY DOG ");
+            pw.write("the quick brown fox jumps over to the lazy dog THE QUICK BROWN FOX JUMPS OVER TO THE LAZY DOG ");
+            pw.write("the quick brown fox jumps over to the lazy dog THE QUICK BROWN FOX JUMPS OVER TO THE LAZY DOG ");
+            pw.write("the quick brown fox jumps over to the lazy dog THE QUICK BROWN FOX JUMPS OVER TO THE LAZY DOG ");
+            pw.write("the quick brown fox jumps over to the lazy dog THE QUICK BROWN FOX JUMPS OVER TO THE LAZY DOG ");
+            pw.write("the quick brown fox jumps over to the lazy dog THE QUICK BROWN FOX JUMPS OVER TO THE LAZY DOG ");
+            pw.write("the quick brown fox jumps over to the lazy dog THE QUICK BROWN FOX JUMPS OVER TO THE LAZY DOG ");
+            pw.write("the quick brown fox jumps over to the lazy dog THE QUICK BROWN FOX JUMPS OVER TO THE LAZY DOG ");
+            pw.write("the quick brown fox jumps over to the lazy dog THE QUICK BROWN FOX JUMPS OVER TO THE LAZY DOG!!! ");
+            pw.write("&valueof2=abcdefghijklmnopqrstuvwxyz1234567890");
+            pw.flush();
+
+            System.out.println("\n\n\nResponse Code is " + con.getResponseCode());
+            System.out.println("\n\n\n");
+
+            byte[] b = new byte[10];
+            while(con.getInputStream().read(b) > 0)
+            {
+                String str = new String(b);
+                System.out.print(str);
+
+            }
+
+
+
+            pw.close();
+        }
+        catch (UnknownHostException e)
+        {
+            System.err.println(e);
+        }
+        catch (IOException e)
+        {
+            System.err.println(e);
+        }
+
+    }
+}
Index: VERSION.txt
===================================================================
--- VERSION.txt	(revision 2039)
+++ VERSION.txt	(working copy)
@@ -1,4 +1,5 @@
 jetty-SNAPSHOT
+ + AJP13 Fix on chunked post
  + Fix cached header optimization for extra characters
  + SetUID option to support setgid
  + Make mx4j used only if runtime uses jdk<1.5

