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
Closed

net/http: ServeContent for a directory unexpectedly closes the socket #10196

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

Comments

@rsto
Copy link
Contributor

rsto 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
Copy link
Contributor

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.

@rsto
Copy link
Contributor Author

rsto 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.
Projects
None yet
Development

No branches or pull requests

3 participants