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

embed: unable to access embed openFile Seek method #44175

Closed
nekinie opened this issue Feb 8, 2021 · 4 comments
Closed

embed: unable to access embed openFile Seek method #44175

nekinie opened this issue Feb 8, 2021 · 4 comments

Comments

@nekinie
Copy link

nekinie commented Feb 8, 2021

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

go version go1.16rc1 linux/amd64

Does this issue reproduce with the latest release?

yes

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

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/nekinie/.cache/go-build"
GOENV="/home/nekinie/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/nekinie/Go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/nekinie/Go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/nekinie/sdk/go1.16rc1"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/nekinie/sdk/go1.16rc1/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.16rc1"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/nekinie/Projects/cthulhu/go.mod"
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 -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build3754598342=/tmp/go-build -gno-record-gcc-switches"

What did you do?

//go:embed html/* css/compiled.css
var static embed.FS

func serveFile(name string) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		file, err := static.Open(name)
		if err != nil {
			http.Error(w, "file not found", http.StatusNotFound)
			return
		}

		defer file.Close()
		http.ServeContent(w, r, file.Name(), file.ModTime(), file)
	}
}

What did you expect to see?

The file to be served.

What did you see instead?

./main.go:32:31: file.Name undefined (type fs.File has no field or method Name)
./main.go:32:44: file.ModTime undefined (type fs.File has no field or method ModTime)
./main.go:32:52: cannot use file (type fs.File) as type io.ReadSeeker in argument to http.ServeContent:
        fs.File does not implement io.ReadSeeker (missing Seek method)

Extra

embed.openFile implements io.ReadSeeker:
https://github.com/golang/go/blob/master/src/embed/embed.go#L357

but we return fs.File interface when opening a file:
https://github.com/golang/go/blob/master/src/embed/embed.go#L295

and the openFile type is not public:
https://github.com/golang/go/blob/master/src/embed/embed.go#L337

My opinion is openFile type should be public and we should return it instead of fs.FS
Edit: On second thought, I think the openFile and openDir types being public would be enough

@nekinie
Copy link
Author

nekinie commented Feb 8, 2021

@ianlancetaylor ianlancetaylor changed the title Unable to access embed openFile Seek method embed: unable to access embed openFile Seek method Feb 8, 2021
@ianlancetaylor
Copy link
Contributor

The intent is that you write the code to work with any file system, perhaps like this:

func serveFile(name string) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		file, err := static.Open(name)
		if err != nil {
			http.Error(w, "file not found", http.StatusNotFound)
			return
		}

		defer file.Close()
		st, err := file.Stat()
		if err != nil {
			http.Error(w, err.Error(), http.StatusForbidden)
			return
		}
		http.ServeContent(w, r, name, st.ModTime(), file.(io.ReadSeeker))
	}
}

@nekinie
Copy link
Author

nekinie commented Feb 9, 2021

I can confirm this resolves my issue.
I assume file.(io.ReadSeeker) works because the underlying Seeker method is already publicly exposed.
Thanks for taking the time to look at this.

@kamranjon
Copy link

Does this work with the renderer? I'm getting:
no such file or directory
When my TMX file references a png tileset.

looking at this line here and wondering if it works with the embedded FS impl: https://github.com/lafriks/go-tiled/blob/master/render/renderer.go#L89

@golang golang locked and limited conversation to collaborators Jan 3, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants