You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Nicolas Maujean <nm...@hotmail.com> on 2005/08/04 14:13:54 UTC

[HttpClient] : Classes and piece of code to compress a stream

Two classes which allow to compress the datas in a stream, and a piece of 
code to use them

import java.io.IOException;

import org.apache.commons.httpclient.HttpConnection;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.HttpRecoverableException;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.methods.PostMethod;

/**
* GZIPPostMethod
*
* <p>
* Titre : GZIPPostMethod
* </p>
*/
public class GZIPPostMethod
   extends PostMethod {

   /** Creates a new instance of GZIPAwarePostMethod */
   public GZIPPostMethod() {
       super();
   }

   /**
    * Constructor specifying a URI.
    *
    * @param uri
    *            either an absolute or relative URI
    *
    * @since 1.0
    */
   public GZIPPostMethod(String uri) {
       super(uri);
   }

   /**
    * Overrides method in {@link HttpMethodBase}.
    *
    * Notifies the server that we can process a GZIP-compressed response 
before sending the request.
    *
    * @param state
    * @param conn
    *
    * @return
    * @throws HttpException
    * @throws HttpRecoverableException
    * @throws IOException
    *
    */
   public int execute(HttpState state,
                      HttpConnection conn) throws HttpException, 
HttpRecoverableException, IOException {
       // Tell the server that we can handle GZIP-compressed data in the 
response body
       addRequestHeader("Content-Encoding", "gzip");

       return super.execute(state,
                            conn);
   }
}


/**
* GZIPRequestEntity
*
* <p>
* Titre : GZIPRequestEntity
* </p>
*/
public class GZIPRequestEntity
   implements RequestEntity {
   /**
    * Total de bytes transfere
    */
   long mTotal = 0;


   /**
    * The content length will be calculated automatically. This implies 
buffering of the content.
    */
   public static final int CONTENT_LENGTH_AUTO = -2;

   private long contentLength;

   private InputStream content;

   /** The buffered request body, if any. */
   private byte[] buffer = null;

   /** The content type */
   private String contentType;

   /**
    * Creates a new InputStreamRequestEntity with the given content and a 
content type of {@link #CONTENT_LENGTH_AUTO}.
    *
    * @param content
    *            The content to set.
    */
   public GZIPRequestEntity(InputStream content) {
       this(content,
            null);
   }

   /**
    * Creates a new InputStreamRequestEntity with the given content, content 
type, and a content length of
    * {@link #CONTENT_LENGTH_AUTO}.
    *
    * @param content
    *            The content to set.
    * @param contentType
    *            The type of the content, or <code>null</code>.
    */
   public GZIPRequestEntity(InputStream content,
                            String contentType) {
       this(content,
            CONTENT_LENGTH_AUTO,
            contentType);
   }

   /**
    * Creates a new InputStreamRequestEntity with the given content and 
content length.
    *
    * @param content
    *            The content to set.
    * @param contentLength
    *            The content size in bytes
    */
   public GZIPRequestEntity(InputStream content,
                            long contentLength) {
       this(content,
            contentLength,
            null);
   }

   /**
    * Creates a new InputStreamRequestEntity with the given content, content 
length, and content type.
    *
    * @param content
    *            The content to set.
    * @param contentLength
    *            The content size in bytes
    *
    * @param contentType
    *            The type of the content, or <code>null</code>.
    */
   public GZIPRequestEntity(InputStream content,
                            long contentLength,
                            String contentType) {
       if (content == null) {
           throw new IllegalArgumentException("The content cannot be null");
       }
       this.content = content;
       this.contentLength = contentLength;
       this.contentType = contentType;
   }

   /*
    * (non-Javadoc)
    *
    * @see 
org.apache.commons.httpclient.methods.RequestEntity#getContentType()
    */
   public String getContentType() {
       return contentType;
   }

   /**
    * Buffers request body input stream.
    */
   private void bufferContent() {

       if (this.buffer != null) {
           // Already been buffered
           return;
       }
       if (this.content != null) {
           try {
               ByteArrayOutputStream tmp = new ByteArrayOutputStream();
               byte[] data = new byte[4096];
               int l = 0;
               while ((l = this.content.read(data)) >= 0) {
                   System.out.println("buffer content l :" + l);
                   tmp.write(data,
                             0,
                             l);
               }
               this.buffer = tmp.toByteArray();
               this.content = null;
               this.contentLength = buffer.length;
           } catch (IOException e) {
               sLogger.debug(e.getMessage(),
                             e);
               this.buffer = null;
               this.content = null;
               this.contentLength = 0;
           }
       }
   }

   /**
    * Tests if this method is repeatable. Only <code>true</code> if the 
content has been buffered.
    *
    * @see #getContentLength()
    */
   public boolean isRepeatable() {
       return buffer != null;
   }

   /*
    * (non-Javadoc)
    *
    * @see 
org.apache.commons.httpclient.RequestEntity#writeRequest(java.io.OutputStream)
    */
   public void writeRequest(OutputStream out) throws IOException {

       GZIPOutputStream gzipOutputStream = new GZIPOutputStream(out);

       try {
           if (content != null) {
               byte[] tmp = new byte[4096];
               int nbreBytes = 0;

               nbreBytes = content.read(tmp);

               while (nbreBytes >= 0) {

                   gzipOutputStream.write(tmp,
                                          0,
                                          nbreBytes);
                   mTotal += nbreBytes;
                   nbreBytes = content.read(tmp);
               }

               gzipOutputStream.flush();
           } else if (buffer != null) {
               System.out.println("write buffer");
               gzipOutputStream.write(buffer);
           } else {
               throw new IllegalStateException("Content must be set before 
entity is written");
           }
       } finally {

           if (gzipOutputStream != null) {

               gzipOutputStream.close();
           }

           gzipOutputStream = null;
       }
   }

   /**
    * Gets the content length. If the content length has not been set, the 
content will be buffered to determine the
    * actual content length.
    */
   public long getContentLength() {
       if (contentLength == CONTENT_LENGTH_AUTO && buffer == null) {
           bufferContent();
       }
       return contentLength;
   }

   /**
    * @return Returns the content.
    */
   public InputStream getContent() {
       return content;
   }

   /**
    * Retourne le nombre de bytes transfere
    *
    * @return Nombre de bytes transfere
    */
   public long getNbreBytesTransfere() {

       return mTotal;
   }
}


Piece of code to use these classes :

       mFluxFichierSource = new BufferedInputStream(new 
FileInputStream(mFichierSource));
       // ignorer les parties avant l'offset et lire celles qui sont apres
       // l'offset
       mFluxFichierSource.skip(mOffsetDebut);

       GZIPPostMethod httppost = new GZIPPostMethod(mURL.toString());

       mGZIPRequestEntity = new GZIPRequestEntity(mFluxFichierSource);

       httppost.setRequestEntity(mGZIPRequestEntity);

       //httppost.setRequestBody(mFluxFichierSource);
       httppost.setContentChunked(true);

       HttpClient client = new HttpClient();

       client.executeMethod(httppost);

       if (httppost.getStatusCode() == HttpStatus.SC_OK) {

           sLogger.debug(httppost.getResponseBodyAsString());
       } else {

           sLogger.debug("Unexpected failure: " + httppost.getStatusLine()
               .toString());
       }

       httppost.releaseConnection();



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org