Jetty throws “Missing content for multipart reques

2019-01-24 21:39发布

问题:

I'm running Jetty 9 (jetty-9.0.5.v20130815) server with servlet-api 3.0.1 (javax.servlet:javax.servlet-api:3.0.1), my servlet is configured to accept multipart requests.

web.xml -

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee"
     xmlns:c="http://java.sun.com/jsp/jstl/core"
     xmlns:fmt="http://java.sun.com/jsp/jstl/fmt"
     xmlns:web="http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
     version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee">

<servlet>
    <servlet-name>restapi</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
    <multipart-form enable="true" />
    <multipart-config>
        <max-file-size>8428800</max-file-size>
        <max-request-size>8428800</max-request-size>
        <file-size-threshold>1048576</file-size-threshold>
    </multipart-config>
</servlet>
</web-app>

applicationContext.xml -

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- one of the properties available; the maximum file size in bytes -->
    <property name="maxUploadSize" value="8000000"/>
</bean>

It implements a POST command that should receive a file upload through HttpServletRequest. But when request.getParts() is called, this exception occurs:

java.io.IOException: Missing content for multipart request
        at org.eclipse.jetty.util.MultiPartInputStreamParser.parse(MultiPartInputStreamParser.java:493)
        at org.eclipse.jetty.util.MultiPartInputStreamParser.getParts(MultiPartInputStreamParser.java:401)
        at org.eclipse.jetty.server.Request.getParts(Request.java:2077)
        at javax.servlet.http.HttpServletRequestWrapper.getParts(HttpServletRequestWrapper.java:351)
        at javax.servlet.http.HttpServletRequestWrapper.getParts(HttpServletRequestWrapper.java:351)

The client is an iOS app using ASIFormDataRequest, but I don't think that client has the problem because it used to work with Apache commons-fileupload.jar. I'm not switching the server to use Jetty's multipart support for receiving files.

Here's the request, as intercepted by a proxy -

POST /mycommand HTTP/1.1
Host: localhost:8080
Proxy-Connection: close
Accept-Encoding: gzip
Content-Type: multipart/form-data; charset=utf-8; boundary=0xKhTmLbOuNdArY-849F4DA3-85DC-46F1-B182-44257808F0B9
Content-Length: 1568
Connection: close

--0xKhTmLbOuNdArY-849F4DA3-85DC-46F1-B182-44257808F0B9
Content-Disposition: form-data; name="param1"

text
--0xKhTmLbOuNdArY-849F4DA3-85DC-46F1-B182-44257808F0B9
Content-Disposition: form-data; name="data"; filename="file"
Content-Type: application/octet-stream

... DATA ...
--0xKhTmLbOuNdArY-849F4DA3-85DC-46F1-B182-44257808F0B9--

Any ideas?

回答1:

We had the exact same problem, and after some hours of debugging we found the issue.

Jetty complains because the InputStream that contains the mulitpart message is empty. The issue for us was that both both Servlet 3.0-style multipart was configured (as you have done with the multipart-* tags in web.xml), and Spring was configured to use Commons FileUpload for multipart parsing. This caused Commons FileUpload to consume the InputStream before Jetty did it in the MultiPartInputStreamParser

The solution to this is simply to remove Commons FileUpload from the classpath and configure Spring not to use it.



回答2:

The error for "Missing content for multipart request" is due to a missing or badly detected first boundary.

There have been numerous edge cases (from clients that badly format multi-part messages) that Jetty compensates for. However, the information you have provided is insufficient to know what the underlying cause might be.

Can you file a bug at bugs.eclipse.org under RT/Jetty with a wireshark capture of the traffic?



回答3:

for spring boot application I found same issue. I remove Commons FileUpload lib and add to properties:

multipart:
  maxFileSize: 32Mb
  maxRequestSize: 32Mb

for size files



回答4:

In my case i had the following ; when i commented the lines below in

org.springframework.web.servlet.DispatcherServlet

It worked.....after commenting

 <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <multipart-config>
            <!-- 52MB max -->
            <max-file-size>52428800</max-file-size>
            <max-request-size>52428800</max-request-size>
            <file-size-threshold>0</file-size-threshold>
        </multipart-config>
    </servlet>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.ico</url-pattern>
        <url-pattern>*.png</url-pattern>
        <url-pattern>*.jpg</url-pattern>
        <url-pattern>*.htc</url-pattern>
        <url-pattern>*.gif</url-pattern>
        <url-pattern>*.swf</url-pattern>
        <url-pattern>*.wmf</url-pattern>
        <url-pattern>*.pdf</url-pattern>
        <url-pattern>*.css</url-pattern>
        <url-pattern>*.js</url-pattern>
        <url-pattern>*.json</url-pattern>
        <url-pattern>*.otf</url-pattern>
        <url-pattern>*.eot</url-pattern>
        <url-pattern>*.svg</url-pattern>
        <url-pattern>*.ttf</url-pattern>
        <url-pattern>*.woff</url-pattern>
        <url-pattern>/files/original/*</url-pattern>      
    </servlet-mapping>
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
<!--        <multipart-config>
             52MB max 
            <max-file-size>52428800</max-file-size>
            <max-request-size>52428800</max-request-size>
            <file-size-threshold>0</file-size-threshold>
        </multipart-config>-->
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.html</url-pattern>
        <url-pattern>*.txt</url-pattern>
        <url-pattern>*.xml</url-pattern>
        <url-pattern>/</url-pattern>
    </servlet-mapping>