markt 2005/05/11 14:39:41
Modified: catalina/src/share/org/apache/catalina/authenticator
FormAuthenticator.java SavedRequest.java
webapps/docs changelog.xml
Log:
Include request body in saved request when using FORM authentication.
- Fixes problem with saved request assuming platform default encoding for
POSTed
parameters.
- Improves restoration of request by using CoyoteRequest
Revision Changes Path
1.20 +89 -25
jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/authenticator/FormAuthenticator.java
Index: FormAuthenticator.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/authenticator/FormAuthenticator.java,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- FormAuthenticator.java 31 Mar 2005 10:31:54 -0000 1.19
+++ FormAuthenticator.java 11 May 2005 21:39:41 -0000 1.20
@@ -19,11 +19,11 @@
import java.io.IOException;
+import java.io.InputStream;
import java.security.Principal;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Locale;
-import java.util.Map;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.Cookie;
@@ -36,11 +36,14 @@
import org.apache.catalina.deploy.LoginConfig;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.coyote.InputBuffer;
+import org.apache.coyote.http11.InputFilter;
+import org.apache.coyote.http11.InternalInputBuffer;
+import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.CharChunk;
import org.apache.tomcat.util.buf.MessageBytes;
-
/**
* An <b>Authenticator</b> and <b>Valve</b> implementation of FORM BASED
* Authentication, as described in the Servlet API Specification, Version
2.2.
@@ -187,7 +190,8 @@
if (matchRequest(request)) {
session = request.getSessionInternal(true);
if (log.isDebugEnabled())
- log.debug("Restore request from session '" +
session.getIdInternal()
+ log.debug("Restore request from session '"
+ + session.getIdInternal()
+ "'");
principal = (Principal)
session.getNote(Constants.FORM_PRINCIPAL_NOTE);
@@ -273,7 +277,8 @@
session = request.getSessionInternal(false);
if (session == null) {
if (containerLog.isDebugEnabled())
- containerLog.debug("User took so long to log on the session
expired");
+ containerLog.debug
+ ("User took so long to log on the session expired");
response.sendError(HttpServletResponse.SC_REQUEST_TIMEOUT,
sm.getString("authenticator.sessionExpired"));
return (false);
@@ -345,7 +350,8 @@
* @param request The request to be restored
* @param session The session containing the saved information
*/
- protected boolean restoreRequest(Request request, Session session) {
+ protected boolean restoreRequest(Request request, Session session)
+ throws IOException {
// Retrieve and remove the SavedRequest object from our session
SavedRequest saved = (SavedRequest)
@@ -361,7 +367,8 @@
while (cookies.hasNext()) {
request.addCookie((Cookie) cookies.next());
}
- request.clearHeaders();
+
+ request.getCoyoteRequest().getMimeHeaders().recycle();
Iterator names = saved.getHeaderNames();
while (names.hasNext()) {
String name = (String) names.next();
@@ -370,24 +377,39 @@
request.addHeader(name, (String) values.next());
}
}
+
request.clearLocales();
Iterator locales = saved.getLocales();
while (locales.hasNext()) {
request.addLocale((Locale) locales.next());
}
- request.clearParameters();
+
+ request.getCoyoteRequest().getParameters().recycle();
+
if ("POST".equalsIgnoreCase(saved.getMethod())) {
- Iterator paramNames = saved.getParameterNames();
- while (paramNames.hasNext()) {
- String paramName = (String) paramNames.next();
- String paramValues[] =
- saved.getParameterValues(paramName);
- request.addParameter(paramName, paramValues);
- }
+ ByteChunk body = saved.getBody();
+
+ // Set content length
+ request.getCoyoteRequest().setContentLength(body.getLength());
+
+ // Restore body
+ InputFilter savedBody = new SavedRequestInputFilter(body);
+ InternalInputBuffer internalBuffer = (InternalInputBuffer)
+ request.getCoyoteRequest().getInputBuffer();
+ internalBuffer.addActiveFilter(savedBody);
+
+ // Set content type
+ MessageBytes contentType = MessageBytes.newInstance();
+ contentType.setString("application/x-www-form-urlencoded");
+ request.getCoyoteRequest().setContentType(contentType);
}
- request.setMethod(saved.getMethod());
- request.setQueryString(saved.getQueryString());
- request.setRequestURI(saved.getRequestURI());
+ request.getCoyoteRequest().method().setString(saved.getMethod());
+
+ request.getCoyoteRequest().queryString().setString
+ (saved.getQueryString());
+
+ request.getCoyoteRequest().requestURI().setString
+ (saved.getRequestURI());
return (true);
}
@@ -398,8 +420,10 @@
*
* @param request The request to be saved
* @param session The session to contain the saved information
+ * @throws IOException
*/
- private void saveRequest(Request request, Session session) {
+ private void saveRequest(Request request, Session session)
+ throws IOException {
// Create and populate a SavedRequest object for this request
SavedRequest saved = new SavedRequest();
@@ -422,13 +446,22 @@
Locale locale = (Locale) locales.nextElement();
saved.addLocale(locale);
}
- Map parameters = request.getParameterMap();
- Iterator paramNames = parameters.keySet().iterator();
- while (paramNames.hasNext()) {
- String paramName = (String) paramNames.next();
- String paramValues[] = (String[]) parameters.get(paramName);
- saved.addParameter(paramName, paramValues);
+
+ if ("POST".equalsIgnoreCase(request.getMethod())) {
+ // Note that the size of the request body is limited by:
+ // request.getConnector().getMaxPostSize()
+
+ byte[] buffer = new byte[4096];
+ int bytesRead;
+ InputStream is = request.getInputStream();
+ ByteChunk body = new ByteChunk();
+
+ while ( (bytesRead = is.read(buffer) ) >= 0) {
+ body.append(buffer, 0, bytesRead);
+ }
+ saved.setBody(body);
}
+
saved.setMethod(request.getMethod());
saved.setQueryString(request.getQueryString());
saved.setRequestURI(request.getRequestURI());
@@ -460,5 +493,36 @@
}
+ protected class SavedRequestInputFilter implements InputFilter {
+
+ protected ByteChunk input = null;
+
+ public SavedRequestInputFilter(ByteChunk input) {
+ this.input = input;
+ }
+
+ public int doRead(ByteChunk chunk, org.apache.coyote.Request request)
+ throws IOException {
+ return input.substract(chunk);
+ }
+
+ public void setRequest(org.apache.coyote.Request request) {
+ }
+
+ public void recycle() {
+ input = null;
+ }
+
+ public ByteChunk getEncodingName() {
+ return null;
+ }
+
+ public void setBuffer(InputBuffer buffer) {
+ }
+
+ public long end() throws IOException {
+ return 0;
+ }
+ }
}
1.4 +15 -6
jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/authenticator/SavedRequest.java
Index: SavedRequest.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/authenticator/SavedRequest.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- SavedRequest.java 27 Feb 2004 14:58:41 -0000 1.3
+++ SavedRequest.java 11 May 2005 21:39:41 -0000 1.4
@@ -25,6 +25,8 @@
import javax.servlet.http.Cookie;
+import org.apache.tomcat.util.buf.ByteChunk;
+
/**
* Object that saves the critical information from a request so that
@@ -34,11 +36,6 @@
* <b>IMPLEMENTATION NOTE</b> - It is assumed that this object is accessed
* only from the context of a single thread, so no synchronization around
* internal collection classes is performed.
- * <p>
- * <b>FIXME</b> - Currently, this object has no mechanism to save or
- * restore the data content of the request, although it does save
- * request parameters so that a POST transaction can be faithfully
- * duplicated.
*
* @author Craig R. McClanahan
* @version $Revision$ $Date$
@@ -167,5 +164,17 @@
this.requestURI = requestURI;
}
+
+ /**
+ * The body of this request.
+ */
+ private ByteChunk body = null;
+
+ public ByteChunk getBody() {
+ return (this.body);
+ }
+ public void setBody(ByteChunk body) {
+ this.body = body;
+ }
}
1.307 +5 -0 jakarta-tomcat-catalina/webapps/docs/changelog.xml
Index: changelog.xml
===================================================================
RCS file: /home/cvs/jakarta-tomcat-catalina/webapps/docs/changelog.xml,v
retrieving revision 1.306
retrieving revision 1.307
diff -u -r1.306 -r1.307
--- changelog.xml 11 May 2005 21:22:14 -0000 1.306
+++ changelog.xml 11 May 2005 21:39:41 -0000 1.307
@@ -148,6 +148,11 @@
<fix>
Fix NPE when POST size exceeds limit defined by maxPostSize. (markt)
</fix>
+ <fix>
+ Fix FORM authentication so POSTed parameters are not assumed to be
encoded with platform
+ default encoding. A side effect of this fix is that the bodies of
POST requests that
+ require FORM authentication are now buffered and made available
after a sucessful login. (markt)
+ </fix>
</changelog>
</subsection>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]