Skip to content

Unable to disable keep-alive in http server #2011

Closed
@gopherbot

Description

@gopherbot

by thomas.intlayer:

If you use http.ListenAndServe() to create a simple HTTP server, you have no way to
force non-keep-alive responses to clients who request keep-alive.

ResponseWriter does not have a Close field and setting a "Connection: close"
header does to work either.
Setting Request.Close to true does not help aswell.

The bug gets bad as serve() in server.go loops one more time because w.closeAfterReply
is false, trying to read another request even if the client is gone which in turn can
take a long time since the default read and write timeouts are set to 0 aka infinity.
This is a problem for server that need to close connections right away or otherwise end
up exhausting file descriptors.

There is a dirty hack to force closing of connections:
send a Connection: close header and overwrite w.ProtoMinor with 0.
This works as HTTP/1.0 does not do keep-alive by default and the Go code will set
w.closeAfterReply to true internally. It might have sideeffects which I did not explore
so be aware!


PS: I would even consider it a security issue that you can't forcefully close
connections as this leaves the server open for trivial DoS attacks.
Though I do not see how this can be completely fixed without some major changes in how
the http package works (you need non-blocking or curl-style callback (to measure
transfer speed) functionality to combat Slowloris for example)


Suggested fixes:
- expose a method to close client connections forcefully, maybe expose ClientConn to the
server
- set w.closeAfterReply if (to be added) w.Close is true or "Connection:
close" header exists
- set default read and write timeouts to something like 300 seconds

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions