cocoon-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Carmona Perez, David" <DPerez...@fcc.es>
Subject Gzip pipeline processor
Date Tue, 13 Jan 2004 11:52:08 GMT
Hi everybody,

I've created a new ProcessingPipeline, in order to compress with gzip.  I want finer control
and integration with Cocoon that the standard servlet filters may offer.

It works ok, but the problem I have with it, is that the browser is terribly slow when getting
the different components of a page (images, CSS sheets, scripts, ...).  
Does someone know if there is any detail I have left off?  
I suspect of not flushing the ouput stream.  Where is it flushed or closed?

Any help will be greatly appreciated.

Here is the full source code:

/** Creado en 12-ene-2004 */
package fcc.ima.cocoon;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.SocketException;
import java.util.Map;
import java.util.zip.GZIPOutputStream;

import org.apache.cocoon.ConnectionResetException;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.components.pipeline.impl.NonCachingProcessingPipeline;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Response;

/**Pipeline that may compress the content with gzip.
 * @author dperezcar */
public class GzipNonCachingProcessingPipeline extends NonCachingProcessingPipeline {
	static protected class StreamHandler {
		protected OutputStream getStream(Environment environment, int outputBufferSize, boolean
shouldSetContentLength) throws IOException {
			// Copy parameters
			this.environment = environment;

			OutputStream result;
			if (shouldSetContentLength) {
				bufferStream = new ByteArrayOutputStream();
				if (shouldCompress()) {
					result = gs = new GZIPOutputStream(bufferStream);
				} else {
					result = bufferStream;
				}
			} else {
				if (shouldCompress()) {
					result = gs = new GZIPOutputStream(environment.getOutputStream(0));
				} else {
					result = environment.getOutputStream(outputBufferSize);
				}
			}
			if (gs != null) {
				Response resp = ObjectModelHelper.getResponse(environment.getObjectModel());
				resp.addHeader("Content-Encoding", "gzip");
			}
			return result;
		}
		protected void end() throws IOException { 
			if (gs != null) {
				gs.finish();
			}
			if (bufferStream != null) {
				byte[] data = bufferStream.toByteArray();
				environment.setContentLength(data.length);
				OutputStream out = environment.getOutputStream(0);
				out.write(data);
				out.flush();
				out.close();
			} else if (gs != null) {
				gs.flush();
				gs.close();
			}
		}
		protected boolean shouldCompress() {
			Map objModel = environment.getObjectModel();
			Request req = ObjectModelHelper.getRequest(objModel);
			if (req != null) {
				String ae = req.getHeader("accept-encoding");
				if (ae != null && ae.indexOf("gzip") != -1) {
					Response resp = ObjectModelHelper.getResponse(objModel);
					if (resp != null && !resp.containsHeader("content-encoding")) {
						//getLogger().debug("GZIP supported, compressing.");
						return true;
					} else {
						//getLogger().debug("Content-encoding already set.");
					}
				}
			}
			return false;
		}
		protected Environment environment;
		protected ByteArrayOutputStream bufferStream;
		protected GZIPOutputStream gs;
	}
	/** @see org.apache.cocoon.components.pipeline.AbstractProcessingPipeline#processReader(org.apache.cocoon.environment.Environment)
*/
	protected boolean processReader(Environment environment) throws ProcessingException {
		try {
			getLogger().info("Ini reader");
			StreamHandler sh = new StreamHandler();
			reader.setOutputStream(sh.getStream(environment, outputBufferSize, reader.shouldSetContentLength()));
			reader.generate();
			sh.end();
			getLogger().info("End reader");
		} catch ( SocketException se ) {
			if (se.getMessage().indexOf("reset") > 0
					|| se.getMessage().indexOf("aborted") > 0
					|| se.getMessage().indexOf("connection abort") > 0) {
				throw new ConnectionResetException("Connection reset by peer", se);
			} else {
				throw new ProcessingException("Failed to execute reader pipeline.", se);
			}
		} catch ( ProcessingException e ) {
			throw e;
		} catch ( Exception e ) {
			throw new ProcessingException("Error executing reader pipeline.",e);
		}
		return true;
	}

	/** @see org.apache.cocoon.components.pipeline.AbstractProcessingPipeline#processXMLPipeline(org.apache.cocoon.environment.Environment)
*/
	protected boolean processXMLPipeline(Environment environment) throws ProcessingException
{
		try {
			getLogger().info("Ini XML");
			if (this.serializer != this.lastConsumer) {
				// internal processing
				this.generator.generate();
			} else {
				StreamHandler sh = new StreamHandler();
				serializer.setOutputStream(sh.getStream(environment, outputBufferSize, serializer.shouldSetContentLength()));
				// execute the pipeline:
				generator.generate();
				sh.end();
			}
			getLogger().info("End XML");
		} catch ( ProcessingException e) {
			throw e;
		} catch ( Exception e ) {
			throw new ProcessingException("Failed to execute pipeline.", e);
		}
		return true;
	}
}



--------
David


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
For additional commands, e-mail: users-help@cocoon.apache.org


Mime
View raw message