Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Large multipart file being read into memory in SpringSingleMultipartFileWriter making OOM issue #121

Open
YEPing02 opened this issue Jan 3, 2024 · 3 comments

Comments

@YEPing02
Copy link

YEPing02 commented Jan 3, 2024

Hello,

When uploading a multipart file via a feign client, the OOM is raised when the file is larger than 500 Mbs (for example).

Log shows that the exception occurs at:
https://github.com/OpenFeign/feign-form/blob/master/feign-form-spring/src/main/java/feign/form/spring/SpringSingleMultipartFileWriter.java#L45

@Override
  protected void write (Output output, String key, Object value) throws EncodeException {
    val file = (MultipartFile) value;
    writeFileMetadata(output, key, file.getOriginalFilename(), file.getContentType());

    byte[] bytes;
    try {
      bytes = file.getBytes();
    } catch (IOException ex) {
      throw new EncodeException("Getting multipart file's content bytes error", ex);
    }
    output.write(bytes);
  }

the write method reads all the bytes of the file into memory.

The solution to avoid OOM would be just to stream the file into the output, could we get this fix?

Thanks

@bbulgarelli-yseop
Copy link

Yes, this has also been opened before here: #88
Honestly, this is really annoying when you have to handle large file transfers...

I'm also waiting for some fix or even any comment by maintainers of this repo.
I can even do a pull request if needed.

I made a workaround by writing a custom writer for MultipartFile that is only based on the getInputStream method, and another one handling MultipartFile[].
Then create a custom SpringFormEncoder and add the writers as the first priority ones to get the correct behavior:
In the constructor

        MultipartFormContentProcessor processor = (MultipartFormContentProcessor) getContentProcessor(MULTIPART);
        processor.addFirstWriter(new CustomStreamManyMultipartFilesWriter(STREAM_BUFFER_SIZE));
        processor.addFirstWriter(new CustomStreamSingleMultipartFileWriter(STREAM_BUFFER_SIZE));

@SanhongWong
Copy link

Yes, this has also been opened before here: #88 Honestly, this is really annoying when you have to handle large file transfers...

I'm also waiting for some fix or even any comment by maintainers of this repo. I can even do a pull request if needed.

I made a workaround by writing a custom writer for MultipartFile that is only based on the getInputStream method, and another one handling MultipartFile[]. Then create a custom SpringFormEncoder and add the writers as the first priority ones to get the correct behavior: In the constructor

        MultipartFormContentProcessor processor = (MultipartFormContentProcessor) getContentProcessor(MULTIPART);
        processor.addFirstWriter(new CustomStreamManyMultipartFilesWriter(STREAM_BUFFER_SIZE));
        processor.addFirstWriter(new CustomStreamSingleMultipartFileWriter(STREAM_BUFFER_SIZE));

Hi, bro,I encounter the same problem, but i guess your code can't solve it,because in the feign.form.MultipartFormContentProcessor#process method end,it also read all into the memory,just like this:

    val bytes = output.toByteArray();
    val body = Request.Body.encoded(bytes, null);
    template.body(body);

@bbulgarelli-yseop
Copy link

bbulgarelli-yseop commented Mar 14, 2024

Oh I didn't see this one...
I guess we are stuck now.
This comes from a deep feign-core explicit byte[] into Request.Body: OpenFeign/feign#1243
It looks like Feign core itself doesn't support upload file streaming...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants