DigestingEntityProducer implements AsyncEntityProducer { @Override public void produce(final DataStreamChannel channel) throws IOException { wrapped.produce(new DataStreamChannel() { @Override public void requestOutput() { channel.requestOutput(); } @Override public int write(final ByteBuffer src) throws IOException { final ByteBuffer dup = src.duplicate(); final int writtenBytes = channel.write(src); if (writtenBytes > 0) { dup.limit(dup.position() + writtenBytes); digester.update(dup); } return writtenBytes; } @Override public void endStream(final List<? extends Header> trailers) throws IOException { digest = digester.digest(); final List<Header> allTrailers = new ArrayList<>(); if (trailers != null) { allTrailers.addAll(trailers); } allTrailers.add(new BasicHeader("digest-algo", digester.getAlgorithm())); allTrailers.add(new BasicHeader("digest", TextUtils.toHexString(digest))); channel.endStream(allTrailers); } @Override public void endStream() throws IOException { endStream(null); } }); } DigestingEntityProducer(
            final String algo,
            final AsyncEntityProducer wrapped); @Override boolean isRepeatable(); @Override long getContentLength(); @Override String getContentType(); @Override String getContentEncoding(); @Override boolean isChunked(); @Override Set<String> getTrailerNames(); @Override int available(); @Override void produce(final DataStreamChannel channel); @Override void failed(final Exception cause); @Override void releaseResources(); byte[] getDigest();  }
@Test public void testProduceData() throws Exception { final DigestingEntityProducer producer = new DigestingEntityProducer("MD5", new StringAsyncEntityProducer("12345", ContentType.TEXT_PLAIN)); final WritableByteChannelMock byteChannel = new WritableByteChannelMock(1024); final BasicDataStreamChannel dataStreamChannel = new BasicDataStreamChannel(byteChannel); while (byteChannel.isOpen()) { producer.produce(dataStreamChannel); } Assert.assertEquals("12345", byteChannel.dump(StandardCharsets.US_ASCII)); final List<Header> trailers = dataStreamChannel.getTrailers(); Assert.assertNotNull(trailers); Assert.assertEquals(2, trailers.size()); Assert.assertEquals("digest-algo", trailers.get(0).getName()); Assert.assertEquals("MD5", trailers.get(0).getValue()); Assert.assertEquals("digest", trailers.get(1).getName()); Assert.assertEquals("0827c0cb0e0ea08a706c4c340a1680910f84e7b", trailers.get(1).getValue()); }