|
Yeah that's a bad repro. Took me a couple minutes to write a concise one. server.go: package main
import (
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.Write([]byte(`
<script>
(async () => {
await fetch("/test", { headers: { range: "bytes=0-4" } }).then(resp => console.log('bytes=0-4', resp.status));
await fetch("/test", { headers: { range: "bytes=0-10" } }).then(resp => console.log('bytes=0-10', resp.status));
})();
</script>
`))
})
http.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
switch r.Header.Get("Range") {
case "bytes=0-4":
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
w.Header().Set("Content-Range", "bytes 0-4/1000000")
w.Header().Set("Last-Modified", "Mon, 03 Mar 2025 00:00:00 GMT")
w.Header().Set("Etag", "1234567890")
w.WriteHeader(http.StatusPartialContent)
w.Write([]byte("01234"))
case "bytes=0-10":
w.WriteHeader(http.StatusForbidden)
w.Write([]byte("Forbidden"))
default:
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("Bad Request"))
}
})
http.ListenAndServe(":8080", nil)
}
`go run server.go` and open up http://localhost:8080 in the browser. For Chrome, in the console one should see bytes=0-4 206
bytes=0-10 206
but if we use "disable cache" this becomes bytes=0-4 206
GET http://localhost:8080/test 403 (Forbidden)
bytes=0-10 403
In both Safari and Firefox the second request is 403, cache or not.Now, is this surprising? Yes. Does this violate any spec? I'll take Chromium dev's word [1] and say likely not. Should it be "fixed"? Hard to say, but I agree that "fixing" it could break existing things. [1] https://issues.chromium.org/issues/390229583#comment16 |