You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by di...@apache.org on 2005/07/30 03:48:10 UTC

cvs commit: ws-axis/java/src/org/apache/axis/transport/http CommonsHTTPSender.java HTTPConstants.java

dims        2005/07/29 18:48:09

  Modified:    java/src/org/apache/axis/transport/http
                        CommonsHTTPSender.java HTTPConstants.java
  Log:
  Fix for AXIS-2136 - support request & response gzip compression on HTTP transport
  
  from Simon Fell
  
  Revision  Changes    Path
  1.39      +83 -10    ws-axis/java/src/org/apache/axis/transport/http/CommonsHTTPSender.java
  
  Index: CommonsHTTPSender.java
  ===================================================================
  RCS file: /home/cvs/ws-axis/java/src/org/apache/axis/transport/http/CommonsHTTPSender.java,v
  retrieving revision 1.38
  retrieving revision 1.39
  diff -u -r1.38 -r1.39
  --- CommonsHTTPSender.java	15 Jun 2005 01:59:24 -0000	1.38
  +++ CommonsHTTPSender.java	30 Jul 2005 01:48:09 -0000	1.39
  @@ -27,9 +27,9 @@
   import org.apache.axis.handlers.BasicHandler;
   import org.apache.axis.soap.SOAP12Constants;
   import org.apache.axis.soap.SOAPConstants;
  +import org.apache.axis.utils.JavaUtils;
   import org.apache.axis.utils.Messages;
   import org.apache.axis.utils.NetworkUtils;
  -import org.apache.axis.utils.JavaUtils;
   import org.apache.commons.httpclient.Cookie;
   import org.apache.commons.httpclient.Credentials;
   import org.apache.commons.httpclient.Header;
  @@ -53,16 +53,19 @@
   import javax.xml.soap.MimeHeader;
   import javax.xml.soap.MimeHeaders;
   import javax.xml.soap.SOAPException;
  +import java.io.ByteArrayOutputStream;
   import java.io.FilterInputStream;
   import java.io.IOException;
   import java.io.InputStream;
   import java.io.OutputStream;
   import java.net.URL;
  +import java.util.ArrayList;
   import java.util.Hashtable;
   import java.util.Iterator;
   import java.util.Map;
   import java.util.StringTokenizer;
  -import java.util.ArrayList;
  +import java.util.zip.GZIPInputStream;
  +import java.util.zip.GZIPOutputStream;
   
   /**
    * This class uses Jakarta Commons's HttpClient to call a SOAP server.
  @@ -84,7 +87,7 @@
       protected HttpConnectionManager connectionManager;
       protected CommonsHTTPClientProperties clientProperties;
       boolean httpChunkStream = true; //Use HTTP chunking or not.
  -    
  +
       public CommonsHTTPSender() {
           initialize();
       }
  @@ -155,8 +158,13 @@
                   
                   addContextInfo(method, httpClient, msgContext, targetURL);
   
  -                ((PostMethod)method).setRequestEntity(
  -                                               new MessageRequestEntity(method, reqMessage, httpChunkStream));
  +                MessageRequestEntity requestEntity = null;
  +                if (msgContext.isPropertyTrue(HTTPConstants.MC_GZIP_REQUEST)) {
  +                	requestEntity = new GzipMessageRequestEntity(method, reqMessage, httpChunkStream);
  +                } else {
  +                	requestEntity = new MessageRequestEntity(method, reqMessage, httpChunkStream);
  +                }
  +                ((PostMethod)method).setRequestEntity(requestEntity);
               } else {
                   method = new GetMethod(targetURL.toString());
                   addContextInfo(method, httpClient, msgContext, targetURL);
  @@ -230,6 +238,22 @@
               InputStream releaseConnectionOnCloseStream = 
                   createConnectionReleasingInputStream(method);
   
  +            Header contentEncoding = 
  +            	method.getResponseHeader(HTTPConstants.HEADER_CONTENT_ENCODING);
  +            if (contentEncoding != null) {
  +            	if (contentEncoding.getValue().
  +            			equalsIgnoreCase(HTTPConstants.COMPRESSION_GZIP)) {
  +            		releaseConnectionOnCloseStream = 
  +            			new GZIPInputStream(releaseConnectionOnCloseStream);
  +            	} else {
  +                    AxisFault fault = new AxisFault("HTTP",
  +                            "unsupported content-encoding of '" 
  +                    		+ contentEncoding.getValue()
  +                            + "' found", null, null);
  +                    throw fault;
  +            	}
  +            		
  +            }
               Message outMsg = new Message(releaseConnectionOnCloseStream,
                                            false, contentType, contentLocation);
               // Transfer HTTP headers of HTTP message to MIME headers of SOAP message
  @@ -512,6 +536,16 @@
               httpClient.getState().setCredentials(AuthScope.ANY, proxyCred);
           }
           
  +        // add compression headers if needed
  +        if (msgContext.isPropertyTrue(HTTPConstants.MC_ACCEPT_GZIP)) {
  +        	method.addRequestHeader(HTTPConstants.HEADER_ACCEPT_ENCODING, 
  +        			HTTPConstants.COMPRESSION_GZIP);
  +        }
  +        if (msgContext.isPropertyTrue(HTTPConstants.MC_GZIP_REQUEST)) {
  +        	method.addRequestHeader(HTTPConstants.HEADER_CONTENT_ENCODING, 
  +        			HTTPConstants.COMPRESSION_GZIP);
  +        }
  +        
           // Transfer MIME headers of SOAPMessage to HTTP headers. 
           MimeHeaders mimeHeaders = msg.getMimeHeaders();
           if (mimeHeaders != null) {
  @@ -806,16 +840,18 @@
               }
           }
   
  +        protected boolean isContentLengthNeeded() {
  +        	return this.method.getParams().getVersion() == HttpVersion.HTTP_1_0 || !httpChunkStream;
  +        }
  +        
           public long getContentLength() {
  -            if (this.method.getParams().getVersion() == HttpVersion.HTTP_1_0 || !httpChunkStream) {
  +            if (isContentLengthNeeded()) {
                   try {
                       return message.getContentLength();
                   } catch (Exception e) {
  -                    return -1; /* -1 for chunked */
                   }
  -            } else {
  -                return -1; /* -1 for chunked */
  -            }
  +            } 
  +            return -1; /* -1 for chunked */
           }
   
           public String getContentType() {
  @@ -823,5 +859,42 @@
           }
           
       }
  +    
  +    private static class GzipMessageRequestEntity extends MessageRequestEntity {
  +
  +    	public GzipMessageRequestEntity(HttpMethodBase method, Message message) {
  +    		super(method, message);
  +        }
  +
  +        public GzipMessageRequestEntity(HttpMethodBase method, Message message, boolean httpChunkStream) {
  +        	super(method, message, httpChunkStream);
  +        }
  +        
  +        public void writeRequest(OutputStream out) throws IOException {
  +        	if (cachedStream != null) {
  +        		cachedStream.writeTo(out);
  +        	} else {
  +        		GZIPOutputStream gzStream = new GZIPOutputStream(out);
  +        		super.writeRequest(gzStream);
  +        		gzStream.finish();
  +        	}
  +        }
  +        
  +        public long getContentLength() {
  +        	if(isContentLengthNeeded()) {
  +        		ByteArrayOutputStream baos = new ByteArrayOutputStream();
  +        		try {
  +        			writeRequest(baos);
  +        			cachedStream = baos;
  +        			return baos.size();
  +        		} catch (IOException e) {
  +        			// fall through to doing chunked.
  +        		}
  +        	}
  +        	return -1; // do chunked 
  +        }
  +        
  +        private ByteArrayOutputStream cachedStream;
  +    }
   }
   
  
  
  
  1.29      +17 -1     ws-axis/java/src/org/apache/axis/transport/http/HTTPConstants.java
  
  Index: HTTPConstants.java
  ===================================================================
  RCS file: /home/cvs/ws-axis/java/src/org/apache/axis/transport/http/HTTPConstants.java,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- HTTPConstants.java	25 Feb 2004 14:02:45 -0000	1.28
  +++ HTTPConstants.java	30 Jul 2005 01:48:09 -0000	1.29
  @@ -72,7 +72,9 @@
       public static final String HEADER_ACCEPT_APPL_SOAP = "application/soap+xml";
       public static final String HEADER_ACCEPT_MULTIPART_RELATED = "multipart/related";
       public static final String HEADER_ACCEPT_APPLICATION_DIME = "application/dime";
  -    
  +    public static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
  +    public static final String HEADER_CONTENT_ENCODING = "Content-Encoding";
  +    public static final String COMPRESSION_GZIP = "gzip";
   
       /**
        * Cookie headers
  @@ -103,6 +105,20 @@
       public static String MC_HTTP_SERVLETLOCATION= "transport.http.servletLocation";
       public static String MC_HTTP_SERVLETPATHINFO= "transport.http.servletPathInfo";
   
  +
  +    /**
  +     * If you want the HTTP sender to indicate that it can accept a gziped 
  +     * response, set this message context property to true. The sender will
  +     * automatically unzip the response if its gzipped.
  +     */
  +    public static final String MC_ACCEPT_GZIP = "transport.http.acceptGzip";
  +    
  +    /**
  +     * by default the HTTP request body is not compressed. set this message
  +     * context property to true to have the request body gzip compressed.
  +     */
  +    public static final String MC_GZIP_REQUEST = "transport.http.gzipRequest";
  + 
       /**
        * @deprecated Should use javax.xml.rpc.Call.SOAPACTION_URI_PROPERTY instead.
        */