Skip to content

Commit f31b2f3

Browse files
committed
Add support to MessageDigestCalculatingInputStream for setting a
consumer for ProxyInputStream.afterRead(int)
1 parent f79a3d6 commit f31b2f3

3 files changed

Lines changed: 45 additions & 7 deletions

File tree

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ The <action> type attribute can be add,update,fix,remove.
7272
<action dev="ggregory" type="add" due-to="Gary Gregory">Add support to ChecksumInputStream for setting a consumer for ProxyInputStream.afterRead(int).</action>
7373
<action dev="ggregory" type="add" due-to="Gary Gregory">Add support to ThrottledInputStream for setting a consumer for ProxyInputStream.afterRead(int).</action>
7474
<action dev="ggregory" type="add" due-to="Gary Gregory">Add support to ObservableInputStream for setting a consumer for ProxyInputStream.afterRead(int).</action>
75+
<action dev="ggregory" type="add" due-to="Gary Gregory">Add support to MessageDigestCalculatingInputStream for setting a consumer for ProxyInputStream.afterRead(int).</action>
7576
<!-- UPDATE -->
7677
<action dev="ggregory" type="update" due-to="Gary Gregory">Bump org.apache.commons:commons-parent from 74 to 78 #670, #676, #679, #688.</action>
7778
<action dev="ggregory" type="update" due-to="Gary Gregory">Bump commons.bytebuddy.version from 1.15.1 to 1.15.10 #672, #673, #685, #686, #694, #696, #698.</action>

src/main/java/org/apache/commons/io/input/MessageDigestCalculatingInputStream.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,9 @@
2121
import java.security.MessageDigest;
2222
import java.security.NoSuchAlgorithmException;
2323
import java.security.Provider;
24+
import java.util.Arrays;
2425
import java.util.Objects;
2526

26-
import org.apache.commons.io.build.AbstractStreamBuilder;
27-
2827
/**
2928
* Calculates a checksum using a {@link MessageDigest}, for example, a SHA-512 sum.
3029
* <p>
@@ -57,12 +56,15 @@ public class MessageDigestCalculatingInputStream extends ObservableInputStream {
5756
* .setMessageDigest("SHA-512")
5857
* .get();}
5958
* </pre>
59+
* <p>
60+
* <em>The MD5 cryptographic algorithm is weak and should not be used.</em>
61+
* </p>
6062
*
6163
* @see #get()
6264
* @since 2.12.0
6365
*/
6466
// @formatter:on
65-
public static class Builder extends AbstractStreamBuilder<MessageDigestCalculatingInputStream, Builder> {
67+
public static class Builder extends AbstractBuilder<Builder> {
6668

6769
private MessageDigest messageDigest;
6870

@@ -101,16 +103,16 @@ public Builder() {
101103
* @throws IOException if an I/O error occurs.
102104
* @see #getInputStream()
103105
*/
104-
@SuppressWarnings("resource")
105106
@Override
106107
public MessageDigestCalculatingInputStream get() throws IOException {
107-
return new MessageDigestCalculatingInputStream(getInputStream(), messageDigest);
108+
setObservers(Arrays.asList(new MessageDigestMaintainingObserver(messageDigest)));
109+
return new MessageDigestCalculatingInputStream(this);
108110
}
109111

110112
/**
111113
* Sets the message digest.
112114
* <p>
113-
* The MD5 cryptographic algorithm is weak and should not be used.
115+
* <em>The MD5 cryptographic algorithm is weak and should not be used.</em>
114116
* </p>
115117
*
116118
* @param messageDigest the message digest.
@@ -122,7 +124,7 @@ public void setMessageDigest(final MessageDigest messageDigest) {
122124
/**
123125
* Sets the name of the name of the message digest algorithm.
124126
* <p>
125-
* The MD5 cryptographic algorithm is weak and should not be used.
127+
* <em>The MD5 cryptographic algorithm is weak and should not be used.</em>
126128
* </p>
127129
*
128130
* @param algorithm the name of the algorithm. See the MessageDigest section in the
@@ -197,6 +199,11 @@ static MessageDigest getDefaultMessageDigest() throws NoSuchAlgorithmException {
197199

198200
private final MessageDigest messageDigest;
199201

202+
private MessageDigestCalculatingInputStream(final Builder builder) throws IOException {
203+
super(builder);
204+
this.messageDigest = builder.messageDigest;
205+
}
206+
200207
/**
201208
* Constructs a new instance, which calculates a signature on the given stream, using a {@link MessageDigest} with the "MD5" algorithm.
202209
* <p>

src/test/java/org/apache/commons/io/input/MessageDigestCalculatingInputStreamTest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import static org.junit.jupiter.api.Assertions.assertEquals;
2121
import static org.junit.jupiter.api.Assertions.assertNotEquals;
2222
import static org.junit.jupiter.api.Assertions.assertThrows;
23+
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
2324
import static org.junit.jupiter.api.Assertions.assertTrue;
2425

2526
import java.io.ByteArrayInputStream;
@@ -28,11 +29,14 @@
2829
import java.nio.file.Files;
2930
import java.nio.file.Paths;
3031
import java.security.MessageDigest;
32+
import java.util.concurrent.atomic.AtomicBoolean;
3133

3234
import org.apache.commons.codec.digest.DigestUtils;
3335
import org.apache.commons.codec.digest.MessageDigestAlgorithms;
36+
import org.apache.commons.io.IOExceptionList;
3437
import org.apache.commons.io.IOUtils;
3538
import org.apache.commons.io.input.MessageDigestCalculatingInputStream.Builder;
39+
import org.apache.commons.io.test.CustomIOException;
3640
import org.junit.jupiter.api.Test;
3741

3842
/**
@@ -50,6 +54,32 @@ private MessageDigestCalculatingInputStream createInputStream(final InputStream
5054
return MessageDigestCalculatingInputStream.builder().setInputStream(origin).get();
5155
}
5256

57+
@Test
58+
public void testAfterReadConsumer() throws Exception {
59+
final AtomicBoolean boolRef = new AtomicBoolean();
60+
// @formatter:off
61+
try (InputStream bounded = MessageDigestCalculatingInputStream.builder()
62+
.setCharSequence("Hi")
63+
.setAfterRead(i -> boolRef.set(true))
64+
.get()) {
65+
IOUtils.consume(bounded);
66+
}
67+
// @formatter:on
68+
assertTrue(boolRef.get());
69+
// Throwing
70+
final String message = "test exception message";
71+
// @formatter:off
72+
try (InputStream bounded = MessageDigestCalculatingInputStream.builder()
73+
.setCharSequence("Hi")
74+
.setAfterRead(i -> {
75+
throw new CustomIOException(message);
76+
})
77+
.get()) {
78+
assertTrue(assertThrowsExactly(IOExceptionList.class, () -> IOUtils.consume(bounded)).getMessage().contains(message));
79+
}
80+
// @formatter:on
81+
}
82+
5383
@SuppressWarnings("resource")
5484
@Test
5585
public void testAvailableAfterClose() throws Exception {

0 commit comments

Comments
 (0)