Skip to content

net/http: possible issues with temporary errors from Accept #6163

Closed
@alberts

Description

@alberts
What steps will reproduce the problem?

net/http's accept loop does this check on errors from Accept:

http://golang.org/src/pkg/net/http/server.go#L1544

if ne, ok := e.(net.Error); ok && ne.Temporary() {

which ends up calling into Temporary here:

http://golang.org/src/pkg/syscall/syscall_unix.go#L108

return e == EINTR || e == EMFILE || e.Timeout()

Timeout does:

return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT

With other Go services, under certain rapid connection setup/teardown conditions, I've
seen Accept return ECONNRESET (connection reset by peer) on kernel 3.3.8. According to
the man page, it could also return ECONNABORTED.

I think at least ECONNRESET and maybe also ECONNABORTED should be treated as Temporary
by net/http's accept loop.

If Temporary() can't be changed, it would be nice to add some code somewhere (maybe in
net?) to help other people to write accept loops correctly.

One other minor note: if a process runs out of file descriptors for another reason than
accepting too many connections, the programmer might want EMFILE to be a fatal error,
especially if you have a Listener that limits the number of open HTTP connections. I've
seen this in the real world with a net/http server on top of a misbehaving LevelDB using
the levigo wrapper with the C implementation and large databases. EMFILE might also fall
out in other places in the program where it can be handled as a fatal error, but it
might not. I guess fixing this might be too complicated for Go 1.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions