Return-Path:
Delivered-To: apmail-tomcat-dev-archive@www.apache.org
Received: (qmail 91260 invoked from network); 2 Jun 2010 15:13:10 -0000
Received: from unknown (HELO mail.apache.org) (140.211.11.3)
by 140.211.11.9 with SMTP; 2 Jun 2010 15:13:10 -0000
Received: (qmail 82993 invoked by uid 500); 2 Jun 2010 15:13:09 -0000
Delivered-To: apmail-tomcat-dev-archive@tomcat.apache.org
Received: (qmail 82935 invoked by uid 500); 2 Jun 2010 15:13:09 -0000
Mailing-List: contact dev-help@tomcat.apache.org; run by ezmlm
Precedence: bulk
List-Help:
List-Unsubscribe:
List-Post:
List-Id:
Reply-To: "Tomcat Developers List"
Delivered-To: mailing list dev@tomcat.apache.org
Received: (qmail 82924 invoked by uid 99); 2 Jun 2010 15:13:09 -0000
Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136)
by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 02 Jun 2010 15:13:09 +0000
X-ASF-Spam-Status: No, hits=-1454.4 required=10.0
tests=ALL_TRUSTED,AWL
X-Spam-Check-By: apache.org
Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4)
by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 02 Jun 2010 15:13:08 +0000
Received: by eris.apache.org (Postfix, from userid 65534)
id 6EEAE238890A; Wed, 2 Jun 2010 15:12:47 +0000 (UTC)
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: svn commit: r950587 - in /tomcat/trunk:
java/org/apache/catalina/AccessLog.java
java/org/apache/catalina/connector/CoyoteAdapter.java
java/org/apache/catalina/valves/AccessLogValve.java
webapps/docs/config/valve.xml
Date: Wed, 02 Jun 2010 15:12:47 -0000
To: dev@tomcat.apache.org
From: markt@apache.org
X-Mailer: svnmailer-1.0.8
Message-Id: <20100602151247.6EEAE238890A@eris.apache.org>
Author: markt
Date: Wed Jun 2 15:12:36 2010
New Revision: 950587
URL: http://svn.apache.org/viewvc?rev=950587&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=49099
Hooking the CoyoteAdaptor into the existing AccessLog wasn't as invasive as I feared so go that route to log requests rejected by the Adaptor before the request/response reaches the AcessLogValve
Added:
tomcat/trunk/java/org/apache/catalina/AccessLog.java (with props)
Modified:
tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
tomcat/trunk/java/org/apache/catalina/valves/AccessLogValve.java
tomcat/trunk/webapps/docs/config/valve.xml
Added: tomcat/trunk/java/org/apache/catalina/AccessLog.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/AccessLog.java?rev=950587&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/AccessLog.java (added)
+++ tomcat/trunk/java/org/apache/catalina/AccessLog.java Wed Jun 2 15:12:36 2010
@@ -0,0 +1,47 @@
+/*
+ * 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;
+
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+
+
+/**
+ * Intended for use by a {@link Valve} to indicate that the {@link Valve}
+ * provides access logging. It is used by the Tomcat internals (the
+ * {@link org.apache.catalina.connector.CoyoteAdapter} at the time of writing)
+ * to identify a Valve that logs access requests so requests that are rejected
+ * earlier in the processing chain can still be added to the access log.
+ * Implementations of this interface should be robust against the provided
+ * {@link Request} and {@link Response} objects being null, having null
+ * attributes or any other 'oddness' that may result from attempting to log
+ * a request that was almost certainly rejected because it was mal-formed.
+ */
+public interface AccessLog {
+
+ /**
+ * Add the request/response to the access log using the specified processing
+ * time.
+ *
+ * @param request Request (associated with the response) to log
+ * @param response Response (associated with the request) to log
+ * @param time Time taken to process the request/response in
+ * milliseconds (use 0 if not known)
+ */
+ public void log(Request request, Response response, long time);
+}
Propchange: tomcat/trunk/java/org/apache/catalina/AccessLog.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java?rev=950587&r1=950586&r2=950587&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java Wed Jun 2 15:12:36 2010
@@ -24,8 +24,13 @@ import java.util.EnumSet;
import javax.servlet.SessionTrackingMode;
+import org.apache.catalina.AccessLog;
+import org.apache.catalina.Container;
import org.apache.catalina.Context;
+import org.apache.catalina.Engine;
import org.apache.catalina.Globals;
+import org.apache.catalina.Host;
+import org.apache.catalina.Valve;
import org.apache.catalina.Wrapper;
import org.apache.tomcat.util.res.StringManager;
import org.apache.catalina.comet.CometEvent;
@@ -115,6 +120,11 @@ public class CoyoteAdapter implements Ad
protected static URLEncoder urlEncoder;
+ /**
+ * Access log to use for rejected requests
+ */
+ private volatile AccessLog accessLog = null;
+
// ----------------------------------------------------- Static Initializer
@@ -512,12 +522,14 @@ public class CoyoteAdapter implements Ad
} catch (IOException ioe) {
res.setStatus(400);
res.setMessage("Invalid URI: " + ioe.getMessage());
+ getAccessLog().log(request, response, 0);
return false;
}
// Normalization
if (!normalize(req.decodedURI())) {
res.setStatus(400);
res.setMessage("Invalid URI");
+ getAccessLog().log(request, response, 0);
return false;
}
// Character decoding
@@ -526,6 +538,7 @@ public class CoyoteAdapter implements Ad
if (!checkNormalize(req.decodedURI())) {
res.setStatus(400);
res.setMessage("Invalid URI character encoding");
+ getAccessLog().log(request, response, 0);
return false;
}
@@ -585,6 +598,7 @@ public class CoyoteAdapter implements Ad
res.setStatus(405);
res.addHeader("Allow", header);
res.setMessage("TRACE method is not allowed");
+ getAccessLog().log(request, response, 0);
return false;
}
@@ -623,6 +637,7 @@ public class CoyoteAdapter implements Ad
redirectPath = redirectPath + "?" + query;
}
response.sendRedirect(redirectPath);
+ getAccessLog().log(request, response, 0);
return false;
}
@@ -1075,4 +1090,61 @@ public class CoyoteAdapter implements Ad
}
+ /**
+ * Obtain a reference to the access log to use to log rejected requests.
+ *
+ * @return
+ */
+ protected AccessLog getAccessLog() {
+ if (accessLog != null) {
+ return accessLog;
+ }
+
+ // First look in Engine for associated service
+ Engine engine = (Engine) connector.getService().getContainer();
+ accessLog = findAccessLog(engine);
+ if (accessLog != null) {
+ return accessLog;
+ }
+
+ // Then look in default host
+ Host defaultHost = (Host) engine.findChild(engine.getDefaultHost());
+ accessLog = findAccessLog(defaultHost);
+ if (accessLog != null) {
+ return accessLog;
+ }
+
+ // Then look in ROOT context of default host
+ Context defaultContext = (Context) defaultHost.findChild("/");
+ accessLog = findAccessLog(defaultContext);
+ if (accessLog != null) {
+ return accessLog;
+ }
+
+ accessLog = new NoopAccessLog();
+ return accessLog;
+ }
+
+ private AccessLog findAccessLog(Container container) {
+ if (container == null) {
+ return new NoopAccessLog();
+ }
+
+ Valve valves[] = container.getPipeline().getValves();
+ for (Valve valve : valves) {
+ if (valve instanceof AccessLog) {
+ return (AccessLog) valve;
+ }
+ }
+ return null;
+ }
+
+ private static final class NoopAccessLog implements AccessLog {
+
+ @Override
+ public void log(Request request, Response response, long time) {
+ // NOOP
+ }
+
+ }
}
Modified: tomcat/trunk/java/org/apache/catalina/valves/AccessLogValve.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/AccessLogValve.java?rev=950587&r1=950586&r2=950587&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/valves/AccessLogValve.java (original)
+++ tomcat/trunk/java/org/apache/catalina/valves/AccessLogValve.java Wed Jun 2 15:12:36 2010
@@ -36,6 +36,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpSession;
+import org.apache.catalina.AccessLog;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleState;
import org.apache.catalina.connector.Request;
@@ -118,7 +119,7 @@ import org.apache.juli.logging.LogFactor
* @version $Id$
*/
-public class AccessLogValve extends ValveBase {
+public class AccessLogValve extends ValveBase implements AccessLog {
private static final Log log = LogFactory.getLog(AccessLogValve.class);
@@ -563,25 +564,30 @@ public class AccessLogValve extends Valv
long t2 = System.currentTimeMillis();
long time = t2 - t1;
-
- if (logElements == null || condition != null
- && null != request.getRequest().getAttribute(condition)) {
- return;
- }
-
- Date date = getDate();
- StringBuilder result = new StringBuilder(128);
-
- for (int i = 0; i < logElements.length; i++) {
- logElements[i].addElement(result, date, request, response, time);
- }
-
- log(result.toString());
+
+ log(request,response, time);
} else
getNext().invoke(request, response);
}
+ public void log(Request request, Response response, long time) {
+ if (logElements == null || condition != null
+ && null != request.getRequest().getAttribute(condition)) {
+ return;
+ }
+
+ Date date = getDate();
+ StringBuilder result = new StringBuilder(128);
+
+ for (int i = 0; i < logElements.length; i++) {
+ logElements[i].addElement(result, date, request, response, time);
+ }
+
+ log(result.toString());
+ }
+
+
/**
* Rename the existing log file to something else. Then open the
* old log file name up once again. Intended to be called by a JMX
Modified: tomcat/trunk/webapps/docs/config/valve.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/valve.xml?rev=950587&r1=950586&r2=950587&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/valve.xml (original)
+++ tomcat/trunk/webapps/docs/config/valve.xml Wed Jun 2 15:12:36 2010
@@ -66,6 +66,15 @@
Host
, or Engine
), and
will record ALL requests processed by that container.
+ Some requests (e.g. those with mal-formed URLs) may be rejected by Tomcat
+ before they are passed to a container. In these cases Tomcat will look in
+ the Engine
, then the default Host
for the
+ Engine
and finally the ROOT (or default) Context
+ for the default Host
for an AccessLogValve
or
+ other AccessLog
implementation. Tomcat will use the first
+ AccessLog
implementation found to log those requests that are
+ rejected before they are passed to a container.
+
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org