package restx.http;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import restx.*;
import restx.factory.Component;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPOutputStream;
/**
* A filter to automatically gzip responses when supported by the client.
*
* You need to @Provide it to enable it, it's not activated by default.
*/
public class GzipFilter implements RestxFilter, RestxHandler {
private final ImmutableCollection<RestxRequestMatcher> matchers;
public GzipFilter(HttpSettings httpSettings) {
ImmutableList.Builder<RestxRequestMatcher> builder = ImmutableList.builder();
for (String path : httpSettings.gzipPaths()) {
builder.add(new StdRestxRequestMatcher("GET", path));
}
matchers = builder.build();
}
@Override
public Optional<RestxHandlerMatch> match(RestxRequest request) {
Optional<String> enc = request.getHeader("Accept-Encoding");
if (!enc.isPresent()) {
return Optional.absent();
}
if (!acceptsGzip(enc.get())) {
return Optional.absent();
}
for (RestxRequestMatcher matcher : matchers) {
Optional<? extends RestxRequestMatch> match = matcher.match(request.getHttpMethod(), request.getRestxPath());
if (match.isPresent()) {
return Optional.of(new RestxHandlerMatch(match.get(), this));
}
}
return Optional.absent();
}
protected boolean acceptsGzip(String acceptsEncoding) {
if ("*".equals(acceptsEncoding)) {
return true;
}
for (String s : acceptsEncoding.split(",")) {
if (s.trim().startsWith("gzip")) {
return true;
}
}
return false;
}
@Override
public void handle(RestxRequestMatch restxRequestMatch, RestxRequest restxRequest, RestxResponse restxResponse,
RestxContext restxContext) throws IOException {
try {
restxContext.nextHandlerMatch().handle(restxRequest, new RestxResponseWrapper(restxResponse) {
private GZIPOutputStream gzipOutputStream;
@Override
public OutputStream getOutputStream() throws IOException {
setHeader("Content-Encoding", "gzip");
return gzipOutputStream = new GZIPOutputStream(super.getOutputStream());
}
@Override
public void close() throws Exception {
if (gzipOutputStream != null) {
try {
gzipOutputStream.close();
} finally {
gzipOutputStream = null;
}
}
super.close();
}
}, restxContext);
} finally {
}
}
}