I thought I'd test out my new status as the resident Ajp13 expert by fixing this bug, 
and I think I've got it.  I'm attaching patches to util/MimeHeaders.java and 
modules/server/Ajp13.java.  I've done some minimal testing, and it seems to fix the 
problem.

I also did a tiny bit of further cleanup in Ajp13 (in case you look at the patch in 
detail).

-Dan


Palle Girgensohn wrote:
> 
> Hi!
> 
> Just installed tomcat 3.2 final.
> 
> I am forced to still use apj12 due to tomcat failing to create
> multiple cookies at once when using ajp13 (and possibly also
> redirect):
> 
> 
> Cheers,
> Palle
> --
>          Partitur Informationsteknik AB
> Wenner-Gren Center             +46 8 566 280 02
> 113 46 Stockholm               +46 70 785 86 02
> Sweden                         [EMAIL PROTECTED]

-- 

Dan Milstein // [EMAIL PROTECTED]
Index: MimeHeaders.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/util/MimeHeaders.java,v
retrieving revision 1.17
diff -u -r1.17 MimeHeaders.java
--- MimeHeaders.java    2000/11/20 21:37:45     1.17
+++ MimeHeaders.java    2000/12/06 05:11:38
@@ -210,18 +210,29 @@
     // -------------------- --------------------
 
     /**
-     * Returns an enumeration of strings representing the header field names.
-     * Field names may appear multiple times in this enumeration, indicating
-     * that multiple fields with that name exist in this header.
+     * Returns an enumeration of strings representing the header field
+     * names.  Field names are unique in this enumeration (which is
+     * actually not that useful) 
      */
     public Enumeration names() {
        return new NamesEnumerator(this);
     }
 
+    /**
+     * Return an enumeration of header values for a given name.
+     */
     public Enumeration values(String name) {
        return new ValuesEnumerator(this, name);
     }
 
+    /**
+     * Return an enumeration of 2-element String arrays representing pairs
+     * of header names and header values.
+     */
+    public Enumeration getNamesValues() {
+       return new NamesValuesEnumerator(this);
+    }
+
     // -------------------- Adding headers --------------------
     
 
@@ -419,6 +430,47 @@
        findNext();
        return current.toString();
     }
+}
+
+/**
+ * Enumerate the names and values together -- cleans up handling of
+ * multiple headers with identical names (Set-Cookie, say).  Each element
+ * of the enumeration is an array of length two: { name, value }
+ **/
+class NamesValuesEnumerator implements Enumeration {
+    int pos;
+    int size;
+    MimeHeaders headers;
+    String[] nextNameValuePair = new String[2];  
+    String[] returnNameValuePair = new String[2]; // Reused -- safe?
+
+    NamesValuesEnumerator(MimeHeaders headers) {
+       pos = 0;
+       this.headers = headers;
+       size = headers.size();
+       findNext();
+    }
+
+    private void findNext() {
+       nextNameValuePair[0] = null;
+       if(pos < size) {
+           nextNameValuePair[0] = headers.getName( pos ).toString();
+           nextNameValuePair[1] = headers.getValue( pos ).toString();
+           pos++;      
+       }
+    }
+    
+    public boolean hasMoreElements() {
+       return nextNameValuePair[0] != null;
+    }
+
+    public Object nextElement() {
+       returnNameValuePair[0] = nextNameValuePair[0];
+       returnNameValuePair[1] = nextNameValuePair[1];
+       findNext();
+       return returnNameValuePair;
+    }
+
 }
 
 class MimeHeaderField {
Index: Ajp13.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/modules/server/Ajp13.java,v
retrieving revision 1.6
diff -u -r1.6 Ajp13.java
--- Ajp13.java  2000/12/05 06:30:15     1.6
+++ Ajp13.java  2000/12/06 05:12:31
@@ -257,7 +257,7 @@
         req.serverName().setString( msg.getString());
         req.setServerPort(          msg.getInt());
 
-       isSSL = (msg.getByte() != 0);
+       isSSL = msg.getBool();
 
        // Decode headers
        MimeHeaders headers = req.getMimeHeaders();
@@ -444,16 +444,18 @@
         
         outBuf.appendInt(headers.size());
         
-        Enumeration e = headers.names();
+        Enumeration e = headers.getNamesValues();
         while(e.hasMoreElements()) {
-            String headerName = (String)e.nextElement();            
+            String[] nameValuePair = (String[]) e.nextElement();            
+           String headerName  = nameValuePair[0];
+           String headerValue = nameValuePair[1];
             int sc = headerNameToSc(headerName);
             if(-1 != sc) {
                 outBuf.appendInt(sc);
             } else {
                 outBuf.appendString(headerName);
             }
-            outBuf.appendString(headers.getHeader(headerName));
+            outBuf.appendString(headerValue);
         }
 
         outBuf.end();
@@ -520,13 +522,13 @@
 
     /**
      * Signal the web server that the servlet has finished handling this
-     * request.  
+     * request, and that the connection can be reused.
      */
     public void finish() throws IOException 
     {
        outBuf.reset();
         outBuf.appendByte(JK_AJP13_END_RESPONSE);
-        outBuf.appendByte((byte)1);        
+        outBuf.appendBool(true); // Reuse this connection
         outBuf.end();
         send(outBuf);
     }
@@ -723,6 +725,10 @@
            buff[pos++] = val;
        }
        
+       public void appendBool( boolean val) {
+           buff[pos++] = (byte) (val ? 1 : 0);
+       }
+
        /**
         * Write a String out at the current write position.  Strings are
         * encoded with the length in two bytes first, then the string, and
@@ -754,7 +760,7 @@
         * terminating \0 (which is <B>not</B> included in the encoded
         * length).
         *
-        * @param b The array from whcih to copy bytes.
+        * @param b The array from which to copy bytes.
         * @param off The offset into the array at which to start copying
         * @param len The number of bytes to copy.  
         */
@@ -803,6 +809,10 @@
 
        public byte peekByte() {
            return buff[pos];
+       }
+
+       public boolean getBool() {
+           return (getByte() == (byte) 1);
        }
 
        public static final String DEFAULT_CHAR_ENCODING = "8859_1";

Reply via email to