kiranchavala opened a new issue, #14506:
URL: https://github.com/apache/cloudstack/issues/14506
### problem
For QCOW2 Direct Download templates, `CheckUrlCommand` also reads the QCOW2
header to obtain the virtual size. When the template URL is `http://` and the
server redirects to `https://`
Related: #12878
### versions
ACS 4.22.x and 4.23.x
### The steps to reproduce the bug
1. Set `store.download.follow.redirects` to `true`.
2. Ensure the HTTPS targets are trusted by the agent (e.g. upload Sectigo
Public Server Authentication Root E46
and ISRG Root X1 via `uploadTemplateDirectDownloadCertificate`) so TLS is
not the failure cause.
3. Register a direct download QCOW2 template:
cmk register template name=cirros-http-redirect displaytext=cirros
format=QCOW2 hypervisor=KVM \
url=http://github.com/cirros-dev/cirros/releases/download/0.6.2/cirros-0.6.2-x86_64-disk.img
\
ostypeid=<id> zoneid=<id> directdownload=true
4. Registration fails; the agent log shows the `QCOW2Utils` error above.
5. The same image via `https://github.com/...` (https→https redirect)
succeeds and returns `templateSize`.
### What to do about it?
Root cause
```
`QCOW2Utils.getVirtualSizeFromUrl()` uses `java.net.HttpURLConnection` with
`setInstanceFollowRedirects(followRedirects)`. By design, the JDK **never
follows redirects that change
protocol** (http→https or https→http), even when instance redirects are
enabled. The connection therefore
returns the `301` response itself:
$ curl -sI
http://github.com/cirros-dev/cirros/releases/download/0.6.2/cirros-0.6.2-x86_64-disk.img
HTTP/1.1 301 Moved Permanently
Content-Length: 0
Location:
https://github.com/cirros-dev/cirros/releases/download/0.6.2/cirros-0.6.2-x86_64-disk.img
`getVirtualSize()` then calls `inputStream.skip(24)` on the empty 301 body,
which throws
"Unable to skip to the virtual size header", reported as "Failed to connect
URL".
So any QCOW2 direct download template registered with an `http://` URL that
redirects to HTTPS
cannot be registered, regardless of `store.download.follow.redirects` or
trust-store configuration.
```
### What to do about it?
- In `QCOW2Utils.getVirtualSizeFromUrl()`, follow redirects manually when
`followRedirects` is true: disable
`setInstanceFollowRedirects`, and on a 3xx response with a `Location`
header, resolve it against the
current URL (`new URL(current, location)`), open a new connection, and
repeat up to a maximum hop
count (e.g. 10).
- Preferably, have the direct download downloaders read the QCOW2 header
through their own HttpClient 4.x
client (GET with `Range: bytes=0-1023`), which handles cross-protocol
redirects and uses the merged
`cloud.jks` + `cacerts` SSL context. This also fixes
`HttpsDirectTemplateDownloader.getRemoteFileSize()`,
which currently sets the custom SSLContext on one connection but reads
from `urlObj.openStream()`
(a new connection using the JVM default `cloud.jks`-only trust store).
- Add unit tests for: http→https 301, relative `Location` headers, and the
max-hop limit.
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]