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

multipart/mixed is not supported #6196

Closed
aaronjwhiteside opened this issue Apr 19, 2021 · 7 comments
Closed

multipart/mixed is not supported #6196

aaronjwhiteside opened this issue Apr 19, 2021 · 7 comments

Comments

@aaronjwhiteside
Copy link

Jetty version
9.4.31.v20200723

Description
I think I remember this working in earlier version of jetty, and I found an issue reported here that mentions multipart/mixed.

#2813

So I guess the question is what happened?

Caused by: javax.servlet.ServletException: Unsupported Content-Type [multipart/mixed; boundary=c2333489e7a56f60], expected [multipart/form-data]
at org.eclipse.jetty.server.Request.getParts(Request.java:2365)
at javax.servlet.http.HttpServletRequestWrapper.getParts(HttpServletRequestWrapper.java:317)
at javax.servlet.http.HttpServletRequestWrapper.getParts(HttpServletRequestWrapper.java:317)
at javax.servlet.http.HttpServletRequestWrapper.getParts(HttpServletRequestWrapper.java:317)
at javax.servlet.http.HttpServletRequestWrapper.getParts(HttpServletRequestWrapper.java:317)
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:95)

And the request that generated this error:

1 > POST http://127.0.0.1:49632/files/mixed
1 > Content-Type: multipart/mixed; boundary=c2333489e7a56f60
1 > Content-Length: 6883
1 > Host: 127.0.0.1:49632
1 > Connection: Keep-Alive
1 > User-Agent: Apache-HttpClient/4.5.12 (Java/11.0.4)
1 > Accept-Encoding: gzip,deflate

content-disposition: form-data; name="myJson"; filename=""
content-type: application/json; charset=UTF-8
content-length: 22
Completed: true
IsInMemory: true

Mixed: content-disposition: form-data; name="myFile"; filename="upload-name.pdf"
content-type: application/pdf; charset=UTF-8
content-length: 6514
Completed: true
IsInMemory: true

The actual part contents have been omitted here.. but the headers should be correct. This works against Tomcat for what it's worth.

@joakime
Copy link
Contributor

joakime commented Apr 19, 2021

Every version of Jetty since 7.6.13 has thrown that exception (9 years ago).

From commit - 7da85a2

This was done for 2 reasons.

  1. The Servlet Spec only supports multipart/form-data for the .getParts() call - see https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletRequest.html#getParts-- (which specifically points out the exception you are getting)
  2. The Multipart Spec dropped multipart/mixed from RFC7578 (back in 2015)

@joakime
Copy link
Contributor

joakime commented Apr 19, 2021

This is likely a bug in org.springframework.web.multipart.support.StandardMultipartHttpServletRequest as it shouldn't use .getParts() if the Content-Type is not multipart/form-data.

The fact that tomcat supports this is wrong on two counts (against the servlet spec, and against the multipart spec).

@aaronjwhiteside
Copy link
Author

@joakime thanks for the quick and detailed response, I'll poke around Spring's StandardMultipartHttpServletRequest

@aaronjwhiteside
Copy link
Author

Spring have accepted this as a bug, so I'll close this issue.

Thanks again @joakime !

@pke
Copy link

pke commented Apr 4, 2024

@joakime

2. The Multipart Spec dropped multipart/mixed from RFC7578 (back in 2015)

Where does it say that? It only deprecated the type inside form-data for multiple files with the same name.
The spec seems pretty much alive and makes absolutely sense for anything but form-data sent by browsers.

@gregw
Copy link
Contributor

gregw commented Apr 4, 2024

@pke Do you have a specific use-case that expects to see a multipart/mixed request body that needs to be accesses as Parts via the servlet API?

@joakime
Copy link
Contributor

joakime commented Apr 4, 2024

@pke since the Servlet spec doesn't support multipart/mixed either as the form, or a nested form (typically used for mapping 1 name to multiple files), there is nothing for Jetty to do with support for multipart/mixed.

The multipart/mixed spec has no concept of "name" (like multipart/form-data and its Content-Disposition part header) either, making it unusable for .getPart(String), .getParts(), .getParameter(String), .getParameterMap(), and .getParameterNames() (even if used as a nested structure within a multipart/form-data). There is an optional URL/URI for each part in multipart/mixed, but that's not a name, that's a resource reference, a different concept in HTTP, HTML, and Servlet.

Simply put multipart/mixed is not a form, it's a structural multipart definition.

The only remaining usecases for multipart/mixed (now that nested structure in mulitpart/form-data is deprecated) is for the Server to send multiple elements in a single response using a multipart/mixed Content-Type. This was used for sending the entire web page with all elements in the past (eg: html + css + javascript + images), but that's not reliable as you have to look for Accept: multipart/mixed and ignore Accept: */* or Accept: multipart/* to have it work with any hope of reliability due to the poor support across user-agents. There was also a time when game developers toyed with the idea of using multipart/mixed for game resources like sprite sheets, but that's completely fallen out of favor as there are more efficient ways to accomplish that while taking advantage of standard web caching specs.

Btw, multipart/mixed was a dead concept by the late 1990's, it was being removed from use in the few organizations that experimented with it. But something new happened in 2000, mobile network providers started the rollout of GPRS, and new mobile devices that could display more complex web pages were being sold, so the mobile providers started to push multipart/mixed as a performance solution, but this was not widely supported across browsers, even mobile browsers that this concept was being pushed for didn't implement it. By the time GPRS and EDGE was being replaced by 3G, the mobile providers stopped trying to make multipart/mixed happen. In the modern era, there are far better ways to get the elements of a web page to a browser in a faster way.

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

4 participants