JBossWeb SVN: r799 - in trunk: webapps/docs and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2008-09-30 16:32:07 -0400 (Tue, 30 Sep 2008)
New Revision: 799
Modified:
trunk/java/org/apache/catalina/servlets/CGIServlet.java
trunk/webapps/docs/changelog.xml
Log:
- Generics cleanup.
Modified: trunk/java/org/apache/catalina/servlets/CGIServlet.java
===================================================================
--- trunk/java/org/apache/catalina/servlets/CGIServlet.java 2008-09-30 15:56:04 UTC (rev 798)
+++ trunk/java/org/apache/catalina/servlets/CGIServlet.java 2008-09-30 20:32:07 UTC (rev 799)
@@ -340,9 +340,9 @@
// Document the properties from ServletRequest
out.println("<h1>ServletRequest Properties</h1>");
out.println("<ul>");
- Enumeration attrs = req.getAttributeNames();
+ Enumeration<String> attrs = req.getAttributeNames();
while (attrs.hasMoreElements()) {
- String attr = (String) attrs.nextElement();
+ String attr = attrs.nextElement();
out.println("<li><b>attribute</b> " + attr + " = " +
req.getAttribute(attr));
}
@@ -352,14 +352,14 @@
req.getContentLength());
out.println("<li><b>contentType</b> = " +
req.getContentType());
- Enumeration locales = req.getLocales();
+ Enumeration<Locale> locales = req.getLocales();
while (locales.hasMoreElements()) {
- Locale locale = (Locale) locales.nextElement();
+ Locale locale = locales.nextElement();
out.println("<li><b>locale</b> = " + locale);
}
- Enumeration params = req.getParameterNames();
+ Enumeration<String> params = req.getParameterNames();
while (params.hasMoreElements()) {
- String param = (String) params.nextElement();
+ String param = params.nextElement();
String values[] = req.getParameterValues(param);
for (int i = 0; i < values.length; i++)
out.println("<li><b>parameter</b> " + param + " = " +
@@ -386,9 +386,9 @@
for (int i = 0; i < cookies.length; i++)
out.println("<li><b>cookie</b> " + cookies[i].getName() +" = " +cookies[i].getValue());
}
- Enumeration headers = req.getHeaderNames();
+ Enumeration<String> headers = req.getHeaderNames();
while (headers.hasMoreElements()) {
- String header = (String) headers.nextElement();
+ String header = headers.nextElement();
out.println("<li><b>header</b> " + header + " = " +
req.getHeader(header));
}
@@ -423,7 +423,7 @@
out.println("<ul>");
attrs = req.getAttributeNames();
while (attrs.hasMoreElements()) {
- String attr = (String) attrs.nextElement();
+ String attr = attrs.nextElement();
out.println("<li><b>" + attr + "</b> = " +
req.getAttribute(attr));
}
@@ -453,7 +453,7 @@
out.println("<ul>");
attrs = session.getAttributeNames();
while (attrs.hasMoreElements()) {
- String attr = (String) attrs.nextElement();
+ String attr = attrs.nextElement();
out.println("<li><b>" + attr + "</b> = " +
session.getAttribute(attr));
}
@@ -475,7 +475,7 @@
out.println("<ul>");
params = getServletConfig().getInitParameterNames();
while (params.hasMoreElements()) {
- String param = (String) params.nextElement();
+ String param = params.nextElement();
String value = getServletConfig().getInitParameter(param);
out.println("<li><b>" + param + "</b> = " + value);
}
@@ -501,7 +501,7 @@
out.println("<ul>");
params = getServletContext().getInitParameterNames();
while (params.hasMoreElements()) {
- String param = (String) params.nextElement();
+ String param = params.nextElement();
String value = getServletContext().getInitParameter(param);
out.println("<li><b>" + param + "</b> = " + value);
}
@@ -513,7 +513,7 @@
out.println("<ul>");
attrs = getServletContext().getAttributeNames();
while (attrs.hasMoreElements()) {
- String attr = (String) attrs.nextElement();
+ String attr = attrs.nextElement();
out.println("<li><b>" + attr + "</b> = " +
getServletContext().getAttribute(attr));
}
@@ -625,6 +625,7 @@
} //doGet
+
/** For future testing use only; does nothing right now */
public static void main(String[] args) {
System.out.println("$Header$");
@@ -664,7 +665,7 @@
private File tmpDir = null;
/** derived cgi environment */
- private Hashtable env = null;
+ private Hashtable<String, String> env = null;
/** cgi command to be invoked */
private String command = null;
@@ -933,7 +934,6 @@
// Add the CGI environment variables
String sPathInfoOrig = null;
- String sPathTranslatedOrig = null;
String sPathInfoCGI = null;
String sPathTranslatedCGI = null;
String sCGIFullPath = null;
@@ -946,10 +946,6 @@
sPathInfoOrig = this.pathInfo;
sPathInfoOrig = sPathInfoOrig == null ? "" : sPathInfoOrig;
- sPathTranslatedOrig = req.getPathTranslated();
- sPathTranslatedOrig =
- sPathTranslatedOrig == null ? "" : sPathTranslatedOrig;
-
if (webAppRootDir == null ) {
// The app has not been deployed in exploded form
webAppRootDir = tmpDir.toString();
@@ -983,7 +979,8 @@
envp.put("SERVER_PROTOCOL", nullsToBlanks(req.getProtocol()));
int port = req.getServerPort();
- Integer iPort = (port == 0 ? new Integer(-1) : new Integer(port));
+ Integer iPort =
+ (port == 0 ? Integer.valueOf(-1) : Integer.valueOf(port));
envp.put("SERVER_PORT", iPort.toString());
envp.put("REQUEST_METHOD", nullsToBlanks(req.getMethod()));
@@ -1032,8 +1029,6 @@
*/
if (sPathInfoCGI != null && !("".equals(sPathInfoCGI))) {
sPathTranslatedCGI = context.getRealPath(sPathInfoCGI);
- } else {
- sPathTranslatedCGI = null;
}
if (sPathTranslatedCGI == null || "".equals(sPathTranslatedCGI)) {
//NOOP
@@ -1065,15 +1060,15 @@
*/
int contentLength = req.getContentLength();
String sContentLength = (contentLength <= 0 ? "" :
- (new Integer(contentLength)).toString());
+ (Integer.valueOf(contentLength)).toString());
envp.put("CONTENT_LENGTH", sContentLength);
- Enumeration headers = req.getHeaderNames();
+ Enumeration<String> headers = req.getHeaderNames();
String header = null;
while (headers.hasMoreElements()) {
header = null;
- header = ((String) headers.nextElement()).toUpperCase();
+ header = headers.nextElement().toUpperCase();
//REMIND: rewrite multiple headers as if received as single
//REMIND: change character set
//REMIND: I forgot what the previous REMIND means
@@ -1145,10 +1140,14 @@
}
// create directories
- String dirPath = new String (destPath.toString().substring(
- 0,destPath.toString().lastIndexOf("/")));
+ String dirPath = destPath.toString().substring(
+ 0,destPath.toString().lastIndexOf("/"));
File dir = new File(dirPath);
- dir.mkdirs();
+ if (!dir.mkdirs() && debug >= 2) {
+ log("expandCGIScript: failed to create directories for '" +
+ dir.getAbsolutePath() + "'");
+ return;
+ }
try {
synchronized (expandFileLock) {
@@ -1174,7 +1173,10 @@
} catch (IOException ioe) {
// delete in case file is corrupted
if (f.exists()) {
- f.delete();
+ if (!f.delete() && debug >= 2) {
+ log("expandCGIScript: failed to delete '" +
+ f.getAbsolutePath() + "'");
+ }
}
}
}
@@ -1205,13 +1207,13 @@
sb.append("</td></tr>");
if (isValid()) {
- Enumeration envk = env.keys();
+ Enumeration<String> envk = env.keys();
while (envk.hasMoreElements()) {
- String s = (String) envk.nextElement();
+ String s = envk.nextElement();
sb.append("<tr><td>");
sb.append(s);
sb.append("</td><td>");
- sb.append(blanksToString((String) env.get(s),
+ sb.append(blanksToString(env.get(s),
"[will be set to blank]"));
sb.append("</td></tr>");
}
@@ -1231,7 +1233,7 @@
sb.append("<tr><td>Command Line Params</td><td>");
for (int i=0; i < cmdLineParameters.size(); i++) {
- String param = (String) cmdLineParameters.get(i);
+ String param = cmdLineParameters.get(i);
sb.append("<p>");
sb.append(param);
sb.append("</p>");
@@ -1275,7 +1277,7 @@
* @return CGI environment
*
*/
- protected Hashtable getEnvironment() {
+ protected Hashtable<String,String> getEnvironment() {
return env;
}
@@ -1287,7 +1289,7 @@
* @return CGI query parameters
*
*/
- protected ArrayList getParameters() {
+ protected ArrayList<String> getParameters() {
return cmdLineParameters;
}
@@ -1389,13 +1391,13 @@
private String command = null;
/** environment used when invoking the cgi script */
- private Hashtable env = null;
+ private Hashtable<String,String> env = null;
/** working directory used when invoking the cgi script */
private File wd = null;
/** command line parameters to be passed to the invoked script */
- private ArrayList params = null;
+ private ArrayList<String> params = null;
/** stdin to be passed to cgi script */
private InputStream stdin = null;
@@ -1423,8 +1425,8 @@
* @param params ArrayList with the script's query command line
* paramters as strings
*/
- protected CGIRunner(String command, Hashtable env, File wd,
- ArrayList params) {
+ protected CGIRunner(String command, Hashtable<String,String> env,
+ File wd, ArrayList<String> params) {
this.command = command;
this.env = env;
this.wd = wd;
@@ -1502,13 +1504,13 @@
* @exception NullPointerException if a hash key has a null value
*
*/
- protected String[] hashToStringArray(Hashtable h)
+ protected String[] hashToStringArray(Hashtable<String,?> h)
throws NullPointerException {
Vector<String> v = new Vector<String>();
- Enumeration e = h.keys();
+ Enumeration<String> e = h.keys();
while (e.hasMoreElements()) {
- String k = e.nextElement().toString();
- v.add(k + "=" + h.get(k));
+ String k = e.nextElement();
+ v.add(k + "=" + h.get(k).toString());
}
String[] strArr = new String[v.size()];
v.copyInto(strArr);
@@ -1596,6 +1598,7 @@
* with major modifications by Martin Dengler
*/
Runtime rt = null;
+ BufferedReader cgiHeaderReader = null;
InputStream cgiOutput = null;
BufferedReader commandsStdErr = null;
BufferedOutputStream commandsStdIn = null;
@@ -1615,7 +1618,7 @@
for (int i=0; i < params.size(); i++) {
cmdAndArgs.append(" ");
- String param = (String) params.get(i);
+ String param = params.get(i);
if (param.indexOf(" ") < 0) {
cmdAndArgs.append(param);
} else {
@@ -1635,7 +1638,7 @@
rt = Runtime.getRuntime();
proc = rt.exec(cmdAndArgs.toString(), hashToStringArray(env), wd);
- String sContentLength = (String) env.get("CONTENT_LENGTH");
+ String sContentLength = env.get("CONTENT_LENGTH");
if(!"".equals(sContentLength)) {
commandsStdIn = new BufferedOutputStream(proc.getOutputStream());
@@ -1658,12 +1661,12 @@
new Thread() {
public void run () {
sendToLog(stdErrRdr) ;
- } ;
+ }
}.start() ;
InputStream cgiHeaderStream =
new HTTPHeaderInputStream(proc.getInputStream());
- BufferedReader cgiHeaderReader =
+ cgiHeaderReader =
new BufferedReader(new InputStreamReader(cgiHeaderStream));
while (isRunning) {
@@ -1726,12 +1729,21 @@
}
}
} //replacement for Process.waitFor()
+
}
catch (IOException e){
log ("Caught exception " + e);
throw e;
}
finally{
+ // Close the header reader
+ if (cgiHeaderReader != null) {
+ try {
+ cgiHeaderReader.close();
+ } catch (IOException ioe) {
+ log ("Exception closing header reader " + ioe);
+ }
+ }
// Close the output stream if used
if (cgiOutput != null) {
try {
@@ -1824,11 +1836,11 @@
rdr.close() ;
} catch (IOException ce) {
log("sendToLog error", ce) ;
- } ;
- } ;
+ }
+ }
if ( lineCount > 0 && debug > 2) {
log("runCGI: " + lineCount + " lines received on stderr") ;
- } ;
+ }
}
} //class CGIRunner
@@ -1837,7 +1849,7 @@
* upto and including the two blank lines terminating the headers. It
* allows the content to be read using bytes or characters as appropriate.
*/
- protected class HTTPHeaderInputStream extends InputStream {
+ protected static class HTTPHeaderInputStream extends InputStream {
private static final int STATE_CHARACTER = 0;
private static final int STATE_FIRST_CR = 1;
private static final int STATE_FIRST_LF = 2;
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2008-09-30 15:56:04 UTC (rev 798)
+++ trunk/webapps/docs/changelog.xml 2008-09-30 20:32:07 UTC (rev 799)
@@ -49,6 +49,9 @@
<fix>
<bug>45906</bug>: Another ETag improvement. Patch provided by Chris Hubick. (remm)
</fix>
+ <fix>
+ CGI servlet generics cleanup. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
16 years, 3 months
JBossWeb SVN: r798 - in trunk: java/org/apache/tomcat/util/buf and 2 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2008-09-30 11:56:04 -0400 (Tue, 30 Sep 2008)
New Revision: 798
Removed:
trunk/java/org/apache/tomcat/util/buf/DateTool.java
Modified:
trunk/java/org/apache/catalina/ssi/ResponseIncludeWrapper.java
trunk/java/org/apache/tomcat/util/buf/MessageBytes.java
trunk/java/org/apache/tomcat/util/http/ServerCookie.java
trunk/webapps/docs/changelog.xml
Log:
- Remove DateTool. Also restore the set timezone that was missing.
Modified: trunk/java/org/apache/catalina/ssi/ResponseIncludeWrapper.java
===================================================================
--- trunk/java/org/apache/catalina/ssi/ResponseIncludeWrapper.java 2008-09-29 15:47:49 UTC (rev 797)
+++ trunk/java/org/apache/catalina/ssi/ResponseIncludeWrapper.java 2008-09-30 15:56:04 UTC (rev 798)
@@ -22,6 +22,8 @@
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
+import java.util.Locale;
+import java.util.TimeZone;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
@@ -29,7 +31,6 @@
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
-import org.apache.catalina.util.DateTool;
/**
* A HttpServletResponseWrapper, used from
* <code>SSIServletExternalResolver</code>
@@ -44,8 +45,9 @@
*/
private static final String CONTENT_TYPE = "content-type";
private static final String LAST_MODIFIED = "last-modified";
- private static final DateFormat format =
- new SimpleDateFormat(DateTool.RFC1123_PATTERN, DateTool.LOCALE_US);
+ private static final DateFormat RFC1123_FORMAT;
+ private final static String RFC1123_PATTERN = "EEE, dd MMM yyyy HH:mm:ss z";
+
protected long lastModified = -1;
private String contentType = null;
@@ -59,7 +61,11 @@
private ServletContext context;
private HttpServletRequest request;
-
+ static {
+ RFC1123_FORMAT = new SimpleDateFormat(RFC1123_PATTERN, Locale.US);
+ RFC1123_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
+ }
+
/**
* Initialize our wrapper with the current HttpServletResponse and
* ServletOutputStream.
@@ -212,8 +218,8 @@
String lname = name.toLowerCase();
if (lname.equals(LAST_MODIFIED)) {
try {
- synchronized(format) {
- lastModified = format.parse(value).getTime();
+ synchronized(RFC1123_FORMAT) {
+ lastModified = RFC1123_FORMAT.parse(value).getTime();
}
} catch (Throwable ignore) { }
} else if (lname.equals(CONTENT_TYPE)) {
@@ -234,8 +240,8 @@
String lname = name.toLowerCase();
if (lname.equals(LAST_MODIFIED)) {
try {
- synchronized(format) {
- lastModified = format.parse(value).getTime();
+ synchronized(RFC1123_FORMAT) {
+ lastModified = RFC1123_FORMAT.parse(value).getTime();
}
} catch (Throwable ignore) { }
}
Deleted: trunk/java/org/apache/tomcat/util/buf/DateTool.java
===================================================================
--- trunk/java/org/apache/tomcat/util/buf/DateTool.java 2008-09-29 15:47:49 UTC (rev 797)
+++ trunk/java/org/apache/tomcat/util/buf/DateTool.java 2008-09-30 15:56:04 UTC (rev 798)
@@ -1,165 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tomcat.util.buf;
-
-import java.text.DateFormat;
-import java.text.FieldPosition;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import org.apache.tomcat.util.res.StringManager;
-
-/**
- * Common place for date utils.
- *
- * @deprecated Will be replaced with a more efficient impl, based on
- * FastDateFormat, with an API using less objects.
- * @author dac(a)eng.sun.com
- * @author Jason Hunter [jch(a)eng.sun.com]
- * @author James Todd [gonzo(a)eng.sun.com]
- * @author Costin Manolache
- */
-public class DateTool {
-
- /** US locale - all HTTP dates are in english
- */
- private final static Locale LOCALE_US = Locale.US;
-
- /** GMT timezone - all HTTP dates are on GMT
- */
- public final static TimeZone GMT_ZONE = TimeZone.getTimeZone("GMT");
-
- /** format for RFC 1123 date string -- "Sun, 06 Nov 1994 08:49:37 GMT"
- */
- public final static String RFC1123_PATTERN =
- "EEE, dd MMM yyyy HH:mm:ss z";
-
- // format for RFC 1036 date string -- "Sunday, 06-Nov-94 08:49:37 GMT"
- public final static String rfc1036Pattern =
- "EEEEEEEEE, dd-MMM-yy HH:mm:ss z";
-
- // format for C asctime() date string -- "Sun Nov 6 08:49:37 1994"
- public final static String asctimePattern =
- "EEE MMM d HH:mm:ss yyyy";
-
- /** Pattern used for old cookies
- */
- private final static String OLD_COOKIE_PATTERN = "EEE, dd-MMM-yyyy HH:mm:ss z";
-
- /** DateFormat to be used to format dates. Called from MessageBytes
- */
- private final static DateFormat rfc1123Format =
- new SimpleDateFormat(RFC1123_PATTERN, LOCALE_US);
-
- /** DateFormat to be used to format old netscape cookies
- Called from ServerCookie
- */
- private final static DateFormat oldCookieFormat =
- new SimpleDateFormat(OLD_COOKIE_PATTERN, LOCALE_US);
-
- private final static DateFormat rfc1036Format =
- new SimpleDateFormat(rfc1036Pattern, LOCALE_US);
-
- private final static DateFormat asctimeFormat =
- new SimpleDateFormat(asctimePattern, LOCALE_US);
-
- static {
- rfc1123Format.setTimeZone(GMT_ZONE);
- oldCookieFormat.setTimeZone(GMT_ZONE);
- rfc1036Format.setTimeZone(GMT_ZONE);
- asctimeFormat.setTimeZone(GMT_ZONE);
- }
-
- private static String rfc1123DS;
- private static long rfc1123Sec;
-
- private static StringManager sm =
- StringManager.getManager("org.apache.tomcat.util.buf.res");
-
- // Called from MessageBytes.getTime()
- static long parseDate( MessageBytes value ) {
- return parseDate( value.toString());
- }
-
- // Called from MessageBytes.setTime
- /**
- */
- public static String format1123( Date d ) {
- String dstr=null;
- synchronized(rfc1123Format) {
- dstr = format1123(d, rfc1123Format);
- }
- return dstr;
- }
-
- public static String format1123( Date d,DateFormat df ) {
- long dt = d.getTime() / 1000;
- if ((rfc1123DS != null) && (dt == rfc1123Sec))
- return rfc1123DS;
- rfc1123DS = df.format( d );
- rfc1123Sec = dt;
- return rfc1123DS;
- }
-
-
- // Called from ServerCookie
- /**
- */
- public static void formatOldCookie( Date d, StringBuffer sb,
- FieldPosition fp )
- {
- synchronized(oldCookieFormat) {
- oldCookieFormat.format( d, sb, fp );
- }
- }
-
- // Called from ServerCookie
- public static String formatOldCookie( Date d )
- {
- String ocf=null;
- synchronized(oldCookieFormat) {
- ocf= oldCookieFormat.format( d );
- }
- return ocf;
- }
-
-
- /** Called from HttpServletRequest.getDateHeader().
- Not efficient - but not very used.
- */
- public static long parseDate( String dateString ) {
- DateFormat [] format = {rfc1123Format,rfc1036Format,asctimeFormat};
- return parseDate(dateString,format);
- }
- public static long parseDate( String dateString, DateFormat []format ) {
- Date date=null;
- for(int i=0; i < format.length; i++) {
- try {
- date = format[i].parse(dateString);
- return date.getTime();
- } catch (ParseException e) { }
- catch (StringIndexOutOfBoundsException e) { }
- }
- String msg = sm.getString("httpDate.pe", dateString);
- throw new IllegalArgumentException(msg);
- }
-
-}
Modified: trunk/java/org/apache/tomcat/util/buf/MessageBytes.java
===================================================================
--- trunk/java/org/apache/tomcat/util/buf/MessageBytes.java 2008-09-29 15:47:49 UTC (rev 797)
+++ trunk/java/org/apache/tomcat/util/buf/MessageBytes.java 2008-09-30 15:56:04 UTC (rev 798)
@@ -17,10 +17,8 @@
package org.apache.tomcat.util.buf;
-import java.text.*;
-import java.util.*;
-import java.io.Serializable;
import java.io.IOException;
+import java.io.Serializable;
/**
* This class is used to represent a subarray of bytes in an HTTP message.
@@ -115,7 +113,6 @@
hasHashCode=false;
hasIntValue=false;
hasLongValue=false;
- hasDateValue=false;
}
@@ -133,7 +130,6 @@
hasHashCode=false;
hasIntValue=false;
hasLongValue=false;
- hasDateValue=false;
}
/** Set the encoding. If the object was constructed from bytes[]. any
@@ -163,7 +159,6 @@
hasHashCode=false;
hasIntValue=false;
hasLongValue=false;
- hasDateValue=false;
}
/** Remove the cached string value. Use it after a conversion on the
@@ -187,7 +182,6 @@
hasHashCode=false;
hasIntValue=false;
hasLongValue=false;
- hasDateValue=false;
if (s == null) {
hasStrValue=false;
type=T_NULL;
@@ -544,34 +538,7 @@
private boolean hasIntValue=false;
private long longValue;
private boolean hasLongValue=false;
- private Date dateValue;
- private boolean hasDateValue=false;
- /**
- * @deprecated The buffer are general purpose, caching for headers should
- * be done in headers. The second parameter allows us to pass a date format
- * instance to avoid synchronization problems.
- */
- public void setTime(long t, DateFormat df) {
- // XXX replace it with a byte[] tool
- recycle();
- if( dateValue==null)
- dateValue=new Date(t);
- else
- dateValue.setTime(t);
- if( df==null )
- strValue=DateTool.format1123(dateValue);
- else
- strValue=DateTool.format1123(dateValue,df);
- hasStrValue=true;
- hasDateValue=true;
- type=T_STR;
- }
-
- public void setTime(long t) {
- setTime( t, null );
- }
-
/** Set the buffer to the representation of an int
*/
public void setInt(int i) {
@@ -611,7 +578,6 @@
hasHashCode=false;
hasIntValue=true;
hasLongValue=false;
- hasDateValue=false;
type=T_BYTES;
}
@@ -654,31 +620,9 @@
hasHashCode=false;
hasIntValue=false;
hasLongValue=true;
- hasDateValue=false;
type=T_BYTES;
}
- /**
- * @deprecated The buffer are general purpose, caching for headers should
- * be done in headers
- */
- public long getTime()
- {
- if( hasDateValue ) {
- if( dateValue==null) return -1;
- return dateValue.getTime();
- }
-
- long l=DateTool.parseDate( this );
- if( dateValue==null)
- dateValue=new Date(l);
- else
- dateValue.setTime(l);
- hasDateValue=true;
- return l;
- }
-
-
// Used for headers conversion
/** Convert the buffer to an int, cache the value
*/
Modified: trunk/java/org/apache/tomcat/util/http/ServerCookie.java
===================================================================
--- trunk/java/org/apache/tomcat/util/http/ServerCookie.java 2008-09-29 15:47:49 UTC (rev 797)
+++ trunk/java/org/apache/tomcat/util/http/ServerCookie.java 2008-09-30 15:56:04 UTC (rev 798)
@@ -23,6 +23,7 @@
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
+import java.util.TimeZone;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.MessageBytes;
@@ -53,6 +54,19 @@
private int maxAge = -1;
private int version = 0;
+ // Other fields
+ private static final String OLD_COOKIE_PATTERN =
+ "EEE, dd-MMM-yyyy HH:mm:ss z";
+ private static final DateFormat OLD_COOKIE_FORMAT;
+ private static final String ancientDate;
+
+
+ static {
+ OLD_COOKIE_FORMAT = new SimpleDateFormat(OLD_COOKIE_PATTERN, Locale.US);
+ OLD_COOKIE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
+ ancientDate = OLD_COOKIE_FORMAT.format(new Date(10000));
+ }
+
/**
* If set to true, we parse cookies according to the servlet spec,
*/
@@ -247,11 +261,6 @@
}
}
- private final static DateFormat oldCookieFormat =
- new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss z", Locale.US);
-
- private static final String ancientDate = oldCookieFormat.format(new Date(10000));
-
// TODO RFC2965 fields also need to be passed
public static void appendCookieValue( StringBuffer headerBuf,
int version,
@@ -262,7 +271,7 @@
String comment,
int maxAge,
boolean isSecure,
- boolean httpOnly)
+ boolean isHttpOnly)
{
StringBuffer buf = new StringBuffer();
// Servlet implementation checks name
@@ -297,16 +306,16 @@
// Wdy, DD-Mon-YY HH:MM:SS GMT ( Expires Netscape format )
buf.append ("; Expires=");
// To expire immediately we need to set the time in past
- if (maxAge == 0) {
+ if (maxAge == 0)
buf.append( ancientDate );
- } else {
- synchronized(oldCookieFormat) {
- oldCookieFormat.format
- (new Date( System.currentTimeMillis() +
- maxAge *1000L), buf,
- new FieldPosition(0));
+ else
+ synchronized (OLD_COOKIE_FORMAT) {
+ OLD_COOKIE_FORMAT.format(
+ new Date(System.currentTimeMillis() +
+ maxAge*1000L),
+ buf, new FieldPosition(0));
}
- }
+
} else {
buf.append ("; Max-Age=");
buf.append (maxAge);
@@ -325,14 +334,13 @@
// Secure
if (isSecure) {
- buf.append ("; Secure");
+ buf.append ("; Secure");
}
// HttpOnly
- if (httpOnly) {
- buf.append ("; HttpOnly");
+ if (isHttpOnly) {
+ buf.append("; HttpOnly");
}
-
headerBuf.append(buf);
}
@@ -457,3 +465,4 @@
bc.setEnd(dest);
}
}
+
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2008-09-29 15:47:49 UTC (rev 797)
+++ trunk/webapps/docs/changelog.xml 2008-09-30 15:56:04 UTC (rev 798)
@@ -61,15 +61,15 @@
needed. (remm)
</fix>
<fix>
- Sync date format usage for old cookies. (remm)
- </fix>
- <fix>
<bug>45026</bug>: AJP should not use an empty reason phrase, due to httpd 2 having a problem
with that at the moment. (rjung)
</fix>
<fix>
Allow AJP to read large body packets, up to the configured packet size. (remm)
</fix>
+ <fix>
+ Remote date tool class, since it has sync issues. (markt, remm)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">
16 years, 3 months
JBossWeb SVN: r797 - trunk/java/org/apache/catalina/servlets.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2008-09-29 11:47:49 -0400 (Mon, 29 Sep 2008)
New Revision: 797
Modified:
trunk/java/org/apache/catalina/servlets/DefaultServlet.java
Log:
- Port the generics usage. No functional change.
Modified: trunk/java/org/apache/catalina/servlets/DefaultServlet.java
===================================================================
--- trunk/java/org/apache/catalina/servlets/DefaultServlet.java 2008-09-29 15:45:21 UTC (rev 796)
+++ trunk/java/org/apache/catalina/servlets/DefaultServlet.java 2008-09-29 15:47:49 UTC (rev 797)
@@ -154,17 +154,15 @@
*/
protected int sendfileSize = 48 * 1024;
-
/**
* Should the Accept-Ranges: bytes header be send with static resources?
*/
protected boolean useAcceptRanges = true;
-
/**
* Full range marker.
*/
- protected static ArrayList FULL = new ArrayList();
+ protected static ArrayList<Range> FULL = new ArrayList<Range>();
// ----------------------------------------------------- Static Initializer
@@ -473,7 +471,7 @@
if (obj instanceof Resource)
oldResource = (Resource) obj;
} catch (NamingException e) {
- ;
+ // Ignore
}
// Copy data in oldRevisionContent to contentFile
@@ -693,7 +691,7 @@
cacheEntry.attributes.setMimeType(contentType);
}
- ArrayList ranges = null;
+ ArrayList<Range> ranges = null;
long contentLength = -1L;
if (cacheEntry.context != null) {
@@ -708,14 +706,12 @@
contentType = "text/html;charset=UTF-8";
} else {
-
if (useAcceptRanges) {
// Accept ranges header
response.setHeader("Accept-Ranges", "bytes");
}
// Parse range specifier
-
ranges = parseRange(request, response, cacheEntry.attributes);
// ETag header
@@ -819,7 +815,7 @@
if (ranges.size() == 1) {
- Range range = (Range) ranges.get(0);
+ Range range = ranges.get(0);
response.addHeader("Content-Range", "bytes "
+ range.start
+ "-" + range.end + "/"
@@ -948,10 +944,9 @@
* @param response The servlet response we are creating
* @return Vector of ranges
*/
- protected ArrayList parseRange(HttpServletRequest request,
- HttpServletResponse response,
- ResourceAttributes resourceAttributes)
- throws IOException {
+ protected ArrayList<Range> parseRange(HttpServletRequest request,
+ HttpServletResponse response,
+ ResourceAttributes resourceAttributes) throws IOException {
// Checking If-Range
String headerValue = request.getHeader("If-Range");
@@ -962,7 +957,7 @@
try {
headerValueTime = request.getDateHeader("If-Range");
} catch (IllegalArgumentException e) {
- ;
+ // Ignore
}
String eTag = resourceAttributes.getETag();
@@ -1010,7 +1005,7 @@
// Vector which will contain all the ranges which are successfully
// parsed.
- ArrayList result = new ArrayList();
+ ArrayList<Range> result = new ArrayList<Range>();
StringTokenizer commaTokenizer = new StringTokenizer(rangeHeader, ",");
// Parsing the range list
@@ -1128,14 +1123,15 @@
try {
// Render the directory entries within this directory
- NamingEnumeration enumeration = resources.list(cacheEntry.name);
+ NamingEnumeration<NameClassPair> enumeration =
+ resources.list(cacheEntry.name);
// rewriteUrl(contextPath) is expensive. cache result for later reuse
String rewrittenContextPath = rewriteUrl(contextPath);
while (enumeration.hasMoreElements()) {
- NameClassPair ncPair = (NameClassPair) enumeration.nextElement();
+ NameClassPair ncPair = enumeration.nextElement();
String resourceName = ncPair.getName();
String trimmed = resourceName/*.substring(trim)*/;
if (trimmed.equalsIgnoreCase("WEB-INF") ||
@@ -1299,11 +1295,12 @@
try {
// Render the directory entries within this directory
- NamingEnumeration enumeration = resources.list(cacheEntry.name);
+ NamingEnumeration<NameClassPair> enumeration =
+ resources.list(cacheEntry.name);
boolean shade = false;
while (enumeration.hasMoreElements()) {
- NameClassPair ncPair = (NameClassPair) enumeration.nextElement();
+ NameClassPair ncPair = enumeration.nextElement();
String resourceName = ncPair.getName();
String trimmed = resourceName/*.substring(trim)*/;
if (trimmed.equalsIgnoreCase("WEB-INF") ||
@@ -1411,9 +1408,9 @@
return buffer.toString();
}
} catch (NamingException e) {
- if (debug > 10) {
+ if (debug > 10)
log("readme '" + readmeFile + "' not found", e);
- }
+
return null;
}
}
@@ -1437,9 +1434,9 @@
return is;
}
} catch (NamingException e) {
- if (debug > 10) {
+ if (debug > 10)
log("localXsltFile '" + localXsltFile + "' not found", e);
- }
+
return null;
}
}
@@ -1574,6 +1571,7 @@
// specified by the client. This is not an error case.
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
response.setHeader("ETag", resourceAttributes.getETag());
+
return false;
}
}
@@ -1631,6 +1629,7 @@
|| ("HEAD".equals(request.getMethod())) ) {
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
response.setHeader("ETag", eTag);
+
return false;
} else {
response.sendError
@@ -1847,7 +1846,7 @@
* @exception IOException if an input/output error occurs
*/
protected void copy(CacheEntry cacheEntry, ServletOutputStream ostream,
- Iterator ranges, String contentType)
+ Iterator<Range> ranges, String contentType)
throws IOException {
IOException exception = null;
@@ -1858,7 +1857,7 @@
InputStream istream =
new BufferedInputStream(resourceInputStream, input);
- Range currentRange = (Range) ranges.next();
+ Range currentRange = ranges.next();
// Writing MIME header.
ostream.println();
@@ -1900,7 +1899,7 @@
* @exception IOException if an input/output error occurs
*/
protected void copy(CacheEntry cacheEntry, PrintWriter writer,
- Iterator ranges, String contentType)
+ Iterator<Range> ranges, String contentType)
throws IOException {
IOException exception = null;
@@ -1917,7 +1916,7 @@
fileEncoding);
}
- Range currentRange = (Range) ranges.next();
+ Range currentRange = ranges.next();
// Writing MIME header.
writer.println();
16 years, 3 months
JBossWeb SVN: r796 - in trunk: java/org/apache/naming/resources and 1 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2008-09-29 11:45:21 -0400 (Mon, 29 Sep 2008)
New Revision: 796
Modified:
trunk/java/org/apache/catalina/servlets/DefaultServlet.java
trunk/java/org/apache/catalina/servlets/WebdavServlet.java
trunk/java/org/apache/naming/resources/ResourceAttributes.java
trunk/webapps/docs/changelog.xml
Log:
- More etag improvements.
Modified: trunk/java/org/apache/catalina/servlets/DefaultServlet.java
===================================================================
--- trunk/java/org/apache/catalina/servlets/DefaultServlet.java 2008-09-29 15:28:37 UTC (rev 795)
+++ trunk/java/org/apache/catalina/servlets/DefaultServlet.java 2008-09-29 15:45:21 UTC (rev 796)
@@ -580,24 +580,6 @@
/**
- * Get the ETag associated with a file.
- *
- * @param resourceAttributes The resource information
- */
- protected String getETag(ResourceAttributes resourceAttributes) {
- String result = null;
- if ((result = resourceAttributes.getETag(true)) != null) {
- return result;
- } else if ((result = resourceAttributes.getETag()) != null) {
- return result;
- } else {
- return "W/\"" + resourceAttributes.getContentLength() + "-"
- + resourceAttributes.getLastModified() + "\"";
- }
- }
-
-
- /**
* URL rewriter.
*
* @param path Path which has to be rewiten
@@ -737,7 +719,7 @@
ranges = parseRange(request, response, cacheEntry.attributes);
// ETag header
- response.setHeader("ETag", getETag(cacheEntry.attributes));
+ response.setHeader("ETag", cacheEntry.attributes.getETag());
// Last-Modified header
response.setHeader("Last-Modified",
@@ -983,7 +965,7 @@
;
}
- String eTag = getETag(resourceAttributes);
+ String eTag = resourceAttributes.getETag();
long lastModified = resourceAttributes.getLastModified();
if (headerValueTime == (-1L)) {
@@ -1535,7 +1517,7 @@
ResourceAttributes resourceAttributes)
throws IOException {
- String eTag = getETag(resourceAttributes);
+ String eTag = resourceAttributes.getETag();
String headerValue = request.getHeader("If-Match");
if (headerValue != null) {
if (headerValue.indexOf('*') == -1) {
@@ -1591,6 +1573,7 @@
// The entity has not been modified since the date
// specified by the client. This is not an error case.
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+ response.setHeader("ETag", resourceAttributes.getETag());
return false;
}
}
@@ -1617,7 +1600,7 @@
ResourceAttributes resourceAttributes)
throws IOException {
- String eTag = getETag(resourceAttributes);
+ String eTag = resourceAttributes.getETag();
String headerValue = request.getHeader("If-None-Match");
if (headerValue != null) {
@@ -1647,6 +1630,7 @@
if ( ("GET".equals(request.getMethod()))
|| ("HEAD".equals(request.getMethod())) ) {
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+ response.setHeader("ETag", eTag);
return false;
} else {
response.sendError
Modified: trunk/java/org/apache/catalina/servlets/WebdavServlet.java
===================================================================
--- trunk/java/org/apache/catalina/servlets/WebdavServlet.java 2008-09-29 15:28:37 UTC (rev 795)
+++ trunk/java/org/apache/catalina/servlets/WebdavServlet.java 2008-09-29 15:45:21 UTC (rev 796)
@@ -2136,7 +2136,7 @@
contentType);
}
generatedXML.writeProperty(null, "getetag",
- getETag(cacheEntry.attributes));
+ cacheEntry.attributes.getETag());
generatedXML.writeElement(null, "resourcetype",
XMLWriter.NO_CONTENT);
} else {
@@ -2262,7 +2262,7 @@
propertiesNotFound.addElement(property);
} else {
generatedXML.writeProperty
- (null, "getetag", getETag(cacheEntry.attributes));
+ (null, "getetag", cacheEntry.attributes.getETag());
}
} else if (property.equals("getlastmodified")) {
if (cacheEntry.context != null) {
Modified: trunk/java/org/apache/naming/resources/ResourceAttributes.java
===================================================================
--- trunk/java/org/apache/naming/resources/ResourceAttributes.java 2008-09-29 15:28:37 UTC (rev 795)
+++ trunk/java/org/apache/naming/resources/ResourceAttributes.java 2008-09-29 15:45:21 UTC (rev 796)
@@ -123,6 +123,12 @@
/**
+ * ETag.
+ */
+ public static final String ALTERNATE_ETAG = "etag";
+
+
+ /**
* Collection type.
*/
public static final String COLLECTION_TYPE = "<collection/>";
@@ -704,43 +710,38 @@
/**
* Get ETag.
*
- * @return Weak ETag
+ * @return strong ETag if available, else weak ETag.
*/
public String getETag() {
- return getETag(false);
- }
-
-
- /**
- * Get ETag.
- *
- * @param strong If true, the strong ETag will be returned
- * @return ETag
- */
- public String getETag(boolean strong) {
- if (strong) {
- // The strong ETag must always be calculated by the resources
- if (strongETag != null)
- return strongETag;
- if (attributes != null) {
- Attribute attribute = attributes.get(ETAG);
- if (attribute != null) {
- try {
- strongETag = attribute.get().toString();
- } catch (NamingException e) {
- ; // No value for the attribute
+ String result = null;
+ if (attributes != null) {
+ Attribute attribute = attributes.get(ETAG);
+ if (attribute != null) {
+ try {
+ result = attribute.get().toString();
+ } catch (NamingException e) {
+ ; // No value for the attribute
+ }
+ }
+ }
+ if (result == null) {
+ if (strongETag != null) {
+ // The strong ETag must always be calculated by the resources
+ result = strongETag;
+ } else {
+ // The weakETag is contentLength + lastModified
+ if (weakETag == null) {
+ long contentLength = getContentLength();
+ long lastModified = getLastModified();
+ if ((contentLength >= 0) || (lastModified >= 0)) {
+ weakETag = "W/\"" + contentLength + "-"
+ + lastModified + "\"";
}
}
+ result = weakETag;
}
- return strongETag;
- } else {
- // The weakETag is contentLenght + lastModified
- if (weakETag == null) {
- weakETag = "W/\"" + getContentLength() + "-"
- + getLastModified() + "\"";
- }
- return weakETag;
}
+ return result;
}
@@ -810,6 +811,14 @@
long contentLength = getContentLength();
if (contentLength < 0) return null;
return new BasicAttribute(ALTERNATE_CONTENT_LENGTH, new Long(contentLength));
+ } else if (attrID.equals(ETAG)) {
+ String etag = getETag();
+ if (etag == null) return null;
+ return new BasicAttribute(ETAG, etag);
+ } else if (attrID.equals(ALTERNATE_ETAG)) {
+ String etag = getETag();
+ if (etag == null) return null;
+ return new BasicAttribute(ALTERNATE_ETAG, etag);
}
} else {
return attributes.get(attrID);
@@ -893,6 +902,11 @@
attributes.addElement(new BasicAttribute(CONTENT_LENGTH, contentLengthLong));
attributes.addElement(new BasicAttribute(ALTERNATE_CONTENT_LENGTH, contentLengthLong));
}
+ String etag = getETag();
+ if (etag != null) {
+ attributes.addElement(new BasicAttribute(ETAG, etag));
+ attributes.addElement(new BasicAttribute(ALTERNATE_ETAG, etag));
+ }
return new RecyclableNamingEnumeration(attributes);
} else {
return attributes.getAll();
@@ -929,6 +943,11 @@
attributeIDs.addElement(CONTENT_LENGTH);
attributeIDs.addElement(ALTERNATE_CONTENT_LENGTH);
}
+ String etag = getETag();
+ if (etag != null) {
+ attributeIDs.addElement(ETAG);
+ attributeIDs.addElement(ALTERNATE_ETAG);
+ }
return new RecyclableNamingEnumeration(attributeIDs);
} else {
return attributes.getIDs();
@@ -947,6 +966,7 @@
if (getName() != null) size++;
if (getResourceType() != null) size += 2;
if (getContentLength() >= 0) size += 2;
+ if (getETag() != null) size += 2;
return size;
} else {
return attributes.size();
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2008-09-29 15:28:37 UTC (rev 795)
+++ trunk/webapps/docs/changelog.xml 2008-09-29 15:45:21 UTC (rev 796)
@@ -46,6 +46,9 @@
<fix>
Sync date format usage in SSI. (markt)
</fix>
+ <fix>
+ <bug>45906</bug>: Another ETag improvement. Patch provided by Chris Hubick. (remm)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
16 years, 3 months
JBossWeb SVN: r795 - in trunk: java/org/apache/tomcat/util/http and 1 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2008-09-29 11:28:37 -0400 (Mon, 29 Sep 2008)
New Revision: 795
Modified:
trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java
trunk/java/org/apache/coyote/ajp/AjpProcessor.java
trunk/java/org/apache/tomcat/util/http/ServerCookie.java
trunk/webapps/docs/changelog.xml
Log:
- Two minor AJP fixes.
- Remove usage of DateTool in ServerCookie (bad syncs).
Modified: trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java
===================================================================
--- trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java 2008-09-27 18:50:25 UTC (rev 794)
+++ trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java 2008-09-29 15:28:37 UTC (rev 795)
@@ -95,6 +95,17 @@
inputBuffer.limit(0);
outputBuffer = ByteBuffer.allocateDirect(packetSize * 2);
+ // Set the get body message buffer
+ AjpMessage getBodyMessage = new AjpMessage(16);
+ getBodyMessage.reset();
+ getBodyMessage.appendByte(Constants.JK_AJP13_GET_BODY_CHUNK);
+ getBodyMessage.appendInt(packetSize - Constants.READ_HEAD_LEN);
+ getBodyMessage.end();
+ getBodyMessageBuffer =
+ ByteBuffer.allocateDirect(getBodyMessage.getLen());
+ getBodyMessageBuffer.put(getBodyMessage.getBuffer(), 0,
+ getBodyMessage.getLen());
+
// Cause loading of HexUtils
int foo = HexUtils.DEC[0];
@@ -238,7 +249,7 @@
/**
* Direct buffer used for sending right away a get body message.
*/
- protected static final ByteBuffer getBodyMessageBuffer;
+ protected final ByteBuffer getBodyMessageBuffer;
/**
@@ -263,17 +274,6 @@
static {
- // Set the get body message buffer
- AjpMessage getBodyMessage = new AjpMessage(16);
- getBodyMessage.reset();
- getBodyMessage.appendByte(Constants.JK_AJP13_GET_BODY_CHUNK);
- getBodyMessage.appendInt(Constants.MAX_READ_SIZE);
- getBodyMessage.end();
- getBodyMessageBuffer =
- ByteBuffer.allocateDirect(getBodyMessage.getLen());
- getBodyMessageBuffer.put(getBodyMessage.getBuffer(), 0,
- getBodyMessage.getLen());
-
// Set the read body message buffer
AjpMessage pongMessage = new AjpMessage(16);
pongMessage.reset();
@@ -924,6 +924,10 @@
} else {
message = message.replace('\n', ' ').replace('\r', ' ');
}
+ if (message == null) {
+ // Many httpd 2.x wants a non empty status message
+ message = Integer.toString(response.getStatus());
+ }
tmpMB.setString(message);
responseHeaderMessage.appendBytes(tmpMB);
Modified: trunk/java/org/apache/coyote/ajp/AjpProcessor.java
===================================================================
--- trunk/java/org/apache/coyote/ajp/AjpProcessor.java 2008-09-27 18:50:25 UTC (rev 794)
+++ trunk/java/org/apache/coyote/ajp/AjpProcessor.java 2008-09-29 15:28:37 UTC (rev 795)
@@ -90,6 +90,16 @@
responseHeaderMessage = new AjpMessage(packetSize);
bodyMessage = new AjpMessage(packetSize);
+ // Set the get body message buffer
+ AjpMessage getBodyMessage = new AjpMessage(16);
+ getBodyMessage.reset();
+ getBodyMessage.appendByte(Constants.JK_AJP13_GET_BODY_CHUNK);
+ getBodyMessage.appendInt(packetSize - Constants.READ_HEAD_LEN);
+ getBodyMessage.end();
+ getBodyMessageArray = new byte[getBodyMessage.getLen()];
+ System.arraycopy(getBodyMessage.getBuffer(), 0, getBodyMessageArray,
+ 0, getBodyMessage.getLen());
+
// Cause loading of HexUtils
int foo = HexUtils.DEC[0];
@@ -240,7 +250,7 @@
/**
* Direct buffer used for sending right away a get body message.
*/
- protected static final byte[] getBodyMessageArray;
+ protected final byte[] getBodyMessageArray;
/**
@@ -265,17 +275,6 @@
static {
- // Set the get body message buffer
-
- AjpMessage getBodyMessage = new AjpMessage(16);
- getBodyMessage.reset();
- getBodyMessage.appendByte(Constants.JK_AJP13_GET_BODY_CHUNK);
- getBodyMessage.appendInt(Constants.MAX_READ_SIZE);
- getBodyMessage.end();
- getBodyMessageArray = new byte[getBodyMessage.getLen()];
- System.arraycopy(getBodyMessage.getBuffer(), 0, getBodyMessageArray,
- 0, getBodyMessage.getLen());
-
// Set the read body message buffer
AjpMessage pongMessage = new AjpMessage(16);
pongMessage.reset();
@@ -930,6 +929,10 @@
} else {
message = message.replace('\n', ' ').replace('\r', ' ');
}
+ if (message == null) {
+ // Many httpd 2.x wants a non empty status message
+ message = Integer.toString(response.getStatus());
+ }
tmpMB.setString(message);
responseHeaderMessage.appendBytes(tmpMB);
Modified: trunk/java/org/apache/tomcat/util/http/ServerCookie.java
===================================================================
--- trunk/java/org/apache/tomcat/util/http/ServerCookie.java 2008-09-27 18:50:25 UTC (rev 794)
+++ trunk/java/org/apache/tomcat/util/http/ServerCookie.java 2008-09-29 15:28:37 UTC (rev 795)
@@ -18,11 +18,13 @@
package org.apache.tomcat.util.http;
import java.io.Serializable;
+import java.text.DateFormat;
import java.text.FieldPosition;
+import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.Locale;
import org.apache.tomcat.util.buf.ByteChunk;
-import org.apache.tomcat.util.buf.DateTool;
import org.apache.tomcat.util.buf.MessageBytes;
@@ -245,9 +247,11 @@
}
}
- private static final String ancientDate =
- DateTool.formatOldCookie(new Date(10000));
+ private final static DateFormat oldCookieFormat =
+ new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss z", Locale.US);
+ private static final String ancientDate = oldCookieFormat.format(new Date(10000));
+
// TODO RFC2965 fields also need to be passed
public static void appendCookieValue( StringBuffer headerBuf,
int version,
@@ -293,14 +297,16 @@
// Wdy, DD-Mon-YY HH:MM:SS GMT ( Expires Netscape format )
buf.append ("; Expires=");
// To expire immediately we need to set the time in past
- if (maxAge == 0)
+ if (maxAge == 0) {
buf.append( ancientDate );
- else
- DateTool.formatOldCookie
+ } else {
+ synchronized(oldCookieFormat) {
+ oldCookieFormat.format
(new Date( System.currentTimeMillis() +
- maxAge *1000L), buf,
- new FieldPosition(0));
-
+ maxAge *1000L), buf,
+ new FieldPosition(0));
+ }
+ }
} else {
buf.append ("; Max-Age=");
buf.append (maxAge);
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2008-09-27 18:50:25 UTC (rev 794)
+++ trunk/webapps/docs/changelog.xml 2008-09-29 15:28:37 UTC (rev 795)
@@ -57,6 +57,16 @@
IntrospectionUtils.replaceProperties should return the original String if no substitutions are
needed. (remm)
</fix>
+ <fix>
+ Sync date format usage for old cookies. (remm)
+ </fix>
+ <fix>
+ <bug>45026</bug>: AJP should not use an empty reason phrase, due to httpd 2 having a problem
+ with that at the moment. (rjung)
+ </fix>
+ <fix>
+ Allow AJP to read large body packets, up to the configured packet size. (remm)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">
16 years, 3 months
JBossWeb SVN: r794 - in trunk: webapps/docs and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2008-09-27 14:50:25 -0400 (Sat, 27 Sep 2008)
New Revision: 794
Modified:
trunk/java/org/apache/catalina/ssi/ResponseIncludeWrapper.java
trunk/webapps/docs/changelog.xml
Log:
- Use a real formatter to fix sync issue.
Modified: trunk/java/org/apache/catalina/ssi/ResponseIncludeWrapper.java
===================================================================
--- trunk/java/org/apache/catalina/ssi/ResponseIncludeWrapper.java 2008-09-27 17:44:11 UTC (rev 793)
+++ trunk/java/org/apache/catalina/ssi/ResponseIncludeWrapper.java 2008-09-27 18:50:25 UTC (rev 794)
@@ -20,6 +20,8 @@
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
@@ -42,6 +44,8 @@
*/
private static final String CONTENT_TYPE = "content-type";
private static final String LAST_MODIFIED = "last-modified";
+ private static final DateFormat format =
+ new SimpleDateFormat(DateTool.RFC1123_PATTERN, DateTool.LOCALE_US);
protected long lastModified = -1;
private String contentType = null;
@@ -66,7 +70,7 @@
* @param captureServletOutputStream The ServletOutputStream to use
*/
public ResponseIncludeWrapper(ServletContext context,
- HttpServletRequest request, HttpServletResponse response,
+ HttpServletRequest request, HttpServletResponse response,
ServletOutputStream captureServletOutputStream) {
super(response);
this.context = context;
@@ -175,7 +179,7 @@
}
else
{
- // return a safe value
+ // return a safe value
setContentType("application/x-octet-stream");
}
}
@@ -208,7 +212,9 @@
String lname = name.toLowerCase();
if (lname.equals(LAST_MODIFIED)) {
try {
- lastModified = DateTool.rfc1123Format.parse(value).getTime();
+ synchronized(format) {
+ lastModified = format.parse(value).getTime();
+ }
} catch (Throwable ignore) { }
} else if (lname.equals(CONTENT_TYPE)) {
contentType = value;
@@ -228,7 +234,9 @@
String lname = name.toLowerCase();
if (lname.equals(LAST_MODIFIED)) {
try {
- lastModified = DateTool.rfc1123Format.parse(value).getTime();
+ synchronized(format) {
+ lastModified = format.parse(value).getTime();
+ }
} catch (Throwable ignore) { }
}
else if (lname.equals(CONTENT_TYPE))
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2008-09-27 17:44:11 UTC (rev 793)
+++ trunk/webapps/docs/changelog.xml 2008-09-27 18:50:25 UTC (rev 794)
@@ -43,6 +43,9 @@
<fix>
Tighten up the max size for content caching (which is often useless due to sendfile). (markt, remm)
</fix>
+ <fix>
+ Sync date format usage in SSI. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
16 years, 3 months
JBossWeb SVN: r793 - in trunk: java/org/apache/catalina/ssi and 4 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2008-09-27 13:44:11 -0400 (Sat, 27 Sep 2008)
New Revision: 793
Modified:
trunk/java/org/apache/catalina/core/StandardContext.java
trunk/java/org/apache/catalina/core/mbeans-descriptors.xml
trunk/java/org/apache/catalina/ssi/SSIMediator.java
trunk/java/org/apache/jasper/xmlparser/ASCIIReader.java
trunk/java/org/apache/naming/resources/BaseDirContext.java
trunk/java/org/apache/naming/resources/ProxyDirContext.java
trunk/java/org/apache/tomcat/util/IntrospectionUtils.java
trunk/webapps/docs/changelog.xml
Log:
- Port the bunch of fixes found by usage of the auto tool.
Modified: trunk/java/org/apache/catalina/core/StandardContext.java
===================================================================
--- trunk/java/org/apache/catalina/core/StandardContext.java 2008-09-25 14:54:16 UTC (rev 792)
+++ trunk/java/org/apache/catalina/core/StandardContext.java 2008-09-27 17:44:11 UTC (rev 793)
@@ -244,7 +244,7 @@
/**
* The broadcaster that sends j2ee notifications.
*/
- private NotificationBroadcasterSupport broadcaster = null;
+ private transient NotificationBroadcasterSupport broadcaster = null;
/**
* The Locale to character set mapper for this application.
@@ -401,7 +401,7 @@
/**
* The mapper associated with this context.
*/
- private org.apache.tomcat.util.http.mapper.Mapper mapper =
+ private transient org.apache.tomcat.util.http.mapper.Mapper mapper =
new org.apache.tomcat.util.http.mapper.Mapper();
@@ -640,6 +640,12 @@
/**
+ * Cache object max size in KB.
+ */
+ protected int cacheObjectMaxSize = 256; // 256K
+
+
+ /**
* Cache TTL in ms.
*/
protected int cacheTTL = 5000;
@@ -803,6 +809,22 @@
/**
+ * Return the maximum size of objects to be cached in KB.
+ */
+ public int getCacheObjectMaxSize() {
+ return cacheObjectMaxSize;
+ }
+
+
+ /**
+ * Set the maximum size of objects to be placed the cache in KB.
+ */
+ public void setCacheObjectMaxSize(int cacheObjectMaxSize) {
+ this.cacheObjectMaxSize = cacheObjectMaxSize;
+ }
+
+
+ /**
* Return the "follow standard delegation model" flag used to configure
* our ClassLoader.
*/
@@ -1896,6 +1918,7 @@
((BaseDirContext) resources).setCached(isCachingAllowed());
((BaseDirContext) resources).setCacheTTL(getCacheTTL());
((BaseDirContext) resources).setCacheMaxSize(getCacheMaxSize());
+ ((BaseDirContext) resources).setCacheObjectMaxSize(getCacheObjectMaxSize());
}
if (resources instanceof FileDirContext) {
filesystemBased = true;
Modified: trunk/java/org/apache/catalina/core/mbeans-descriptors.xml
===================================================================
--- trunk/java/org/apache/catalina/core/mbeans-descriptors.xml 2008-09-25 14:54:16 UTC (rev 792)
+++ trunk/java/org/apache/catalina/core/mbeans-descriptors.xml 2008-09-27 17:44:11 UTC (rev 793)
@@ -41,6 +41,10 @@
description="Maximum cache size in KB"
type="int"/>
+ <attribute name="cacheObjectMaxSize"
+ description="Maximum cached object size in KB"
+ type="int"/>
+
<attribute name="cacheTTL"
description="Time interval in ms between cache refeshes"
type="int"/>
Modified: trunk/java/org/apache/catalina/ssi/SSIMediator.java
===================================================================
--- trunk/java/org/apache/catalina/ssi/SSIMediator.java 2008-09-25 14:54:16 UTC (rev 792)
+++ trunk/java/org/apache/catalina/ssi/SSIMediator.java 2008-09-27 17:44:11 UTC (rev 793)
@@ -211,10 +211,10 @@
if (val.indexOf('$') < 0 && val.indexOf('&') < 0) return val;
// HTML decoding
- val.replace("<", "<");
- val.replace(">", ">");
- val.replace(""", "\"");
- val.replace("&", "&");
+ val = val.replace("<", "<");
+ val = val.replace(">", ">");
+ val = val.replace(""", "\"");
+ val = val.replace("&", "&");
StringBuffer sb = new StringBuffer(val);
int charStart = sb.indexOf("&#");
Modified: trunk/java/org/apache/jasper/xmlparser/ASCIIReader.java
===================================================================
--- trunk/java/org/apache/jasper/xmlparser/ASCIIReader.java 2008-09-25 14:54:16 UTC (rev 792)
+++ trunk/java/org/apache/jasper/xmlparser/ASCIIReader.java 2008-09-27 17:44:11 UTC (rev 793)
@@ -112,7 +112,7 @@
}
int count = fInputStream.read(fBuffer, 0, length);
for (int i = 0; i < count; i++) {
- int b0 = fBuffer[i];
+ int b0 = (0xff & fBuffer[i]); // Convert to unsigned
if (b0 > 0x80) {
throw new IOException(Localizer.getMessage("jsp.error.xml.invalidASCII",
Integer.toString(b0)));
Modified: trunk/java/org/apache/naming/resources/BaseDirContext.java
===================================================================
--- trunk/java/org/apache/naming/resources/BaseDirContext.java 2008-09-25 14:54:16 UTC (rev 792)
+++ trunk/java/org/apache/naming/resources/BaseDirContext.java 2008-09-27 17:44:11 UTC (rev 793)
@@ -105,11 +105,17 @@
/**
- * Max size of resources which will have their content cached.
+ * Max size of cache.
*/
protected int cacheMaxSize = 10240; // 10 MB
+ /**
+ * Max size of resources that will be content cached.
+ */
+ protected int cacheObjectMaxSize = 256; // 256 K
+
+
// ------------------------------------------------------------- Properties
@@ -192,6 +198,22 @@
}
+ /**
+ * Return the maximum size of objects to be cached in KB.
+ */
+ public int getCacheObjectMaxSize() {
+ return cacheObjectMaxSize;
+ }
+
+
+ /**
+ * Set the maximum size of objects to be placed the cache in KB.
+ */
+ public void setCacheObjectMaxSize(int cacheObjectMaxSize) {
+ this.cacheObjectMaxSize = cacheObjectMaxSize;
+ }
+
+
// --------------------------------------------------------- Public Methods
Modified: trunk/java/org/apache/naming/resources/ProxyDirContext.java
===================================================================
--- trunk/java/org/apache/naming/resources/ProxyDirContext.java 2008-09-25 14:54:16 UTC (rev 792)
+++ trunk/java/org/apache/naming/resources/ProxyDirContext.java 2008-09-27 17:44:11 UTC (rev 793)
@@ -76,7 +76,12 @@
}
cache.setCacheMaxSize(baseDirContext.getCacheMaxSize());
cacheTTL = baseDirContext.getCacheTTL();
- cacheObjectMaxSize = baseDirContext.getCacheMaxSize() / 20;
+ cacheObjectMaxSize = baseDirContext.getCacheObjectMaxSize();
+ // cacheObjectMaxSize must be less than cacheMaxSize
+ // Set a sensible limit
+ if (cacheObjectMaxSize > baseDirContext.getCacheMaxSize()/32) {
+ cacheObjectMaxSize = baseDirContext.getCacheMaxSize()/32;
+ }
}
}
hostName = (String) env.get(HOST);
Modified: trunk/java/org/apache/tomcat/util/IntrospectionUtils.java
===================================================================
--- trunk/java/org/apache/tomcat/util/IntrospectionUtils.java 2008-09-25 14:54:16 UTC (rev 792)
+++ trunk/java/org/apache/tomcat/util/IntrospectionUtils.java 2008-09-27 17:44:11 UTC (rev 793)
@@ -477,6 +477,9 @@
*/
public static String replaceProperties(String value, Hashtable staticProp,
PropertySource dynamicProp[]) {
+ if (value.indexOf("$") < 0) {
+ return value;
+ }
StringBuffer sb = new StringBuffer();
int prev = 0;
// assert value!=nil
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2008-09-25 14:54:16 UTC (rev 792)
+++ trunk/webapps/docs/changelog.xml 2008-09-27 17:44:11 UTC (rev 793)
@@ -37,6 +37,12 @@
<add>
LockOutRealm to lock out users after a number of failed authentication attempts. (markt)
</add>
+ <fix>
+ Fix SSI HTML replacement bug. (markt)
+ </fix>
+ <fix>
+ Tighten up the max size for content caching (which is often useless due to sendfile). (markt, remm)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
@@ -44,6 +50,10 @@
<add>
Package renamed JSON library. (remm)
</add>
+ <fix>
+ IntrospectionUtils.replaceProperties should return the original String if no substitutions are
+ needed. (remm)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">
@@ -65,6 +75,9 @@
<fix>
Remove unused code in ELSupport. (markt)
</fix>
+ <fix>
+ Ascii parsing bug. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Others">
16 years, 3 months
JBossWeb SVN: r792 - in trunk: java/org/apache/jasper and 2 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2008-09-25 10:54:16 -0400 (Thu, 25 Sep 2008)
New Revision: 792
Modified:
trunk/java/org/apache/el/lang/ELSupport.java
trunk/java/org/apache/jasper/Constants.java
trunk/res/jboss-web.nsi
trunk/webapps/docs/changelog.xml
Log:
- Cleanup.
- Add a missing sys property.
Modified: trunk/java/org/apache/el/lang/ELSupport.java
===================================================================
--- trunk/java/org/apache/el/lang/ELSupport.java 2008-09-24 14:40:04 UTC (rev 791)
+++ trunk/java/org/apache/el/lang/ELSupport.java 2008-09-25 14:54:16 UTC (rev 792)
@@ -36,8 +36,6 @@
*/
public class ELSupport {
- private final static ELSupport REF = new ELSupport();
-
private final static Long ZERO = new Long(0L);
public final static void throwUnhandled(Object base, Object property)
@@ -433,9 +431,8 @@
public final static boolean isStringFloat(final String str) {
int len = str.length();
if (len > 1) {
- char c = 0;
for (int i = 0; i < len; i++) {
- switch (c = str.charAt(i)) {
+ switch (str.charAt(i)) {
case 'E':
return true;
case 'e':
Modified: trunk/java/org/apache/jasper/Constants.java
===================================================================
--- trunk/java/org/apache/jasper/Constants.java 2008-09-24 14:40:04 UTC (rev 791)
+++ trunk/java/org/apache/jasper/Constants.java 2008-09-25 14:54:16 UTC (rev 792)
@@ -196,6 +196,6 @@
* The name of the path parameter used to pass the session identifier
* back and forth with the client.
*/
- public static final String SESSION_PARAMETER_NAME = "jsessionid";
+ public static final String SESSION_PARAMETER_NAME = System.getProperty("org.apache.catalina.jsessionid", "jsessionid");
}
Modified: trunk/res/jboss-web.nsi
===================================================================
--- trunk/res/jboss-web.nsi 2008-09-24 14:40:04 UTC (rev 791)
+++ trunk/res/jboss-web.nsi 2008-09-25 14:54:16 UTC (rev 792)
@@ -115,6 +115,7 @@
SetOutPath $INSTDIR
File jboss-web.ico
File LICENSE
+ File NOTICE
SetOutPath $INSTDIR\lib
File /r lib\*.*
SetOutPath $INSTDIR\logs
@@ -598,6 +599,7 @@
RMDir /r "$SMPROGRAMS\JBoss Web 2.1"
Delete "$INSTDIR\jboss-web.ico"
Delete "$INSTDIR\LICENSE"
+ Delete "$INSTDIR\NOTICE"
RMDir /r "$INSTDIR\bin"
RMDir /r "$INSTDIR\lib"
Delete "$INSTDIR\conf\*.dtd"
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2008-09-24 14:40:04 UTC (rev 791)
+++ trunk/webapps/docs/changelog.xml 2008-09-25 14:54:16 UTC (rev 792)
@@ -62,6 +62,9 @@
should all now be fixed. The two pass parsing means we can do away with the previous 'replace with
unused unicode character' trick. (markt)
</fix>
+ <fix>
+ Remove unused code in ELSupport. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Others">
16 years, 3 months
JBossWeb SVN: r791 - in trunk: webapps/docs and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2008-09-24 10:40:04 -0400 (Wed, 24 Sep 2008)
New Revision: 791
Added:
trunk/java/org/apache/catalina/realm/LockOutRealm.java
Modified:
trunk/java/org/apache/catalina/realm/CombinedRealm.java
trunk/java/org/apache/catalina/realm/LocalStrings.properties
trunk/java/org/apache/catalina/realm/RealmBase.java
trunk/java/org/apache/catalina/realm/mbeans-descriptors.xml
trunk/webapps/docs/changelog.xml
Log:
- Avoid JMX names clashes.
- Add lockout realm (useful feature).
Modified: trunk/java/org/apache/catalina/realm/CombinedRealm.java
===================================================================
--- trunk/java/org/apache/catalina/realm/CombinedRealm.java 2008-09-23 08:45:30 UTC (rev 790)
+++ trunk/java/org/apache/catalina/realm/CombinedRealm.java 2008-09-24 14:40:04 UTC (rev 791)
@@ -23,6 +23,8 @@
import java.util.LinkedList;
import java.util.List;
+import javax.management.ObjectName;
+
import org.apache.catalina.Container;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleException;
@@ -33,7 +35,8 @@
/**
* Realm implementation that contains one or more realms. Authentication is
* attempted for each realm in the order they were configured. If any realm
- * authenticates the user then the authentication succeeds.
+ * authenticates the user then the authentication succeeds. When combining
+ * realms usernames should be unique across all combined realms.
*/
public class CombinedRealm extends RealmBase {
@@ -66,6 +69,21 @@
/**
+ * Return the set of Realms that this Realm is wrapping
+ */
+ public ObjectName[] getRealms() {
+ ObjectName[] result = new ObjectName[realms.size()];
+ for (Realm realm : realms) {
+ if (realm instanceof RealmBase) {
+ result[realms.indexOf(realm)] =
+ ((RealmBase) realm).getObjectName();
+ }
+ }
+ return result;
+ }
+
+
+ /**
* Return the Principal associated with the specified username and
* credentials, if there is one; otherwise return <code>null</code>.
*
@@ -178,8 +196,14 @@
* @param container The associated Container
*/
public void setContainer(Container container) {
- // Set the container for sub-realms. Mainly so logging works.
for(Realm realm : realms) {
+ // Set the realmPath for JMX naming
+ if (realm instanceof RealmBase) {
+ ((RealmBase) realm).setRealmPath(
+ getRealmPath() + "/realm" + realms.indexOf(realm));
+ }
+
+ // Set the container for sub-realms. Mainly so logging works.
realm.setContainer(container);
}
super.setContainer(container);
Modified: trunk/java/org/apache/catalina/realm/LocalStrings.properties
===================================================================
--- trunk/java/org/apache/catalina/realm/LocalStrings.properties 2008-09-23 08:45:30 UTC (rev 790)
+++ trunk/java/org/apache/catalina/realm/LocalStrings.properties 2008-09-24 14:40:04 UTC (rev 791)
@@ -78,3 +78,5 @@
combinedRealm.authFailed=Failed to authenticate user "{0}" with realm "{1}"
combinedRealm.authSucess=Authenticated user "{0}" with realm "{1}"
combinedRealm.addRealm=Add "{0}" realm, making a total of "{1}" realms
+lockOutRealm.authLockedUser=An attempt was made to authenticate the locked user "{0}"
+lockOutRealm.removeWarning=User "{0}" was removed from the failed users cache after {1} seconds to keep the cache size within the limit set
Added: trunk/java/org/apache/catalina/realm/LockOutRealm.java
===================================================================
--- trunk/java/org/apache/catalina/realm/LockOutRealm.java (rev 0)
+++ trunk/java/org/apache/catalina/realm/LockOutRealm.java 2008-09-24 14:40:04 UTC (rev 791)
@@ -0,0 +1,414 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.catalina.realm;
+
+import java.security.Principal;
+import java.security.cert.X509Certificate;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.catalina.LifecycleException;
+import org.jboss.logging.Logger;
+
+/**
+ * This class extends the CombinedRealm (hence it can wrap other Realms) to
+ * provide a user lock out mechanism if there are too many failed
+ * authentication attempts in a given period of time. To ensure correct
+ * operation, there is a reasonable degree of synchronisation in this Realm.
+ * This Realm does not require modification to the underlying Realms or the
+ * associated user storage mecahisms. It achieves this by recording all failed
+ * logins, including those for users that do not exist. To prevent a DOS by
+ * deliberating making requests with invalid users (and hence causing this cache
+ * to grow) the size of the list of users that have failed authentication is
+ * limited.
+ */
+public class LockOutRealm extends CombinedRealm {
+
+ private static Logger log = Logger.getLogger(LockOutRealm.class);
+
+ /**
+ * The number of times in a row a user has to fail authentication to be
+ * locked out. Defaults to 5.
+ */
+ protected int failureCount = 5;
+
+ /**
+ * The time (in seconds) a user is locked out for after too many
+ * authentication failures. Defaults to 300 (5 minutes).
+ */
+ protected int lockOutTime = 300;
+
+ /**
+ * Number of users that have failed authentication to keep in cache. Over
+ * time the cache will grow to this size and may not shrink. Defaults to
+ * 1000.
+ */
+ protected int cacheSize = 1000;
+
+ /**
+ * If a failed user is removed from the cache because the cache is too big
+ * before it has been in the cache for at least this period of time (in
+ * seconds) a warning message will be logged. Defaults to 3600 (1 hour).
+ */
+ protected int cacheRemovalWarningTime = 3600;
+
+ /**
+ * Users whose last authentication attempt failed. Entries will be ordered
+ * in access order from least recent to most recent.
+ */
+ protected Map<String,LockRecord> failedUsers = null;
+
+
+ /**
+ * Prepare for the beginning of active use of the public methods of this
+ * component. This method should be called before any of the public
+ * methods of this component are utilized. It should also send a
+ * LifecycleEvent of type START_EVENT to any registered listeners.
+ *
+ * @exception LifecycleException if this component detects a fatal error
+ * that prevents this component from being used
+ */
+ public void start() throws LifecycleException {
+ // Configure the list of failed users to delete the oldest entry once it
+ // exceeds the specified size
+ failedUsers = new LinkedHashMap<String, LockRecord>(cacheSize, 0.75f,
+ true) {
+ protected boolean removeEldestEntry(
+ Map.Entry<String, LockRecord> eldest) {
+ if (size() > cacheSize) {
+ // Check to see if this element has been removed too quickly
+ long timeInCache = (System.currentTimeMillis() -
+ eldest.getValue().getLastFailureTime())/1000;
+
+ if (timeInCache < cacheRemovalWarningTime) {
+ log.warn(sm.getString("lockOutRealm.removeWarning",
+ eldest.getKey(), Long.valueOf(timeInCache)));
+ }
+ return true;
+ }
+ return false;
+ }
+ };
+
+ super.start();
+ }
+
+
+ /**
+ * Return the Principal associated with the specified username and
+ * credentials, if there is one; otherwise return <code>null</code>.
+ *
+ * @param username Username of the Principal to look up
+ * @param credentials Password or other credentials to use in
+ * authenticating this username
+ */
+ public Principal authenticate(String username, byte[] credentials) {
+ if (isLocked(username)) {
+ // Trying to authenticate a locked user is an automatic failure
+ registerAuthFailure(username);
+
+ log.warn(sm.getString("lockOutRealm.authLockedUser", username));
+ return null;
+ }
+
+ Principal authenticatedUser = super.authenticate(username, credentials);
+
+ if (authenticatedUser == null) {
+ registerAuthFailure(username);
+ } else {
+ registerAuthSuccess(username);
+ }
+ return authenticatedUser;
+ }
+
+
+ /**
+ * Return the Principal associated with the specified username, which
+ * matches the digest calculated using the given parameters using the
+ * method described in RFC 2069; otherwise return <code>null</code>.
+ *
+ * @param username Username of the Principal to look up
+ * @param clientDigest Digest which has been submitted by the client
+ * @param nOnce Unique (or supposedly unique) token which has been used
+ * for this request
+ * @param realm Realm name
+ * @param md5a2 Second MD5 digest used to calculate the digest :
+ * MD5(Method + ":" + uri)
+ */
+ public Principal authenticate(String username, String clientDigest,
+ String once, String nc, String cnonce, String qop,
+ String realmName, String md5a2) {
+
+ if (isLocked(username)) {
+ // Trying to authenticate a locked user is an automatic failure
+ registerAuthFailure(username);
+
+ log.warn(sm.getString("lockOutRealm.authLockedUser", username));
+ return null;
+ }
+
+ Principal authenticatedUser = super.authenticate(username, clientDigest,
+ once, nc, cnonce, qop, realmName, md5a2);
+
+ if (authenticatedUser == null) {
+ registerAuthFailure(username);
+ } else {
+ registerAuthSuccess(username);
+ }
+ return authenticatedUser;
+ }
+
+
+ /**
+ * Return the Principal associated with the specified username and
+ * credentials, if there is one; otherwise return <code>null</code>.
+ *
+ * @param username Username of the Principal to look up
+ * @param credentials Password or other credentials to use in
+ * authenticating this username
+ */
+ public Principal authenticate(String username, String credentials) {
+ if (isLocked(username)) {
+ // Trying to authenticate a locked user is an automatic failure
+ registerAuthFailure(username);
+
+ log.warn(sm.getString("lockOutRealm.authLockedUser", username));
+ return null;
+ }
+
+ Principal authenticatedUser = super.authenticate(username, credentials);
+
+ if (authenticatedUser == null) {
+ registerAuthFailure(username);
+ } else {
+ registerAuthSuccess(username);
+ }
+ return authenticatedUser;
+ }
+
+
+ /**
+ * Return the Principal associated with the specified chain of X509
+ * client certificates. If there is none, return <code>null</code>.
+ *
+ * @param certs Array of client certificates, with the first one in
+ * the array being the certificate of the client itself.
+ */
+ public Principal authenticate(X509Certificate[] certs) {
+ String username = null;
+ if (certs != null && certs.length >0) {
+ username = certs[0].getSubjectDN().getName();
+ }
+
+ if (isLocked(username)) {
+ // Trying to authenticate a locked user is an automatic failure
+ registerAuthFailure(username);
+
+ log.warn(sm.getString("lockOutRealm.authLockedUser", username));
+ return null;
+ }
+
+ Principal authenticatedUser = super.authenticate(certs);
+
+ if (authenticatedUser == null) {
+ registerAuthFailure(username);
+ } else {
+ registerAuthSuccess(username);
+ }
+ return authenticatedUser;
+ }
+
+
+ /**
+ * Unlock the specified username. This will remove all records of
+ * authentication failures for this user.
+ *
+ * @param username The user to unlock
+ */
+ public void unlock(String username) {
+ // Auth success clears the lock record so...
+ registerAuthSuccess(username);
+ }
+
+ /*
+ * Checks to see if the current user is locked. If this is associated with
+ * a login attempt, then the last access time will be recorded and any
+ * attempt to authenticated a locked user will log a warning.
+ */
+ private boolean isLocked(String username) {
+ LockRecord lockRecord = null;
+ synchronized (this) {
+ lockRecord = failedUsers.get(username);
+ }
+
+ // No lock record means user can't be locked
+ if (lockRecord == null) {
+ return false;
+ }
+
+ // Check to see if user is locked
+ if (lockRecord.getFailures() >= failureCount &&
+ (System.currentTimeMillis() -
+ lockRecord.getLastFailureTime())/1000 < lockOutTime) {
+ return true;
+ }
+
+ // User has not, yet, exceeded lock thresholds
+ return false;
+ }
+
+
+ /*
+ * After successful authentication, any record of previous authentication
+ * failure is removed.
+ */
+ private synchronized void registerAuthSuccess(String username) {
+ // Successful authentication means removal from the list of failed users
+ failedUsers.remove(username);
+ }
+
+
+ /*
+ * After a failed authentication, add the record of the failed
+ * authentication.
+ */
+ private void registerAuthFailure(String username) {
+ LockRecord lockRecord = null;
+ synchronized (this) {
+ if (!failedUsers.containsKey(username)) {
+ lockRecord = new LockRecord();
+ failedUsers.put(username, lockRecord);
+ } else {
+ lockRecord = failedUsers.get(username);
+ if (lockRecord.getFailures() >= failureCount &&
+ ((System.currentTimeMillis() -
+ lockRecord.getLastFailureTime())/1000)
+ > lockOutTime) {
+ // User was previously locked out but lockout has now
+ // expired so reset failure count
+ lockRecord.setFailures(0);
+ }
+ }
+ }
+ lockRecord.registerFailure();
+ }
+
+
+ /**
+ * Get the number of failed authentication attempts required to lock the
+ * user account.
+ * @return the failureCount
+ */
+ public int getFailureCount() {
+ return failureCount;
+ }
+
+
+ /**
+ * Set the number of failed authentication attempts required to lock the
+ * user account.
+ * @param failureCount the failureCount to set
+ */
+ public void setFailureCount(int failureCount) {
+ this.failureCount = failureCount;
+ }
+
+
+ /**
+ * Get the period for which an account will be locked.
+ * @return the lockOutTime
+ */
+ public int getLockOutTime() {
+ return lockOutTime;
+ }
+
+
+ /**
+ * Set the period for which an account will be locked.
+ * @param lockOutTime the lockOutTime to set
+ */
+ public void setLockOutTime(int lockOutTime) {
+ this.lockOutTime = lockOutTime;
+ }
+
+
+ /**
+ * Get the maximum number of users for which authentication failure will be
+ * kept in the cache.
+ * @return the cacheSize
+ */
+ public int getCacheSize() {
+ return cacheSize;
+ }
+
+
+ /**
+ * Set the maximum number of users for which authentication failure will be
+ * kept in the cache.
+ * @param cacheSize the cacheSize to set
+ */
+ public void setCacheSize(int cacheSize) {
+ this.cacheSize = cacheSize;
+ }
+
+
+ /**
+ * Get the minimum period a failed authentication must remain in the cache
+ * to avoid generating a warning if it is removed from the cache to make
+ * space for a new entry.
+ * @return the cacheRemovalWarningTime
+ */
+ public int getCacheRemovalWarningTime() {
+ return cacheRemovalWarningTime;
+ }
+
+
+ /**
+ * Set the minimum period a failed authentication must remain in the cache
+ * to avoid generating a warning if it is removed from the cache to make
+ * space for a new entry.
+ * @param cacheRemovalWarningTime the cacheRemovalWarningTime to set
+ */
+ public void setCacheRemovalWarningTime(int cacheRemovalWarningTime) {
+ this.cacheRemovalWarningTime = cacheRemovalWarningTime;
+ }
+
+
+ protected class LockRecord {
+ private AtomicInteger failures = new AtomicInteger(0);
+ private long lastFailureTime = 0;
+
+ public int getFailures() {
+ return failures.get();
+ }
+
+ public void setFailures(int theFailures) {
+ failures.set(theFailures);
+ }
+
+ public long getLastFailureTime() {
+ return lastFailureTime;
+ }
+
+ public void registerFailure() {
+ failures.incrementAndGet();
+ lastFailureTime = System.currentTimeMillis();
+ }
+ }
+}
Modified: trunk/java/org/apache/catalina/realm/RealmBase.java
===================================================================
--- trunk/java/org/apache/catalina/realm/RealmBase.java 2008-09-23 08:45:30 UTC (rev 790)
+++ trunk/java/org/apache/catalina/realm/RealmBase.java 2008-09-24 14:40:04 UTC (rev 791)
@@ -786,10 +786,14 @@
log.debug(" No user authenticated, cannot grant access");
} else {
for (int j = 0; j < roles.length; j++) {
- if (hasRole(principal, roles[j]))
+ if (hasRole(principal, roles[j])) {
status = true;
- if( log.isDebugEnabled() )
- log.debug( "No role found: " + roles[j]);
+ if( log.isDebugEnabled() )
+ log.debug( "Role found: " + roles[j]);
+ } else {
+ if( log.isDebugEnabled() )
+ log.debug( "No role found: " + roles[j]);
+ }
}
}
}
@@ -1280,6 +1284,7 @@
protected String domain;
protected String host;
protected String path;
+ protected String realmPath = "/realm0";
protected ObjectName oname;
protected ObjectName controller;
protected MBeanServer mserver;
@@ -1304,6 +1309,14 @@
return type;
}
+ public String getRealmPath() {
+ return realmPath;
+ }
+
+ public void setRealmPath(String theRealmPath) {
+ realmPath = theRealmPath;
+ }
+
public ObjectName preRegister(MBeanServer server,
ObjectName name) throws Exception {
oname=name;
@@ -1361,7 +1374,8 @@
// register
try {
ContainerBase cb=(ContainerBase)container;
- oname=new ObjectName(cb.getDomain()+":type=Realm" + cb.getContainerSuffix());
+ oname=new ObjectName(cb.getDomain()+":type=Realm" +
+ getRealmSuffix() + cb.getContainerSuffix());
Registry.getRegistry(null, null).registerComponent(this, oname, null );
if(log.isDebugEnabled())
log.debug("Register Realm "+oname);
@@ -1372,7 +1386,11 @@
}
+ protected String getRealmSuffix() {
+ return ",realmPath=" + getRealmPath();
+ }
+
protected static class AllRolesMode {
private String name;
Modified: trunk/java/org/apache/catalina/realm/mbeans-descriptors.xml
===================================================================
--- trunk/java/org/apache/catalina/realm/mbeans-descriptors.xml 2008-09-23 08:45:30 UTC (rev 790)
+++ trunk/java/org/apache/catalina/realm/mbeans-descriptors.xml 2008-09-24 14:40:04 UTC (rev 791)
@@ -1,4 +1,20 @@
<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
<mbeans-descriptors>
<mbean name="DataSourceRealm"
@@ -18,8 +34,7 @@
type="java.lang.String"/>
<attribute name="digest"
- description="Digest algorithm used in storing passwords in a
- non-plaintext format"
+ description="Digest algorithm used in storing passwords in a non-plaintext format"
type="java.lang.String"/>
<attribute name="localDataSource"
@@ -31,18 +46,15 @@
type="java.lang.String"/>
<attribute name="userCredCol"
- description="The column in the user table that holds the user's
- credentials"
+ description="The column in the user table that holds the user's credentials"
type="java.lang.String"/>
<attribute name="userNameCol"
- description="The column in the user table that holds the user's
- username"
+ description="The column in the user table that holds the user's username"
type="java.lang.String"/>
<attribute name="userRoleTable"
- description="The table that holds the relation between user's and
- roles"
+ description="The table that holds the relation between user's and roles"
type="java.lang.String"/>
<attribute name="userTable"
@@ -58,16 +70,13 @@
</mbean>
<mbean name="JAASRealm"
- description="Implmentation of Realm that authenticates users via the
- Java Authentication and Authorization Service (JAAS)"
+ description="Implmentation of Realm that authenticates users via the Java Authentication and Authorization Service (JAAS)"
domain="Catalina"
group="Realm"
type="org.apache.catalina.realm.JAASRealm">
<attribute name="appName"
- description="The application name passed to the JAAS LoginContext,
- which uses it to select the set of relevant
- LoginModules"
+ description="The application name passed to the JAAS LoginContext, which uses it to select the set of relevant LoginModules"
type="java.lang.String"/>
<attribute name="className"
@@ -76,23 +85,19 @@
writeable="false"/>
<attribute name="digest"
- description="Digest algorithm used in storing passwords in a
- non-plaintext format"
+ description="Digest algorithm used in storing passwords in a non-plaintext format"
type="java.lang.String"/>
<attribute name="roleClassNames"
- description="Comma-delimited list of javax.security.Principal classes
- that represent security roles"
+ description="Comma-delimited list of javax.security.Principal classes that represent security roles"
type="java.lang.String"/>
<attribute name="userClassNames"
- description="Comma-delimited list of javax.security.Principal classes
- that represent individual users"
+ description="Comma-delimited list of javax.security.Principal classes that represent individual users"
type="java.lang.String"/>
<attribute name="validate"
- description="Should we validate client certificate chains when they
- are presented?"
+ description="Should we validate client certificate chains when they are presented?"
type="java.lang.String"/>
@@ -104,8 +109,7 @@
<mbean name="JDBCRealm"
- description="Implementation of Realm that works with any JDBC
- supported database"
+ description="Implementation of Realm that works with any JDBC supported database"
domain="Catalina"
group="Realm"
type="org.apache.catalina.realm.JDBCRealm">
@@ -116,23 +120,19 @@
writeable="false"/>
<attribute name="connectionName"
- description="The connection username to use when trying to connect to
- the database"
+ description="The connection username to use when trying to connect to the database"
type="java.lang.String"/>
<attribute name="connectionPassword"
- description="The connection URL to use when trying to connect to the
- database"
+ description="The connection URL to use when trying to connect to the database"
type="java.lang.String"/>
<attribute name="connectionURL"
- description="The connection URL to use when trying to connect to the
- database"
+ description="The connection URL to use when trying to connect to the database"
type="java.lang.String"/>
<attribute name="digest"
- description="Digest algorithm used in storing passwords in a
- non-plaintext format"
+ description="Digest algorithm used in storing passwords in a non-plaintext format"
type="java.lang.String"/>
<attribute name="driverName"
@@ -144,18 +144,15 @@
type="java.lang.String"/>
<attribute name="userCredCol"
- description="The column in the user table that holds the user's
- credentials"
+ description="The column in the user table that holds the user's credentials"
type="java.lang.String"/>
<attribute name="userNameCol"
- description="The column in the user table that holds the user's
- username"
+ description="The column in the user table that holds the user's username"
type="java.lang.String"/>
<attribute name="userRoleTable"
- description="The table that holds the relation between user's and
- roles"
+ description="The table that holds the relation between user's and roles"
type="java.lang.String"/>
<attribute name="userTable"
@@ -170,9 +167,7 @@
</mbean>
<mbean name="JNDIRealm"
- description="Implementation of Realm that works with a directory
- server accessed via the Java Naming and Directory
- Interface (JNDI) APIs"
+ description="Implementation of Realm that works with a directory server accessed via the Java Naming and Directory Interface (JNDI) APIs"
domain="Catalina"
group="Realm"
type="org.apache.catalina.realm.JNDIRealm">
@@ -199,8 +194,7 @@
type="java.lang.String"/>
<attribute name="digest"
- description="Digest algorithm used in storing passwords in a
- non-plaintext format"
+ description="Digest algorithm used in storing passwords in a non-plaintext format"
type="java.lang.String"/>
<attribute name="roleBase"
@@ -216,8 +210,7 @@
type="java.lang.String"/>
<attribute name="roleSubtree"
- description="Should we search the entire subtree for matching
- memberships?"
+ description="Should we search the entire subtree for matching memberships?"
type="boolean"/>
<attribute name="userBase"
@@ -233,8 +226,7 @@
type="java.lang.String"/>
<attribute name="userRoleName"
- description="The name of the attribute in the user's entry containing
- roles for that user"
+ description="The name of the attribute in the user's entry containing roles for that user"
type="java.lang.String"/>
<attribute name="userSearch"
@@ -242,8 +234,7 @@
type="java.lang.String"/>
<attribute name="userSubtree"
- description="Should we search the entire subtree for matching
- users?"
+ description="Should we search the entire subtree for matching users?"
type="boolean"/>
@@ -254,8 +245,7 @@
</mbean>
<mbean name="MemoryRealm"
- description="Simple implementation of Realm that reads an XML file to
- configure the valid users, passwords, and roles"
+ description="Simple implementation of Realm that reads an XML file to configure the valid users, passwords, and roles"
domain="Catalina"
group="Realm"
type="org.apache.catalina.realm.MemoryRealm">
@@ -266,8 +256,7 @@
writeable="false"/>
<attribute name="pathname"
- description="The pathname of the XML file containing our database
- information"
+ description="The pathname of the XML file containing our database information"
type="java.lang.String"/>
<operation name="start" description="Start" impact="ACTION" returnType="void" />
@@ -278,8 +267,7 @@
</mbean>
<mbean name="UserDatabaseRealm"
- description="Realm connected to a UserDatabase as a global JNDI
- resource"
+ description="Realm connected to a UserDatabase as a global JNDI resource"
domain="Catalina"
group="Realm"
type="org.apache.catalina.realm.UserDatabaseRealm">
@@ -295,4 +283,103 @@
</mbean>
+ <mbean name="CombinedRealm"
+ description="Realm implementation that can be used to chain multiple realms"
+ domain="Catalina"
+ group="Realm"
+ type="org.apache.catalina.realm.CombinedRealm">
+
+ <attribute name="className"
+ description="Fully qualified class name of the managed object"
+ type="java.lang.String"
+ writeable="false"/>
+
+ <attribute name="realms"
+ description="The set of realms that the combined realm is wrapping"
+ type="[Ljavax.management.ObjectName;"
+ writeable="false"/>
+
+ <operation name="addRealm"
+ description="Add a new Realm to the set of Realms wrapped by this realm"
+ impact="ACTION"
+ returnType="void">
+ <parameter name="theRealm"
+ description="New Realm to add"
+ type="org.apache.catalina.Realm"/>
+ </operation>
+
+ <operation name="start"
+ description="Start"
+ impact="ACTION"
+ returnType="void" />
+
+ <operation name="stop"
+ description="Stop"
+ impact="ACTION"
+ returnType="void" />
+
+ </mbean>
+
+ <mbean name="LockOutRealm"
+ description="Realm implementation that can be used to wrap existing realms to provide a user lock-out capability"
+ domain="Catalina"
+ group="Realm"
+ type="org.apache.catalina.realm.LockOutRealm">
+
+ <attribute name="className"
+ description="Fully qualified class name of the managed object"
+ type="java.lang.String"
+ writeable="false"/>
+
+ <attribute name="realms"
+ description="The set of realms that the lockout realm is wrapping"
+ type="[Ljavax.management.ObjectName;"
+ writeable="false"/>
+
+ <attribute name="cacheRemovalWarningTime"
+ description="If a failed user is removed from the cache because the cache is too big before it has been in the cache for at least this period of time (in seconds) a warning message will be logged. Defaults to 3600 (1 hour)."
+ type="int" />
+
+ <attribute name="cacheSize"
+ description="Number of users that have failed authentication to keep in cache. Over time the cache will grow to this size and may not shrink. Defaults to 1000."
+ type="int" />
+
+ <attribute name="failureCount"
+ description="The number of times in a row a user has to fail authentication to be locked out. Defaults to 5."
+ type="int" />
+
+ <attribute name="lockOutTime"
+ description="The time (in seconds) a user is locked out for after too many authentication failures. Defaults to 300 (5 minutes)."
+ type="int" />
+
+ <operation name="addRealm"
+ description="Add a new Realm to the set of Realms wrapped by this realm"
+ impact="ACTION"
+ returnType="void">
+ <parameter name="theRealm"
+ description="New Realm to add"
+ type="org.apache.catalina.Realm"/>
+ </operation>
+
+ <operation name="unlock"
+ description="Unlock the specified user"
+ impact="ACTION"
+ returnType="void">
+ <parameter name="username"
+ description="User to unlock"
+ type="java.lang.String"/>
+ </operation>
+
+ <operation name="start"
+ description="Start"
+ impact="ACTION"
+ returnType="void" />
+
+ <operation name="stop"
+ description="Stop"
+ impact="ACTION"
+ returnType="void" />
+
+ </mbean>
+
</mbeans-descriptors>
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2008-09-23 08:45:30 UTC (rev 790)
+++ trunk/webapps/docs/changelog.xml 2008-09-24 14:40:04 UTC (rev 791)
@@ -34,6 +34,9 @@
<add>
Bayeux support using a BayeuxServlet written as an event driven servlet. (remm, fhanik)
</add>
+ <add>
+ LockOutRealm to lock out users after a number of failed authentication attempts. (markt)
+ </add>
</changelog>
</subsection>
<subsection name="Coyote">
16 years, 3 months
JBossWeb SVN: r790 - in trunk: webapps/docs and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: jfrederic.clere(a)jboss.com
Date: 2008-09-23 04:45:30 -0400 (Tue, 23 Sep 2008)
New Revision: 790
Modified:
trunk/java/org/jboss/web/rewrite/Substitution.java
trunk/webapps/docs/changelog.xml
Log:
Fix for JBWEB-122 (Thanks Vicky).
Modified: trunk/java/org/jboss/web/rewrite/Substitution.java
===================================================================
--- trunk/java/org/jboss/web/rewrite/Substitution.java 2008-09-22 16:52:37 UTC (rev 789)
+++ trunk/java/org/jboss/web/rewrite/Substitution.java 2008-09-23 08:45:30 UTC (rev 790)
@@ -202,10 +202,10 @@
((ServerVariableEnvElement) newElement).key = sub.substring(colon + 1, close);
} else if (type.equals("SSL")) {
newElement = new ServerVariableSslElement();
- ((ServerVariableEnvElement) newElement).key = sub.substring(colon + 1, close);
+ ((ServerVariableSslElement) newElement).key = sub.substring(colon + 1, close);
} else if (type.equals("HTTP")) {
newElement = new ServerVariableHttpElement();
- ((ServerVariableEnvElement) newElement).key = sub.substring(colon + 1, close);
+ ((ServerVariableHttpElement) newElement).key = sub.substring(colon + 1, close);
} else {
throw new IllegalArgumentException(sub + ": Bad type: " + type);
}
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2008-09-22 16:52:37 UTC (rev 789)
+++ trunk/webapps/docs/changelog.xml 2008-09-23 08:45:30 UTC (rev 790)
@@ -61,6 +61,13 @@
</fix>
</changelog>
</subsection>
+ <subsection name="Others">
+ <changelog>
+ <fix>
+ <jboss-jira>JBWEB-122</jboss-jira>: Fix exception when using SSL and HTTP variables. (jfclere)
+ </fix>
+ </changelog>
+ </subsection>
</section>
<section name="JBoss Web 2.1.1.CR7 (remm)">
16 years, 3 months