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);
> >     }
> > }
> >
>

Reply via email to