package com.ctriposs.baiji.rpc.server.netty;
import com.ctriposs.baiji.rpc.server.HttpRequestRouter;
import com.ctriposs.baiji.rpc.server.HttpResponseWrapper;
import com.ctriposs.baiji.rpc.server.RequestContext;
import com.google.common.base.Preconditions;
import io.netty.buffer.ByteBufInputStream;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.SocketException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
public class ServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
private static final Logger _logger = LoggerFactory.getLogger(ServerHandler.class);
private final HttpRequestRouter _requestRouter;
public ServerHandler(HttpRequestRouter requestRouter) {
super(true);
Preconditions.checkNotNull(requestRouter, "Request router can not be null.");
_requestRouter = requestRouter;
}
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, FullHttpRequest fullHttpRequest) throws Exception {
RequestContext requestContext = createRequestContext(fullHttpRequest);
HttpResponseWrapper responseWrapper = createResponseWrapper(channelHandlerContext, fullHttpRequest);
_requestRouter.process(requestContext, responseWrapper);
}
@Override
public void channelReadComplete(final ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (cause instanceof SocketException) {
// SocketExceptions are normal, ignore them
} else {
_logger.warn("Exception caught in netty handler.", cause);
}
}
private RequestContext createRequestContext(FullHttpRequest request) throws URISyntaxException {
RequestContext context = new RequestContext();
context.RequestBody = new ByteBufInputStream(request.content());
if (request.headers() != null) {
context.RequestHeaders = new HashMap<String, String>();
for (Map.Entry<String, String> headerEntry : request.headers()) {
context.RequestHeaders.put(headerEntry.getKey(), headerEntry.getValue());
}
}
context.RequestMethod = request.getMethod().name();
URI uri = new URI(request.getUri());
context.RequestPath = uri.getPath();
context.RequestProtocol = request.getProtocolVersion().toString();
context.RequestQueryString = uri.getQuery();
context.RequestScheme = uri.getScheme();
return context;
}
private HttpResponseWrapper createResponseWrapper(ChannelHandlerContext channelHandlerContext, FullHttpRequest fullHttpRequest) {
return new NettyHttpResponseWrapper(channelHandlerContext, fullHttpRequest);
}
}