diff --git a/cmd/api-router.go b/cmd/api-router.go index cf2a18648..28e749b65 100644 --- a/cmd/api-router.go +++ b/cmd/api-router.go @@ -112,21 +112,21 @@ func registerAPIRouter(router *mux.Router, encryptionEnabled, allowSSEKMS bool) // DeleteObject bucket.Methods(http.MethodDelete).Path("/{object:.+}").HandlerFunc(collectAPIStats("deleteobject", httpTraceAll(api.DeleteObjectHandler))) // PutObjectLegalHold - bucket.Methods(http.MethodPut).Path("/{object:.+}").HandlerFunc(httpTraceHdrs(api.PutObjectLegalHoldHandler)).Queries("legal-hold", "").Queries("versionId", "") + bucket.Methods(http.MethodPut).Path("/{object:.+}").HandlerFunc(collectAPIStats("putobjectlegalhold", httpTraceHdrs(api.PutObjectLegalHoldHandler))).Queries("legal-hold", "").Queries("versionId", "") // GetObjectLegalHold - bucket.Methods(http.MethodGet).Path("/{object:.+}").HandlerFunc(httpTraceHdrs(api.GetObjectLegalHoldHandler)).Queries("legal-hold", "").Queries("versionId", "") + bucket.Methods(http.MethodGet).Path("/{object:.+}").HandlerFunc(collectAPIStats("getobjectlegalhold", httpTraceHdrs(api.GetObjectLegalHoldHandler))).Queries("legal-hold", "").Queries("versionId", "") // PutObjectRetention - bucket.Methods(http.MethodPut).Path("/{object:.+}").HandlerFunc(httpTraceHdrs(api.PutObjectRetentionHandler)).Queries("retention", "").Queries("versionId", "") + bucket.Methods(http.MethodPut).Path("/{object:.+}").HandlerFunc(collectAPIStats("putobjectretention", httpTraceHdrs(api.PutObjectRetentionHandler))).Queries("retention", "").Queries("versionId", "") // GetObjectRetention - bucket.Methods(http.MethodGet).Path("/{object:.+}").HandlerFunc(httpTraceHdrs(api.GetObjectRetentionHandler)).Queries("retention", "").Queries("versionId", "") + bucket.Methods(http.MethodGet).Path("/{object:.+}").HandlerFunc(collectAPIStats("getobjectretention", httpTraceHdrs(api.GetObjectRetentionHandler))).Queries("retention", "").Queries("versionId", "") /// Bucket operations // GetBucketLocation bucket.Methods(http.MethodGet).HandlerFunc(collectAPIStats("getbucketlocation", httpTraceAll(api.GetBucketLocationHandler))).Queries("location", "") // GetBucketPolicy - bucket.Methods("GET").HandlerFunc(collectAPIStats("getbucketpolicy", httpTraceAll(api.GetBucketPolicyHandler))).Queries("policy", "") + bucket.Methods(http.MethodGet).HandlerFunc(collectAPIStats("getbucketpolicy", httpTraceAll(api.GetBucketPolicyHandler))).Queries("policy", "") // GetBucketLifecycle - bucket.Methods("GET").HandlerFunc(collectAPIStats("getbucketlifecycle", httpTraceAll(api.GetBucketLifecycleHandler))).Queries("lifecycle", "") + bucket.Methods(http.MethodGet).HandlerFunc(collectAPIStats("getbucketlifecycle", httpTraceAll(api.GetBucketLifecycleHandler))).Queries("lifecycle", "") // Dummy Bucket Calls // GetBucketACL -- this is a dummy call. @@ -153,9 +153,9 @@ func registerAPIRouter(router *mux.Router, encryptionEnabled, allowSSEKMS bool) bucket.Methods(http.MethodDelete).HandlerFunc(collectAPIStats("deletebuckettagging", httpTraceAll(api.DeleteBucketTaggingHandler))).Queries("tagging", "") // GetBucketObjectLockConfig - bucket.Methods(http.MethodGet).HandlerFunc(httpTraceAll(api.GetBucketObjectLockConfigHandler)).Queries("object-lock", "") + bucket.Methods(http.MethodGet).HandlerFunc(collectAPIStats("getbucketobjectlockconfiguration", httpTraceAll(api.GetBucketObjectLockConfigHandler))).Queries("object-lock", "") // GetBucketVersioning - bucket.Methods(http.MethodGet).HandlerFunc(httpTraceAll(api.GetBucketVersioningHandler)).Queries("versioning", "") + bucket.Methods(http.MethodGet).HandlerFunc(collectAPIStats("getbucketversioning", httpTraceAll(api.GetBucketVersioningHandler))).Queries("versioning", "") // GetBucketNotification bucket.Methods(http.MethodGet).HandlerFunc(collectAPIStats("getbucketnotification", httpTraceAll(api.GetBucketNotificationHandler))).Queries("notification", "") // ListenBucketNotification @@ -167,16 +167,16 @@ func registerAPIRouter(router *mux.Router, encryptionEnabled, allowSSEKMS bool) // ListBucketVersions bucket.Methods(http.MethodGet).HandlerFunc(collectAPIStats("listbucketversions", httpTraceAll(api.ListBucketObjectVersionsHandler))).Queries("versions", "") // ListObjectsV1 (Legacy) - bucket.Methods("GET").HandlerFunc(collectAPIStats("listobjectsv1", httpTraceAll(api.ListObjectsV1Handler))) + bucket.Methods(http.MethodGet).HandlerFunc(collectAPIStats("listobjectsv1", httpTraceAll(api.ListObjectsV1Handler))) // PutBucketLifecycle - bucket.Methods("PUT").HandlerFunc(collectAPIStats("putbucketlifecycle", httpTraceAll(api.PutBucketLifecycleHandler))).Queries("lifecycle", "") + bucket.Methods(http.MethodPut).HandlerFunc(collectAPIStats("putbucketlifecycle", httpTraceAll(api.PutBucketLifecycleHandler))).Queries("lifecycle", "") // PutBucketPolicy - bucket.Methods("PUT").HandlerFunc(collectAPIStats("putbucketpolicy", httpTraceAll(api.PutBucketPolicyHandler))).Queries("policy", "") + bucket.Methods(http.MethodPut).HandlerFunc(collectAPIStats("putbucketpolicy", httpTraceAll(api.PutBucketPolicyHandler))).Queries("policy", "") // PutBucketObjectLockConfig - bucket.Methods(http.MethodPut).HandlerFunc(httpTraceAll(api.PutBucketObjectLockConfigHandler)).Queries("object-lock", "") + bucket.Methods(http.MethodPut).HandlerFunc(collectAPIStats("putbucketobjectlockconfig", httpTraceAll(api.PutBucketObjectLockConfigHandler))).Queries("object-lock", "") // PutBucketVersioning - bucket.Methods(http.MethodPut).HandlerFunc(httpTraceAll(api.PutBucketVersioningHandler)).Queries("versioning", "") + bucket.Methods(http.MethodPut).HandlerFunc(collectAPIStats("putbucketversioning", httpTraceAll(api.PutBucketVersioningHandler))).Queries("versioning", "") // PutBucketNotification bucket.Methods(http.MethodPut).HandlerFunc(collectAPIStats("putbucketnotification", httpTraceAll(api.PutBucketNotificationHandler))).Queries("notification", "") // PutBucket @@ -188,9 +188,9 @@ func registerAPIRouter(router *mux.Router, encryptionEnabled, allowSSEKMS bool) // DeleteMultipleObjects bucket.Methods(http.MethodPost).HandlerFunc(collectAPIStats("deletemultipleobjects", httpTraceAll(api.DeleteMultipleObjectsHandler))).Queries("delete", "") // DeleteBucketPolicy - bucket.Methods("DELETE").HandlerFunc(collectAPIStats("deletebucketpolicy", httpTraceAll(api.DeleteBucketPolicyHandler))).Queries("policy", "") + bucket.Methods(http.MethodDelete).HandlerFunc(collectAPIStats("deletebucketpolicy", httpTraceAll(api.DeleteBucketPolicyHandler))).Queries("policy", "") // DeleteBucketLifecycle - bucket.Methods("DELETE").HandlerFunc(collectAPIStats("deletebucketlifecycle", httpTraceAll(api.DeleteBucketLifecycleHandler))).Queries("lifecycle", "") + bucket.Methods(http.MethodDelete).HandlerFunc(collectAPIStats("deletebucketlifecycle", httpTraceAll(api.DeleteBucketLifecycleHandler))).Queries("lifecycle", "") // DeleteBucket bucket.Methods(http.MethodDelete).HandlerFunc(collectAPIStats("deletebucket", httpTraceAll(api.DeleteBucketHandler))) } diff --git a/cmd/bucket-handlers.go b/cmd/bucket-handlers.go index fb8bb2c90..1bffe0fc6 100644 --- a/cmd/bucket-handlers.go +++ b/cmd/bucket-handlers.go @@ -984,7 +984,9 @@ func (api objectAPIHandlers) PutBucketObjectLockConfigHandler(w http.ResponseWri config, err := parseObjectLockConfig(r.Body) if err != nil { - writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMalformedXML), r.URL, guessIsBrowserReq(r)) + apiErr := errorCodes.ToAPIErr(ErrMalformedXML) + apiErr.Description = err.Error() + writeErrorResponse(ctx, w, apiErr, r.URL, guessIsBrowserReq(r)) return } diff --git a/cmd/object-lock.go b/cmd/object-lock.go index c64e483b1..9dbc4e687 100644 --- a/cmd/object-lock.go +++ b/cmd/object-lock.go @@ -94,6 +94,13 @@ type DefaultRetention struct { Years *uint64 `xml:"Years"` } +// Maximum support retention days and years supported by AWS S3. +const ( + // This tested by using `mc lock` command + maximumRetentionDays = 36500 + maximumRetentionYears = 100 +) + // UnmarshalXML - decodes XML data. func (dr *DefaultRetention) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { // Make subtype to avoid recursive UnmarshalXML(). @@ -120,10 +127,15 @@ func (dr *DefaultRetention) UnmarshalXML(d *xml.Decoder, start xml.StartElement) if retention.Days != nil { if *retention.Days == 0 { - return fmt.Errorf("Days should not be zero") + return fmt.Errorf("Default retention period must be a positive integer value for 'Days'") + } + if *retention.Days > maximumRetentionDays { + return fmt.Errorf("Default retention period too large for 'Days' %w", *retention.Days) } } else if *retention.Years == 0 { - return fmt.Errorf("Years should not be zero") + return fmt.Errorf("Default retention period must be a positive integer value for 'Years'") + } else if *retention.Years > maximumRetentionYears { + return fmt.Errorf("Default retention period too large for 'Years' %w", *retention.Years) } *dr = DefaultRetention(retention) diff --git a/cmd/peer-rest-common.go b/cmd/peer-rest-common.go index 483541dfd..574e9ebe5 100644 --- a/cmd/peer-rest-common.go +++ b/cmd/peer-rest-common.go @@ -58,7 +58,7 @@ const ( peerRESTMethodLog = "/log" peerRESTMethodHardwareCPUInfo = "/cpuhardwareinfo" peerRESTMethodHardwareNetworkInfo = "/networkhardwareinfo" - peerRESTMethodPutBucketObjectLockConfig = "putbucketobjectlockconfig" + peerRESTMethodPutBucketObjectLockConfig = "/putbucketobjectlockconfig" ) const (