• Tom Bergan's avatar
    http2: always delay closing the connection after sending GOAWAY · cd69bc3f
    Tom Bergan authored
    Currently, we close the connection immediately after sending a GOAWAY
    frame if all outstanding responses have been completely sent. However,
    the client may have had requests in-flight at that time which have been
    queued in the kernel receive buffer. On both Windows and Linux, if the
    connection is close()'d when the receive buffer is not empty, the kernel
    sends RST. This has the effect of aborting both sides of the connection,
    meaning the client may not actually receive all responses that were sent
    before the GOAWAY.
    
    Instead, we should delay calling close() until after the receive buffer
    has been drained. We don't want to delay indefinitely, which means we
    need some kind of timeout. Ideally that timeout should be about 1 RTT +
    epsilon, under the assumption that the client will not send any more
    frames after receiving the GOAWAY. However, 1 RTT is difficult to
    measure. It turns out we were already using a 1 second delay in other
    cases, so we reuse that same delay here.
    
    Note that we do not call CloseWrite() to half-close the underlying TLS
    connection. This seems unnecessary -- GOAWAY is effectively a half-close
    at the HTTP/2 level.
    
    Updates golang/go#18701 (fixes after it's bundled into net/http)
    
    Change-Id: I4d68bada6369ba95e5db02afe6dfad0a393c0334
    Reviewed-on: https://go-review.googlesource.com/71372
    Run-TryBot: Tom Bergan <tombergan@google.com>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
    Reviewed-by: 's avatarJoe Tsai <thebrokentoaster@gmail.com>
    cd69bc3f
write.go 10.5 KB