diff --git a/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/PutTaskRequestContent.java b/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/PutTaskRequestContent.java index 026b728cd..4117e9e0a 100644 --- a/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/PutTaskRequestContent.java +++ b/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/PutTaskRequestContent.java @@ -243,7 +243,7 @@ public Content.Chunk read() { return last; } lockedSetTerminal(Content.Chunk.EOF); - } catch (Exception e) { + } catch (IOException e) { lockedSetTerminal(Content.Chunk.from(e, true)); } } @@ -295,11 +295,10 @@ public boolean rewind() { offsetRemaining = 0; totalRead = 0; return true; - } catch (Exception e) { + } catch (IOException e) { lockedSetTerminal(Content.Chunk.from(e, true)); + return false; } - - return true; } } } diff --git a/maven-resolver-transport-jetty/src/test/java/org/eclipse/aether/transport/jetty/PutTaskRequestContentTest.java b/maven-resolver-transport-jetty/src/test/java/org/eclipse/aether/transport/jetty/PutTaskRequestContentTest.java index c904d9ed4..99b9432f8 100644 --- a/maven-resolver-transport-jetty/src/test/java/org/eclipse/aether/transport/jetty/PutTaskRequestContentTest.java +++ b/maven-resolver-transport-jetty/src/test/java/org/eclipse/aether/transport/jetty/PutTaskRequestContentTest.java @@ -18,6 +18,7 @@ */ package org.eclipse.aether.transport.jetty; +import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.ReadableByteChannel; import java.nio.channels.SeekableByteChannel; @@ -25,9 +26,31 @@ import org.eclipse.jetty.io.ByteBufferPool; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; class PutTaskRequestContentTest { + @Test + void readPropagatesUnexpectedRuntimeExceptionsFromChannel() { + ReadableByteChannel channel = new ReadableByteChannel() { + @Override + public int read(ByteBuffer destination) { + throw new IllegalStateException("unexpected read failure"); + } + + @Override + public boolean isOpen() { + return true; + } + + @Override + public void close() {} + }; + PutTaskRequestContent content = new PutTaskRequestContent(ByteBufferPool.SIZED_NON_POOLING, () -> channel); + + assertThrows(IllegalStateException.class, content::read); + } + @Test void readPropagatesErrorsFromChannel() { ReadableByteChannel channel = new ReadableByteChannel() { @@ -49,6 +72,52 @@ public void close() {} assertThrows(AssertionError.class, content::read); } + @Test + void rewindPropagatesUnexpectedRuntimeExceptionsFromSeekableChannel() { + SeekableByteChannel channel = new SeekableByteChannel() { + @Override + public int read(ByteBuffer destination) { + return -1; + } + + @Override + public int write(ByteBuffer source) { + return 0; + } + + @Override + public long position() { + return 0; + } + + @Override + public SeekableByteChannel position(long newPosition) { + throw new IllegalStateException("unexpected rewind failure"); + } + + @Override + public long size() { + return 0; + } + + @Override + public SeekableByteChannel truncate(long size) { + return this; + } + + @Override + public boolean isOpen() { + return true; + } + + @Override + public void close() {} + }; + PutTaskRequestContent content = new PutTaskRequestContent(ByteBufferPool.SIZED_NON_POOLING, () -> channel); + + assertThrows(IllegalStateException.class, content::rewind); + } + @Test void rewindPropagatesErrorsFromSeekableChannel() { SeekableByteChannel channel = new SeekableByteChannel() { @@ -94,4 +163,50 @@ public void close() {} assertThrows(AssertionError.class, content::rewind); } + + @Test + void rewindReturnsFalseWhenPositionFailsWithIOException() { + SeekableByteChannel channel = new SeekableByteChannel() { + @Override + public int read(ByteBuffer destination) { + return -1; + } + + @Override + public int write(ByteBuffer source) { + return 0; + } + + @Override + public long position() { + return 0; + } + + @Override + public SeekableByteChannel position(long newPosition) throws IOException { + throw new IOException("rewind failed"); + } + + @Override + public long size() { + return 0; + } + + @Override + public SeekableByteChannel truncate(long size) { + return this; + } + + @Override + public boolean isOpen() { + return true; + } + + @Override + public void close() {} + }; + PutTaskRequestContent content = new PutTaskRequestContent(ByteBufferPool.SIZED_NON_POOLING, () -> channel); + + assertFalse(content.rewind()); + } }