Thread: [Winstone-devel] winstone/src/java/winstone WinstoneOutputStream.java, 1.17, 1.18 WinstoneRequest.j
Status: Beta
Brought to you by:
rickknowles
From: Rick K. <ric...@us...> - 2006-08-11 16:19:00
|
Update of /cvsroot/winstone/winstone/src/java/winstone In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv20682/src/java/winstone Modified Files: WinstoneOutputStream.java WinstoneRequest.java RequestDispatcher.java WinstoneResponse.java Log Message: More 2.5 spec fixes. This should be a completely 2.5 compliant version, as there are only 2 tests failing: 1 is waiting for a TCK correction (the test is wrong) and the other is waiting on a clarification that's 90% likely to be a TCK correction as well. Index: WinstoneOutputStream.java =================================================================== RCS file: /cvsroot/winstone/winstone/src/java/winstone/WinstoneOutputStream.java,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** WinstoneOutputStream.java 10 Aug 2006 15:17:39 -0000 1.17 --- WinstoneOutputStream.java 11 Aug 2006 16:14:59 -0000 1.18 *************** *** 33,36 **** --- 33,37 ---- protected WinstoneResponse owner; protected boolean disregardMode = false; + protected boolean closed = false; protected Stack includeByteStreams; *************** *** 78,84 **** this.disregardMode = disregard; } public void write(int oneChar) throws IOException { ! if (this.disregardMode) { return; } --- 79,89 ---- this.disregardMode = disregard; } + + public void setClosed(boolean closed) { + this.closed = closed; + } public void write(int oneChar) throws IOException { ! if (this.disregardMode || this.closed) { return; } *************** *** 193,197 **** public void close() throws IOException { ! if (!isCommitted() && !this.disregardMode && (this.owner.getHeader(WinstoneResponse.CONTENT_LENGTH_HEADER) == null)) { if ((this.owner != null) && !this.bodyOnly) { --- 198,202 ---- public void close() throws IOException { ! if (!isCommitted() && !this.disregardMode && !this.closed && (this.owner.getHeader(WinstoneResponse.CONTENT_LENGTH_HEADER) == null)) { if ((this.owner != null) && !this.bodyOnly) { Index: WinstoneResponse.java =================================================================== RCS file: /cvsroot/winstone/winstone/src/java/winstone/WinstoneResponse.java,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** WinstoneResponse.java 10 Aug 2006 15:17:39 -0000 1.36 --- WinstoneResponse.java 11 Aug 2006 16:14:59 -0000 1.37 *************** *** 34,41 **** */ public class WinstoneResponse implements HttpServletResponse { ! protected static final DateFormat df = new SimpleDateFormat( "EEE, dd MMM yyyy HH:mm:ss z", Locale.US); static { ! df.setTimeZone(TimeZone.getTimeZone("GMT")); } --- 34,44 ---- */ public class WinstoneResponse implements HttpServletResponse { ! private static final DateFormat HTTP_DF = new SimpleDateFormat( "EEE, dd MMM yyyy HH:mm:ss z", Locale.US); + private static final DateFormat VERSION0_DF = new SimpleDateFormat( + "EEE, dd-MMM-yy HH:mm:ss z", Locale.US); static { ! HTTP_DF.setTimeZone(TimeZone.getTimeZone("GMT")); ! VERSION0_DF.setTimeZone(TimeZone.getTimeZone("GMT")); } *************** *** 64,69 **** private List headers; ! private String explicitlySetEncoding; ! private String currentEncoding; private List cookies; --- 67,72 ---- private List headers; ! private String explicitEncoding; ! private String implicitEncoding; private List cookies; *************** *** 83,87 **** this.statusCode = SC_OK; this.locale = null; //Locale.getDefault(); ! this.explicitlySetEncoding = null; this.protocol = null; this.reqKeepAliveHeader = null; --- 86,90 ---- this.statusCode = SC_OK; this.locale = null; //Locale.getDefault(); ! this.explicitEncoding = null; this.protocol = null; this.reqKeepAliveHeader = null; *************** *** 104,109 **** this.errorStatusCode = null; this.locale = null; //Locale.getDefault(); ! this.explicitlySetEncoding = null; ! this.currentEncoding = null; } --- 107,112 ---- this.errorStatusCode = null; this.locale = null; //Locale.getDefault(); ! this.explicitEncoding = null; ! this.implicitEncoding = null; } *************** *** 198,202 **** protected static String getCharsetFromContentTypeHeader(String type, StringBuffer remainder) { if (type == null) { ! type = "text/html"; } // Parse type to set encoding if needed --- 201,205 ---- protected static String getCharsetFromContentTypeHeader(String type, StringBuffer remainder) { if (type == null) { ! return null; } // Parse type to set encoding if needed *************** *** 234,254 **** Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, "WinstoneResponse.ForcingContentLength", "" + bodyBytes); ! setHeader(CONTENT_LENGTH_HEADER, "" + bodyBytes, true); lengthHeader = getHeader(CONTENT_LENGTH_HEADER); } } ! setHeader(KEEP_ALIVE_HEADER, !closeAfterRequest() ? KEEP_ALIVE_OPEN : KEEP_ALIVE_CLOSE, true); String contentType = getHeader(CONTENT_TYPE_HEADER); ! if ((contentType == null) && (this.statusCode != SC_MOVED_TEMPORARILY)) { ! // Bypass normal encoding ! String enc = getCurrentEncoding(); ! setHeader(CONTENT_TYPE_HEADER, "text/html" + ! (enc == null ? "" : ";charset=" + enc), true); } - if (getHeader(DATE_HEADER) == null) - setHeader(DATE_HEADER, formatHeaderDate(new Date()), true); - if (getHeader(X_POWERED_BY_HEADER) == null) - setHeader(X_POWERED_BY_HEADER, POWERED_BY_WINSTONE, true); if (this.locale != null) { String lang = this.locale.getLanguage(); --- 237,264 ---- Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, "WinstoneResponse.ForcingContentLength", "" + bodyBytes); ! forceHeader(CONTENT_LENGTH_HEADER, "" + bodyBytes); lengthHeader = getHeader(CONTENT_LENGTH_HEADER); } } ! forceHeader(KEEP_ALIVE_HEADER, !closeAfterRequest() ? KEEP_ALIVE_OPEN : KEEP_ALIVE_CLOSE); String contentType = getHeader(CONTENT_TYPE_HEADER); ! if (this.statusCode != SC_MOVED_TEMPORARILY) { ! if (contentType == null) { ! // Bypass normal encoding ! forceHeader(CONTENT_TYPE_HEADER, "text/html;charset=" + getCharacterEncoding()); ! } else if (contentType.startsWith("text/")) { ! // replace charset in content ! StringBuffer remainder = new StringBuffer(); ! getCharsetFromContentTypeHeader(contentType, remainder); ! forceHeader(CONTENT_TYPE_HEADER, remainder.toString() + ";charset=" + getCharacterEncoding()); ! } ! } ! if (getHeader(DATE_HEADER) == null) { ! forceHeader(DATE_HEADER, formatHeaderDate(new Date())); ! } ! if (getHeader(X_POWERED_BY_HEADER) == null) { ! forceHeader(X_POWERED_BY_HEADER, POWERED_BY_WINSTONE); } if (this.locale != null) { String lang = this.locale.getLanguage(); *************** *** 256,267 **** lang = lang + "-" + this.locale.getCountry(); } ! setHeader(CONTENT_LANGUAGE_HEADER, lang, true); } // If we don't have a webappConfig, exit here, cause we definitely don't // have a session ! if (req.getWebAppConfig() == null) return; ! // Write out the new session cookie if it's present HostConfiguration hostConfig = req.getHostGroup().getHostByName(req.getServerName()); --- 266,277 ---- lang = lang + "-" + this.locale.getCountry(); } ! forceHeader(CONTENT_LANGUAGE_HEADER, lang); } // If we don't have a webappConfig, exit here, cause we definitely don't // have a session ! if (req.getWebAppConfig() == null) { return; ! } // Write out the new session cookie if it's present HostConfiguration hostConfig = req.getHostGroup().getHostByName(req.getServerName()); *************** *** 350,357 **** long expiryMS = System.currentTimeMillis() + (1000 * (long) cookie.getMaxAge()); ! Date expiryDate = new Date(expiryMS); ! out.append("; Expires=").append(formatHeaderDate(expiryDate)); } else if (cookie.getMaxAge() == 0) { ! out.append("; Expires=").append(formatHeaderDate(new Date(5000))); } if (cookie.getPath() != null) --- 360,374 ---- long expiryMS = System.currentTimeMillis() + (1000 * (long) cookie.getMaxAge()); ! String expiryDate = null; ! synchronized (VERSION0_DF) { ! expiryDate = VERSION0_DF.format(new Date(expiryMS)); ! } ! out.append("; Expires=").append(expiryDate); } else if (cookie.getMaxAge() == 0) { ! String expiryDate = null; ! synchronized (VERSION0_DF) { ! expiryDate = VERSION0_DF.format(new Date(5000)); ! } ! out.append("; Expires=").append(expiryDate); } if (cookie.getPath() != null) *************** *** 365,370 **** private static String formatHeaderDate(Date dateIn) { String date = null; ! synchronized (df) { ! date = df.format(dateIn); } return date; --- 382,387 ---- private static String formatHeaderDate(Date dateIn) { String date = null; ! synchronized (HTTP_DF) { ! date = HTTP_DF.format(dateIn); } return date; *************** *** 416,446 **** return false; } - - private WinstoneOutputStream getTopOutputStream() { - WinstoneOutputStream outStream = this.outputStream; - // if (!this.includeOutputStreams.isEmpty()) { - // outStream = (WinstoneOutputStream) this.includeOutputStreams.peek(); - // } - return outStream; - } // ServletResponse interface methods public void flushBuffer() throws IOException { - WinstoneOutputStream outStream = getTopOutputStream(); - // PrintWriter outWriter = (PrintWriter) this.outPrintWriters.get(outStream); if (this.outputWriter != null) { this.outputWriter.flush(); } ! outStream.flush(); } public void setBufferSize(int size) { ! WinstoneOutputStream outStream = getTopOutputStream(); ! outStream.setBufferSize(size); } public int getBufferSize() { ! WinstoneOutputStream outStream = getTopOutputStream(); ! return outStream.getBufferSize(); } --- 433,451 ---- return false; } // ServletResponse interface methods public void flushBuffer() throws IOException { if (this.outputWriter != null) { this.outputWriter.flush(); } ! this.outputStream.flush(); } public void setBufferSize(int size) { ! this.outputStream.setBufferSize(size); } public int getBufferSize() { ! return this.outputStream.getBufferSize(); } *************** *** 451,460 **** public void setCharacterEncoding(String encoding) { ! Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, "WinstoneResponse.SettingEncoding", encoding); ! StringBuffer remainderHeader = new StringBuffer(); ! getCharsetFromContentTypeHeader(getContentType(), remainderHeader); ! setContentType(remainderHeader + ";charset=" + encoding); } public String getContentType() { return getHeader(CONTENT_TYPE_HEADER); --- 456,477 ---- public void setCharacterEncoding(String encoding) { ! if ((this.outputWriter == null) && !isCommitted()) { ! Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, "WinstoneResponse.SettingEncoding", encoding); ! this.explicitEncoding = encoding; ! correctContentTypeHeaderEncoding(encoding); ! } } + private void correctContentTypeHeaderEncoding(String encoding) { + String contentType = getContentType(); + if (contentType != null) { + StringBuffer remainderHeader = new StringBuffer(); + getCharsetFromContentTypeHeader(contentType, remainderHeader); + if (remainderHeader.length() != 0) { + forceHeader(CONTENT_TYPE_HEADER, remainderHeader + ";charset=" + encoding); + } + } + } + public String getContentType() { return getHeader(CONTENT_TYPE_HEADER); *************** *** 470,474 **** private boolean isIncluding() { - // return !this.includeOutputStreams.isEmpty(); return this.outputStream.isIncluding(); } --- 487,490 ---- *************** *** 477,511 **** if (isIncluding()) { return; ! } ! ! if (isCommitted()) { Logger.log(Logger.WARNING, Launcher.RESOURCES, "WinstoneResponse.SetLocaleTooLate"); ! // } else if ((this.outPrintWriters.get(this.outputStream) == null) ! } else if ((this.outputWriter == null) ! && (this.explicitlySetEncoding == null)) { ! String localeEncoding = getEncodingFromLocale(loc); ! if (localeEncoding != null) { ! this.currentEncoding = localeEncoding; ! String contentTypeHeader = getContentType(); ! if (contentTypeHeader == null) { ! this.headers.add(CONTENT_TYPE_HEADER + ": text/html;charset=" + localeEncoding); ! } else { ! StringBuffer remainderHeader = new StringBuffer(); ! getCharsetFromContentTypeHeader(contentTypeHeader, remainderHeader); ! String contentHeader = remainderHeader + ";charset=" + localeEncoding; ! boolean found = false; ! for (int n = 0; (n < this.headers.size()) && !found; n++) { ! String header = (String) this.headers.get(n); ! if (header.startsWith(CONTENT_TYPE_HEADER + ": ")) { ! this.headers.set(n, CONTENT_TYPE_HEADER + ": " + contentHeader); ! found = true; ! } ! } } } - } - - if (!isCommitted()) { this.locale = loc; } --- 493,507 ---- if (isIncluding()) { return; ! } else if (isCommitted()) { Logger.log(Logger.WARNING, Launcher.RESOURCES, "WinstoneResponse.SetLocaleTooLate"); ! } else { ! if ((this.outputWriter == null) && (this.explicitEncoding == null)) { ! String localeEncoding = getEncodingFromLocale(loc); ! if (localeEncoding != null) { ! this.implicitEncoding = localeEncoding; ! correctContentTypeHeaderEncoding(localeEncoding); } } this.locale = loc; } *************** *** 514,527 **** public ServletOutputStream getOutputStream() throws IOException { Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, "WinstoneResponse.GetOutputStream"); ! return getTopOutputStream(); } public PrintWriter getWriter() throws IOException { Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, "WinstoneResponse.GetWriter"); - WinstoneOutputStream outStream = getTopOutputStream(); if (this.outputWriter != null) return this.outputWriter; else { ! this.outputWriter = new WinstoneResponseWriter(outStream, this); return this.outputWriter; } --- 510,522 ---- public ServletOutputStream getOutputStream() throws IOException { Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, "WinstoneResponse.GetOutputStream"); ! return this.outputStream; } public PrintWriter getWriter() throws IOException { Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, "WinstoneResponse.GetWriter"); if (this.outputWriter != null) return this.outputWriter; else { ! this.outputWriter = new WinstoneResponseWriter(this.outputStream, this); return this.outputWriter; } *************** *** 592,610 **** Logger.log(Logger.DEBUG, Launcher.RESOURCES, "WinstoneResponse.HeaderAfterCommitted", new String[] {name, value}); ! } else { if (name.equals(CONTENT_TYPE_HEADER)) { StringBuffer remainderHeader = new StringBuffer(); ! String headerEncoding = getCharsetFromContentTypeHeader( ! value, remainderHeader); ! if ((headerEncoding != null) && ! // (this.outPrintWriters.get(getTopOutputStream()) == null)) { ! (this.outputWriter == null)) { ! value = remainderHeader.toString() + "; charset=" + headerEncoding; ! this.explicitlySetEncoding = headerEncoding; ! this.currentEncoding = headerEncoding; ! } else { ! value = remainderHeader.toString() + ! (getCurrentEncoding() == null ? "" : ! ";charset=" + getCurrentEncoding()); } } --- 587,598 ---- Logger.log(Logger.DEBUG, Launcher.RESOURCES, "WinstoneResponse.HeaderAfterCommitted", new String[] {name, value}); ! } else if (value != null) { if (name.equals(CONTENT_TYPE_HEADER)) { StringBuffer remainderHeader = new StringBuffer(); ! String headerEncoding = getCharsetFromContentTypeHeader(value, remainderHeader); ! if (this.outputWriter != null) { ! value = remainderHeader + ";charset=" + getCharacterEncoding(); ! } else if (headerEncoding != null) { ! this.explicitEncoding = headerEncoding; } } *************** *** 622,629 **** public void setHeader(String name, String value) { ! setHeader(name, value, false); ! } ! private void setHeader(String name, String value, boolean ignoreInclude) { ! if (!ignoreInclude && isIncluding()) { Logger.log(Logger.DEBUG, Launcher.RESOURCES, "WinstoneResponse.HeaderInInclude", new String[] {name, value}); --- 610,614 ---- public void setHeader(String name, String value) { ! if (isIncluding()) { Logger.log(Logger.DEBUG, Launcher.RESOURCES, "WinstoneResponse.HeaderInInclude", new String[] {name, value}); *************** *** 633,668 **** } else { boolean found = false; ! for (int n = 0; (n < this.headers.size()) && !found; n++) { String header = (String) this.headers.get(n); if (header.startsWith(name + ": ")) { if (name.equals(CONTENT_TYPE_HEADER)) { ! StringBuffer remainderHeader = new StringBuffer(); ! String headerEncoding = getCharsetFromContentTypeHeader( ! value, remainderHeader); ! if ((headerEncoding != null) && ! // (this.outPrintWriters.get(getTopOutputStream()) == null)) { ! (this.outputWriter == null)) { ! value = remainderHeader.toString() + "; charset=" + headerEncoding; ! this.explicitlySetEncoding = headerEncoding; ! this.currentEncoding = headerEncoding; ! } else { ! value = remainderHeader.toString() + ! (getCurrentEncoding() == null ? "" : ! "; charset=" + getCurrentEncoding()); } } ! this.headers.set(n, name + ": " + value); found = true; } } ! if (!found) addHeader(name, value); } } private String getCurrentEncoding() { ! if (this.currentEncoding != null) { ! return this.currentEncoding; } else if ((this.req != null) && (this.req.getCharacterEncoding() != null)) { try { --- 618,674 ---- } else { boolean found = false; ! for (int n = 0; (n < this.headers.size()); n++) { String header = (String) this.headers.get(n); if (header.startsWith(name + ": ")) { + if (found) { + this.headers.remove(n); + continue; + } if (name.equals(CONTENT_TYPE_HEADER)) { ! if (value != null) { ! StringBuffer remainderHeader = new StringBuffer(); ! String headerEncoding = getCharsetFromContentTypeHeader( ! value, remainderHeader); ! if (this.outputWriter != null) { ! value = remainderHeader + ";charset=" + getCharacterEncoding(); ! } else if (headerEncoding != null) { ! this.explicitEncoding = headerEncoding; ! } } } ! if (value != null) { ! this.headers.set(n, name + ": " + value); ! } else { ! this.headers.remove(n); ! } found = true; } } ! if (!found) { addHeader(name, value); + } } } + private void forceHeader(String name, String value) { + boolean found = false; + for (int n = 0; (n < this.headers.size()); n++) { + String header = (String) this.headers.get(n); + if (header.startsWith(name + ": ")) { + found = true; + this.headers.set(n, name + ": " + value); + } + } + if (!found) { + this.headers.add(name + ": " + value); + } + } + private String getCurrentEncoding() { ! if (this.explicitEncoding != null) { ! return this.explicitEncoding; ! } else if (this.implicitEncoding != null) { ! return this.implicitEncoding; } else if ((this.req != null) && (this.req.getCharacterEncoding() != null)) { try { *************** *** 771,776 **** if ((this.webAppConfig != null) && (this.req != null)) { - // && (this.webAppConfig.getErrorPagesByCode().get("" + sc) != null)) { - // String errorPage = (String) this.webAppConfig.getErrorPagesByCode().get("" + sc); RequestDispatcher rd = this.webAppConfig --- 777,780 ---- Index: RequestDispatcher.java =================================================================== RCS file: /cvsroot/winstone/winstone/src/java/winstone/RequestDispatcher.java,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** RequestDispatcher.java 10 Aug 2006 12:55:27 -0000 1.14 --- RequestDispatcher.java 11 Aug 2006 16:14:59 -0000 1.15 *************** *** 334,337 **** --- 334,340 ---- } else { this.servletConfig.execute(request, response, this.webAppConfig.getContextPath() + this.requestURI); + WinstoneResponse rsp = getUnwrappedResponse(response); + rsp.flushBuffer(); + rsp.getWinstoneOutputStream().setClosed(true); } } Index: WinstoneRequest.java =================================================================== RCS file: /cvsroot/winstone/winstone/src/java/winstone/WinstoneRequest.java,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** WinstoneRequest.java 10 Aug 2006 12:54:58 -0000 1.28 --- WinstoneRequest.java 11 Aug 2006 16:14:59 -0000 1.29 *************** *** 1230,1234 **** public boolean isRequestedSessionIdFromCookie() { ! return true; } --- 1230,1234 ---- public boolean isRequestedSessionIdFromCookie() { ! return (getRequestedSessionId() != null); } |