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 for a directory unexpectedly closes the socket #10196

Closed
rsto opened this issue Mar 19, 2015 · 2 comments

Comments

Projects
None yet
3 participants
@rsto
Copy link
Contributor

commented Mar 19, 2015

Using http's ServeContent, a GET on a directory opened by os.Open unexpectedly closes the socket. The Content-Length header contains a non-zero size but then not a single byte is written in the HTTP body.

This is because a directory opened with os.Open seeks to a positive size but fails when read. I report this as an issue for net/http, instead os, since I am not sure if this is allowed behaviour for a directory. For HTTP, reporting a non-zero Content-Length with an empty body during GET in my understanding isn't.

How to reproduce this issue

GET a directory served by http.ServeContent on a real filesystem:

$ curl -i http://localhost:8080/
HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 68
Content-Type: text/plain; charset=utf-8
Last-Modified: Thu, 19 Mar 2015 07:57:56 GMT
Date: Thu, 19 Mar 2015 07:57:56 GMT

curl: (18) transfer closed with 68 bytes remaining to read

Source: https://play.golang.org/p/Tm5SPq9uag

$ go version
go version devel +ecd630d Wed Mar 18 00:59:49 2015 +0000 darwin/amd64

Same for Go 1.4.1 and 1.4.2 on OS X and Linux.

Demo that a directory seeks to a positive size but fails when read

seekdir.go seeks a directory, rewinds and tries to read:

$ go run seekdir.go
seekSize: 374
2015/03/19 09:09:29 read /tmp: is a directory
exit status 1

Source: https://play.golang.org/p/aeJkT4OsPV

How to fix this

Unfortunately I couldn't come up with a good solution. In my understanding, http.ServeContent is fine.

I had hoped that inspecting the return values of CopyN in fs.go line 257 for zero or error would help. But at this point, one can't rewrite the Content-Length header.

If a directory should remain seekable but not readable, a workaround in ServeContent could be to try to read the first n bytes in a buffer before calling WriteHeader.

@bradfitz bradfitz added this to the Go1.5 milestone Mar 20, 2015

@bradfitz bradfitz self-assigned this Mar 20, 2015

@bradfitz

This comment has been minimized.

Copy link
Member

commented Mar 23, 2015

I'm inclined to do nothing here. It's the caller's fault for passing bogus values to ServeContent.

I don't see the value in hiding the problem.

Please argue if I'm missing the point.

@bradfitz bradfitz closed this Mar 23, 2015

@rsto

This comment has been minimized.

Copy link
Contributor Author

commented Mar 23, 2015

No need to argue, I agree (but had hoped to see this fixed here). I'll check back with Nigel Tao if he wants to work around this in net/webdav. Thanks.

@golang golang locked and limited conversation to collaborators Jun 25, 2016

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.