aboutsummaryrefslogtreecommitdiff
path: root/src/net/http/server.go
diff options
context:
space:
mode:
authorKenny Grant <kennygrant@gmail.com>2016-08-26 22:21:00 +0100
committerBrad Fitzpatrick <bradfitz@golang.org>2016-11-11 18:16:12 +0000
commit84ded8ba8a0233a7f38e3c777dc1c213f98d00a2 (patch)
tree5c9f1fd76c674e7c1775db2f7e004dc3baa822e7 /src/net/http/server.go
parent238247eb59cdddeedaa5c5db67734df2cd1049ab (diff)
downloadgo-84ded8ba8a0233a7f38e3c777dc1c213f98d00a2.tar.xz
net/http: make Server log on bad requests from clients
Fixes #12745 Change-Id: Iebb7c97cb5b68dc080644d796a6ca1c120d41b26 Reviewed-on: https://go-review.googlesource.com/27950 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/net/http/server.go')
-rw-r--r--src/net/http/server.go37
1 files changed, 29 insertions, 8 deletions
diff --git a/src/net/http/server.go b/src/net/http/server.go
index 257d82f8ac..8a79a6c6a4 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -1682,6 +1682,23 @@ func (e badRequestError) Error() string { return "Bad Request: " + string(e) }
// trace to the server's error log.
var ErrAbortHandler = errors.New("net/http: abort Handler")
+// isCommonNetReadError reports whether err is a common error
+// encountered during reading a request off the network when the
+// client has gone away or had its read fail somehow. This is used to
+// determine which logs are interesting enough to log about.
+func isCommonNetReadError(err error) bool {
+ if err == io.EOF {
+ return true
+ }
+ if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
+ return true
+ }
+ if oe, ok := err.(*net.OpError); ok && oe.Op == "read" {
+ return true
+ }
+ return false
+}
+
// Serve a new connection.
func (c *conn) serve(ctx context.Context) {
c.remoteAddr = c.rwc.RemoteAddr().String()
@@ -1737,27 +1754,31 @@ func (c *conn) serve(ctx context.Context) {
c.setState(c.rwc, StateActive)
}
if err != nil {
+ const errorHeaders = "\r\nContent-Type: text/plain; charset=utf-8\r\nConnection: close\r\n\r\n"
+
if err == errTooLarge {
// Their HTTP client may or may not be
// able to read this if we're
// responding to them and hanging up
// while they're still writing their
// request. Undefined behavior.
- io.WriteString(c.rwc, "HTTP/1.1 431 Request Header Fields Too Large\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\n431 Request Header Fields Too Large")
+ const publicErr = "431 Request Header Fields Too Large"
+ c.server.logf("http: %s", publicErr)
+ fmt.Fprintf(c.rwc, "HTTP/1.1 "+publicErr+errorHeaders+publicErr)
c.closeWriteAndWait()
return
}
- if err == io.EOF {
+ if isCommonNetReadError(err) {
return // don't reply
}
- if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
- return // don't reply
- }
- var publicErr string
+
+ publicErr := "400 Bad Request"
if v, ok := err.(badRequestError); ok {
- publicErr = ": " + string(v)
+ publicErr = publicErr + ": " + string(v)
}
- io.WriteString(c.rwc, "HTTP/1.1 400 Bad Request\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\n400 Bad Request"+publicErr)
+
+ c.server.logf("http: %s", publicErr)
+ fmt.Fprintf(c.rwc, "HTTP/1.1 "+publicErr+errorHeaders+publicErr)
return
}