func (c connState) Wrap(nc net.Conn, s http.ConnState) { // There are a few other states defined, most notably StateActive. // Unfortunately it doesn't look like it's possible to make use of // StateActive to implement graceful shutdown, since StateActive is set // after a complete request has been read off the wire with an intent to // process it. If we were to race a graceful shutdown against a // connection that was just read off the wire (but not yet in // StateActive), we would accidentally close the connection out from // underneath an active request. // // We already needed to work around this for Go 1.2 by shimming out a // full net.Conn object, so we can just fall back to the old behavior // there. // // I started a golang-nuts thread about this here: // https://groups.google.com/forum/#!topic/golang-nuts/Xi8yjBGWfCQ // I'd be very eager to find a better way to do this, so reach out to me // if you have any ideas. switch s { case http.StateIdle: if err := listener.MarkIdle(nc); err != nil { log.Printf("error marking conn as idle: %v", err) } case http.StateHijacked: if err := listener.Disown(nc); err != nil { log.Printf("error disowning hijacked conn: %v", err) } } if c != nil { c(nc, s) } }
func (f *fancyWriter) Hijack() (c net.Conn, b *bufio.ReadWriter, e error) { hj := f.basicWriter.ResponseWriter.(http.Hijacker) c, b, e = hj.Hijack() if e == nil { e = listener.Disown(c) } return }