mirror of
https://github.com/minio/minio.git
synced 2025-11-07 04:42:56 -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:
@@ -24,6 +24,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -297,7 +298,6 @@ const (
|
||||
ErrAdminConfigLDAPValidation
|
||||
ErrAdminConfigIDPCfgNameAlreadyExists
|
||||
ErrAdminConfigIDPCfgNameDoesNotExist
|
||||
ErrAdminCredentialsMismatch
|
||||
ErrInsecureClientRequest
|
||||
ErrObjectTampered
|
||||
|
||||
@@ -1425,11 +1425,6 @@ var errorCodes = errorCodeMap{
|
||||
Description: "Unable to perform the requested operation because profiling is not enabled",
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
},
|
||||
ErrAdminCredentialsMismatch: {
|
||||
Code: "XMinioAdminCredentialsMismatch",
|
||||
Description: "Credentials in config mismatch with server environment variables",
|
||||
HTTPStatusCode: http.StatusServiceUnavailable,
|
||||
},
|
||||
ErrAdminBucketQuotaExceeded: {
|
||||
Code: "XMinioAdminBucketQuotaExceeded",
|
||||
Description: "Bucket quota exceeded",
|
||||
@@ -2082,6 +2077,11 @@ func toAPIErrorCode(ctx context.Context, err error) (apiErr APIErrorCode) {
|
||||
return ErrNone
|
||||
}
|
||||
|
||||
// Errors that are generated by net.Conn and any context errors must be handled here.
|
||||
if errors.Is(err, os.ErrDeadlineExceeded) || errors.Is(err, context.DeadlineExceeded) {
|
||||
return ErrRequestTimedout
|
||||
}
|
||||
|
||||
// Only return ErrClientDisconnected if the provided context is actually canceled.
|
||||
// This way downstream context.Canceled will still report ErrRequestTimedout
|
||||
if contextCanceled(ctx) && errors.Is(ctx.Err(), context.Canceled) {
|
||||
|
||||
@@ -946,11 +946,13 @@ func writeSuccessResponseHeadersOnly(w http.ResponseWriter) {
|
||||
|
||||
// writeErrorRespone writes error headers
|
||||
func writeErrorResponse(ctx context.Context, w http.ResponseWriter, err APIError, reqURL *url.URL) {
|
||||
switch err.Code {
|
||||
case "SlowDown", "XMinioServerNotInitialized", "XMinioReadQuorum", "XMinioWriteQuorum":
|
||||
if err.HTTPStatusCode == http.StatusServiceUnavailable {
|
||||
// Set retry-after header to indicate user-agents to retry request after 120secs.
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
|
||||
w.Header().Set(xhttp.RetryAfter, "120")
|
||||
}
|
||||
|
||||
switch err.Code {
|
||||
case "InvalidRegion":
|
||||
err.Description = fmt.Sprintf("Region does not match; expecting '%s'.", globalSite.Region)
|
||||
case "AuthorizationHeaderMalformed":
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -394,6 +394,7 @@ func buildServerCtxt(ctx *cli.Context, ctxt *serverCtxt) (err error) {
|
||||
ctxt.UserTimeout = ctx.Duration("conn-user-timeout")
|
||||
ctxt.ConnReadDeadline = ctx.Duration("conn-read-deadline")
|
||||
ctxt.ConnWriteDeadline = ctx.Duration("conn-write-deadline")
|
||||
ctxt.ConnClientReadDeadline = ctx.Duration("conn-client-read-deadline")
|
||||
|
||||
ctxt.ShutdownTimeout = ctx.Duration("shutdown-timeout")
|
||||
ctxt.IdleTimeout = ctx.Duration("idle-timeout")
|
||||
|
||||
@@ -160,9 +160,10 @@ type serverCtxt struct {
|
||||
FTP []string
|
||||
SFTP []string
|
||||
|
||||
UserTimeout time.Duration
|
||||
ConnReadDeadline time.Duration
|
||||
ConnWriteDeadline time.Duration
|
||||
UserTimeout time.Duration
|
||||
ConnReadDeadline time.Duration
|
||||
ConnWriteDeadline time.Duration
|
||||
ConnClientReadDeadline time.Duration
|
||||
|
||||
ShutdownTimeout time.Duration
|
||||
IdleTimeout time.Duration
|
||||
|
||||
@@ -101,6 +101,12 @@ var ServerFlags = []cli.Flag{
|
||||
EnvVar: "MINIO_READ_HEADER_TIMEOUT",
|
||||
Hidden: true,
|
||||
},
|
||||
cli.DurationFlag{
|
||||
Name: "conn-client-read-deadline",
|
||||
Usage: "custom connection READ deadline for incoming requests",
|
||||
Hidden: true,
|
||||
EnvVar: "MINIO_CONN_CLIENT_READ_DEADLINE",
|
||||
},
|
||||
cli.DurationFlag{
|
||||
Name: "conn-read-deadline",
|
||||
Usage: "custom connection READ deadline",
|
||||
@@ -351,8 +357,9 @@ func serverHandleCmdArgs(ctxt serverCtxt) {
|
||||
})
|
||||
|
||||
globalTCPOptions = xhttp.TCPOptions{
|
||||
UserTimeout: int(ctxt.UserTimeout.Milliseconds()),
|
||||
Interface: ctxt.Interface,
|
||||
UserTimeout: int(ctxt.UserTimeout.Milliseconds()),
|
||||
ClientReadTimeout: ctxt.ConnClientReadDeadline,
|
||||
Interface: ctxt.Interface,
|
||||
}
|
||||
|
||||
// On macOS, if a process already listens on LOCALIPADDR:PORT, net.Listen() falls back
|
||||
|
||||
Reference in New Issue
Block a user