ZCU-PUB/fix: RFC 5987 Content-Disposition for single-file + allzip download (backport #1368) - #1369
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Backports RFC 5987-compliant Content-Disposition handling to prevent mangled diacritics and malformed headers in both single-bitstream downloads and “allzip” downloads.
Changes:
- Updated single-file download responses to emit both
filename(ASCII fallback) andfilename*(RFC 5987 encoded UTF-8) instead of RFC 2047 encoded-words. - Introduced
ContentDispositionUtilsand applied it toMetadataBitstreamControllerto safely build allzipContent-Disposition. - Added/updated integration + unit tests covering non-ASCII, spaces, and quoting behavior.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/HttpHeadersInitializer.java | Switches single-file Content-Disposition to RFC 5987-style filename* + ASCII fallback. |
| dspace-server-webapp/src/main/java/org/dspace/app/rest/MetadataBitstreamController.java | Uses shared utility to generate safe allzip Content-Disposition. |
| dspace-api/src/main/java/org/dspace/util/ContentDispositionUtils.java | New utility for building safe RFC 5987 Content-Disposition values. |
| dspace-api/src/test/java/org/dspace/util/ContentDispositionUtilsTest.java | Adds unit tests for escaping, encoding, and control-char handling. |
| dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamRestControllerIT.java | Updates expectations for new header format on single-file download endpoint. |
| dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataBitstreamControllerIT.java | Adds IT coverage for quotes + diacritics in allzip filenames. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Backport of the allzip half of #1368 (dtq-dev) to customer/zcu-pub. The allzip endpoint built its header as a bare `attachment;filename="<name>"`, so item names with diacritics arrived mangled and a double quote in a name closed the quoted-string early (ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION). MetadataBitstreamController has no counterpart upstream, so it carries its own private copy of vanilla's createFallbackAsciiName / createEncodedUtf8Name rather than a shared fork utility — same as on dtq-dev. One deliberate deviation from vanilla, marked in the code: the ASCII fallback escapes \ and ". Vanilla omits this, so a name containing a quote closes the quoted-string early — exactly the bug #1267 was raised for. Differs from #1368 in one way: BitstreamByHandleRestController does not exist on this branch (the curl endpoint from #1252 was never backported here), so it is not touched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
cb9d679 to
f9343f8
Compare
…ersInitializer Address Copilot review on #1369: - createFallbackAsciiName now escapes \ and " so a filename containing a quote can't close the filename="..." quoted-string early (the ERR_RESPONSE_ HEADERS_MULTIPLE_CONTENT_DISPOSITION class of bug, #1267). Brings it to parity with the sibling method in MetadataBitstreamController. - createEncodedUtf8Name now uses URLEncoder.encode(String, Charset); UTF-8 is always supported, so the UnsupportedEncodingException catch was dead code. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Backport of #1368 to
customer/zcu-pub. Fixes the wrong filename when downloading a file whose name has diacritics — both causes.Customer branches never merge
dtq-dev(they sit ~258 commits behind and take individual backports), so this cannot ride along on #1368.Evidence
The before/after A/B run is in #1368 — two real backend images against the same database. It was run on the
dtq-devpair, not on this branch, so treat it as evidence for the shared fix rather than for this backport specifically.What's fixed
MetadataBitstreamControllerbuiltattachment;filename="<raw name>"with no encoding. Raw UTF-8 in a header makes Tomcat drop the header entirely, so the browser gets no filename at all and falls back to the URL segment (allzip.zip). A"in an item name closed the quoted-string early (ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION).HttpHeadersInitializerusedMimeUtility.encodeText, i.e. an RFC 2047 encoded-word, which RFC 6266 App. C.1 forbids in HTTP. Cherry-pick of vanillafe4077acee(#11269 → 7.6.6). Note Chrome and Firefox decode RFC 2047 anyway, so this half is invisible to them — it bites Safari andcurl -OJ.As on #1368,
MetadataBitstreamControllercarries its own private copy of vanilla'screateFallbackAsciiName/createEncodedUtf8Namerather than a shared fork helper: it is a fork-only class with no upstream counterpart, so copying keeps it tracking vanilla and adds no API to maintain.Differences from #1368 — please check these in review
BitstreamByHandleRestControllerdoes not exist on this branch (the curl endpoint from UFAL/Fix: add bitstream download-by-handle endpoint for curl instructions #1252 was never backported here), so it is not touched.HttpHeadersInitializercherry-pick conflicted and was hand-resolved. This branch's copy predates vanilla'sisNullOrEmpty(disposition)guard and has its ownMETHOD_HEADearly-return; I kept this branch's structure and swapped only the encoding. Unlike ondtq-dev, this file is not byte-identical to vanilla — it already wasn't.One deviation from vanilla
The ASCII fallback escapes
\and"; vanilla omits this, so a name containing a quote breaks the header even on a clean 7.6.6. Copying vanilla verbatim would have regressed #1267. Marked in a comment at the call site.Verified
mvn test-compileondspace-api+dspace-server-webapp— passdtq-devdtq-devpair, not on this branch🤖 Generated with Claude Code