@Override
    public void handleRequest(
            final HttpRequest request,
            final EntityDetails entityDetails,
            final ResponseChannel responseChannel,
            final HttpContext context) throws HttpException, IOException {
        final String method = request.getMethod();
        if (!"GET".equalsIgnoreCase(method) &&
                !"HEAD".equalsIgnoreCase(method) &&
                !"POST".equalsIgnoreCase(method) &&
                !"PUT".equalsIgnoreCase(method)) {
            throw new MethodNotSupportedException(method + " not supported by " + getClass().getName());
        }
        if (entityDetails != null) {

            final ContentType contentType = ContentType.parseLenient(entityDetails.getContentType());
            entityConsumer.streamStart(entityDetails, new FutureCallback<byte[]>() {

                @Override
                public void completed(final byte[] content) {
                    final BasicAsyncEntityProducer entityProducer = new BasicAsyncEntityProducer(content, contentType);
                    entityProducerRef.set(entityProducer);
                    try {
                        responseChannel.sendResponse(new BasicHttpResponse(HttpStatus.SC_OK), entityProducer, context);
                    } catch (final IOException | HttpException ex) {
                        failed(ex);
                    }
                }

                @Override
                public void failed(final Exception ex) {
                    releaseResources();
                }

                @Override
                public void cancelled() {
                    releaseResources();
                }

            });
        } else {
            responseChannel.sendResponse(new BasicHttpResponse(HttpStatus.SC_OK), null, context);
            entityConsumer.releaseResources();
        }
    }
A handler that echos the incoming request entity.
httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AsyncEchoHandler.java