/* * Copyright 2012 The Solmix Project * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.gnu.org/licenses/ * or see the FSF site: http://www.fsf.org. */ package org.solmix.web.compression; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.io.PrintWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.solmix.api.context.WebContext; import org.solmix.api.interfaces.CompressionService; import org.solmix.web.ServletTools; /** * * @author solmix.f@gmail.com * @version $Id$ 2011-6-7 */ public class CompressionServiceImpl implements CompressionService { private static final Logger log = LoggerFactory.getLogger(CompressionServiceImpl.class.getName()); public ByteArrayOutputStream wrapBuf; public OutputStream servletOutputStream; public boolean compressing; /** * {@inheritDoc} * * @see org.solmix.services.interfaces.SingletonInstance#staticInstance() */ @Override public Object staticInstance() throws Exception { return new CompressionServiceImpl(); } /** * {@inheritDoc} * * @see org.solmix.services.interfaces.CompressionService#canCompress(java.lang.Object) */ @Override public boolean canCompress(Object requestContext) { WebContext context = (WebContext)requestContext; return ServletTools.compressionEnabled() && ServletTools.browserClaimsGZSupport(context.getRequest())/* && !ServletTools.contextIsIncluded(context)*/; } /** * {@inheritDoc} * * @see org.solmix.services.interfaces.CompressionService#compressIfPossible(java.lang.Object) */ @Override public boolean compressIfPossible(Object requestContext) throws Exception { WebContext context = (WebContext)requestContext; if(!canCompress(context)) return false; try { servletOutputStream = context.getResponse().getOutputStream(); } catch(Exception exception) { String s = context.getRequestPath() + ": "; log.error(s + "Can't compress response because the servlet output stream is already in use: " + exception.toString()); return false; } wrapBuf = new ByteArrayOutputStream(); context.setOut(new PrintWriter(wrapBuf)); compressing = true; return true; } /** * {@inheritDoc} * * @see org.solmix.services.interfaces.CompressionService#completeResponse(java.lang.Object) */ @Override public void completeResponse(Object requestContext) throws Exception { WebContext context = (WebContext)requestContext; if(!compressing) return; try { context.getOut().flush(); } catch(Exception _ex) { } try { context.getOut().close(); } catch(Exception _ex) { } compressAndSend(context, wrapBuf); } /** * {@inheritDoc} * * @see org.solmix.services.interfaces.CompressionService#compressAndSend(java.lang.Object, java.io.ByteArrayOutputStream) */ @Override public void compressAndSend(Object requestContext, ByteArrayOutputStream byteArrayOutputStream)throws Exception { compressAndSend(requestContext, byteArrayOutputStream, -1); } /** * {@inheritDoc} * * @see org.solmix.services.interfaces.CompressionService#compressAndSend(java.lang.Object, java.io.ByteArrayOutputStream, int) */ @Override public void compressAndSend(Object requestContext, ByteArrayOutputStream byteArrayOutputStream, int size) throws Exception { WebContext context = (WebContext)requestContext; String s = context.getRequestPath() + ": "; if(servletOutputStream == null) servletOutputStream = context.getResponse().getOutputStream(); if(size == -1) size =250; // if(i == -1) // i = config.getInt("compressionFilter.compressThreshold", 250); if(byteArrayOutputStream.size() < size && (!ServletTools.IENeedsToSeeACompressedPage(context) || context.getRequest().getContentType() == null || context.getRequest().getContentType().indexOf("text/html") == -1)) { log.debug(s + "Result data size of " + byteArrayOutputStream.size() + " bytes is less than set threshold of " + size + " bytes - not compressing"); byteArrayOutputStream.writeTo(servletOutputStream); try { servletOutputStream.flush(); } catch(Exception _ex) { } try { context.getResponse().flushBuffer(); } catch(Exception _ex) { } return; } ByteArrayOutputStream bytearrayoutputstream1 = (new CompressionImpl()).compressBuffer(byteArrayOutputStream, context.getRequest().getContentType()); log.info(s + byteArrayOutputStream.size() + " -> " + bytearrayoutputstream1.size() + " bytes"); context.getResponse().setHeader("Content-Encoding", "gzip"); if(!ServletTools.compressionReadyCookieIsSet(context)) ServletTools.setCompressionReadyCookie(context); context.getResponse().setContentLength(bytearrayoutputstream1.size()); bytearrayoutputstream1.writeTo(servletOutputStream); try { servletOutputStream.flush(); } catch(Exception _ex) { } try { context.getResponse().flushBuffer(); } catch(Exception _ex) { } } }