У меня установлен http-сервер netty 4.
public void start() {
System.out.println("In Start method");
try {
ServerBootstrap b = new ServerBootstrap();
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new HttpServerPipelineFactory())
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.WRITE_BUFFER_WATER_MARK, WriteBufferWaterMark.DEFAULT)
.childOption(ChannelOption.AUTO_READ, false)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture f = b.bind(listenerPort).sync();
System.out.println("server started listening on port " + listenerPort);
f.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
}
}
Класс фабрики конвейера HTTP - -
public class HttpServerPipelineFactory extends ChannelInitializer<Channel> {
@Override
protected void initChannel(Channel ch) {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("codec", new HttpServerCodec());
pipeline.addLast("compress", new HttpContentCompressor());
pipeline.addLast("decompress", new HttpContentDecompressor());
pipeline.addLast("aggregator", new HttpObjectAggregator( 512 * 1024));
pipeline.addLast("chunked", new ChunkedWriteHandler());
pipeline.addLast("flow", new FlowControlHandler());
pipeline.addLast("keep-alive", new HttpServerKeepAliveHandler());
pipeline.addLast("request", new HTTPRequestHandler());
}
}
HTTPRequestHandler - -
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH;
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
import static io.netty.util.CharsetUtil.UTF_8;
public class HTTPRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
private static Logger logger = LoggerFactory.getLogger(HTTPRequestHandler.class);
@Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) {
System.out.println("uri is " + request.uri());
String responseStr = request.method() +"/ Got request at " + request.uri();
System.out.println("body is \n" + request.content().toString(UTF_8));
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.copiedBuffer(responseStr.getBytes()), false);
response.headers().set(CONTENT_LENGTH, response.content().readableBytes());
ctx.channel().writeAndFlush(response);
ctx.read();
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
ctx.read();
}
}
Когда я отправить нормальный запрос, он работает нормально. Когда я отправляю сжатый gzip запрос, я получаю сообщение об ошибке -
io.netty.handler.code c .compression.DecompressionException: неподдерживаемый метод сжатия 0 в заголовке GZIP на io.netty.handler .code c .compression. .handler.code c .ByteToMessageDecoder. .code c .ByteToMessageDecoder.channelRead (ByteToMessageDecoder. java: 276) по адресу io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead (AbstractChannelHandlerContext. java: 365) на io.netty.channel.AbstractChannelHandlerContext.fireChannelRead (AbstractChannelHandler Context. java: 357) по адресу io.netty.channel.DefaultChannelPipeline $ HeadContext.channelRead (DefaultChannelPipeline. java: 1410) по адресу io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead (AbstractChannelHandlerConoxt): io9 * at9) atte. .netty.channel. . java: 343) в io.netty.handler.code c .http.HttpContentDecoder.decode (HttpContentDecoder. java: 254) в io.netty.handler.code c .http.HttpContentDecoder.decodeContent (HttpContentDecoder. java: 161) по адресу io.netty.handler.code c .http.HttpContentDecoder.decode (HttpContentDecoder. java: 150) по адресу io.netty.handler.code c .http.HttpContentDecoder .decode (HttpContentDecoder. java: 47) по адресу io.netty.handler.code c .MessageToMessageDecoder.channelRead (MessageToMessageDecoder. java: 8 8) по адресу io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead (AbstractChannelHandlerContext. java: 379) по адресу io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead (AbstractChannelHandlerConhannel.Channel.Chent. (AbstractChannelHandlerContext. java: 357) на io.netty.handler.code c .MessageToMessageDecoder.channelRead (MessageToMessageDecoder. java: 102) на io.netty.handler.code c .MessageToMessageCode. channelRead (MessageToMessageCode c. java: 111) по адресу io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead (AbstractChannelHandlerContext. java: 379) по адресу io.netty.channel.AbstractChannelHandlerContek .InteContext. ) в io.netty.channel.AbstractChannelHandlerContext.fireChannelRead (AbstractChannelHandlerContext. java: 357) в io.netty.channel.CombinedChannelDuplexHandler $ DelegatingChannelHandlerContext.fireChannelRead (CombinedChannelRead (CombinedChannelDad *) 65 *: 436) по адресу io.netty.handler.code c .ByteToMessageDecoder.fireChannelRead (ByteToMessageDecoder. java: 321) по адресу io.netty.handler.code c .ByteToMessageDecoder.channelMess * 10 *. : 295) по адресу io.netty.channel.CombinedChannelDuplexHandler.channelRead (CombinedChannelDuplexHandler. java: 251) по адресу io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead (AbstractChannelHandlerContext.Net.chante. invokeChannelRead (AbstractChannelHandlerContext. java: 365) по адресу io.netty.channel.AbstractChannelHandlerContext.fireChannelRead (AbstractChannelHandlerContext. java: 357) по адресу io.netty.channel.DefaultChannelPipeline $ HeadContext.channelRead (DefaultChannelPipeline. java: 1410) по адресу io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead (AbstractChannelHandlerConteo.net: at 10) * 10) * .channel.AbstractChannelHandlerContext.invokeChannelRead (AbstractChannelHandlerContext. java: 365) по адресу io.netty.channel.DefaultChannelPipeline.fireChannelRead (DefaultChannelPipeline. java: 919) по адресу io.netty.neltehannioBeanNeBeNeNeBeNeNeBeNeNeBeNeNeBeNeNeBeNeBeNeBeNeNeBeB . java: 163) на io.netty.channel.nio.NioEventL oop .processSelectedKey (NioEventL oop. java: 714) на io.netty.channel.nio.NioEventL oop .processSelectedKeysOptimized ( NioEventL oop. java: 650) на io.netty.channel.nio.NioEventL oop .processSelectedKeys (NioEventL oop. java: 576) на io.netty.channel.nio.NioEventL oop .run (NioEventL oop. java: 493) на io.netty.util.concurrent.SingleThreadEventExecutor $ 4.run (SingleThreadEventExecutor. java: 989) на io.netty.util.internal.Th readExecutorMap $ 2.run (ThreadExecutorMap. java: 74) на io.netty.util.concurrent.FastThreadLocalRunnable.run (FastThreadLocalRunnable. java: 30) на java .lang.Thread.run (Thread. java). : 748)
Пример запроса: -
curl --location --request POST 'http://localhost:5880/' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'Accept-Encoding: gzip' \
--header 'Accept-Language: en-US,en;q=0.9' \
--header 'Connection: Keep-Alive' \
--header 'Content-Encoding: gzip' \
--header 'Content-Type: text/plain' \
--data-raw '�VP*I-.QR�R0T���-!'
Полезная нагрузка запроса '�VP * I-.QR�R0T���-!' такое сжатие Gzip строки "{ \"test\" : 1 }"
с использованием приведенной ниже логики c -
public static byte[] compress(String str) throws Exception {
if (str == null || str.length() == 0) {
return null;
}
System.out.println("String length : " + str.length());
ByteArrayOutputStream obj=new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(obj, 2);
gzip.write(str.getBytes("UTF-8"));
gzip.close();
return obj.toByteArray();
}
Как правильно настроить декомпрессию Http на сервере netty?