Hi, of course I use it together with multipart request. I have spring boot 2 + zuul on tomcat 8.5.31. And I cannot proxy traffic with multipart request due to that error. I know that available return the right number of bytes but later you have method makeAvailable() which tries to read more than allowed! Some greedy developer wrote that :) Please check unit tests which I added. The should explain you everything.
Also here is example issue: https://stackoverflow.com/questions/3263809/apache-commons-file-upload-stream-ended-unexpectedly I saw a lot of them -- all unresolved. On 2 July 2018 at 16:58, Rémy Maucherat <r...@apache.org> wrote: > On Mon, Jul 2, 2018 at 4:35 PM Piotr Joński <p.jon...@pojo.pl> wrote: > > > Java: openjdk version "1.8.0_163" > > OpenJDK Runtime Environment (Zulu 8.28.0.1-linux64) (build 1.8.0_163-b01) > > OpenJDK 64-Bit Server VM (Zulu 8.28.0.1-linux64) (build 25.163-b01, mixed > > mode) > > > > OS: Ubuntu 18.04 Linux local 4.15.0-23-generic #25-Ubuntu SMP Wed May 23 > > 18:02:16 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux > > > > > > The problem is that > > > > org.apache.tomcat.util.http.fileupload.MultipartStream. > ItemInputStream#read(byte[], > > int, int) method does not update pos field after reading from buffer / > > stream. > > > > pos is set to the next separator which (IMO) should work fine since > available returns the right amount of bytes which are allowed to be read. > Doesn't this work for you ? This is not a generic utility class, it's > supposed to be used with multipart content, is it at least what you are > doing ? > > Rémy > > > > > > Unfortunately I cannot provide full example as this is private project. > > > > Here are sample unit tests. First reproduces the error and second use > > reflection to set proper field value to simulate proper behaviour: > > > > package org.apache.tomcat.util.http.fileupload; > > > > import org.junit.jupiter.api.Test; > > > > import java.io.ByteArrayInputStream; > > import java.io.IOException; > > import java.lang.reflect.Field; > > > > import static org.assertj.core.api.Assertions.assertThat; > > > > class ItemInputStreamTest { > > > > @Test > > void Should_Read_Bytes_But_Throws_Exception() throws IOException { > > // given > > byte[] bytes = new byte[]{1, 2, 3}; > > final ByteArrayInputStream inputStream = new > > ByteArrayInputStream(bytes); > > final MultipartStream.ProgressNotifier progressNotifier = new > > MultipartStream.ProgressNotifier(null, 1111); > > final MultipartStream multipartStream = new > > MultipartStream(inputStream, > > > bytes, > > > > progressNotifier); > > MultipartStream.ItemInputStream itemInputStream = > > multipartStream.new ItemInputStream(); > > > > // when > > byte[] buffer = new byte[8196]; > > int result = itemInputStream.read(buffer, 0, 8196); > > > > // then > > assertThat(result).isEqualTo(3); > > } > > > > @Test > > void Should_Read_Bytes_Fixed() throws IOException, > > NoSuchFieldException, IllegalAccessException { > > // given > > byte[] bytes = new byte[]{1, 2, 3}; > > final ByteArrayInputStream inputStream = new > > ByteArrayInputStream(bytes); > > final MultipartStream.ProgressNotifier progressNotifier = new > > MultipartStream.ProgressNotifier(null, 1111); > > final MultipartStream multipartStream = new > > MultipartStream(inputStream, > > > bytes, > > > > progressNotifier); > > MultipartStream.ItemInputStream itemInputStream = > > multipartStream.new ItemInputStream(); > > > > Field pos = itemInputStream.getClass() > > .getDeclaredField("pos"); > > pos.setAccessible(true); > > pos.set(itemInputStream, 3); > > > > // when > > byte[] buffer = new byte[8196]; > > int result = itemInputStream.read(buffer, 0, 8196); > > > > // then > > assertThat(result).isEqualTo(3); > > } > > } > > >