Remy,

I checked the cvs and found there are some number of changes in the writer and response in coyote starting from 4.1.12. (See the diff from 4.1.12). Many of the changes are started at around 4.1.15/16.

I think there is the problem in the roll out procedures, especially when a release is voted by the committer as stable and before the release manager declare it as GA. Stability test and code review should be thoroughly run.

May be in 5.0, we could do better on this.

- Punky

P.S. I remember there was discussion in the release procedure or numbering guides. But I cannot find one in tomcat site. Is it just from http project? (http://httpd.apache.org/dev/release.html)


Remy Maucherat wrote:
A bug exists (unfortunately) in Tomcat 4.1.16 and Tomcat 4.1.17 which causes the servlet Writer to stay in an invalid state after an IOException occurs (99% of the time caused by an abrupt client disconnection). After this happens, the processor will never be able to output data using the Writer, causing blank pages. This is more often seen with JSPs.

The bug affects Coyote HTTP/1.1, and may also affect Coyote JK 2, although this is less likely.

It is proposed that Tomcat 4.1.18, based on the Tomcat 4.1.17 code, with the addition of the patch committed by Bill fixing JK 2 SSL support, as well as the following patch (which I committed one hour ago):

Index: CoyoteResponse.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteResponse.java,v
retrieving revision 1.30
diff -r1.30 CoyoteResponse.java
322a323,324
> writer.recycle();
>
Index: CoyoteWriter.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteWriter.java,v
retrieving revision 1.2
diff -r1.2 CoyoteWriter.java
98a99,109
> // -------------------------------------------------------- Package Methods
>
>
> /**
> * Recycle.
> */
> void recycle() {
> error = false;
> }
>
>

Please review, and vote ASAP:

<ballot>
[ ] Yes
[ ] No
</ballot>

Remy


--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>


===================================================================
RCS file: 
/home/cvspublic/jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteResponse.java,v
retrieving revision 1.25
retrieving revision 1.31
diff -u -r1.25 -r1.31
--- 
jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteResponse.java
     2002/09/12 06:42:11     1.25
+++ 
+jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteResponse.java
+     2002/12/19 08:59:50     1.31
@@ -1,7 +1,7 @@
 /*
- * $Header: 
/home/cvspublic/jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteResponse.java,v
 1.25 2002/09/12 06:42:11 amyroh Exp $
- * $Revision: 1.25 $
- * $Date: 2002/09/12 06:42:11 $
+ * $Header: 
+/home/cvspublic/jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteResponse.java,v
+ 1.31 2002/12/19 08:59:50 remm Exp $
+ * $Revision: 1.31 $
+ * $Date: 2002/12/19 08:59:50 $
  *
  * ====================================================================
  *
@@ -69,7 +69,6 @@
 import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.net.MalformedURLException;
-import java.net.URL;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
@@ -95,6 +94,7 @@
 import org.apache.tomcat.util.buf.UEncoder;
 import org.apache.tomcat.util.http.MimeHeaders;
 import org.apache.tomcat.util.http.ServerCookie;
+import org.apache.tomcat.util.net.URL;
 
 import org.apache.coyote.Response;
 
@@ -116,7 +116,7 @@
  *
  * @author Remy Maucherat
  * @author Craig R. McClanahan
- * @version $Revision: 1.25 $ $Date: 2002/09/12 06:42:11 $
+ * @version $Revision: 1.31 $ $Date: 2002/12/19 08:59:50 $
  */
 
 public class CoyoteResponse
@@ -320,6 +320,8 @@
             facade = null;
         }
 
+        writer.recycle();
+
     }
 
 
@@ -330,7 +332,7 @@
      * Return the number of bytes actually written to the output stream.
      */
     public int getContentCount() {
-        return outputBuffer.getBytesWritten();
+        return outputBuffer.getContentWritten();
     }
 
 
@@ -501,7 +503,6 @@
         } catch(Throwable t) {
             t.printStackTrace();
         }
-        coyoteResponse.finish();
     }
 
 
