Skip to content

Instantly share code, notes, and snippets.

@mnadel
Created February 22, 2014 18:32
Show Gist options
  • Save mnadel/9159626 to your computer and use it in GitHub Desktop.
Save mnadel/9159626 to your computer and use it in GitHub Desktop.
Netty HTTP Server
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.Charset;
import static io.netty.handler.codec.http.HttpHeaders.Names.*;
import static io.netty.handler.codec.http.HttpHeaders.is100ContinueExpected;
import static io.netty.handler.codec.http.HttpHeaders.isKeepAlive;
import static io.netty.handler.codec.http.HttpResponseStatus.CONTINUE;
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
public class RequestHandler extends ChannelInboundHandlerAdapter {
private static final Logger log = LoggerFactory.getLogger(RequestHandler.class);
private static final Charset UTF8 = Charset.forName("UTF-8");
public RequestHandler() {
log.trace("Created handler: {}", this.hashCode());
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
log.trace("Handler {} got: {}", this.hashCode(), msg.getClass());
if (msg instanceof DefaultHttpRequest) {
HttpRequest req = (DefaultHttpRequest) msg;
log.debug("Got request: {}", msg);
if (is100ContinueExpected(req)) {
ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE));
}
String resp = "Hello world!";
FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(resp.getBytes(UTF8)));
res.headers().set(CONTENT_TYPE, "text/plain");
res.headers().set(CONTENT_LENGTH, res.content().readableBytes());
if (isKeepAlive(req)) {
res.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
ctx.write(res);
} else {
ctx.write(res).addListener(ChannelFutureListener.CLOSE);
}
}
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
log.error("Crap!", cause);
ctx.close();
}
}
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpServerCodec;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.Options;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Server {
private static final Logger log = LoggerFactory.getLogger(Server.class);
private int port;
public Server(int port) {
this.port = port;
}
public void run() throws Exception {
EventLoopGroup masterGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(masterGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast("codec", new HttpServerCodec());
ch.pipeline().addLast("handler", new RequestHandler());
}
})
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture f = b.bind(port).sync();
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
masterGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
Options opts = new Options();
opts.addOption("p", "port", true, "Listen port (default: 8080)");
CommandLineParser parser = new GnuParser();
CommandLine cmd = parser.parse(opts, args);
int port = Integer.parseInt(cmd.getOptionValue("port", "8080"));
new Server(port).run();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment