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

Reply via email to