fix #89: reconstruct baseUrl from URL components to avoid query/fragment corruption - #109
Conversation
…/fragment corruption
When DefaultDownloadManager split a download URL into baseUrl and
remotePath, it used string arithmetic:
String remotePath = sourceUrl.getPath();
String baseUrl = url.substring(0, url.length() - remotePath.length());
sourceUrl.getPath() returns only the path portion (e.g. /path/file.jar),
stripping any query string or fragment. The full 'url' string still
carries those suffixes, so the substring cut lands in the middle of the
path, producing a completely wrong baseUrl and breaking Wagon
connectivity (e.g. http://host/path/file.j instead of http://host).
Fix: reconstruct baseUrl explicitly from the URL object's own
protocol/userInfo/host/port components, which are never contaminated
by query strings or fragments.
Adds two regression tests (query string and fragment) that capture
the Repository argument passed to wagon.connect() and assert the URL
equals exactly "http://example.com" with no trailing path or query.
bf570dd to
cc51f2c
Compare
There was a problem hiding this comment.
Pull request overview
This PR fixes a URL-splitting bug in DefaultDownloadManager where reconstructing the Wagon baseUrl via string subtraction could corrupt the URL when a query string (?…) or fragment (#…) is present, breaking Wagon connectivity.
Changes:
- Reworks
baseUrlreconstruction inDefaultDownloadManagerto avoid query/fragment corruption. - Adds regression tests asserting the exact
Repository.getUrl()passed towagon.connect()for URLs containing a query string or fragment.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/main/java/org/apache/maven/shared/io/download/DefaultDownloadManager.java | Updates base URL reconstruction logic used for Wagon connection. |
| src/test/java/org/apache/maven/shared/io/download/DefaultDownloadManagerTest.java | Adds regression coverage to ensure baseUrl excludes query strings/fragments. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| import org.junit.jupiter.api.BeforeEach; | ||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| import org.easymock.Capture; | ||
|
|
| String remotePath = sourceUrl.getPath(); | ||
| String baseUrl = url.substring(0, url.length() - remotePath.length()); | ||
| int port = sourceUrl.getPort(); | ||
| String baseUrl = sourceUrl.getProtocol() + "://" |
There was a problem hiding this comment.
Been a minute since I looked into the official URI specs but I'm not sure this is a complete URL reconstruction. The authority can have a password component, and not all absolute URIs (URLs?) have ://. Some just have :. This is tricky. Might be OK here. I'm just not sure.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Summary
Fixes #89
Problem
DefaultDownloadManager.javareconstructed the WagonbaseUrlby subtractingthe length of the URL path from the end of the raw URL string:
Contribution Checklist
Note that commits might be squashed by a maintainer on merge.
(Two regression tests added:
shouldHandleUrlWithQueryStringandshouldHandleUrlWithFragment—both assert the exact
baseUrlpassed towagon.connect()and would fail without the fix.All 82 tests pass.)
mvn verifyto make sure basic checks pass.(Ran
mvn surefire:test— 82 tests, 0 failures, 0 errors.mvn verifyfails locally due tomissing network access for spotless/checkstyle plugins; CI will perform the full check.)
If your pull request is about ~20 lines of code you don't need to sign an
Individual Contributor License Agreement if you are unsure
please ask on the developers list.
(This PR changes 56 lines of code — ICLA may be required. Please check with the developers list if unsure.)
To make clear that you license your contribution under
the Apache License Version 2.0, January 2004
you have to acknowledge this by using the following check-box.