mirror of
https://github.com/minio/minio.git
synced 2025-11-07 12:52:58 -05:00
introduce reader deadlines for net.Conn (#19023)
Bonus: set "retry-after" header for AWS SDKs if possible to honor them.
This commit is contained in:
@@ -22,6 +22,9 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio/internal/deadlineconn"
|
||||
)
|
||||
|
||||
type acceptResult struct {
|
||||
@@ -32,6 +35,7 @@ type acceptResult struct {
|
||||
|
||||
// httpListener - HTTP listener capable of handling multiple server addresses.
|
||||
type httpListener struct {
|
||||
opts TCPOptions
|
||||
tcpListeners []*net.TCPListener // underlying TCP listeners.
|
||||
acceptCh chan acceptResult // channel where all TCP listeners write accepted connection.
|
||||
ctx context.Context
|
||||
@@ -74,7 +78,8 @@ func (listener *httpListener) Accept() (conn net.Conn, err error) {
|
||||
select {
|
||||
case result, ok := <-listener.acceptCh:
|
||||
if ok {
|
||||
return result.conn, result.err
|
||||
return deadlineconn.New(result.conn).
|
||||
WithReadDeadline(listener.opts.ClientReadTimeout), result.err
|
||||
}
|
||||
case <-listener.ctx.Done():
|
||||
}
|
||||
@@ -119,9 +124,10 @@ func (listener *httpListener) Addrs() (addrs []net.Addr) {
|
||||
|
||||
// TCPOptions specify customizable TCP optimizations on raw socket
|
||||
type TCPOptions struct {
|
||||
UserTimeout int // this value is expected to be in milliseconds
|
||||
Interface string // this is a VRF device passed via `--interface` flag
|
||||
Trace func(msg string) // Trace when starting.
|
||||
UserTimeout int // this value is expected to be in milliseconds
|
||||
ClientReadTimeout time.Duration // When the net.Conn is idle for more than ReadTimeout duration, we close the connection on the client proactively.
|
||||
Interface string // this is a VRF device passed via `--interface` flag
|
||||
Trace func(msg string) // Trace when starting.
|
||||
}
|
||||
|
||||
// newHTTPListener - creates new httpListener object which is interface compatible to net.Listener.
|
||||
@@ -173,6 +179,7 @@ func newHTTPListener(ctx context.Context, serverAddrs []string, opts TCPOptions)
|
||||
listener = &httpListener{
|
||||
tcpListeners: tcpListeners,
|
||||
acceptCh: make(chan acceptResult, len(tcpListeners)),
|
||||
opts: opts,
|
||||
}
|
||||
listener.ctx, listener.ctxCanceler = context.WithCancel(ctx)
|
||||
if opts.Trace != nil {
|
||||
|
||||
@@ -109,8 +109,12 @@ func (srv *Server) Init(listenCtx context.Context, listenErrCallback func(listen
|
||||
wrappedHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// If server is in shutdown.
|
||||
if atomic.LoadUint32(&srv.inShutdown) != 0 {
|
||||
// To indicate disable keep-alive
|
||||
// To indicate disable keep-alive, server is shutting down.
|
||||
w.Header().Set("Connection", "close")
|
||||
|
||||
// Add 1 minute retry header, incase-client wants to honor it
|
||||
w.Header().Set(RetryAfter, "60")
|
||||
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
w.Write([]byte(http.ErrServerClosed.Error()))
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user