Author: markt Date: Fri Jan 7 13:01:00 2011 New Revision: 1056298 URL: http://svn.apache.org/viewvc?rev=1056298&view=rev Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=50496 Differentiate between content written (what the app writes to the output stream) and bytes written (what Tomcat writes to the socket) and use bytes for the access logs
Modified: tomcat/trunk/java/org/apache/catalina/connector/Response.java tomcat/trunk/java/org/apache/catalina/valves/AccessLogValve.java tomcat/trunk/java/org/apache/catalina/valves/ErrorReportValve.java tomcat/trunk/java/org/apache/catalina/valves/JDBCAccessLogValve.java tomcat/trunk/java/org/apache/coyote/OutputBuffer.java tomcat/trunk/java/org/apache/coyote/RequestInfo.java tomcat/trunk/java/org/apache/coyote/Response.java tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java tomcat/trunk/java/org/apache/coyote/http11/AbstractOutputBuffer.java tomcat/trunk/java/org/apache/coyote/http11/InternalAprOutputBuffer.java tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java tomcat/trunk/java/org/apache/coyote/http11/InternalOutputBuffer.java tomcat/trunk/java/org/apache/coyote/http11/filters/ChunkedOutputFilter.java tomcat/trunk/java/org/apache/coyote/http11/filters/GzipOutputFilter.java tomcat/trunk/java/org/apache/coyote/http11/filters/IdentityOutputFilter.java tomcat/trunk/java/org/apache/coyote/http11/filters/VoidOutputFilter.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/org/apache/catalina/connector/Response.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Response.java?rev=1056298&r1=1056297&r2=1056298&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/Response.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/Response.java Fri Jan 7 13:01:00 2011 @@ -308,12 +308,30 @@ public class Response /** - * Return the number of bytes actually written to the output stream. + * Return the number of bytes the application has actually written to the + * output stream. This excludes chunking, compression, etc. as well as + * headers. */ - public long getContentCount() { + public long getContentWritten() { return outputBuffer.getContentWritten(); } + + /** + * Return the number of bytes the actually written to the socket. This + * includes chunking, compression, etc. but excludes headers. + */ + public long getBytesWritten(boolean flush) { + if (flush) { + try { + outputBuffer.flush(); + } catch (IOException ioe) { + // Ignore - the client has probably closed the connection + } + } + return coyoteResponse.getBytesWritten(flush); + } + /** * Set the application commit flag. * @@ -330,7 +348,7 @@ public class Response public boolean isAppCommitted() { return (this.appCommitted || isCommitted() || isSuspended() || ((getContentLength() > 0) - && (getContentCount() >= getContentLength()))); + && (getContentWritten() >= getContentLength()))); } 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=1056298&r1=1056297&r2=1056298&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/valves/AccessLogValve.java (original) +++ tomcat/trunk/java/org/apache/catalina/valves/AccessLogValve.java Fri Jan 7 13:01:00 2011 @@ -1049,7 +1049,7 @@ public class AccessLogValve extends Valv @Override public void addElement(StringBuilder buf, Date date, Request request, Response response, long time) { - long length = response.getContentCount() ; + long length = response.getBytesWritten(true); if (length <= 0 && conversion) { buf.append('-'); } else { Modified: tomcat/trunk/java/org/apache/catalina/valves/ErrorReportValve.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/ErrorReportValve.java?rev=1056298&r1=1056297&r2=1056298&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/valves/ErrorReportValve.java (original) +++ tomcat/trunk/java/org/apache/catalina/valves/ErrorReportValve.java Fri Jan 7 13:01:00 2011 @@ -157,7 +157,7 @@ public class ErrorReportValve extends Va // Do nothing on a 1xx, 2xx and 3xx status // Do nothing if anything has been written already - if ((statusCode < 400) || (response.getContentCount() > 0)) + if ((statusCode < 400) || (response.getContentWritten() > 0)) return; String message = RequestUtil.filter(response.getMessage()); Modified: tomcat/trunk/java/org/apache/catalina/valves/JDBCAccessLogValve.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/JDBCAccessLogValve.java?rev=1056298&r1=1056297&r2=1056298&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/valves/JDBCAccessLogValve.java (original) +++ tomcat/trunk/java/org/apache/catalina/valves/JDBCAccessLogValve.java Fri Jan 7 13:01:00 2011 @@ -457,7 +457,7 @@ public final class JDBCAccessLogValve ex String user = request.getRemoteUser(); String query=request.getRequestURI(); - long bytes = response.getContentCount() ; + long bytes = response.getBytesWritten(true); if(bytes < 0) bytes = 0; int status = response.getStatus(); Modified: tomcat/trunk/java/org/apache/coyote/OutputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/OutputBuffer.java?rev=1056298&r1=1056297&r2=1056298&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/OutputBuffer.java (original) +++ tomcat/trunk/java/org/apache/coyote/OutputBuffer.java Fri Jan 7 13:01:00 2011 @@ -25,8 +25,8 @@ import org.apache.tomcat.util.buf.ByteCh /** * Output buffer. * - * This class is used internally by the protocol implementation. All writes from higher level code should happen - * via Resonse.doWrite(). + * This class is used internally by the protocol implementation. All writes from + * higher level code should happen via Resonse.doWrite(). * * @author Remy Maucherat */ @@ -37,11 +37,18 @@ public interface OutputBuffer { * Write the response. The caller ( tomcat ) owns the chunks. * * @param chunk data to write - * @param response used to allow buffers that can be shared by multiple responses. + * @param response used to allow buffers that can be shared by multiple + * responses. * @throws IOException */ public int doWrite(ByteChunk chunk, Response response) throws IOException; - + /** + * Bytes written to the underlying socket. This includes the effects of + * chunking, compression, etc. + * + * @return Bytes written for the current request + */ + public long getBytesWritten(); } Modified: tomcat/trunk/java/org/apache/coyote/RequestInfo.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/RequestInfo.java?rev=1056298&r1=1056297&r2=1056298&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/RequestInfo.java (original) +++ tomcat/trunk/java/org/apache/coyote/RequestInfo.java Fri Jan 7 13:01:00 2011 @@ -107,7 +107,7 @@ public class RequestInfo { } public long getRequestBytesSent() { - return req.getResponse().getBytesWritten(); + return req.getResponse().getContentWritten(); } public long getRequestProcessingTime() { @@ -140,7 +140,7 @@ public class RequestInfo { */ void updateCounters() { bytesReceived+=req.getBytesRead(); - bytesSent+=req.getResponse().getBytesWritten(); + bytesSent+=req.getResponse().getContentWritten(); requestCount++; if( req.getResponse().getStatus() >=400 ) Modified: tomcat/trunk/java/org/apache/coyote/Response.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/Response.java?rev=1056298&r1=1056297&r2=1056298&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/Response.java (original) +++ tomcat/trunk/java/org/apache/coyote/Response.java Fri Jan 7 13:01:00 2011 @@ -97,7 +97,7 @@ public final class Response { private Locale locale = DEFAULT_LOCALE; // General informations - private long bytesWritten=0; + private long contentWritten = 0; /** * Holds request error exception. @@ -531,7 +531,7 @@ public final class Response { throws IOException { outputBuffer.doWrite(chunk, this); - bytesWritten+=chunk.getLength(); + contentWritten+=chunk.getLength(); } // -------------------- @@ -551,10 +551,23 @@ public final class Response { headers.clear(); // update counters - bytesWritten=0; + contentWritten=0; } - public long getBytesWritten() { - return bytesWritten; + /** + * Bytes written by application - i.e. before compression, chunking, etc. + */ + public long getContentWritten() { + return contentWritten; + } + + /** + * Bytes written to socket - i.e. after compression, chunking, etc. + */ + public long getBytesWritten(boolean flush) { + if (flush) { + action(ActionCode.CLIENT_FLUSH, this); + } + return outputBuffer.getBytesWritten(); } } Modified: tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java?rev=1056298&r1=1056297&r2=1056298&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java Fri Jan 7 13:01:00 2011 @@ -176,6 +176,12 @@ public abstract class AbstractAjpProcess */ protected AsyncStateMachine asyncStateMachine = new AsyncStateMachine(this); + + /** + * Bytes written to client for the current request + */ + protected long byteCount = 0; + // ------------------------------------------------------------- Properties @@ -379,6 +385,7 @@ public abstract class AbstractAjpProcess request.recycle(); response.recycle(); certificates.recycle(); + byteCount = 0; } // ------------------------------------------------------ Connector Methods Modified: tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java?rev=1056298&r1=1056297&r2=1056298&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java Fri Jan 7 13:01:00 2011 @@ -725,7 +725,13 @@ public class AjpAprProcessor extends Abs off += thisTime; } + byteCount += chunk.getLength(); return chunk.getLength(); } + + @Override + public long getBytesWritten() { + return byteCount; + } } } Modified: tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java?rev=1056298&r1=1056297&r2=1056298&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java Fri Jan 7 13:01:00 2011 @@ -590,9 +590,7 @@ public class AjpProcessor extends Abstra * This class is an output buffer which will write data to an output * stream. */ - protected class SocketOutputBuffer - implements OutputBuffer { - + protected class SocketOutputBuffer implements OutputBuffer { /** * Write chunk. @@ -631,7 +629,13 @@ public class AjpProcessor extends Abstra off += thisTime; } + byteCount += chunk.getLength(); return chunk.getLength(); } + + @Override + public long getBytesWritten() { + return byteCount; + } } } Modified: tomcat/trunk/java/org/apache/coyote/http11/AbstractOutputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/AbstractOutputBuffer.java?rev=1056298&r1=1056297&r2=1056298&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/AbstractOutputBuffer.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/AbstractOutputBuffer.java Fri Jan 7 13:01:00 2011 @@ -88,6 +88,11 @@ public abstract class AbstractOutputBuff */ protected OutputBuffer outputStreamOutputBuffer; + /** + * Bytes written to client for the current request + */ + protected long byteCount = 0; + // -------------------------------------------------------------- Variables @@ -185,7 +190,18 @@ public abstract class AbstractOutputBuff return activeFilters[lastActiveFilter].doWrite(chunk, res); } - + + + @Override + public long getBytesWritten() { + if (lastActiveFilter == -1) { + return outputStreamOutputBuffer.getBytesWritten(); + } else { + return activeFilters[lastActiveFilter].getBytesWritten(); + } + } + + // --------------------------------------------------------- Public Methods @@ -299,7 +315,7 @@ public abstract class AbstractOutputBuff if (lastActiveFilter != -1) activeFilters[lastActiveFilter].end(); finished = true; - + byteCount = 0; } public abstract void sendAck() throws IOException; Modified: tomcat/trunk/java/org/apache/coyote/http11/InternalAprOutputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/InternalAprOutputBuffer.java?rev=1056298&r1=1056297&r2=1056298&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/InternalAprOutputBuffer.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/InternalAprOutputBuffer.java Fri Jan 7 13:01:00 2011 @@ -227,8 +227,7 @@ public class InternalAprOutputBuffer ext * This class is an output buffer which will write data to an output * stream. */ - protected class SocketOutputBuffer - implements OutputBuffer { + protected class SocketOutputBuffer implements OutputBuffer { /** @@ -253,11 +252,14 @@ public class InternalAprOutputBuffer ext len = len - thisTime; start = start + thisTime; } + byteCount += chunk.getLength(); return chunk.getLength(); - } - + @Override + public long getBytesWritten() { + return byteCount; + } } Modified: tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java?rev=1056298&r1=1056297&r2=1056298&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java Fri Jan 7 13:01:00 2011 @@ -295,11 +295,14 @@ public class InternalNioOutputBuffer ext int start = chunk.getStart(); byte[] b = chunk.getBuffer(); addToBB(b, start, len); + byteCount += chunk.getLength(); return chunk.getLength(); - } - + @Override + public long getBytesWritten() { + return byteCount; + } } Modified: tomcat/trunk/java/org/apache/coyote/http11/InternalOutputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/InternalOutputBuffer.java?rev=1056298&r1=1056297&r2=1056298&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/InternalOutputBuffer.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/InternalOutputBuffer.java Fri Jan 7 13:01:00 2011 @@ -74,6 +74,7 @@ public class InternalOutputBuffer extend */ protected boolean useSocketBuffer = false; + /** * Set the underlying socket output stream. */ @@ -255,11 +256,14 @@ public class InternalOutputBuffer extend outputStream.write(chunk.getBuffer(), chunk.getStart(), length); } - return length; - + byteCount += chunk.getLength(); + return chunk.getLength(); } - + @Override + public long getBytesWritten() { + return byteCount; + } } Modified: tomcat/trunk/java/org/apache/coyote/http11/filters/ChunkedOutputFilter.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/filters/ChunkedOutputFilter.java?rev=1056298&r1=1056297&r2=1056298&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/filters/ChunkedOutputFilter.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/filters/ChunkedOutputFilter.java Fri Jan 7 13:01:00 2011 @@ -126,6 +126,12 @@ public class ChunkedOutputFilter impleme } + @Override + public long getBytesWritten() { + return buffer.getBytesWritten(); + } + + // --------------------------------------------------- OutputFilter Methods Modified: tomcat/trunk/java/org/apache/coyote/http11/filters/GzipOutputFilter.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/filters/GzipOutputFilter.java?rev=1056298&r1=1056297&r2=1056298&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/filters/GzipOutputFilter.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/filters/GzipOutputFilter.java Fri Jan 7 13:01:00 2011 @@ -82,6 +82,12 @@ public class GzipOutputFilter implements } + @Override + public long getBytesWritten() { + return buffer.getBytesWritten(); + } + + // --------------------------------------------------- OutputFilter Methods /** Modified: tomcat/trunk/java/org/apache/coyote/http11/filters/IdentityOutputFilter.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/filters/IdentityOutputFilter.java?rev=1056298&r1=1056297&r2=1056298&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/filters/IdentityOutputFilter.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/filters/IdentityOutputFilter.java Fri Jan 7 13:01:00 2011 @@ -99,6 +99,12 @@ public class IdentityOutputFilter implem } + @Override + public long getBytesWritten() { + return buffer.getBytesWritten(); + } + + // --------------------------------------------------- OutputFilter Methods Modified: tomcat/trunk/java/org/apache/coyote/http11/filters/VoidOutputFilter.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/filters/VoidOutputFilter.java?rev=1056298&r1=1056297&r2=1056298&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/filters/VoidOutputFilter.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/filters/VoidOutputFilter.java Fri Jan 7 13:01:00 2011 @@ -50,6 +50,12 @@ public class VoidOutputFilter implements } + @Override + public long getBytesWritten() { + return 0; + } + + // --------------------------------------------------- OutputFilter Methods Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1056298&r1=1056297&r2=1056298&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Fri Jan 7 13:01:00 2011 @@ -189,6 +189,10 @@ (markt) </update> <fix> + <bug>50496</bug>: Bytes sent in the access log are now counted after + compression, chunking etc rather than before. (markt) + </fix> + <fix> <bug>50550</bug>: When a new directory is created (e.g. via WebDAV) ensure that a subsequent request for that directory does not result in a 404 response. (markt) --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org