On explicit flush, create an empty (8 bytes)
authormturk <mturk@13f79535-47bb-0310-9956-ffa450edef68>
Sun, 29 Oct 2006 16:50:56 +0000 (16:50 +0000)
committermturk <mturk@13f79535-47bb-0310-9956-ffa450edef68>
Sun, 29 Oct 2006 16:50:56 +0000 (16:50 +0000)
SEND_BODY_CHUNK message, that can be used by
web server to flush the packet.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk@468937 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/coyote/ajp/AjpAprProcessor.java
java/org/apache/coyote/ajp/AjpProcessor.java
java/org/apache/coyote/ajp/Constants.java

index c684ef9..dda1cef 100644 (file)
@@ -265,6 +265,11 @@ public class AjpAprProcessor implements ActionHook {
      */
     protected static final byte[] endMessageArray;
 
+    /**
+     * Direct buffer used for sending explicit flush message.
+     */
+    protected static final ByteBuffer flushMessageBuffer;
+
 
     // ----------------------------------------------------- Static Initializer
 
@@ -272,7 +277,7 @@ public class AjpAprProcessor implements ActionHook {
     static {
 
         // Set the get body message buffer
-        AjpMessage getBodyMessage = new AjpMessage(128);
+        AjpMessage getBodyMessage = new AjpMessage(16);
         getBodyMessage.reset();
         getBodyMessage.appendByte(Constants.JK_AJP13_GET_BODY_CHUNK);
         getBodyMessage.appendInt(Constants.MAX_READ_SIZE);
@@ -283,7 +288,7 @@ public class AjpAprProcessor implements ActionHook {
                 getBodyMessage.getLen());
 
         // Set the read body message buffer
-        AjpMessage pongMessage = new AjpMessage(128);
+        AjpMessage pongMessage = new AjpMessage(16);
         pongMessage.reset();
         pongMessage.appendByte(Constants.JK_AJP13_CPONG_REPLY);
         pongMessage.end();
@@ -292,7 +297,7 @@ public class AjpAprProcessor implements ActionHook {
                 pongMessage.getLen());
 
         // Allocate the end message array
-        AjpMessage endMessage = new AjpMessage(128);
+        AjpMessage endMessage = new AjpMessage(16);
         endMessage.reset();
         endMessage.appendByte(Constants.JK_AJP13_END_RESPONSE);
         endMessage.appendByte(1);
@@ -301,6 +306,18 @@ public class AjpAprProcessor implements ActionHook {
         System.arraycopy(endMessage.getBuffer(), 0, endMessageArray, 0,
                 endMessage.getLen());
 
+        // Set the flush message buffer
+        AjpMessage flushMessage = new AjpMessage(16);
+        flushMessage.reset();
+        flushMessage.appendByte(Constants.JK_AJP13_SEND_BODY_CHUNK);
+        flushMessage.appendInt(0);
+        flushMessage.appendByte(0);
+        flushMessage.end();
+        flushMessageBuffer =
+            ByteBuffer.allocateDirect(flushMessage.getLen());
+        flushMessageBuffer.put(flushMessage.getBuffer(), 0,
+                flushMessage.getLen());
+
     }
 
 
@@ -504,6 +521,11 @@ public class AjpAprProcessor implements ActionHook {
 
             try {
                 flush();
+                // Send explicit flush message
+                if (Socket.sendb(socket, flushMessageBuffer, 0,
+                                 flushMessageBuffer.position()) < 0) {
+                    error = true;                    
+                }
             } catch (IOException e) {
                 // Set error flag
                 error = true;
index 487e2aa..b06d216 100644 (file)
@@ -254,6 +254,11 @@ public class AjpProcessor implements ActionHook {
      */
     protected static final byte[] endMessageArray;
 
+    /**
+     * Flush message array.
+     */
+    protected static final byte[] flushMessageArray;
+
 
     // ----------------------------------------------------- Static Initializer
 
@@ -261,7 +266,8 @@ public class AjpProcessor implements ActionHook {
     static {
 
         // Set the get body message buffer
-        AjpMessage getBodyMessage = new AjpMessage(128);
+
+        AjpMessage getBodyMessage = new AjpMessage(16);
         getBodyMessage.reset();
         getBodyMessage.appendByte(Constants.JK_AJP13_GET_BODY_CHUNK);
         getBodyMessage.appendInt(Constants.MAX_READ_SIZE);
@@ -271,7 +277,7 @@ public class AjpProcessor implements ActionHook {
                 0, getBodyMessage.getLen());
 
         // Set the read body message buffer
-        AjpMessage pongMessage = new AjpMessage(128);
+        AjpMessage pongMessage = new AjpMessage(16);
         pongMessage.reset();
         pongMessage.appendByte(Constants.JK_AJP13_CPONG_REPLY);
         pongMessage.end();
@@ -280,7 +286,7 @@ public class AjpProcessor implements ActionHook {
                 0, pongMessage.getLen());
 
         // Allocate the end message array
-        AjpMessage endMessage = new AjpMessage(128);
+        AjpMessage endMessage = new AjpMessage(16);
         endMessage.reset();
         endMessage.appendByte(Constants.JK_AJP13_END_RESPONSE);
         endMessage.appendByte(1);
@@ -289,6 +295,17 @@ public class AjpProcessor implements ActionHook {
         System.arraycopy(endMessage.getBuffer(), 0, endMessageArray, 0,
                 endMessage.getLen());
 
+        // Allocate the flush message array
+        AjpMessage flushMessage = new AjpMessage(16);
+        flushMessage.reset();
+        flushMessage.appendByte(Constants.JK_AJP13_SEND_BODY_CHUNK);
+        flushMessage.appendInt(0);
+        flushMessage.appendByte(0);
+        flushMessage.end();
+        flushMessageArray = new byte[flushMessage.getLen()];
+        System.arraycopy(flushMessage.getBuffer(), 0, flushMessageArray, 0,
+                flushMessage.getLen());
+
     }
 
 
@@ -1073,7 +1090,8 @@ public class AjpProcessor implements ActionHook {
      */
     protected void flush()
         throws IOException {
-        // Note: at the moment, there's no buffering at the socket level
+        // Send the flush message
+        output.write(flushMessageArray);
     }
 
 
index 73489b2..6074b49 100644 (file)
@@ -89,19 +89,27 @@ public final class Constants {
     public static final byte SC_A_ARE_DONE      = (byte)0xFF;
 
     // Ajp13 specific -  needs refactoring for the new model
+
     /**
-     * Maximum Total byte size for a AJP packet
+     * Default maximum total byte size for a AJP packet
      */
     public static final int MAX_PACKET_SIZE = 8192;
     /**
      * Size of basic packet header
      */
     public static final int H_SIZE = 4;
+
+    /**
+     * Size of the header metadata
+     */
+    public static final int  READ_HEAD_LEN = 6;
+    public static final int  SEND_HEAD_LEN = 8;
+
     /**
-     * Maximum size of data that can be sent in one packet
+     * Default maximum size of data that can be sent in one packet
      */
-    public static final int  MAX_READ_SIZE = MAX_PACKET_SIZE - H_SIZE - 2;
-    public static final int  MAX_SEND_SIZE = MAX_PACKET_SIZE - H_SIZE - 4;
+    public static final int  MAX_READ_SIZE = MAX_PACKET_SIZE - READ_HEAD_LEN;
+    public static final int  MAX_SEND_SIZE = MAX_PACKET_SIZE - SEND_HEAD_LEN;
 
     // Translates integer codes to names of HTTP methods
     public static final String []methodTransArray = {