From e48005ddc72d0a26f689a77962a15d8eaa99bfe2 Mon Sep 17 00:00:00 2001 From: Praveen raj Mani Date: Thu, 3 Oct 2019 12:38:12 +0530 Subject: [PATCH] Add more context to rpc version mismatch errors (#8271) Fixes #5665 --- cmd/admin-router.go | 2 +- cmd/api-errors.go | 6 ++++++ cmd/api-response.go | 11 +++++++++++ cmd/handler-utils.go | 15 +++++++++++++++ cmd/lock-rest-server.go | 2 +- cmd/peer-rest-server.go | 2 +- cmd/storage-rest-server.go | 2 +- 7 files changed, 36 insertions(+), 4 deletions(-) diff --git a/cmd/admin-router.go b/cmd/admin-router.go index 47f987c66..aee2dd9cd 100644 --- a/cmd/admin-router.go +++ b/cmd/admin-router.go @@ -142,5 +142,5 @@ func registerAdminRouter(router *mux.Router, enableConfigOps, enableIAMOps bool) adminV1Router.Methods(http.MethodGet).Path("/kms/key/status").HandlerFunc(httpTraceAll(adminAPI.KMSKeyStatusHandler)) // If none of the routes match, return error. - adminV1Router.NotFoundHandler = http.HandlerFunc(httpTraceHdrs(notFoundHandlerJSON)) + adminV1Router.MethodNotAllowedHandler = http.HandlerFunc(httpTraceAll(versionMismatchHandler)) } diff --git a/cmd/api-errors.go b/cmd/api-errors.go index 153070a25..fb2dcca54 100644 --- a/cmd/api-errors.go +++ b/cmd/api-errors.go @@ -141,6 +141,7 @@ const ( ErrInvalidPrefixMarker ErrBadRequest ErrKeyTooLongError + ErrInvalidAPIVersion // Add new error codes here. // SSE-S3 related API errors @@ -1502,6 +1503,11 @@ var errorCodes = errorCodeMap{ Description: "Invalid according to Policy: Policy Condition failed", HTTPStatusCode: http.StatusForbidden, }, + ErrInvalidAPIVersion: { + Code: "ErrInvalidAPIVersion", + Description: "Invalid version found in the request", + HTTPStatusCode: http.StatusNotFound, + }, // Add your error structure here. } diff --git a/cmd/api-response.go b/cmd/api-response.go index 24f86567f..e9d3f0709 100644 --- a/cmd/api-response.go +++ b/cmd/api-response.go @@ -703,6 +703,17 @@ func writeErrorResponseJSON(ctx context.Context, w http.ResponseWriter, err APIE writeResponse(w, err.HTTPStatusCode, encodedErrorResponse, mimeJSON) } +// writeVersionMismatchResponse - writes custom error responses for version mismatches. +func writeVersionMismatchResponse(ctx context.Context, w http.ResponseWriter, err APIError, reqURL *url.URL, isJSON bool) { + if isJSON { + // Generate error response. + errorResponse := getAPIErrorResponse(ctx, err, reqURL.String(), w.Header().Get(xhttp.AmzRequestID), globalDeploymentID) + writeResponse(w, err.HTTPStatusCode, encodeResponseJSON(errorResponse), mimeJSON) + } else { + writeResponse(w, err.HTTPStatusCode, []byte(err.Description), mimeNone) + } +} + // writeCustomErrorResponseJSON - similar to writeErrorResponseJSON, // but accepts the error message directly (this allows messages to be // dynamically generated.) diff --git a/cmd/handler-utils.go b/cmd/handler-utils.go index 981c739c4..068fb54ef 100644 --- a/cmd/handler-utils.go +++ b/cmd/handler-utils.go @@ -385,6 +385,21 @@ func notFoundHandler(w http.ResponseWriter, r *http.Request) { writeErrorResponse(context.Background(), w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) } +// If the API version does not match with current version. +func versionMismatchHandler(w http.ResponseWriter, r *http.Request) { + path := r.URL.Path + switch { + case strings.HasPrefix(path, minioReservedBucketPath+"/peer/"): + writeVersionMismatchResponse(r.Context(), w, errorCodes.ToAPIErr(ErrInvalidAPIVersion), r.URL, false) + case strings.HasPrefix(path, minioReservedBucketPath+"/storage/"): + writeVersionMismatchResponse(r.Context(), w, errorCodes.ToAPIErr(ErrInvalidAPIVersion), r.URL, false) + case strings.HasPrefix(path, minioReservedBucketPath+"/lock/"): + writeVersionMismatchResponse(r.Context(), w, errorCodes.ToAPIErr(ErrInvalidAPIVersion), r.URL, false) + default: + writeVersionMismatchResponse(r.Context(), w, errorCodes.ToAPIErr(ErrInvalidAPIVersion), r.URL, true) + } +} + // gets host name for current node func getHostName(r *http.Request) (hostName string) { if globalIsDistXL { diff --git a/cmd/lock-rest-server.go b/cmd/lock-rest-server.go index 4ba7ef75b..77c940876 100644 --- a/cmd/lock-rest-server.go +++ b/cmd/lock-rest-server.go @@ -255,7 +255,7 @@ func registerLockRESTHandlers(router *mux.Router) { subrouter.Methods(http.MethodPost).Path(SlashSeparator + lockRESTMethodForceUnlock).HandlerFunc(httpTraceHdrs(globalLockServer.ForceUnlockHandler)).Queries(queries...) subrouter.Methods(http.MethodPost).Path(SlashSeparator + lockRESTMethodExpired).HandlerFunc(httpTraceAll(globalLockServer.ExpiredHandler)).Queries(queries...) - router.NotFoundHandler = http.HandlerFunc(httpTraceAll(notFoundHandler)) + router.MethodNotAllowedHandler = http.HandlerFunc(httpTraceAll(versionMismatchHandler)) // Start lock maintenance from all lock servers. go startLockMaintenance(globalLockServer) diff --git a/cmd/peer-rest-server.go b/cmd/peer-rest-server.go index 2c6c90610..196e14ede 100644 --- a/cmd/peer-rest-server.go +++ b/cmd/peer-rest-server.go @@ -1007,5 +1007,5 @@ func registerPeerRESTHandlers(router *mux.Router) { subrouter.Methods(http.MethodPost).Path(SlashSeparator + peerRESTMethodBackgroundHealStatus).HandlerFunc(server.BackgroundHealStatusHandler) subrouter.Methods(http.MethodPost).Path(SlashSeparator + peerRESTMethodLog).HandlerFunc(server.ConsoleLogHandler) - router.NotFoundHandler = http.HandlerFunc(httpTraceAll(notFoundHandler)) + router.MethodNotAllowedHandler = http.HandlerFunc(httpTraceAll(versionMismatchHandler)) } diff --git a/cmd/storage-rest-server.go b/cmd/storage-rest-server.go index 14d464215..ef7b95d73 100644 --- a/cmd/storage-rest-server.go +++ b/cmd/storage-rest-server.go @@ -617,5 +617,5 @@ func registerStorageRESTHandlers(router *mux.Router, endpoints EndpointList) { subrouter.Methods(http.MethodPost).Path(SlashSeparator + storageRESTMethodGetInstanceID).HandlerFunc(httpTraceAll(server.GetInstanceID)) } - router.NotFoundHandler = http.HandlerFunc(httpTraceAll(notFoundHandler)) + router.MethodNotAllowedHandler = http.HandlerFunc(httpTraceAll(versionMismatchHandler)) }