Example usage for io.netty.handler.codec.http HttpHeaderNames REFERER

List of usage examples for io.netty.handler.codec.http HttpHeaderNames REFERER

Introduction

In this page you can find the example usage for io.netty.handler.codec.http HttpHeaderNames REFERER.

Prototype

AsciiString REFERER

To view the source code for io.netty.handler.codec.http HttpHeaderNames REFERER.

Click Source Link

Document

"referer"

Usage

From source file:ccwihr.client.t1.HttpUploadClient.java

License:Apache License

/**
 * Standard usage of HTTP API in Netty without file Upload (get is not able
 * to achieve File upload due to limitation on request size).
 *
 * @return the list of headers that will be used in every example after
 **///from  w w  w  . j a  va  2s.  c  o  m
private static List<Entry<String, String>> formget(Bootstrap bootstrap, String host, int port, String get,
        URI uriSimple) throws Exception {
    // XXX /formget
    // No use of HttpPostRequestEncoder since not a POST
    Channel channel = bootstrap.connect(host, port).sync().channel();

    // Prepare the HTTP request.
    QueryStringEncoder encoder = new QueryStringEncoder(get);
    // add Form attribute
    encoder.addParam("getform", "GET");
    encoder.addParam("info", "first value");
    encoder.addParam("secondinfo", "secondvalue &");
    // not the big one since it is not compatible with GET size
    // encoder.addParam("thirdinfo", textArea);
    encoder.addParam("thirdinfo", "third value\r\ntest second line\r\n\r\nnew line\r\n");
    encoder.addParam("Send", "Send");

    URI uriGet = new URI(encoder.toString());
    HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uriGet.toASCIIString());
    HttpHeaders headers = request.headers();
    headers.set(HttpHeaderNames.HOST, host);
    headers.set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);
    headers.set(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.GZIP + "," + HttpHeaderValues.DEFLATE);

    headers.set(HttpHeaderNames.ACCEPT_CHARSET, "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
    headers.set(HttpHeaderNames.ACCEPT_LANGUAGE, "fr");
    headers.set(HttpHeaderNames.REFERER, uriSimple.toString());
    headers.set(HttpHeaderNames.USER_AGENT, "Netty Simple Http Client side");
    headers.set(HttpHeaderNames.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");

    // connection will not close but needed
    // headers.set("Connection","keep-alive");
    // headers.set("Keep-Alive","300");

    headers.set(HttpHeaderNames.COOKIE, ClientCookieEncoder.STRICT.encode(new DefaultCookie("my-cookie", "foo"),
            new DefaultCookie("another-cookie", "bar")));

    // send request
    channel.writeAndFlush(request);

    // Wait for the server to close the connection.
    channel.closeFuture().sync();

    // convert headers to list
    return headers.entries();
}

From source file:cn.wcl.test.netty.HttpUploadClient.java

License:Apache License

/**
 * Standard usage of HTTP API in Netty without file Upload (get is not able to achieve File upload
 * due to limitation on request size)./*from www  . j ava  2  s  . c  o m*/
 *
 * @return the list of headers that will be used in every example after
 **/
private static List<Entry<String, String>> formget(Bootstrap bootstrap, String host, int port, String get,
        URI uriSimple) throws Exception {
    // XXX /formget
    // No use of HttpPostRequestEncoder since not a POST
    Channel channel = bootstrap.connect(host, port).sync().channel();

    // Prepare the HTTP request.
    QueryStringEncoder encoder = new QueryStringEncoder(get);
    // add Form attribute
    encoder.addParam("getform", "GET");
    encoder.addParam("info", "first value");
    encoder.addParam("secondinfo", "secondvalue &");
    // not the big one since it is not compatible with GET size
    // encoder.addParam("thirdinfo", textArea);
    encoder.addParam("thirdinfo", "third value\r\ntest second line\r\n\r\nnew line\r\n");
    encoder.addParam("Send", "Send");

    URI uriGet = new URI(encoder.toString());
    HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uriGet.toASCIIString());
    HttpHeaders headers = request.headers();
    headers.set(HttpHeaderNames.HOST, host);
    headers.set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);
    headers.set(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.GZIP + "," + HttpHeaderValues.DEFLATE);

    headers.set(HttpHeaderNames.ACCEPT_CHARSET, "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
    headers.set(HttpHeaderNames.ACCEPT_LANGUAGE, "fr");
    headers.set(HttpHeaderNames.REFERER, uriSimple.toString());
    headers.set(HttpHeaderNames.USER_AGENT, "Netty Simple Http Client side");
    headers.set(HttpHeaderNames.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");

    //connection will not close but needed
    // headers.set("Connection","keep-alive");
    // headers.set("Keep-Alive","300");

    headers.set(HttpHeaderNames.COOKIE, ClientCookieEncoder.STRICT.encode(new DefaultCookie("my-cookie", "foo"),
            new DefaultCookie("another-cookie", "bar")));

    // send request
    channel.writeAndFlush(request);

    // Wait for the server to close the connection.
    channel.closeFuture().sync();

    // convert headers to list
    return headers.entries();
}

From source file:com.phei.netty.nio.http.upload.HttpUploadClient.java

License:Apache License

/**
 * Standard usage of HTTP API in Netty without file Upload (get is not able to achieve File upload
 * due to limitation on request size)./*from   w  w  w  .j  a v a 2s .c  o  m*/
 *
 * @return the list of headers that will be used in every example after
 **/
private static List<Entry<String, String>> formget(Bootstrap bootstrap, String host, int port, String get,
        URI uriSimple) throws Exception {
    // XXX /formget
    // No use of HttpPostRequestEncoder since not a POST
    Channel channel = bootstrap.connect(host, port).sync().channel();

    // Prepare the HTTP request.
    QueryStringEncoder encoder = new QueryStringEncoder(get);
    // add Form attribute
    encoder.addParam("getform", "GET");
    encoder.addParam("info", "first value");
    encoder.addParam("secondinfo", "secondvalue &");
    // not the big one since it is not compatible with GET size
    // encoder.addParam("thirdinfo", textArea);
    encoder.addParam("thirdinfo", "third value\r\ntest second line\r\n\r\nnew line\r\n");
    encoder.addParam("Send", "Send");

    URI uriGet = new URI(encoder.toString());
    HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uriGet.toASCIIString());
    HttpHeaders headers = request.headers();
    headers.set(HttpHeaderNames.HOST, host);
    headers.set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);
    headers.set(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.GZIP + "," + HttpHeaderValues.DEFLATE);

    headers.set(HttpHeaderNames.ACCEPT_CHARSET, "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
    headers.set(HttpHeaderNames.ACCEPT_LANGUAGE, "fr");
    headers.set(HttpHeaderNames.REFERER, uriSimple.toString());
    headers.set(HttpHeaderNames.USER_AGENT, "Netty Simple Http Client side");
    headers.set(HttpHeaderNames.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");

    //connection will not close but needed
    // headers.set("Connection","keep-alive");

    headers.set(HttpHeaderNames.COOKIE, ClientCookieEncoder.encode(new DefaultCookie("my-cookie", "foo"),
            new DefaultCookie("another-cookie", "bar")));

    // send request
    List<Entry<String, String>> entries = headers.entriesConverted();
    channel.writeAndFlush(request);

    // Wait for the server to close the connection.
    channel.closeFuture().sync();

    return entries;
}

From source file:com.vmware.dcp.common.http.netty.NettyHttpClientRequestHandler.java

License:Open Source License

private void parseRequestHeaders(ChannelHandlerContext ctx, Operation request, HttpRequest nettyRequest) {
    HttpHeaders headers = nettyRequest.headers();

    String referer = headers.getAndRemoveAndConvert(HttpHeaderNames.REFERER);
    if (referer != null) {
        try {//from   w  w w .ja  va  2s.com
            request.setReferer(new URI(referer));
        } catch (URISyntaxException e) {
            setRefererFromSocketContext(ctx, request);
        }
    } else {
        setRefererFromSocketContext(ctx, request);
    }

    if (headers.isEmpty()) {
        return;
    }

    request.setKeepAlive(HttpHeaderUtil.isKeepAlive(nettyRequest));
    if (HttpHeaderUtil.isContentLengthSet(nettyRequest)) {
        request.setContentLength(HttpHeaderUtil.getContentLength(nettyRequest));
    }

    request.setContextId(headers.getAndRemoveAndConvert(Operation.CONTEXT_ID_HEADER));

    String contentType = headers.getAndRemoveAndConvert(HttpHeaderNames.CONTENT_TYPE);
    if (contentType != null) {
        request.setContentType(contentType);
    }

    String cookie = headers.getAndRemoveAndConvert(HttpHeaderNames.COOKIE);
    if (cookie != null) {
        request.setCookies(CookieJar.decodeCookies(cookie));
    }

    for (Entry<String, String> h : headers.entriesConverted()) {
        String key = h.getKey();
        String value = h.getValue();
        request.addRequestHeader(key, value);
    }

    // Add peer Principal and CertificateChain to operation in case if client was successfully authenticated
    // by Netty using client certificate
    SslHandler sslHandler = (SslHandler) ctx.channel().pipeline().get(NettyHttpServerInitializer.SSL_HANDLER);
    if (sslHandler != null) {
        try {
            if (sslHandler.engine().getWantClientAuth() || sslHandler.engine().getNeedClientAuth()) {
                SSLSession session = sslHandler.engine().getSession();
                request.setPeerCertificates(session.getPeerPrincipal(), session.getPeerCertificateChain());
            }
        } catch (Exception e) {
            this.host.log(Level.FINE, "Failed to get peer principal " + Utils.toString(e));
        }
    }
}

From source file:com.vmware.xenon.common.http.netty.NettyHttpServiceClient.java

License:Open Source License

private void doSendRequest(Operation op) {
    final Object originalBody = op.getBodyRaw();
    try {/*  w w  w  .  jav  a 2 s. c  om*/
        byte[] body = Utils.encodeBody(op);
        if (op.getContentLength() > getRequestPayloadSizeLimit()) {
            stopTracking(op);
            Exception e = new IllegalArgumentException("Content-Length " + op.getContentLength()
                    + " is greater than max size allowed " + getRequestPayloadSizeLimit());
            op.setBody(ServiceErrorResponse.create(e, Operation.STATUS_CODE_BAD_REQUEST));
            op.fail(e);
            return;
        }

        String pathAndQuery;
        String path = op.getUri().getPath();
        String query = op.getUri().getRawQuery();
        String userInfo = op.getUri().getRawUserInfo();
        path = path == null || path.isEmpty() ? "/" : path;
        if (query != null) {
            pathAndQuery = path + "?" + query;
        } else {
            pathAndQuery = path;
        }

        /**
         * NOTE: Pay close attention to calls that access the operation request headers, since
         * they will cause a memory allocation. We avoid the allocation by first checking if
         * the operation has any custom headers to begin with, then we check for the specific
         * header
         */
        boolean hasRequestHeaders = op.hasRequestHeaders();
        boolean useHttp2 = op.isConnectionSharing();
        if (this.httpProxy != null || useHttp2 || userInfo != null) {
            pathAndQuery = op.getUri().toString();
        }

        NettyFullHttpRequest request = null;
        HttpMethod method = HttpMethod.valueOf(op.getAction().toString());
        if (body == null || body.length == 0) {
            request = new NettyFullHttpRequest(HttpVersion.HTTP_1_1, method, pathAndQuery, Unpooled.buffer(0),
                    false);
        } else {
            ByteBuf content = Unpooled.wrappedBuffer(body, 0, (int) op.getContentLength());
            request = new NettyFullHttpRequest(HttpVersion.HTTP_1_1, method, pathAndQuery, content, false);
        }

        if (useHttp2) {
            // when operation is cloned, it may contain original streamId header. remove it.
            if (hasRequestHeaders) {
                op.getRequestHeaders().remove(Operation.STREAM_ID_HEADER);
            }
            // We set the operation so that once a streamId is assigned, we can record
            // the correspondence between the streamId and operation: this will let us
            // handle responses properly later.
            request.setOperation(op);

        }

        String pragmaHeader = op.getRequestHeader(Operation.PRAGMA_HEADER);

        if (op.isFromReplication() && pragmaHeader == null) {
            request.headers().set(HttpHeaderNames.PRAGMA, Operation.PRAGMA_DIRECTIVE_REPLICATED);
        }

        if (op.getTransactionId() != null) {
            request.headers().set(Operation.TRANSACTION_ID_HEADER, op.getTransactionId());
        }

        if (op.getContextId() != null) {
            request.headers().set(Operation.CONTEXT_ID_HEADER, op.getContextId());
        }

        AuthorizationContext ctx = op.getAuthorizationContext();
        if (ctx != null && ctx.getToken() != null) {
            request.headers().set(Operation.REQUEST_AUTH_TOKEN_HEADER, ctx.getToken());
        }

        boolean isXenonToXenon = op.isFromReplication();
        boolean isRequestWithCallback = false;
        if (hasRequestHeaders) {
            for (Entry<String, String> nameValue : op.getRequestHeaders().entrySet()) {
                String key = nameValue.getKey();
                if (!isXenonToXenon) {
                    if (Operation.REQUEST_CALLBACK_LOCATION_HEADER.equals(key)) {
                        isRequestWithCallback = true;
                        isXenonToXenon = true;
                    } else if (Operation.RESPONSE_CALLBACK_STATUS_HEADER.equals(key)) {
                        isXenonToXenon = true;
                    }
                }
                request.headers().set(nameValue.getKey(), nameValue.getValue());
            }
        }

        request.headers().set(HttpHeaderNames.CONTENT_LENGTH, Long.toString(op.getContentLength()));
        request.headers().set(HttpHeaderNames.CONTENT_TYPE, op.getContentType());
        request.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);

        if (!isXenonToXenon) {
            if (op.getCookies() != null) {
                String header = CookieJar.encodeCookies(op.getCookies());
                request.headers().set(HttpHeaderNames.COOKIE, header);
            }

            if (op.hasReferer()) {
                request.headers().set(HttpHeaderNames.REFERER, op.getRefererAsString());
            }

            request.headers().set(HttpHeaderNames.USER_AGENT, this.userAgent);
            if (op.getRequestHeader(Operation.ACCEPT_HEADER) == null) {
                request.headers().set(HttpHeaderNames.ACCEPT, Operation.MEDIA_TYPE_EVERYTHING_WILDCARDS);
            }

            request.headers().set(HttpHeaderNames.HOST, op.getUri().getHost());
        }

        boolean doCookieJarUpdate = !isXenonToXenon;
        boolean stopTracking = !isRequestWithCallback;
        op.nestCompletion((o, e) -> {
            if (e != null) {
                fail(e, op, originalBody);
                return;
            }

            if (stopTracking) {
                stopTracking(op);
            }

            if (doCookieJarUpdate) {
                updateCookieJarFromResponseHeaders(o);
            }

            // After request is sent control is transferred to the
            // NettyHttpServerResponseHandler. The response handler will nest completions
            // and call complete() when response is received, which will invoke this completion
            op.complete();
        });

        op.getSocketContext().writeHttpRequest(request);
    } catch (Throwable e) {
        op.setBody(ServiceErrorResponse.create(e, Operation.STATUS_CODE_BAD_REQUEST,
                EnumSet.of(ErrorDetail.SHOULD_RETRY)));
        fail(e, op, originalBody);
    }
}

From source file:Netty4.book.http.upload.HttpUploadClient.java

License:Apache License

/**
 * Standard usage of HTTP API in Netty without file Upload (get is not able to achieve File upload
 * due to limitation on request size).// w w  w.  jav  a2 s  .  c om
 *
 * @return the list of headers that will be used in every example after
 **/
private static List<Entry<String, String>> formget(Bootstrap bootstrap, String host, int port, String get,
        URI uriSimple) throws Exception {
    // XXX /formget
    // No use of HttpPostRequestEncoder since not a POST
    Channel channel = bootstrap.connect(host, port).sync().channel();

    // Prepare the HTTP request.
    QueryStringEncoder encoder = new QueryStringEncoder(get);
    // add Form attribute
    encoder.addParam("getform", "GET");
    encoder.addParam("info", "first value");
    encoder.addParam("secondinfo", "secondvalue &");
    // not the big one since it is not compatible with GET size
    // encoder.addParam("thirdinfo", textArea);
    encoder.addParam("thirdinfo", "third value\r\ntest second line\r\n\r\nnew line\r\n");
    encoder.addParam("Send", "Send");

    URI uriGet = new URI(encoder.toString());
    HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uriGet.toASCIIString());
    HttpHeaders headers = request.headers();
    headers.set(HttpHeaderNames.HOST, host);
    headers.set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);
    headers.set(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.GZIP + "," + HttpHeaderValues.DEFLATE);

    headers.set(HttpHeaderNames.ACCEPT_CHARSET, "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
    headers.set(HttpHeaderNames.ACCEPT_LANGUAGE, "fr");
    headers.set(HttpHeaderNames.REFERER, uriSimple.toString());
    headers.set(HttpHeaderNames.USER_AGENT, "Netty Simple Http Client side");
    headers.set(HttpHeaderNames.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");

    //connection will not close but needed
    // headers.set("Connection","keep-alive");
    // headers.set("Keep-Alive","300");

    headers.set(HttpHeaderNames.COOKIE, ClientCookieEncoder.STRICT.encode(new DefaultCookie("my-cookie", "foo"),
            new DefaultCookie("another-cookie", "bar")));

    // send request
    List<Entry<String, String>> entries = headers.entries();
    channel.writeAndFlush(request);

    // Wait for the server to close the connection.
    channel.closeFuture().sync();

    return entries;
}

From source file:org.waarp.gateway.kernel.http.HttpRequestHandler.java

License:Open Source License

/**
 * To allow quick answer even if in very bad shape
 * /*from   w w  w  .j  av  a2  s  .  c  o m*/
 * @param ctx
 */
protected void forceClosing(ChannelHandlerContext ctx) {
    if (status == HttpResponseStatus.OK) {
        status = HttpResponseStatus.INTERNAL_SERVER_ERROR;
    }
    if (ctx.channel().isActive()) {
        willClose = true;
        String answer = "<html><body>Error " + status.reasonPhrase() + "</body></html>";
        FullHttpResponse response = getResponse(Unpooled.wrappedBuffer(answer.getBytes(WaarpStringUtils.UTF8)));
        response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html");
        response.headers().set(HttpHeaderNames.REFERER, request.uri());
        ChannelFuture future = ctx.writeAndFlush(response);
        logger.debug("Will close");
        future.addListener(WaarpSslUtility.SSLCLOSE);
    }
    WaarpActionLogger.logErrorAction(DbConstant.admin.getSession(), session, "Error: " + httpPage.getPagename(),
            status);
}

From source file:org.waarp.gateway.kernel.http.HttpRequestHandler.java

License:Open Source License

/**
 * Write a simple page from current httpPage and businessRequest
 * //w  w w.j  a v  a2s  .  c o  m
 * @param ctx
 * @throws HttpIncorrectRequestException
 */
protected void writeSimplePage(ChannelHandlerContext ctx) throws HttpIncorrectRequestException {
    logger.debug("HttpPage: " + (httpPage != null ? httpPage.getPagename() : "no page") + " businessRequest: "
            + (businessRequest != null ? businessRequest.getClass().getName() : "no BR"));
    if (httpPage.getPagerole() == PageRole.ERROR) {
        try {
            httpPage.setValue(businessRequest, AbstractHttpField.ERRORINFO, errorMesg, FieldPosition.BODY);
        } catch (HttpIncorrectRequestException e) {
            // ignore
        }
    }
    String answer = httpPage.getHtmlPage(this.businessRequest);
    int length = 0;
    // Convert the response content to a ByteBuf.
    ByteBuf buf = Unpooled.wrappedBuffer(answer.getBytes(CharsetUtil.UTF_8));
    FullHttpResponse response = getResponse(buf);
    response.headers().set(HttpHeaderNames.CONTENT_TYPE, this.businessRequest.getContentType());
    response.headers().set(HttpHeaderNames.REFERER, request.uri());
    length = buf.readableBytes();
    if (!willClose) {
        // There's no need to add 'Content-Length' header
        // if this is the last response.
        response.headers().set(HttpHeaderNames.CONTENT_LENGTH, String.valueOf(length));
    }
    // Write the response.
    ChannelFuture future = ctx.writeAndFlush(response);
    // Close the connection after the write operation is done if necessary.
    if (willClose) {
        logger.debug("Will close");
        future.addListener(WaarpSslUtility.SSLCLOSE);
    }
}

From source file:org.waarp.gateway.kernel.rest.client.HttpRestClientSimpleResponseHandler.java

License:Apache License

@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
    if (msg instanceof HttpResponse) {
        HttpResponse response = (HttpResponse) msg;
        HttpResponseStatus status = response.status();
        logger.debug(HttpHeaderNames.REFERER + ": " + response.headers().get(HttpHeaderNames.REFERER)
                + " STATUS: " + status);
    }//  w w w .j a v  a  2  s . c  o m
    if (msg instanceof HttpContent) {
        HttpContent chunk = (HttpContent) msg;
        if (chunk instanceof LastHttpContent) {
            ByteBuf content = chunk.content();
            if (content != null && content.isReadable()) {
                if (cumulativeBody != null) {
                    cumulativeBody = Unpooled.wrappedBuffer(cumulativeBody, content);
                } else {
                    cumulativeBody = content;
                }
            }
            // get the Json equivalent of the Body
            if (cumulativeBody == null) {
                jsonObject = JsonHandler.createObjectNode();
            } else {
                try {
                    String json = cumulativeBody.toString(WaarpStringUtils.UTF8);
                    jsonObject = JsonHandler.getFromString(json);
                } catch (Throwable e2) {
                    logger.warn("Error", e2);
                    throw new HttpIncorrectRequestException(e2);
                }
                cumulativeBody = null;
            }
            actionFromResponse(ctx.channel());
        } else {
            ByteBuf content = chunk.content();
            if (content != null && content.isReadable()) {
                if (cumulativeBody != null) {
                    cumulativeBody = Unpooled.wrappedBuffer(cumulativeBody, content);
                } else {
                    cumulativeBody = content;
                }
            }
        }
    }
}

From source file:org.waarp.gateway.kernel.rest.DataModelRestMethodHandler.java

License:Open Source License

@Override
public ChannelFuture sendResponse(HttpRestHandler handler, ChannelHandlerContext ctx, RestArgument arguments,
        RestArgument result, Object body, HttpResponseStatus status) {
    String answer = result.toString();
    ByteBuf buffer = Unpooled.wrappedBuffer(answer.getBytes(WaarpStringUtils.UTF8));
    HttpResponse response = handler.getResponse(buffer);
    if (status == HttpResponseStatus.UNAUTHORIZED) {
        ChannelFuture future = ctx.writeAndFlush(response);
        return future;
    }//from w w w.  j av a 2  s  .c o  m
    response.headers().add(HttpHeaderNames.CONTENT_TYPE, "application/json");
    response.headers().add(HttpHeaderNames.REFERER, handler.getRequest().uri());
    logger.debug("Will write: {}", body);
    ChannelFuture future = ctx.writeAndFlush(response);
    if (handler.isWillClose()) {
        System.err.println("Will close session in DataModelRestMethodHandler");
        return future;
    }
    return null;
}