Skip to content

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

Closed
@rsto

Description

@rsto

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions