Return-Path: Delivered-To: apmail-jakarta-tomcat-dev-archive@apache.org Received: (qmail 26703 invoked from network); 20 Dec 2002 02:08:00 -0000 Received: from exchange.sun.com (HELO nagoya.betaversion.org) (192.18.33.10) by daedalus.apache.org with SMTP; 20 Dec 2002 02:08:00 -0000 Received: (qmail 7777 invoked by uid 97); 20 Dec 2002 02:09:13 -0000 Delivered-To: qmlist-jakarta-archive-tomcat-dev@jakarta.apache.org Received: (qmail 7758 invoked by uid 97); 20 Dec 2002 02:09:12 -0000 Mailing-List: contact tomcat-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Tomcat Developers List" Reply-To: "Tomcat Developers List" Delivered-To: mailing list tomcat-dev@jakarta.apache.org Received: (qmail 7745 invoked by uid 98); 20 Dec 2002 02:09:11 -0000 X-Antivirus: nagoya (v4218 created Aug 14 2002) Message-ID: <3E027B1D.30401@punknix.com> Date: Fri, 20 Dec 2002 10:06:21 +0800 From: Punky Tse User-Agent: Mozilla/5.0 (Windows; U; WinNT4.0; en-US; rv:1.2.1) Gecko/20021130 X-Accept-Language: en-us MIME-Version: 1.0 To: Tomcat Developers List Subject: Re: [VOTE] Tomcat 4.1.18 release References: <200212190132.gBJ1WRQr026801@ensodex.com> <3E017456.1050609@apache.org> <3E01AA47.5070004@apache.org> In-Reply-To: <3E01AA47.5070004@apache.org> Content-Type: multipart/mixed; boundary="------------030508090905080902000202" X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N --------------030508090905080902000202 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit 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: > > > [ ] Yes > [ ] No > > > Remy > > > -- > To unsubscribe, e-mail: > > For additional commands, e-mail: > > --------------030508090905080902000202 Content-Type: text/plain; name="CoyoteResponse.java.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="CoyoteResponse.java.diff" =================================================================== 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()); } --------------030508090905080902000202 Content-Type: text/plain; name="CoyoteWriter.java.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="CoyoteWriter.java.diff" =================================================================== 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(); + } + + +} --------------030508090905080902000202 Content-Type: text/plain; charset=us-ascii -- To unsubscribe, e-mail: For additional commands, e-mail: --------------030508090905080902000202--