Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/http: ServeContent sends 416 Requested Range Not Satisfiable when content is empty and range include 0 #54794

Open
Jorropo opened this issue Aug 31, 2022 · 4 comments
Labels
help wanted NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@Jorropo
Copy link
Contributor

Jorropo commented Aug 31, 2022

What version of Go are you using (go version)?

$ go version
go version devel go1.20-d3b35a4242 Wed Aug 31 15:12:21 2022 +0000 linux/amd64

Does this issue reproduce with the latest release?

Yes (go1.19)

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/hugo/.cache/go-build"
GOENV="/home/hugo/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/hugo/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/hugo/go"
GOPRIVATE=""
GOPROXY="direct"
GOROOT="/home/hugo/k/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/hugo/k/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="devel go1.20-d3b35a4242 Wed Aug 31 15:12:21 2022 +0000"
GCCGO="gccgo"
GOAMD64="v3"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/dev/null"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build827233857=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Run this code:

package main

import (
	"errors"
	"io"
	"net/http"
	"time"
)

var nothing io.ReadSeeker = empty{}

type empty struct{}

func (empty) Read(_ []byte) (int, error) {
	return 0, io.EOF
}
func (empty) Seek(offset int64, _ int) (int64, error) {
	if offset == 0 {
		return 0, nil
	}
	return 0, errors.New("out of bound")
}

type handler struct{}

func (handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	http.ServeContent(w, r, "", time.Now(), nothing)
}

func main() {
	err := http.ListenAndServe("127.0.0.1:11111", handler{})
	if err != nil {
		panic(err)
	}
}
$ go run a.go # run in the background
$ curl -IL localhost:11111 -H "Range: bytes=0-1048575"

What did you expect to see?

A 200 with the "complete" file:

HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 0
Content-Type: text/plain; charset=utf-8
Last-Modified: Wed, 31 Aug 2022 15:21:28 GMT
Date: Wed, 31 Aug 2022 15:21:28 GMT

What did you see instead?

HTTP/1.1 416 Requested Range Not Satisfiable
Content-Range: bytes */0
Content-Type: text/plain; charset=utf-8
Last-Modified: Wed, 31 Aug 2022 15:26:49 GMT
X-Content-Type-Options: nosniff
Date: Wed, 31 Aug 2022 15:26:49 GMT
Content-Length: 33

Comments

FWIW Nginx's behaviour is 200 and this is my prefered solution (nothing forces the server to always use requested ranges, you can always decide to override this and send 200).

RFC7233 specify [x,y] ranging.

Reason it's a problem

This make our go backend clash with our nginx caching reverse proxy because we have fragment caching enabled and therefore add a header "Range: bytes=0-1048575" to any requests that dont already have them (which is common practice).
See ipfs/kubo#9238

@seankhliao seankhliao added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Aug 31, 2022
@seankhliao
Copy link
Member

seankhliao commented Aug 31, 2022

cc @neild

@neild
Copy link
Contributor

neild commented Aug 31, 2022

I agree that returning 200 here seems sensible.

@neild neild added help wanted NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Aug 31, 2022
@gopherbot
Copy link

gopherbot commented Aug 31, 2022

Change https://go.dev/cl/427195 mentions this issue: net/http: ignore ranges if the content is empty in serveContent

@seankhliao seankhliao added this to the Go1.20 milestone Sep 3, 2022
@gopherbot
Copy link

gopherbot commented Sep 5, 2022

Change https://go.dev/cl/428355 mentions this issue: net: ServeContent sends 200 when content is empty and range include 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

4 participants