quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.59k stars 2.63k forks source link

Quarkus Reactive support download multiple files multipart/form-data #26164

Closed eye0fra closed 2 years ago

eye0fra commented 2 years ago

Description

Quarkus Reactive supports multipart response thanks to the #21038 commit.

The download feature is incomplete, at least compared to the upload capability. In particular, I would like multiple files with their filename under the same content-disposition name to be generated as a list of content-disposition on the wire. I desire List<FileDownload> attribute in my multipart DTO to be supported.

The code of MultipartMessageBodyWriter seems to cover only the multipart DTO with a simple static attribute (not a list), not a list of FileDownload. On the contrary, the upload supports lists of FileUpload. So the current implementation is not symmetric.

Implementation ideas

No response

quarkus-bot[bot] commented 2 years ago

/cc @FroMage, @stuartwdouglas

geoand commented 2 years ago

@Sgitario are you interested in this feature? I think it shouldn't be too difficult - but I am also waiting for additional clarification.

eye0fra commented 2 years ago

The basis is the RFC 7585, specially chap 4.2. and 4.4 RFC 7578 - Returning Values from Forms: multipart/form-data (ietf.org)

Content-Disposition Header Field for Each Part

Each part MUST contain a Content-Disposition header field [RFC2183] where the disposition type is "form-data".
The Content-Disposition header field MUST also contain an additional parameter of "name"; the value of the "name" parameter is the original field name from the form (possibly encoded; see Section 5.1).
For example, a part might contain a header field such as the following, with the body of the part containing the form data of the "user" field:

Content-Disposition: form-data; name="user"

For form data that represents the content of a file, a name for the file SHOULD be supplied as well, by using a "filename" parameter of the Content-Disposition header field. The file name isn't mandatory for cases where the file name isn't available or is meaningless or private; this might result, for example, when selection or drag-and-drop is used or when the form data content is streamed directly from a device.

If a "filename" parameter is supplied, the requirements of Section 2.3 of [RFC2183] for the "receiving MUA" (i.e., the receiving Mail User Agent) apply to receivers of multipart/form-data as well: do not use the file name blindly, check and possibly change to match local file system conventions if applicable, and do not use directory path information that may be present. .. Content-Type Header Field for Each Part Each part MAY have an (optional) "Content-Type" header field, which defaults to "text/plain". If the contents of a file are to be sent, the file data SHOULD be labeled with an appropriate media type, if known, or "application/octet-stream".

Moreover, the RFC2183 RFC 2183 - Communicating Presentation Information in Internet Messages: The Content-Disposition Header Field (ietf.org) seems to indicate that the filename should not contain a directory structure but the proper file name only:

The receiving MUA SHOULD NOT respect any directory path information that may seem to be present in the filename parameter. The filename should be treated as a terminal component only. Portable specification of directory paths might possibly be done in the future via a separate Content-Disposition parameter, but no provision is made for it in this draft.

Sample of an on-the-wire content-disposition body:

--AaB03x
content-disposition: form-data; name="state"; filename="cfg.json"
content-type: application/json;charset=UTF-8
(the json file)
--AaB03x
content-disposition: form-data; name="api-bundles"; filename="bundle.zip"
content-type: application/octet-stream
(binary data)
--AaB03x
content-disposition: form-data; name="api-bundles"; filename="exported-bundle.zip"
content-type: application/octet-stream
(binary data)
--AaB03x
content-disposition: form-data; name="sf-bundles"; filename="invalid-bundle.zip"
content-type: application/octet-stream
(binary data)
--AaB03x

Note that the name (e.g. ”api-bundles”) may appear multiple times.

geoand commented 2 years ago

@Sgitario do you want to take a look?

Sgitario commented 2 years ago

@Sgitario do you want to take a look?

Sure, working on it.