@@ -982,10 +983,16 @@
      * @param url URL to be encoded
      */
     public String encodeURL(String url) {
-
-        if (isEncodeable(toAbsolute(url))) {
+        
+        String absolute = toAbsolute(url);
+        if (isEncodeable(absolute)) {
             HttpServletRequest hreq =
                 (HttpServletRequest) request.getRequest();
+            
+            // W3c spec clearly said 
+            if (url.equalsIgnoreCase("")){
+                url = absolute;
+            }
             return (toEncoded(url, hreq.getSession().getId()));
         } else {
             return (url);
@@ -1305,48 +1312,22 @@
         if (location == null)
             return (location);
 
-        boolean leadingSlash = location.startsWith("/");
-
-        if (leadingSlash 
-            || (!leadingSlash && (location.indexOf("://") == -1))) {
-
-            redirectURLCC.recycle();
-
-            String scheme = request.getScheme();
-            String name = request.getServerName();
-            int port = request.getServerPort();
-
+        // Construct a new absolute URL if possible (cribbed from
+        // the DefaultErrorPage servlet)
+        URL url = null;
+        try {
+            url = new URL(location);
+        } catch (MalformedURLException e1) {
+            HttpServletRequest hreq =
+                (HttpServletRequest) request.getRequest();
+            String requrl = request.getRequestURL().toString();
             try {
-                redirectURLCC.append(scheme, 0, scheme.length());
-                redirectURLCC.append("://", 0, 3);
-                redirectURLCC.append(name, 0, name.length());
-                if ((scheme.equals("http") && port != 80)
-                    || (scheme.equals("https") && port != 443)) {
-                    redirectURLCC.append(':');
-                    String portS = port + "";
-                    redirectURLCC.append(portS, 0, portS.length());
-                }
-                if (!leadingSlash) {
-                    String relativePath = request.getDecodedRequestURI();
-                    int pos = relativePath.lastIndexOf('/');
-                    relativePath = relativePath.substring(0, pos);
-                    String encodedURI = urlEncoder.encodeURL(relativePath);
-                    redirectURLCC.append(encodedURI, 0, encodedURI.length());
-                    redirectURLCC.append('/');
-                }
-                redirectURLCC.append(location, 0, location.length());
-            } catch (IOException e) {
+                url = new URL(new URL(requrl), location);
+            } catch (MalformedURLException e2) {
                 throw new IllegalArgumentException(location);
             }
-
-            return redirectURLCC.toString();
-
-        } else {
-
-            return (location);
-
         }
-
+        return (url.toExternalForm());
     }
 
 
===================================================================
RCS file: 
/home/cvspublic/jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteWriter.java,v
retrieving revision 1.1
retrieving revision 1.3
diff -u -r1.1 -r1.3
--- 
jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteWriter.java  
     2002/03/07 04:27:23     1.1
+++ 
+jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteWriter.java 
+      2002/12/19 08:59:50     1.3
@@ -68,17 +68,23 @@
 /**
  * Coyote implementation of the servlet writer.
  * 
- * @author Costin Manolache
  * @author Remy Maucherat
  */
 final class CoyoteWriter
     extends PrintWriter {
 
 
+    // -------------------------------------------------------------- Constants
+
+
+    private static final char[] LINE_SEP = { '\r', '\n' };
+
+
     // ----------------------------------------------------- Instance Variables
 
 
     protected OutputBuffer ob;
+    protected boolean error = false;
 
 
     // ----------------------------------------------------------- Constructors
@@ -90,47 +96,218 @@
     }
 
 
-    // --------------------------------------------------------- Writer Methods
+    // -------------------------------------------------------- Package Methods
 
 
-    public void flush() {
-        super.flush();
+    /**
+     * Recycle.
+     */
+    void recycle() {
+        error = false;
     }
 
 
-    public void write(char buf[], int offset, int count) {
-        super.write(buf, offset, count);
-    }
+    // --------------------------------------------------------- Writer Methods
+
+
+    public void flush() {
+
+        if (error)
+            return;
 
+        try {
+            ob.flush();
+        } catch (IOException e) {
+            error = true;
+        }
 
-    public void write(String str) {
-        super.write( str );
     }
 
 
     public void close() {
+
         // We don't close the PrintWriter - super() is not called,
         // so the stream can be reused. We close ob.
         try {
             ob.close();
         } catch (IOException ex ) {
-            ex.printStackTrace();
+            ;
+        }
+        error = false;
+
+    }
+
+
+    public boolean checkError() {
+        flush();
+        return error;
+    }
+
+
+    public void write(int c) {
+
+        if (error)
+            return;
+
+        try {
+            ob.write(c);
+        } catch (IOException e) {
+            error = true;
         }
+
+    }
+
+
+    public void write(char buf[], int off, int len) {
+
+        if (error)
+            return;
+
+        try {
+            ob.write(buf, off, len);
+        } catch (IOException e) {
+            error = true;
+        }
+
+    }
+
+
+    public void write(char buf[]) {
+       write(buf, 0, buf.length);
+    }
+
+
+    public void write(String s, int off, int len) {
+
+        if (error)
+            return;
+
+        try {
+            ob.write(s, off, len);
+        } catch (IOException e) {
+            error = true;
+        }
+
+    }
+
+
+    public void write(String s) {
+        write(s, 0, s.length());
     }
 
 
     // ---------------------------------------------------- PrintWriter Methods
 
 
-    public void print(String str) {
-        super.print( str );
+    public void print(boolean b) {
+        if (b) {
+            write("true");
+        } else {
+            write("false");
+        }
     }
 
 
-    public void println(String str) {
-        super.println(str);
+    public void print(char c) {
+        write(c);
     }
 
 
-}
+    public void print(int i) {
+        write(String.valueOf(i));
+    }
 
+
+    public void print(long l) {
+        write(String.valueOf(l));
+    }
+
+
+    public void print(float f) {
+        write(String.valueOf(f));
+    }
+
+
+    public void print(double d) {
+        write(String.valueOf(d));
+    }
+
+
+    public void print(char s[]) {
+        write(s);
+    }
+
+
+    public void print(String s) {
+        if (s == null) {
+            s = "null";
+        }
+        write(s);
+    }
+
+
+    public void print(Object obj) {
+        write(String.valueOf(obj));
+    }
+
+
+    public void println() {
+        write(LINE_SEP);
+    }
+
+
+    public void println(boolean b) {
+        print(b);
+        println();
+    }
+
+
+    public void println(char c) {
+        print(c);
+        println();
+    }
+
+
+    public void println(int i) {
+        print(i);
+        println();
+    }
+
+
+    public void println(long l) {
+        print(l);
+        println();
+    }
+
+
+    public void println(float f) {
+        print(f);
+        println();
+    }
+
+
+    public void println(double d) {
+        print(d);
+        println();
+    }
+
+
+    public void println(char c[]) {
+        print(c);
+        println();
+    }
+
+
+    public void println(String s) {
+        print(s);
+        println();
+    }
+
+
+    public void println(Object o) {
+        print(o);
+        println();
+    }
+
+
+}

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to