package org.mockserver.codec; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.QueryStringDecoder; import io.netty.handler.codec.http.cookie.*; import org.mockserver.mappers.ContentTypeMapper; import org.mockserver.model.*; import org.mockserver.model.Cookie; import org.mockserver.url.URLParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.nio.charset.Charset; import java.util.List; import java.util.Set; import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE; import static io.netty.handler.codec.http.HttpHeaderNames.COOKIE; import static io.netty.handler.codec.http.HttpUtil.isKeepAlive; import static org.mockserver.mappers.ContentTypeMapper.*; /** * @author jamesdbloom */ public class MockServerRequestDecoder extends MessageToMessageDecoder<FullHttpRequest> { private static final Logger logger = LoggerFactory.getLogger(MockServerRequestDecoder.class); private final boolean isSecure; public MockServerRequestDecoder(boolean isSecure) { this.isSecure = isSecure; } @Override protected void decode(ChannelHandlerContext ctx, FullHttpRequest fullHttpRequest, List<Object> out) { HttpRequest httpRequest = new HttpRequest(); if (fullHttpRequest != null) { setMethod(httpRequest, fullHttpRequest); QueryStringDecoder queryStringDecoder = new QueryStringDecoder(fullHttpRequest.uri()); setPath(httpRequest, queryStringDecoder); setQueryString(httpRequest, queryStringDecoder); setBody(httpRequest, fullHttpRequest); setHeaders(httpRequest, fullHttpRequest); setCookies(httpRequest, fullHttpRequest); httpRequest.withKeepAlive(isKeepAlive(fullHttpRequest)); httpRequest.withSecure(isSecure); } out.add(httpRequest); } private void setMethod(HttpRequest httpRequest, FullHttpRequest fullHttpResponse) { httpRequest.withMethod(fullHttpResponse.method().name()); } private void setPath(HttpRequest httpRequest, QueryStringDecoder queryStringDecoder) { httpRequest.withPath(URLParser.returnPath(queryStringDecoder.path())); } private void setQueryString(HttpRequest httpRequest, QueryStringDecoder queryStringDecoder) { try { httpRequest.withQueryStringParameters(queryStringDecoder.parameters()); } catch (IllegalArgumentException iae) { logger.debug("Exception while parsing query string", iae); } } private void setBody(HttpRequest httpRequest, FullHttpRequest fullHttpRequest) { if (fullHttpRequest.content() != null && fullHttpRequest.content().readableBytes() > 0) { byte[] bodyBytes = new byte[fullHttpRequest.content().readableBytes()]; fullHttpRequest.content().readBytes(bodyBytes); if (bodyBytes.length > 0) { if (ContentTypeMapper.isBinary(fullHttpRequest.headers().get(CONTENT_TYPE))) { httpRequest.withBody(new BinaryBody(bodyBytes)); } else { Charset requestCharset = determineCharsetForMessage(fullHttpRequest); httpRequest.withBody(new StringBody(new String(bodyBytes, requestCharset), DEFAULT_HTTP_CHARACTER_SET.equals(requestCharset) ? null : requestCharset)); } } } } private void setHeaders(HttpRequest httpRequest, FullHttpRequest fullHttpResponse) { HttpHeaders headers = fullHttpResponse.headers(); for (String headerName : headers.names()) { httpRequest.withHeader(new Header(headerName, headers.getAll(headerName))); } } private void setCookies(HttpRequest httpRequest, FullHttpRequest fullHttpResponse) { for (String cookieHeader : fullHttpResponse.headers().getAll(COOKIE)) { Set<io.netty.handler.codec.http.cookie.Cookie> decodedCookies = ServerCookieDecoder.LAX.decode(cookieHeader); for (io.netty.handler.codec.http.cookie.Cookie decodedCookie: decodedCookies) { httpRequest.withCookie(new Cookie( decodedCookie.name(), decodedCookie.value() )); } } } }