package org.jboss.resteasy.plugins.server.netty; import static io.netty.handler.codec.http.HttpHeaders.is100ContinueExpected; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.handler.codec.http.HttpContent; import io.netty.handler.codec.http.HttpHeaders; import java.util.List; import org.jboss.resteasy.core.SynchronousDispatcher; import org.jboss.resteasy.plugins.server.netty.i18n.LogMessages; import org.jboss.resteasy.plugins.server.netty.i18n.Messages; import org.jboss.resteasy.specimpl.ResteasyHttpHeaders; import org.jboss.resteasy.spi.ResteasyUriInfo; /** * This {@link MessageToMessageDecoder} is responsible for decode {@link io.netty.handler.codec.http.HttpRequest} * to {@link NettyHttpRequest}'s * * This implementation is {@link Sharable} * * @author Norman Maurer * */ @Sharable public class RestEasyHttpRequestDecoder extends MessageToMessageDecoder<io.netty.handler.codec.http.HttpRequest> { private final SynchronousDispatcher dispatcher; private final String servletMappingPrefix; private final String proto; public enum Protocol { HTTPS, HTTP } public RestEasyHttpRequestDecoder(SynchronousDispatcher dispatcher, String servletMappingPrefix, Protocol protocol) { this.dispatcher = dispatcher; this.servletMappingPrefix = servletMappingPrefix; if (protocol == Protocol.HTTP) { proto = "http"; } else { proto = "https"; } } @Override protected void decode(ChannelHandlerContext ctx, io.netty.handler.codec.http.HttpRequest request, List<Object> out) throws Exception { boolean keepAlive = HttpHeaders.isKeepAlive(request); final NettyHttpResponse response = new NettyHttpResponse(ctx, keepAlive, dispatcher.getProviderFactory(), request.method()); final ResteasyHttpHeaders headers; final ResteasyUriInfo uriInfo; try { headers = NettyUtil.extractHttpHeaders(request); uriInfo = NettyUtil.extractUriInfo(request, servletMappingPrefix, proto); NettyHttpRequest nettyRequest = new NettyHttpRequest(ctx, headers, uriInfo, request.getMethod().name(), dispatcher, response, is100ContinueExpected(request) ); if (request instanceof HttpContent) { HttpContent content = (HttpContent) request; ByteBuf byteBuf = content.content(); // Does the request contain a body that will need to be retained if(byteBuf.readableBytes() > 0) { ByteBuf buf = byteBuf.retain(); nettyRequest.setContentBuffer(buf); } out.add(nettyRequest); } } catch (Exception e) { response.sendError(400); // made it warn so that people can filter this. LogMessages.LOGGER.warn(Messages.MESSAGES.failedToParseRequest(), e); } } }