You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2008/07/21 19:21:58 UTC

svn commit: r678490 - in /cxf/trunk: api/src/main/java/org/apache/cxf/io/ rt/transports/http/src/main/java/org/apache/cxf/transport/http/gzip/ rt/transports/http/src/test/java/org/apache/cxf/transport/http/gzip/ systests/src/test/java/org/apache/cxf/sy...

Author: dkulp
Date: Mon Jul 21 10:21:58 2008
New Revision: 678490

URL: http://svn.apache.org/viewvc?rev=678490&view=rev
Log:
Change gzip to using the new Threshold output stream stuff so that it can keep streaming instead of buffering everything.


Modified:
    cxf/trunk/api/src/main/java/org/apache/cxf/io/AbstractThresholdOutputStream.java
    cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/gzip/GZIPInInterceptor.java
    cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/gzip/GZIPOutInterceptor.java
    cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/gzip/GZIPAcceptEncodingTest.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxws/DocLitWrappedCodeFirstService.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxws/DocLitWrappedCodeFirstServiceImpl.java

Modified: cxf/trunk/api/src/main/java/org/apache/cxf/io/AbstractThresholdOutputStream.java
URL: http://svn.apache.org/viewvc/cxf/trunk/api/src/main/java/org/apache/cxf/io/AbstractThresholdOutputStream.java?rev=678490&r1=678489&r2=678490&view=diff
==============================================================================
--- cxf/trunk/api/src/main/java/org/apache/cxf/io/AbstractThresholdOutputStream.java (original)
+++ cxf/trunk/api/src/main/java/org/apache/cxf/io/AbstractThresholdOutputStream.java Mon Jul 21 10:21:58 2008
@@ -43,8 +43,8 @@
     }
     
     
-    public abstract void thresholdReached();
-    public abstract void thresholdNotReached();
+    public abstract void thresholdReached() throws IOException;
+    public abstract void thresholdNotReached() throws IOException;
     
     
     @Override

Modified: cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/gzip/GZIPInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/gzip/GZIPInInterceptor.java?rev=678490&r1=678489&r2=678490&view=diff
==============================================================================
--- cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/gzip/GZIPInInterceptor.java (original)
+++ cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/gzip/GZIPInInterceptor.java Mon Jul 21 10:21:58 2008
@@ -95,7 +95,12 @@
                     message.setContent(InputStream.class, zipInput);
 
                     // remove content encoding header as we've now dealt with it
-                    protocolHeaders.remove("Content-Encoding");
+                    for (String key : protocolHeaders.keySet()) {
+                        if (key.equalsIgnoreCase("Content-Encoding")) {
+                            protocolHeaders.remove(key);
+                            break;
+                        }
+                    }
 
                     // add the ending interceptor
                     message.getInterceptorChain().add(ending);

Modified: cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/gzip/GZIPOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/gzip/GZIPOutInterceptor.java?rev=678490&r1=678489&r2=678490&view=diff
==============================================================================
--- cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/gzip/GZIPOutInterceptor.java (original)
+++ cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/gzip/GZIPOutInterceptor.java Mon Jul 21 10:21:58 2008
@@ -37,7 +37,7 @@
 import org.apache.cxf.helpers.HttpHeaderHelper;
 import org.apache.cxf.interceptor.Fault;
 import org.apache.cxf.interceptor.MessageSenderInterceptor;
-import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.io.AbstractThresholdOutputStream;
 import org.apache.cxf.message.Exchange;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.phase.AbstractPhaseInterceptor;
@@ -93,10 +93,6 @@
     private static final ResourceBundle BUNDLE = BundleUtils.getBundle(GZIPOutInterceptor.class);
     private static final Logger LOG = LogUtils.getL7dLogger(GZIPOutInterceptor.class);
 
-    /**
-     * Ending interceptor that handles the compression process.
-     */
-    private GZIPOutEndingInterceptor ending = new GZIPOutEndingInterceptor();
 
     /**
      * Compression threshold in bytes - messages smaller than this will not be
@@ -124,15 +120,15 @@
             // data to this later
             OutputStream os = message.getContent(OutputStream.class);
             message.put(ORIGINAL_OUTPUT_STREAM_KEY, os);
-
             message.put(USE_GZIP_KEY, use);
 
             // new stream to cache the message
-            CachedOutputStream cs = new CachedOutputStream();
+            GZipThresholdOutputStream cs 
+                = new GZipThresholdOutputStream(threshold,
+                                                os,
+                                                use == UseGzip.FORCE,
+                                                message);
             message.setContent(OutputStream.class, cs);
-
-            // add the ending interceptor that does the work
-            message.getInterceptorChain().add(ending);
         }
     }
 
@@ -156,6 +152,7 @@
             LOG.fine("Requestor role, so gzip enabled");
             permitted = UseGzip.YES;
             message.put(GZIP_ENCODING_KEY, "gzip");
+            addHeader(message, "Accept-Encoding", "gzip;q=1.0, identity; q=0.5, *;q=0"); 
         } else {
             LOG.fine("Response role, checking accept-encoding");
             Exchange exchange = message.getExchange();
@@ -238,80 +235,74 @@
         }
         return permitted;
     }
-
-    /**
-     * Ending interceptor to actually do the compression.
-     */
-    public class GZIPOutEndingInterceptor extends AbstractPhaseInterceptor<Message> {
-
-        public GZIPOutEndingInterceptor() {
-            super(Phase.PREPARE_SEND_ENDING);
-            addBefore(MessageSenderInterceptor.MessageSenderEndingInterceptor.class.getName());
+    
+    static class GZipThresholdOutputStream extends AbstractThresholdOutputStream {
+        Message message;
+        
+        public GZipThresholdOutputStream(int t, OutputStream orig,
+                                         boolean force, Message msg) {
+            super(t);
+            super.wrappedStream = orig;
+            message = msg;
+            if (force) {
+                setupGZip();
+            }
+        }
+        
+        private void setupGZip() {
+            
         }
 
-        /**
-         * Copies the message content to the real output stream, compressing it
-         * if we have to or if the message is larger than the threshold.
-         */
-        public void handleMessage(Message message) throws Fault {
-            try {
-                CachedOutputStream cs = (CachedOutputStream)message.getContent(OutputStream.class);
-                cs.flush();
-                OutputStream originalOutput = (OutputStream)message.get(ORIGINAL_OUTPUT_STREAM_KEY);
-                if (UseGzip.FORCE == message.get(USE_GZIP_KEY) || cs.size() > threshold) {
-                    LOG.fine("Compressing message.");
-                    // Set the Content-Encoding HTTP header
-                    addHeader(message, "Content-Encoding", (String)message.get(GZIP_ENCODING_KEY));
-                    // if this is a response message, add the Vary header
-                    if (!Boolean.TRUE.equals(message.get(Message.REQUESTOR_ROLE))) {
-                        addHeader(message, "Vary", "Accept-Encoding");
-                    }
-
-                    // gzip the result
-                    GZIPOutputStream zipOutput = new GZIPOutputStream(originalOutput);
-                    cs.writeCacheTo(zipOutput);
-                    zipOutput.finish();
-                } else {
-                    LOG.fine("Message is smaller than compression threshold, not compressing.");
-                    cs.writeCacheTo(originalOutput);
-                }
-
-                cs.close();
-                originalOutput.flush();
-
-                message.setContent(OutputStream.class, originalOutput);
-            } catch (IOException ex) {
-                throw new Fault(new org.apache.cxf.common.i18n.Message("COULD_NOT_ZIP", BUNDLE), ex);
-            }
+        @Override
+        public void thresholdNotReached() {
+            //nothing
+            LOG.fine("Message is smaller than compression threshold, not compressing.");
         }
 
-        /**
-         * Adds a value to a header. If the given header name is not currently
-         * set in the message, an entry is created with the given single value.
-         * If the header is already set, the value is appended to the first
-         * element of the list, following a comma.
-         * 
-         * @param message the message
-         * @param name the header to set
-         * @param value the value to add
-         */
-        private void addHeader(Message message, String name, String value) {
-            Map<String, List<String>> protocolHeaders = CastUtils.cast((Map<?, ?>)message
-                .get(Message.PROTOCOL_HEADERS));
-            if (protocolHeaders == null) {
-                protocolHeaders = new HashMap<String, List<String>>();
-                message.put(Message.PROTOCOL_HEADERS, protocolHeaders);
-            }
-            List<String> header = CastUtils.cast((List<?>)protocolHeaders.get(name));
-            if (header == null) {
-                header = new ArrayList<String>();
-                protocolHeaders.put(name, header);
-            }
-            if (header.size() == 0) {
-                header.add(value);
-            } else {
-                header.set(0, header.get(0) + "," + value);
-            }
+        @Override
+        public void thresholdReached() throws IOException {
+            LOG.fine("Compressing message.");
+            // Set the Content-Encoding HTTP header
+            String enc = (String)message.get(GZIP_ENCODING_KEY);
+            addHeader(message, "Content-Encoding", enc);
+            // if this is a response message, add the Vary header
+            if (!Boolean.TRUE.equals(message.get(Message.REQUESTOR_ROLE))) {
+                addHeader(message, "Vary", "Accept-Encoding");
+            } 
+
+            // gzip the result
+            GZIPOutputStream zipOutput = new GZIPOutputStream(wrappedStream);
+            wrappedStream = zipOutput;
         }
     }
+    
+    /**
+     * Adds a value to a header. If the given header name is not currently
+     * set in the message, an entry is created with the given single value.
+     * If the header is already set, the value is appended to the first
+     * element of the list, following a comma.
+     * 
+     * @param message the message
+     * @param name the header to set
+     * @param value the value to add
+     */
+    private static void addHeader(Message message, String name, String value) {
+        Map<String, List<String>> protocolHeaders = CastUtils.cast((Map<?, ?>)message
+            .get(Message.PROTOCOL_HEADERS));
+        if (protocolHeaders == null) {
+            protocolHeaders = new HashMap<String, List<String>>();
+            message.put(Message.PROTOCOL_HEADERS, protocolHeaders);
+        }
+        List<String> header = CastUtils.cast((List<?>)protocolHeaders.get(name));
+        if (header == null) {
+            header = new ArrayList<String>();
+            protocolHeaders.put(name, header);
+        }
+        if (header.size() == 0) {
+            header.add(value);
+        } else {
+            header.set(0, header.get(0) + "," + value);
+        }
+    }    
+
 }

Modified: cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/gzip/GZIPAcceptEncodingTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/gzip/GZIPAcceptEncodingTest.java?rev=678490&r1=678489&r2=678490&view=diff
==============================================================================
--- cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/gzip/GZIPAcceptEncodingTest.java (original)
+++ cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/gzip/GZIPAcceptEncodingTest.java Mon Jul 21 10:21:58 2008
@@ -111,9 +111,7 @@
     private void singleTest(String encoding, boolean expectEndingInterceptor,
                             GZIPOutInterceptor.UseGzip expectedUseGzip, String expectedGzipEncoding)
         throws Exception {
-        if (expectEndingInterceptor) {
-            outInterceptors.add(EasyMock.isA(GZIPOutInterceptor.GZIPOutEndingInterceptor.class));
-        }
+
         EasyMock.replay(outInterceptors);
         setAcceptEncoding(encoding);
         interceptor.handleMessage(outMessage);

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxws/DocLitWrappedCodeFirstService.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxws/DocLitWrappedCodeFirstService.java?rev=678490&r1=678489&r2=678490&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxws/DocLitWrappedCodeFirstService.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxws/DocLitWrappedCodeFirstService.java Mon Jul 21 10:21:58 2008
@@ -40,7 +40,9 @@
             targetNamespace = "http://cxf.apache.org/systest/jaxws/DocLitWrappedCodeFirstService")
 @SOAPBinding(style = SOAPBinding.Style.DOCUMENT,
              use = SOAPBinding.Use.LITERAL)
-@Features(features = { "org.apache.cxf.feature.FastInfosetFeature" })
+//@Features(features = { "org.apache.cxf.feature.FastInfosetFeature" })
+@Features(features = { "org.apache.cxf.transport.http.gzip.GZIPFeature", 
+                       "org.apache.cxf.feature.FastInfosetFeature" })
 public interface DocLitWrappedCodeFirstService {
 
     @WebMethod

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxws/DocLitWrappedCodeFirstServiceImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxws/DocLitWrappedCodeFirstServiceImpl.java?rev=678490&r1=678489&r2=678490&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxws/DocLitWrappedCodeFirstServiceImpl.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxws/DocLitWrappedCodeFirstServiceImpl.java Mon Jul 21 10:21:58 2008
@@ -39,7 +39,9 @@
             serviceName = "DocLitWrappedCodeFirstService",
             portName = "DocLitWrappedCodeFirstServicePort",
             targetNamespace = "http://cxf.apache.org/systest/jaxws/DocLitWrappedCodeFirstService")
-@Features(features = { "org.apache.cxf.feature.FastInfosetFeature" })
+//@Features(features = { "org.apache.cxf.feature.FastInfosetFeature" })
+@Features(features = { "org.apache.cxf.transport.http.gzip.GZIPFeature", 
+                       "org.apache.cxf.feature.FastInfosetFeature" })
 public class DocLitWrappedCodeFirstServiceImpl implements DocLitWrappedCodeFirstService {
     public static final String DATA[] = new String[] {"string1", "string2", "string3"};