8

I've faced a problem uploading big files through zuul. I'm using apache-commons file upload(https://commons.apache.org/proper/commons-fileupload/) to stream large files as well as I use zuul on the front. In my Spring Boot application I have disabled upload provided by Spring to use the one from apache commons:

  spring:
      http:
          multipart:
              enabled: false

Controller looks like that:

public ResponseEntity insertFile(@PathVariable Long profileId, 
    HttpServletRequest request) throws Exception {
    ServletFileUpload upload = new ServletFileUpload();
    FileItemIterator uploadItemIterator = upload.getItemIterator(request);
    if (!uploadItemIterator.hasNext()) {
        throw new FileUploadException("FileItemIterator was empty"); 
    } 
    while (uploadItemIterator.hasNext()) {
        FileItemStream fileItemStream = uploadItemIterator.next();
        if (fileItemStream.isFormField()) {
            continue; 
        } 
       //do stuff 
    } 
    return new ResponseEntity(HttpStatus.OK);
} 

If I access my application directly(without zuul), file upload works as intended. However, if it's accessed through zuul, FileItemIterator doesn't have items to traverse and request finishes with error immediately(ERR_CONNECTION_RESET). For zuul I have also disabled multipart given by Spring. Otherwise, it works. However, the files are not streamed. They are loaded completely and only after I get inside the controller(regular Spring behavior). Is there a way to use apache-commons streaming options with zuul?

dvelopp
  • 4,095
  • 3
  • 31
  • 57

2 Answers2

11

I've found a solution. It's basically described here:

http://cloud.spring.io/spring-cloud-static/spring-cloud.html#_uploading_files_through_zuul

What I did to make it work. Just step by step:

  1. To bypass the Spring DispatcherServlet I changed the URL:

From: http://localhost:8081/MyService/file

To: http://localhost:8081/zuul/MyService/file

  1. Preserved disabling of Spring multipart upload:

    spring:
        http:
            multipart:
                enabled: false
    

The following header is not required. Transfer-Encoding: chunked

I tried to upload a large file without that one and it was fine.

dvelopp
  • 4,095
  • 3
  • 31
  • 57
  • This solution really works but it should stressed that with disabling Spring multipart handling you are also disabling support of `MultipartProperties`, e.g. `spring.http.multipart.max-file-size` and thus rely on FileUpload's default values (which are quite unrestricted in fact). – Toparvion Feb 20 '18 at 07:33
  • 1
    But how i can do this without changing the URL route? – Dev Utkarsh Apr 08 '19 at 14:03
  • 1
    I have been facing the same issue - uploading large files through a Zuul gateway. I tried the solution above but I'm getting CORS refusals. ("Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource"). My Zuul server has a WebMvcConfigurer which overrides #addCorsMappings and lets everything through. This works fine for other routes but not for the same routes prefixed with "zuul" as instructed. Any ideas? Cheers – ChambreNoire Oct 01 '19 at 13:19
  • @AnthonyWebster did you get the solution? i got same – MasterLuV Jul 22 '20 at 07:14
  • For CORS, zuul wont come into picture as it is bypassed, so fileupload microservice has to take care of that. – Munish Chandel Oct 15 '20 at 05:45
0

I have found solution as described below. In my case the requirement is to allow upto 30MB. Adding below Spring Servlet mulitpart configuration helped as I noticed the error is thrown from embeded tomcat. Note that the request size should be slightly more than the max-file-size as the request will have additional parameters like headers with token etc. In our case I have to add additional 2MB for the max-request-size to allow headers etc.

spring: servlet: multipart: max-file-size: 30MB max-request-size:32MB

Prakhya
  • 21
  • 3
  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 20 '22 at 07:33