diff options
| author | Kenny Grant <kennygrant@gmail.com> | 2016-08-26 22:21:00 +0100 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@golang.org> | 2016-11-11 18:16:12 +0000 |
| commit | 84ded8ba8a0233a7f38e3c777dc1c213f98d00a2 (patch) | |
| tree | 5c9f1fd76c674e7c1775db2f7e004dc3baa822e7 /src/net/http/server.go | |
| parent | 238247eb59cdddeedaa5c5db67734df2cd1049ab (diff) | |
| download | go-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.go | 37 |
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 } |
