/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.filters;
import java.io.IOException;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
/**
* A response stream that figures out whether or not to compress the output
* just before the first write. The decision is based on the mimetype set
* for the output request.
*
* @author David Winslow <dwinslow@openplans.org>
*/
public class AlternativesResponseStream extends ServletOutputStream {
HttpServletResponse myResponse;
ServletOutputStream myStream;
Set myCompressibleTypes;
Logger logger = org.geotools.util.logging.Logging.getLogger("org.geoserver.filters");
int contentLength;
public AlternativesResponseStream(HttpServletResponse response, Set compressible, int contentLength) throws IOException {
super();
myResponse = response;
myCompressibleTypes = compressible;
this.contentLength = contentLength;
}
public void close() throws IOException {
if (isDirty())
getStream().close();
}
public void flush() throws IOException {
if (isDirty())
getStream().flush();
}
public void write(int b) throws IOException {
getStream().write(b);
}
public void write(byte b[]) throws IOException {
getStream().write(b);
}
public void write(byte b[], int off, int len) throws IOException {
getStream().write(b, off, len);
}
protected ServletOutputStream getStream() throws IOException{
if (myStream != null) return myStream;
String type = myResponse.getContentType();
// if (type == null){
// logger.warning("Mime type was not set before first write!");
// }
if (type != null && isCompressible(type)){
logger.log(Level.FINE, "Compressing output for mimetype: {0}", type);
myResponse.addHeader("Content-Encoding", "gzip");
myStream = new GZIPResponseStream(myResponse);
} else {
logger.log(Level.FINE, "Not compressing output for mimetype: {0}", type);
if(contentLength >= 0) {
myResponse.setContentLength(contentLength);
}
myStream = myResponse.getOutputStream();
}
return myStream;
}
protected boolean isDirty(){
return myStream != null;
}
protected boolean isCompressible(String mimetype){
String stripped = stripParams(mimetype);
Iterator it = myCompressibleTypes.iterator();
while (it.hasNext()){
Pattern pat = (Pattern)it.next();
Matcher matcher = pat.matcher(stripped);
if (matcher.matches()) return true;
}
return false;
}
protected String stripParams(String mimetype){
int firstSemicolon = mimetype.indexOf(";");
if (firstSemicolon != -1){
return mimetype.substring(0, firstSemicolon);
}
return mimetype;
}
}