[BUG]: A download that answers 403, 429 or 500 is saved as the archive, and the install ends in "Checksum error"
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 72/100
Direzione di ricerca
Il bug si trova in Download in internal/sdk/sdk.go, dove prima di scrivere il file viene controllato solo resp.StatusCode == http.StatusNotFound. Riproducilo con il plugin repro a quattro file e il server Go della issue, esegui vfox install repro@403 e controlla l'output 'Checksum error'. È completato quando qualsiasi stato diverso da 2xx fa fallire il download con un errore che indica lo stato e l'URL, e il messaggio per il 404 resta invariato. La questione dello User-Agent è una decisione separata e più ampia, e va esclusa da questa correzione.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Version
vfox 1.0.13 (release binary) and main at cdf0747 (2026-11-02, RuntimeVersion is still 1.0.13). The two builds print the same lines in everything below.
OS
Linux amd64, in a golang:1.27.1 container. The code involved depends on neither the OS nor the shell.
Describe the bug
Download in internal/sdk/sdk.go fails on one status only, 404 (source file not found). For any other status, 403, 429, 500 and so on, it saves the body as the archive and goes on, so the install fails one step later on a page of HTML, and nothing in the output says the server refused the download or with which status:
- With a checksum from
PreInstall:Checksum error, file: …/repro.zip, thenchecksum error. - Without one:
WARNING: Checksum is not provided, skip verify..., thenunpack failed, err:zip: not a valid zip file.
This is not hypothetical. Huawei Cloud's mirror of Gradle answers a download from Go-http-client/1.1 with a 403 and a page of HTML, and serves the same file to other agents. With the vfox-gradle plugin and VFOX_GRADLE_MIRRORS=https://repo.huaweicloud.com/gradle, vfox install [email protected] ends in Checksum error, and a user cannot tell that it was an HTTP 403 from the mirror.
Steps to reproduce
No plugin from the registry is needed. A plugin of four small files, whose PreInstall gets the digest with http.get as most plugins do, and a server that answers the status that is the first part of the path.
metadata.lua:
PLUGIN = {}
PLUGIN.name = "repro"
PLUGIN.version = "0.0.1"
PLUGIN.homepage = "https://example.invalid"
PLUGIN.license = "Apache 2.0"
PLUGIN.description = "A download that answers something else than 200 or 404"
hooks/available.lua:
function PLUGIN:Available(ctx)
return { { version = "403" } }
end
hooks/env_keys.lua:
function PLUGIN:EnvKeys(ctx)
return { { key = "PATH", value = ctx.path } }
end
hooks/pre_install.lua:
local http = require("http")
-- The version is the status the server answers the download with: 403, 500, ...
function PLUGIN:PreInstall(ctx)
local base = "http://127.0.0.1:18080/" .. ctx.version
local result = { version = ctx.version, url = base .. "/repro.zip" }
if os.getenv("REPRO_NO_SUM") == nil then
-- A request the plugin makes itself, as most plugins do for a checksum.
local resp = http.get({ url = base .. "/repro.zip.sha256" })
result.sha256 = resp.body
end
return result
end
server.go:
package main
import (
"fmt"
"log"
"net/http"
"strconv"
"strings"
)
// /<status>/repro.zip answers <status> with a page of HTML, and
// /<status>/repro.zip.sha256 answers 200 with a digest of 64 zeros.
func main() {
log.SetFlags(0)
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
log.Printf("%s %s User-Agent: %s", r.Method, r.URL.Path, r.UserAgent())
parts := strings.Split(strings.Trim(r.URL.Path, "/"), "/")
status, err := strconv.Atoi(parts[0])
if err != nil || len(parts) != 2 {
http.NotFound(w, r)
return
}
if strings.HasSuffix(parts[1], ".sha256") {
fmt.Fprint(w, strings.Repeat("0", 64))
return
}
w.Header().Set("Content-Type", "text/html")
w.WriteHeader(status)
fmt.Fprintf(w, "<html><body>HTTP %d</body></html>", status)
})
log.Fatal(http.ListenAndServe("127.0.0.1:18080", nil))
}
$ go run server.go &
$ zip -r repro.zip metadata.lua hooks
$ vfox add repro --source ./repro.zip
$ vfox install repro@404
$ vfox install repro@403
$ vfox install repro@500
$ REPRO_NO_SUM=1 vfox install repro@403
Actual behavior
The 404 is reported as what it is:
$ vfox install repro@404
Preinstalling repro@404...
failed to download repro@404 file, err:source file not found
failed to install repro
The 403 is not, and the 500 and the 429 print the same lines as the 403:
$ vfox install repro@403
Preinstalling repro@403...
Verifying checksum 0000000000000000000000000000000000000000000000000000000000000000...
Checksum error, file: …/.vfox/cache/repro/repro.zip
checksum error
failed to install repro
Without a checksum:
$ REPRO_NO_SUM=1 vfox install repro@403
Preinstalling repro@403...
Verifying checksum ...
WARNING: Checksum is not provided, skip verify...
Unpacking …/.vfox/cache/repro/repro.zip...
unpack failed, err:zip: not a valid zip file
failed to install repro
Expected behavior
Like the 404, a status outside 2xx fails the download itself, naming the status and the URL, for example failed to download repro@403 file, err:unexpected HTTP status 403 Forbidden. Nothing is saved, so the checksum and the unpacking never see a page of HTML.
Where
Download is called by moveRemoteFile, which wraps its error as failed to download <label> file, err:…. The 404 is the only status it looks at, and the file is opened and written right after:
if resp.StatusCode == http.StatusNotFound {
return "", errors.New("source file not found")
}
A check of resp.StatusCode for 2xx after it, before the file is opened, would do. (Downloader.Download in internal/shared/util/downloader.go has the same check, but nothing calls NewDownloader.)
Related: the User-Agent of a download
The requests a plugin makes with http.get carry vfox/1.0.13 vfox-repro/0.0.1 (ensureUserAgent and ComputeUserAgent), but the download goes out as Go-http-client/1.1, unless PreInstall returns headers. The log of the server above shows both:
GET /403/repro.zip.sha256 User-Agent: vfox/1.0.13 vfox-repro/0.0.1
GET /403/repro.zip User-Agent: Go-http-client/1.1
Mirrors and CDNs that refuse Go's default agent, like the one above, are what turns this into the bug. A plugin can work around it by returning headers = { ["User-Agent"] = … } from PreInstall, which vfox applies to the download: with it, the install through Huawei Cloud's mirror above succeeds and passes the checksum. If the download used the agent that the plugin's own requests use, no plugin would have to. I can split this into an issue of its own if you prefer.
- Lingua principale
- Go
- Stelle
- 4k
- Fork
- 167
- Merge medio
- 2g 10h
- PR unite (30g)
- 8
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di version-fox/vfox
-
bug help wanted
Difficoltà 3/5 Mezza giornata Idoneità per principianti 45/100
version-fox/vfox#745 ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement help wanted
Difficoltà 3/5 1-2 giorni Idoneità per principianti 70/100
version-fox/vfox#743 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Follow-ups of #736: plugin updates, the path.mode default and vfox configForse già presa @linghengqian l’ha presa 12 giorni fa. Apertaplan plugin
version-fox/vfox#737 · 1 commento · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
[Feature]: Improve the E2E experience for certain plugin repositories on Windows containersForse già presa @linghengqian l’ha presa 14 giorni fa. Apertaenhancement
version-fox/vfox#733 · 2 commenti · 2 reazioni · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
[BUG]: On Windows, `vfox use java@X` doesn't change `java` when a JDK is in the system PATH and a global SDK is setForse già presa @linghengqian l’ha presa 13 giorni fa. Apertabug
Difficoltà 4/5 3-5 giorni Idoneità per principianti 47/100
version-fox/vfox#732 · 2 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di version-fox/vfox
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
riverqueue/river#1576 ·
I maintainer di solito rispondono entro 1 giorno
-
NFS StorageProvider renders a missing nfsSubDir as "<no value>"Forse già presa @ldming l’ha presa oggi. Apertakind/bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
apecloud/kubeblocks#11067 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
emersion/go-msgauth#87 ·
-
CLI: `describe <ns>.<table>` reports "namespace does not exist" when only the table is missingForse già presa @Shruthirdy l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
apache/iceberg-go#2423 ·
I maintainer di solito rispondono entro 2 giorni
-
good first issue help wanted
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
mafzalkalwardev/mailforge#21 ·