/* * Copyright 2012 The Netty Project * * The Netty Project licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package org.ireland.jnetty; import io.netty.buffer.ByteBuf; import io.netty.buffer.PooledByteBufAllocator; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundMessageHandlerAdapter; import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.DecoderResult; import io.netty.handler.codec.http.Cookie; import io.netty.handler.codec.http.CookieDecoder; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.DefaultHttpResponse; import io.netty.handler.codec.http.FullHttpMessage; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpContent; import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpObject; import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.LastHttpContent; import io.netty.handler.codec.http.QueryStringDecoder; import io.netty.handler.codec.http.ServerCookieEncoder; import io.netty.util.CharsetUtil; import java.io.IOException; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import javax.servlet.ServletException; import org.ireland.jnetty.http.HttpServletRequestImpl; import org.ireland.jnetty.http.HttpServletResponseImpl; import org.ireland.jnetty.webapp.RequestDispatcherImpl; import org.ireland.jnetty.webapp.WebApp; import static io.netty.handler.codec.http.HttpHeaders.Names.*; import static io.netty.handler.codec.http.HttpHeaders.*; import static io.netty.handler.codec.http.HttpResponseStatus.*; import static io.netty.handler.codec.http.HttpVersion.*; /** * HttpHandler是无状态的,故标记为@Sharable,可让所有ChannelPipeline共享 * * @author KEN * */ @Sharable public class HttpHandler extends ChannelInboundMessageHandlerAdapter<FullHttpMessage> { private final WebApp webApp; public HttpHandler(WebApp webApp) { this.webApp = webApp; } @Override public void messageReceived(ChannelHandlerContext ctx, FullHttpMessage message) throws Exception { if (message instanceof FullHttpRequest) { FullHttpRequest request = (FullHttpRequest) message; if (is100ContinueExpected(request)) { send100Continue(ctx); } //TODO: UnpooledHeapByteBuf 是基于内存复制 来扩展容量的,这里可以改为 (池化 + 增量 组合模式) 来优化 FullHttpResponse response = new DefaultFullHttpResponse(request.getProtocolVersion(), OK, PooledByteBufAllocator.DEFAULT.directBuffer(0)); handle(ctx, request, response); // flush(ctx, request,response); need flush?? } } private void handle(ChannelHandlerContext ctx, FullHttpRequest fullHttpRequest, FullHttpResponse fullHttpResponse) throws ServletException, IOException { HttpServletResponseImpl response = new HttpServletResponseImpl(webApp,(SocketChannel) ctx.channel(), ctx, fullHttpResponse, fullHttpRequest); HttpServletRequestImpl request = new HttpServletRequestImpl(webApp, webApp, (SocketChannel) ctx.channel(), ctx, fullHttpResponse, fullHttpRequest,response); response.setHttpServletRequest(request); // String rawUri = fullHttpRequest.getUri(); dispatch(rawUri, request, response); } /** * * @param rawContextUri * 带参数的uri(带参数(?)) * @param request * @param response * @throws IOException * @throws ServletException */ private void dispatch(String rawContextUri, HttpServletRequestImpl request, HttpServletResponseImpl response) throws ServletException, IOException { RequestDispatcherImpl dispatcher = webApp.getRequestDispatcher(rawContextUri); dispatcher.dispatch(request, response); } private static void send100Continue(ChannelHandlerContext ctx) { HttpResponse response = new DefaultHttpResponse(HTTP_1_1, CONTINUE); ctx.nextOutboundMessageBuffer().add(response); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } }