package netty;
import static io.netty.handler.codec.http.HttpHeaderNames.CONNECTION;
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH;
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE;
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
import static org.jboss.netty.handler.codec.http.HttpHeaders.Values.KEEP_ALIVE;
import com.alibaba.fastjson.JSON;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.HttpServerExpectContinueHandler;
import io.netty.handler.codec.http.HttpUtil;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslHandler;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import lombok.Cleanup;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
/**
* Test
*
* @author xfyou
*/
public class Test {
@SneakyThrows
public static void main(String[] args) {
HttpServer server = new HttpServer(8080);
server.start();
}
@RequiredArgsConstructor
private static class HttpServer {
private final Integer port;
@SneakyThrows
public void start() {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup(20);
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializerImpl());
ChannelFuture future = serverBootstrap.bind(port).sync();
System.out.println("Server started...");
future.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
private static final class ChannelInitializerImpl extends ChannelInitializer<Channel> {
private final SslContext sslContext;
@SneakyThrows
public ChannelInitializerImpl() {
sslContext = createSslContext();
}
@SneakyThrows
private SslContext createSslContext() {
String keyStoreFilePath = "/root/.ssl/test.pkcs12";
String keyStorePassword = "passwd";
KeyStore keyStore = KeyStore.getInstance("PKCS12");
@Cleanup InputStream inputStream = new FileInputStream(keyStoreFilePath);
keyStore.load(inputStream, keyStorePassword.toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, keyStorePassword.toCharArray());
return SslContextBuilder.forServer(keyManagerFactory).build();
}
@Override
protected void initChannel(Channel ch) {
ChannelPipeline cp = ch.pipeline();
// support SSL/TLS
cp.addLast(new SslHandler(sslContext.newEngine(ch.alloc())));
// decode and encode
cp.addLast(new HttpServerCodec());
// handle message-body of POST
cp.addLast(new HttpObjectAggregator(Integer.MAX_VALUE));
cp.addLast(new HttpServerExpectContinueHandler());
cp.addLast(new SimpleChannelInboundHandler<FullHttpRequest>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) {
System.out.println(msg.content().toString(StandardCharsets.UTF_8));
System.out.println(ch);
String res = "I am OK";
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(JSON.toJSONString(res).getBytes(StandardCharsets.UTF_8)));
response.headers().set(CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON);
response.headers().set(CONTENT_LENGTH, response.content().readableBytes());
if (HttpUtil.isKeepAlive(msg)) {
response.headers().set(CONNECTION, KEEP_ALIVE);
ctx.writeAndFlush(response);
} else {
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
}
ctx.flush();
}
});
}
}
}