Skip to content

utils: follow http to https redirects when reading the QCOW2 virtual size - #14582

Open
yuminn-k wants to merge 1 commit into
apache:4.22from
yuminn-k:fix-qcow2-cross-protocol-redirect
Open

yuminn-k wants to merge 1 commit into
apache:4.22from
yuminn-k:fix-qcow2-cross-protocol-redirect

Conversation

@yuminn-k

@yuminn-k yuminn-k commented Nov 5, 2026

Copy link
Copy Markdown

Description

This PR fixes the QCOW2 virtual size check for KVM direct download templates whose http:// URL redirects to https://.

QCOW2Utils.getVirtualSizeFromUrl() used HttpURLConnection.setInstanceFollowRedirects(followRedirects). HttpURLConnection never follows a redirect that changes the protocol, so with store.download.follow.redirects=true an http:// to https:// redirect returned the 301 response itself. Reading the header from the empty body then failed with "Unable to skip to the virtual size header", reported as "Failed to connect URL", so the template could not be registered.

Changes in QCOW2Utils:

  • When followRedirects is true, redirects (301, 302, 303, 307, 308) are followed in the method itself, up to 10 hops, and the Location header is resolved against the current URL so relative locations work.
  • Only http and https targets are followed. An https URL is never redirected to http: the downgrade is refused, logged and fails the check, the same as any other connection error. Same-scheme redirects and http to https upgrades are allowed.
  • When followRedirects is false the behaviour is unchanged: the redirect is not followed.

Not covered here: #14505 (trust store used by the commons-httpclient based HEAD/GET checks) and the HttpsDirectTemplateDownloader.getRemoteFileSize() trust store point mentioned in the issue. Those are separate code paths.

Fixes: #14506

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)
  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (improves an existing feature and functionality)
  • Cleanup (Code refactoring and cleanup, that may add test cases)
  • Build/CI
  • Test (unit or integration test code)

Feature/Enhancement Scale or Bug Severity

Feature/Enhancement Scale

  • Major
  • Minor

Bug Severity

  • BLOCKER
  • Critical
  • Major
  • Minor
  • Trivial

Screenshots (if appropriate):

How Has This Been Tested?

New unit tests in QCOW2UtilsTest, using a local com.sun.net.httpserver.HttpServer:

  • getRedirectUrl: relative Location resolution, http to https allowed, https to http refused, non-HTTP scheme (file:) refused, missing Location refused.
  • getVirtualSizeFromUrl: follows a relative redirect and returns the virtual size; does not follow a redirect when followRedirects is false; stops after 10 redirects (11 requests); follows an http to https redirect (the test checks that the https target port receives a connection; the TLS handshake then fails because the target is a plain socket).

Results (JDK 17, Maven 3.9):

  • mvn -pl utils test -Dtest=QCOW2UtilsTest: 11 tests pass, checkstyle passes.
  • With the previous getVirtualSizeFromUrl body, getVirtualSizeFromUrlFollowsHttpToHttpsRedirect fails (the https target is never contacted) and getVirtualSizeFromUrlStopsAfterTooManyRedirects fails (expected:<11> but was:<20>).
  • mvn -pl utils test: 2405 tests, 0 failures, 14 skipped.
  • Manual check against the URL from the issue, calling QCOW2Utils.getVirtualSizeFromUrl(url, true) from a small Java program: http://github.com/cirros-dev/cirros/releases/download/0.6.2/cirros-0.6.2-x86_64-disk.img returns 117440512 with this change, and throws IllegalArgumentException: Failed to connect URL with the current 4.22 class.

Not tested: a full template registration on a KVM host and management server.

How did you try to break this feature and the system with this change?

  • Redirect loops stop after 10 hops instead of the JDK default of 20.
  • https to http downgrades and redirects to other schemes such as file: are refused.
  • The only caller is HttpDirectTemplateDownloader.getRemoteFileSize(); the method signature is unchanged.

Assisted-by: Claude Opus 5.5 (Claude Code)

…size

HttpURLConnection never follows redirects that change the protocol, so a
direct download QCOW2 template registered with an http:// URL that
redirects to https:// failed the virtual size check with "Failed to
connect URL".

When redirects are enabled, follow them in QCOW2Utils with a limit of 10
hops, resolving relative Location headers against the current URL. Only
http and https targets are followed and https is never downgraded to
http.

Fixes apache#14506

Assisted-by: Claude Opus 5.5 (Claude Code)
@boring-cyborg

boring-cyborg Bot commented Nov 5, 2026

Copy link
Copy Markdown

Congratulations on your first Pull Request and welcome to the Apache CloudStack community! If you have any issues or are unsure about any anything please check our Contribution Guide (https://github.com/apache/cloudstack/blob/main/CONTRIBUTING.md)
Here are some useful points:

This branch has not been deployed

No deployments
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

Successfully merging this pull request may close these issues.

1 participant