Skip to content

fix: Sanitize percent characters in resource URLs#24031

Open
tltv wants to merge 5 commits intomainfrom
fix-issue-22677
Open

fix: Sanitize percent characters in resource URLs#24031
tltv wants to merge 5 commits intomainfrom
fix-issue-22677

Conversation

@tltv
Copy link
Copy Markdown
Member

@tltv tltv commented Mar 27, 2026

Jetty 12 rejects URLs containing %25 (percent-encoded percent) as ambiguous URI path encoding, causing downloads to fail with HTTP 400 when filenames contain "%" characters.

Add UrlUtil.sanitizeForUrl() that replaces "%" with "_" in the URL path segment. The actual download filename from Content-Disposition is unaffected since each resource has a unique ID for lookup.

Fixes #22677

Artur- and others added 2 commits March 27, 2026 11:14
…ibility

Jetty 12 rejects URLs containing %25 (percent-encoded percent) as
ambiguous URI path encoding, causing downloads to fail with HTTP 400
when filenames contain "%" characters.

Add UrlUtil.sanitizeForUrl() that replaces "%" with "_" in the URL
path segment. The actual download filename from Content-Disposition
is unaffected since each resource has a unique ID for lookup.

Fixes #22677
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 27, 2026

Test Results

 1 386 files  ±0   1 386 suites  ±0   1h 26m 50s ⏱️ -5s
 9 933 tests +6   9 863 ✅ +7  70 💤  - 1  0 ❌ ±0 
10 406 runs  +6  10 327 ✅ +7  79 💤  - 1  0 ❌ ±0 

Results for commit 8c5a7fa. ± Comparison against base commit d877765.

♻️ This comment has been updated with latest results.

}

/**
* Sanitizes a resource name for safe use in URL path segments.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This javadoc does not really make sense as the only thing it does is replace % with _. It also talks about where the result is used and about Content-Disposition - completely unrelated to URLs. Maybe the correct place would be in StreamRequestHandler if that's the only place there is a problem

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved code to StreamRequestHandler.generateURI.

open();

assertDownloadedContent("percent-link", "file%25.jpg");
assertDownloadedContent("percent-link", "file_.jpg");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this really test anything now?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to assert that file%.jpg filename in StreamResource given to the anchor has url with has file_.jpg properly. Looks correct to me.

@sonarqubecloud
Copy link
Copy Markdown

@sonarqubecloud
Copy link
Copy Markdown

❌ The last analysis has failed.

See analysis details on SonarQube Cloud

@github-actions github-actions bot added +1.0.0 and removed +0.0.1 labels Mar 27, 2026
@tltv tltv requested a review from mshabarov April 14, 2026 12:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Download of files containing "%" in their name fails with Jetty 12

2 participants