package org.yamcs.web; import java.util.List; import org.yamcs.api.MediaType; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPromise; import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpChunkedInput; import io.netty.handler.codec.http.HttpContentCompressor; import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpHeaderValues; import io.netty.handler.codec.http.HttpObject; import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpResponse; /** * Better version of {@link HttpContentCompressor}. Netty's HttpContentCompressor fails for chunked writes * <p> * The main reason for compressing is that it significantly reduces size of textual api responses (json), which are * being used more often than protobuf these days. * <p> * Should be revisited with Netty upgrades, to see if this workaround is still needed. * * @see <a href="http://stackoverflow.com/questions/20136334/netty-httpstaticfileserver-example-not-working-with-httpcontentcompressor"> this post</a> */ public class SmartHttpContentCompressor extends HttpContentCompressor { private static final int MIN_COMPRESSABLE_CONTENT_LENGTH = 1024; /* @Override protected void decode(ChannelHandlerContext ctx, HttpRequest msg, List<Object> out) throws Exception { System.out.println("================ dencoding http message "+msg); super.decode(ctx, msg, out); } @Override protected void encode(ChannelHandlerContext ctx, HttpObject msg, List<Object> out) throws Exception { System.out.println("=============== encoding http message "+msg); super.encode(ctx, msg, out); } @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { System.out.println("=============== writing msg: "+msg); if(msg instanceof HttpChunkedInput) { System.out.println("length of chunk is "+((HttpChunkedInput)msg).length()); } super.write(ctx, msg, promise); } */ @Override protected Result beginEncode(HttpResponse res, String acceptEncoding) throws Exception { Result r = super.beginEncode(res, acceptEncoding); System.out.println("in smart compressor returning: "+r.contentEncoder()+" with handlers "); return r; /* if (!(res instanceof FullHttpResponse)) { if (!HttpHeaderValues.CHUNKED.equals(res.headers().get(HttpHeaderNames.TRANSFER_ENCODING))) { return null; } } String contentType = res.headers().get(HttpHeaderNames.CONTENT_TYPE); if (MediaType.PROTOBUF.is(contentType)) { // Already compressed return null; } // If the content length is less than 1 kB but known, skip compression if (res.headers().contains(HttpHeaderNames.CONTENT_LENGTH)) { int contentLength = Integer.parseInt(res.headers().get(HttpHeaderNames.CONTENT_LENGTH)); if (contentLength > 0 && contentLength < MIN_COMPRESSABLE_CONTENT_LENGTH) { return null; } } System.out.println("starting encdoing :"+acceptEncoding); return super.beginEncode(res, acceptEncoding);*/ } }