1

My system consists of an angular application that communicates with a REST endpoint (POST) in a spring boot application. Spring boot is configured to use jetty as the embedded server. The angular application has TypeScript code that calls the REST endpoint and sends a json object as payload. The size of the json object will vary from 1 MB to 10 MB based on user selection in the browser. My spring boot application runs in an Azure VM that runs Linux (CentOS). For certain requests i get the HTTP error 413: Request size is too large. I did some searches and found 2 mechanisms to tune the spring boot application to overcome this limit.

Option 1 Change the request size limit in application.properties using this property server.jetty.max-http-post-size=20971520 # Maximum size in bytes of the HTTP post or put content.

Option 2 Override the jetty maxFormContentSize using some java code in the main application class

@Bean
public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() {
    JettyEmbeddedServletContainerFactory jettyContainer =
            new JettyEmbeddedServletContainerFactory();
    org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainer serverContainer = (org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainer)jettyContainer.getEmbeddedServletContainer();
    serverContainer.getServer().setAttribute("org.eclipse.jetty.server.Request.maxFormContentSize", "20971520");
    return jettyContainer;
}

None of these options work and I still get the error when certain requests are large.

Is there a better way to solve this problem?

Note: I see this error only in the Azure VM environment that runs CentOS. In my machine which runs windows 10, I don't see this error

Update: I noticed that when the web server is rebooted, the very first request goes through but subsequent requests fail. This suggests that there some buffer or cache at the server which is not getting cleared in time. Is my understanding correct?

Aaron Dsouza
  • 121
  • 3
  • 9
  • *None of these options work and I still get the error when certain requests are large.* - Are you 100% sure that the payload is at most 10MB large? You are setting the limit to 20MB, are you 100% sure you aren't exceeding this limit? – BackSlash Mar 15 '18 at 08:22
  • I used the Chrome browser debugger and copied the json payload in a text file. The request size was 4 MB. – Aaron Dsouza Mar 15 '18 at 08:29
  • Your 413 could be from abuse of the request line or headers too. Make sure you are not sending that JSON object as a query string on your URI (for example), and that your request headers are reasonable in size. If Jetty is replying with a 413, then your server logs should tell you why you got a 413 (or 431). If you don't see these logs, then you can be sure that its not a Jetty configuration causing that 413/431 result. – Joakim Erdfelt Mar 15 '18 at 22:15
  • The header size is within the limits. Is there a way to check what is the current limit of the request payload? Perhaps some java API in spring boot? – Aaron Dsouza Mar 16 '18 at 06:13

3 Answers3

0

Add these in application.properties file in case the request is multipart and tune them as per your need:

multipart.maxFileSize=20Mb

multipart.maxRequestSize=20Mb

Otherwise, have a look at this : https://stackoverflow.com/a/3861510/945214 and this: https://stackoverflow.com/a/36899004/945214

gargkshitiz
  • 2,130
  • 17
  • 19
0

spring.http.multipart.max-file-size=200MB

spring.http.multipart.max-request-size=200MB

These setting will work when you are running with embedded TOMCAT.

Raj5198
  • 25
  • 1
  • 9
0

In your example, the JettyEmbeddedServletContainer you instantiate in your bean definition is never used, the bean you can override is the JettyEmbeddedServletContainerFactory. Have a look at EmbeddedServletContainerAutoConfiguration.EmbeddedJetty where the magic happens.

To modify the property like you want, you could use the JettyServerCustomizer interface :

@Bean
public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() {
    JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory();
    factory.addServerCustomizers(server -> server.setAttribute("org.eclipse.jetty.server.Request.maxFormContentSize", 20971520));
    return factor;
}

or EmbeddedServletContainerCustomizer :

@Component
public class FormSizeCustomizer implements EmbeddedServletContainerCustomizer {
    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        JettyEmbeddedServletContainerFactory factory = (JettyEmbeddedServletContainerFactory) container;
        factory.addServerCustomizers(server -> server.setAttribute("org.eclipse.jetty.server.Request.maxFormContentSize",
                                                                   20971520));
    }
}

This limit is only applied to requests with a application/x-www-form-urlencoded content type. To enforce a maximum size on application/json requests (or other content types), you'll need custom code. You can do it by checking the Content-Length header or by wrapping the ServletInputStream and enforcing a max size while consuming for chunked requests.

Source (Joakim is a Jetty developer) : Jetty and max content size

jebeaudet
  • 1,533
  • 16
  • 15