2021-04-18 15:41:13 -04:00
|
|
|
// Copyright (c) 2015-2021 MinIO, Inc.
|
|
|
|
//
|
|
|
|
// This file is part of MinIO Object Storage stack
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Affero General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Affero General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2016-03-27 15:37:21 -04:00
|
|
|
|
2016-08-18 19:23:42 -04:00
|
|
|
package cmd
|
2016-03-27 15:37:21 -04:00
|
|
|
|
2018-03-28 17:14:06 -04:00
|
|
|
import (
|
2021-07-12 13:49:50 -04:00
|
|
|
"compress/gzip"
|
2020-09-09 12:57:37 -04:00
|
|
|
"net"
|
2018-03-28 17:14:06 -04:00
|
|
|
"net/http"
|
|
|
|
|
2021-07-12 13:49:50 -04:00
|
|
|
"github.com/klauspost/compress/gzhttp"
|
2021-11-18 20:19:58 -05:00
|
|
|
"github.com/minio/console/restapi"
|
2021-06-01 17:59:40 -04:00
|
|
|
xhttp "github.com/minio/minio/internal/http"
|
2021-08-09 15:45:59 -04:00
|
|
|
"github.com/minio/minio/internal/logger"
|
2023-01-23 06:12:47 -05:00
|
|
|
"github.com/minio/mux"
|
2021-05-28 18:17:01 -04:00
|
|
|
"github.com/minio/pkg/wildcard"
|
2020-07-06 23:55:19 -04:00
|
|
|
"github.com/rs/cors"
|
2018-03-28 17:14:06 -04:00
|
|
|
)
|
2016-03-27 15:37:21 -04:00
|
|
|
|
2019-12-02 18:54:26 -05:00
|
|
|
func newHTTPServerFn() *xhttp.Server {
|
2021-01-03 14:27:57 -05:00
|
|
|
globalObjLayerMutex.RLock()
|
|
|
|
defer globalObjLayerMutex.RUnlock()
|
2019-12-02 18:54:26 -05:00
|
|
|
return globalHTTPServer
|
|
|
|
}
|
|
|
|
|
2021-01-03 14:27:57 -05:00
|
|
|
func setHTTPServer(h *xhttp.Server) {
|
2019-11-09 12:27:23 -05:00
|
|
|
globalObjLayerMutex.Lock()
|
2021-01-03 14:27:57 -05:00
|
|
|
globalHTTPServer = h
|
|
|
|
globalObjLayerMutex.Unlock()
|
|
|
|
}
|
|
|
|
|
2021-11-18 20:19:58 -05:00
|
|
|
func newConsoleServerFn() *restapi.Server {
|
|
|
|
globalObjLayerMutex.RLock()
|
|
|
|
defer globalObjLayerMutex.RUnlock()
|
|
|
|
return globalConsoleSrv
|
|
|
|
}
|
|
|
|
|
|
|
|
func setConsoleSrv(srv *restapi.Server) {
|
|
|
|
globalObjLayerMutex.Lock()
|
|
|
|
globalConsoleSrv = srv
|
|
|
|
globalObjLayerMutex.Unlock()
|
|
|
|
}
|
|
|
|
|
2021-01-03 14:27:57 -05:00
|
|
|
func newObjectLayerFn() ObjectLayer {
|
|
|
|
globalObjLayerMutex.RLock()
|
|
|
|
defer globalObjLayerMutex.RUnlock()
|
2019-11-09 12:27:23 -05:00
|
|
|
return globalObjectAPI
|
|
|
|
}
|
|
|
|
|
|
|
|
func newCachedObjectLayerFn() CacheObjectLayer {
|
2021-01-03 14:27:57 -05:00
|
|
|
globalObjLayerMutex.RLock()
|
|
|
|
defer globalObjLayerMutex.RUnlock()
|
2019-11-09 12:27:23 -05:00
|
|
|
return globalCacheObjectAPI
|
|
|
|
}
|
|
|
|
|
2021-01-03 14:27:57 -05:00
|
|
|
func setCacheObjectLayer(c CacheObjectLayer) {
|
|
|
|
globalObjLayerMutex.Lock()
|
|
|
|
globalCacheObjectAPI = c
|
|
|
|
globalObjLayerMutex.Unlock()
|
|
|
|
}
|
|
|
|
|
2020-10-28 12:18:35 -04:00
|
|
|
func setObjectLayer(o ObjectLayer) {
|
|
|
|
globalObjLayerMutex.Lock()
|
|
|
|
globalObjectAPI = o
|
|
|
|
globalObjLayerMutex.Unlock()
|
|
|
|
}
|
|
|
|
|
2016-04-12 15:45:15 -04:00
|
|
|
// objectAPIHandler implements and provides http handlers for S3 API.
|
|
|
|
type objectAPIHandlers struct {
|
2016-07-31 17:11:14 -04:00
|
|
|
ObjectAPI func() ObjectLayer
|
2018-03-28 17:14:06 -04:00
|
|
|
CacheAPI func() CacheObjectLayer
|
2016-03-27 15:37:21 -04:00
|
|
|
}
|
|
|
|
|
2020-09-09 12:57:37 -04:00
|
|
|
// getHost tries its best to return the request host.
|
|
|
|
// According to section 14.23 of RFC 2616 the Host header
|
|
|
|
// can include the port number if the default value of 80 is not used.
|
|
|
|
func getHost(r *http.Request) string {
|
|
|
|
if r.URL.IsAbs() {
|
|
|
|
return r.URL.Host
|
|
|
|
}
|
|
|
|
return r.Host
|
|
|
|
}
|
|
|
|
|
2021-03-31 02:19:36 -04:00
|
|
|
func notImplementedHandler(w http.ResponseWriter, r *http.Request) {
|
2021-06-17 23:27:04 -04:00
|
|
|
writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL)
|
2021-03-31 02:19:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
type rejectedAPI struct {
|
|
|
|
api string
|
|
|
|
methods []string
|
|
|
|
queries []string
|
|
|
|
path string
|
|
|
|
}
|
|
|
|
|
2021-05-19 12:21:34 -04:00
|
|
|
var rejectedObjAPIs = []rejectedAPI{
|
|
|
|
{
|
|
|
|
api: "torrent",
|
|
|
|
methods: []string{http.MethodPut, http.MethodDelete, http.MethodGet},
|
|
|
|
queries: []string{"torrent", ""},
|
|
|
|
path: "/{object:.+}",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
api: "acl",
|
|
|
|
methods: []string{http.MethodDelete},
|
|
|
|
queries: []string{"acl", ""},
|
|
|
|
path: "/{object:.+}",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var rejectedBucketAPIs = []rejectedAPI{
|
2021-03-31 02:19:36 -04:00
|
|
|
{
|
|
|
|
api: "inventory",
|
|
|
|
methods: []string{http.MethodGet, http.MethodPut, http.MethodDelete},
|
|
|
|
queries: []string{"inventory", ""},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
api: "cors",
|
|
|
|
methods: []string{http.MethodPut, http.MethodDelete},
|
|
|
|
queries: []string{"cors", ""},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
api: "metrics",
|
|
|
|
methods: []string{http.MethodGet, http.MethodPut, http.MethodDelete},
|
|
|
|
queries: []string{"metrics", ""},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
api: "website",
|
|
|
|
methods: []string{http.MethodPut},
|
|
|
|
queries: []string{"website", ""},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
api: "logging",
|
|
|
|
methods: []string{http.MethodPut, http.MethodDelete},
|
|
|
|
queries: []string{"logging", ""},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
api: "accelerate",
|
|
|
|
methods: []string{http.MethodPut, http.MethodDelete},
|
|
|
|
queries: []string{"accelerate", ""},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
api: "requestPayment",
|
|
|
|
methods: []string{http.MethodPut, http.MethodDelete},
|
|
|
|
queries: []string{"requestPayment", ""},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
api: "acl",
|
|
|
|
methods: []string{http.MethodDelete, http.MethodPut, http.MethodHead},
|
|
|
|
queries: []string{"acl", ""},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
api: "publicAccessBlock",
|
|
|
|
methods: []string{http.MethodDelete, http.MethodPut, http.MethodGet},
|
|
|
|
queries: []string{"publicAccessBlock", ""},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
api: "ownershipControls",
|
|
|
|
methods: []string{http.MethodDelete, http.MethodPut, http.MethodGet},
|
|
|
|
queries: []string{"ownershipControls", ""},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
api: "intelligent-tiering",
|
|
|
|
methods: []string{http.MethodDelete, http.MethodPut, http.MethodGet},
|
|
|
|
queries: []string{"intelligent-tiering", ""},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
api: "analytics",
|
|
|
|
methods: []string{http.MethodDelete, http.MethodPut, http.MethodGet},
|
|
|
|
queries: []string{"analytics", ""},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2016-03-27 15:37:21 -04:00
|
|
|
// registerAPIRouter - registers S3 compatible APIs.
|
2020-09-15 16:57:15 -04:00
|
|
|
func registerAPIRouter(router *mux.Router) {
|
2016-10-05 15:48:07 -04:00
|
|
|
// Initialize API.
|
|
|
|
api := objectAPIHandlers{
|
2019-11-09 12:27:23 -05:00
|
|
|
ObjectAPI: newObjectLayerFn,
|
|
|
|
CacheAPI: newCachedObjectLayerFn,
|
2016-10-05 15:48:07 -04:00
|
|
|
}
|
|
|
|
|
2016-03-27 15:37:21 -04:00
|
|
|
// API Router
|
2019-08-06 15:08:58 -04:00
|
|
|
apiRouter := router.PathPrefix(SlashSeparator).Subrouter()
|
2020-09-09 12:57:37 -04:00
|
|
|
|
2018-04-21 22:23:54 -04:00
|
|
|
var routers []*mux.Router
|
2019-02-22 22:18:01 -05:00
|
|
|
for _, domainName := range globalDomainNames {
|
2020-09-09 12:57:37 -04:00
|
|
|
if IsKubernetes() {
|
|
|
|
routers = append(routers, apiRouter.MatcherFunc(func(r *http.Request, match *mux.RouteMatch) bool {
|
2020-09-23 15:10:09 -04:00
|
|
|
host, _, err := net.SplitHostPort(getHost(r))
|
|
|
|
if err != nil {
|
|
|
|
host = r.Host
|
|
|
|
}
|
2020-09-09 12:57:37 -04:00
|
|
|
// Make sure to skip matching minio.<domain>` this is
|
|
|
|
// specifically meant for operator/k8s deployment
|
|
|
|
// The reason we need to skip this is for a special
|
|
|
|
// usecase where we need to make sure that
|
|
|
|
// minio.<namespace>.svc.<cluster_domain> is ignored
|
|
|
|
// by the bucketDNS style to ensure that path style
|
|
|
|
// is available and honored at this domain.
|
|
|
|
//
|
|
|
|
// All other `<bucket>.<namespace>.svc.<cluster_domain>`
|
|
|
|
// makes sure that buckets are routed through this matcher
|
|
|
|
// to match for `<bucket>`
|
|
|
|
return host != minioReservedBucket+"."+domainName
|
|
|
|
}).Host("{bucket:.+}."+domainName).Subrouter())
|
|
|
|
} else {
|
|
|
|
routers = append(routers, apiRouter.Host("{bucket:.+}."+domainName).Subrouter())
|
|
|
|
}
|
2017-11-14 19:56:24 -05:00
|
|
|
}
|
|
|
|
routers = append(routers, apiRouter.PathPrefix("/{bucket}").Subrouter())
|
2016-03-27 15:37:21 -04:00
|
|
|
|
2021-08-09 15:45:59 -04:00
|
|
|
gz, err := gzhttp.NewWrapper(gzhttp.MinSize(1000), gzhttp.CompressionLevel(gzip.BestSpeed))
|
|
|
|
if err != nil {
|
|
|
|
// Static params, so this is very unlikely.
|
|
|
|
logger.Fatal(err, "Unable to initialize server")
|
2021-07-12 13:49:50 -04:00
|
|
|
}
|
|
|
|
|
2021-03-31 02:19:36 -04:00
|
|
|
for _, router := range routers {
|
2021-05-19 12:21:34 -04:00
|
|
|
// Register all rejected object APIs
|
|
|
|
for _, r := range rejectedObjAPIs {
|
|
|
|
t := router.Methods(r.methods...).
|
|
|
|
HandlerFunc(collectAPIStats(r.api, httpTraceAll(notImplementedHandler))).
|
|
|
|
Queries(r.queries...)
|
|
|
|
t.Path(r.path)
|
|
|
|
}
|
|
|
|
|
2017-11-14 19:56:24 -05:00
|
|
|
// Object operations
|
|
|
|
// HeadObject
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodHead).Path("/{object:.+}").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("headobject", maxClients(gz(httpTraceAll(api.HeadObjectHandler)))))
|
2017-11-14 19:56:24 -05:00
|
|
|
// CopyObjectPart
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPut).Path("/{object:.+}").
|
2020-09-09 12:57:37 -04:00
|
|
|
HeadersRegexp(xhttp.AmzCopySource, ".*?(\\/|%2F).*?").
|
2021-07-12 13:49:50 -04:00
|
|
|
HandlerFunc(collectAPIStats("copyobjectpart", maxClients(gz(httpTraceAll(api.CopyObjectPartHandler))))).
|
2020-09-09 12:57:37 -04:00
|
|
|
Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}")
|
2017-11-14 19:56:24 -05:00
|
|
|
// PutObjectPart
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPut).Path("/{object:.+}").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("putobjectpart", maxClients(gz(httpTraceHdrs(api.PutObjectPartHandler))))).Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}")
|
2019-08-19 17:02:54 -04:00
|
|
|
// ListObjectParts
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).Path("/{object:.+}").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("listobjectparts", maxClients(gz(httpTraceAll(api.ListObjectPartsHandler))))).Queries("uploadId", "{uploadId:.*}")
|
2017-11-14 19:56:24 -05:00
|
|
|
// CompleteMultipartUpload
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPost).Path("/{object:.+}").HandlerFunc(
|
2021-08-24 10:14:34 -04:00
|
|
|
collectAPIStats("completemultipartupload", maxClients(gz(httpTraceAll(api.CompleteMultipartUploadHandler))))).Queries("uploadId", "{uploadId:.*}")
|
2017-11-14 19:56:24 -05:00
|
|
|
// NewMultipartUpload
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPost).Path("/{object:.+}").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("newmultipartupload", maxClients(gz(httpTraceAll(api.NewMultipartUploadHandler))))).Queries("uploads", "")
|
2017-11-14 19:56:24 -05:00
|
|
|
// AbortMultipartUpload
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodDelete).Path("/{object:.+}").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("abortmultipartupload", maxClients(gz(httpTraceAll(api.AbortMultipartUploadHandler))))).Queries("uploadId", "{uploadId:.*}")
|
2018-05-31 22:43:50 -04:00
|
|
|
// GetObjectACL - this is a dummy call.
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).Path("/{object:.+}").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getobjectacl", maxClients(gz(httpTraceHdrs(api.GetObjectACLHandler))))).Queries("acl", "")
|
2020-02-16 01:07:52 -05:00
|
|
|
// PutObjectACL - this is a dummy call.
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPut).Path("/{object:.+}").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("putobjectacl", maxClients(gz(httpTraceHdrs(api.PutObjectACLHandler))))).Queries("acl", "")
|
2020-01-20 11:45:59 -05:00
|
|
|
// GetObjectTagging
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).Path("/{object:.+}").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getobjecttagging", maxClients(gz(httpTraceHdrs(api.GetObjectTaggingHandler))))).Queries("tagging", "")
|
2020-01-20 11:45:59 -05:00
|
|
|
// PutObjectTagging
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPut).Path("/{object:.+}").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("putobjecttagging", maxClients(gz(httpTraceHdrs(api.PutObjectTaggingHandler))))).Queries("tagging", "")
|
2020-01-20 11:45:59 -05:00
|
|
|
// DeleteObjectTagging
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodDelete).Path("/{object:.+}").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("deleteobjecttagging", maxClients(gz(httpTraceHdrs(api.DeleteObjectTaggingHandler))))).Queries("tagging", "")
|
2018-08-15 06:30:19 -04:00
|
|
|
// SelectObjectContent
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPost).Path("/{object:.+}").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("selectobjectcontent", maxClients(gz(httpTraceHdrs(api.SelectObjectContentHandler))))).Queries("select", "").Queries("select-type", "2")
|
2019-11-20 16:18:09 -05:00
|
|
|
// GetObjectRetention
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).Path("/{object:.+}").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getobjectretention", maxClients(gz(httpTraceAll(api.GetObjectRetentionHandler))))).Queries("retention", "")
|
2020-01-16 18:41:56 -05:00
|
|
|
// GetObjectLegalHold
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).Path("/{object:.+}").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getobjectlegalhold", maxClients(gz(httpTraceAll(api.GetObjectLegalHoldHandler))))).Queries("legal-hold", "")
|
|
|
|
// GetObject - note gzip compression is *not* added due to Range requests.
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).Path("/{object:.+}").HandlerFunc(
|
2022-02-14 12:19:01 -05:00
|
|
|
collectAPIStats("getobject", maxClients(gz(httpTraceHdrs(api.GetObjectHandler)))))
|
2017-11-14 19:56:24 -05:00
|
|
|
// CopyObject
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPut).Path("/{object:.+}").HeadersRegexp(xhttp.AmzCopySource, ".*?(\\/|%2F).*?").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("copyobject", maxClients(gz(httpTraceAll(api.CopyObjectHandler)))))
|
2019-11-20 16:18:09 -05:00
|
|
|
// PutObjectRetention
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPut).Path("/{object:.+}").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("putobjectretention", maxClients(gz(httpTraceAll(api.PutObjectRetentionHandler))))).Queries("retention", "")
|
2020-01-16 18:41:56 -05:00
|
|
|
// PutObjectLegalHold
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPut).Path("/{object:.+}").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("putobjectlegalhold", maxClients(gz(httpTraceAll(api.PutObjectLegalHoldHandler))))).Queries("legal-hold", "")
|
2020-01-16 18:41:56 -05:00
|
|
|
|
2021-03-26 20:15:09 -04:00
|
|
|
// PutObject with auto-extract support for zip
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPut).Path("/{object:.+}").HeadersRegexp(xhttp.AmzSnowballExtract, "true").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("putobject", maxClients(gz(httpTraceHdrs(api.PutObjectExtractHandler)))))
|
2021-03-26 20:15:09 -04:00
|
|
|
|
2017-11-14 19:56:24 -05:00
|
|
|
// PutObject
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPut).Path("/{object:.+}").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("putobject", maxClients(gz(httpTraceHdrs(api.PutObjectHandler)))))
|
2021-03-26 20:15:09 -04:00
|
|
|
|
2017-11-14 19:56:24 -05:00
|
|
|
// DeleteObject
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodDelete).Path("/{object:.+}").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("deleteobject", maxClients(gz(httpTraceAll(api.DeleteObjectHandler)))))
|
2016-03-27 15:37:21 -04:00
|
|
|
|
2021-03-02 02:10:33 -05:00
|
|
|
// PostRestoreObject
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPost).Path("/{object:.+}").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("restoreobject", maxClients(gz(httpTraceAll(api.PostRestoreObjectHandler))))).Queries("restore", "")
|
2021-03-02 02:10:33 -05:00
|
|
|
|
2021-11-16 12:28:29 -05:00
|
|
|
// Bucket operations
|
|
|
|
|
2017-11-14 19:56:24 -05:00
|
|
|
// GetBucketLocation
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getbucketlocation", maxClients(gz(httpTraceAll(api.GetBucketLocationHandler))))).Queries("location", "")
|
2017-11-14 19:56:24 -05:00
|
|
|
// GetBucketPolicy
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getbucketpolicy", maxClients(gz(httpTraceAll(api.GetBucketPolicyHandler))))).Queries("policy", "")
|
2019-07-19 16:20:33 -04:00
|
|
|
// GetBucketLifecycle
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getbucketlifecycle", maxClients(gz(httpTraceAll(api.GetBucketLifecycleHandler))))).Queries("lifecycle", "")
|
2020-02-05 04:42:34 -05:00
|
|
|
// GetBucketEncryption
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getbucketencryption", maxClients(gz(httpTraceAll(api.GetBucketEncryptionHandler))))).Queries("encryption", "")
|
2020-07-21 20:49:56 -04:00
|
|
|
// GetBucketObjectLockConfig
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getbucketobjectlockconfiguration", maxClients(gz(httpTraceAll(api.GetBucketObjectLockConfigHandler))))).Queries("object-lock", "")
|
2020-07-21 20:49:56 -04:00
|
|
|
// GetBucketReplicationConfig
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getbucketreplicationconfiguration", maxClients(gz(httpTraceAll(api.GetBucketReplicationConfigHandler))))).Queries("replication", "")
|
2020-07-21 20:49:56 -04:00
|
|
|
// GetBucketVersioning
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getbucketversioning", maxClients(gz(httpTraceAll(api.GetBucketVersioningHandler))))).Queries("versioning", "")
|
2020-07-21 20:49:56 -04:00
|
|
|
// GetBucketNotification
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getbucketnotification", maxClients(gz(httpTraceAll(api.GetBucketNotificationHandler))))).Queries("notification", "")
|
2020-07-21 20:49:56 -04:00
|
|
|
// ListenNotification
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2022-06-05 17:29:12 -04:00
|
|
|
collectAPIStats("listennotification", gz(httpTraceAll(api.ListenNotificationHandler)))).Queries("events", "{events:.*}")
|
2022-02-10 13:16:52 -05:00
|
|
|
// ResetBucketReplicationStatus - MinIO extension API
|
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
|
|
|
collectAPIStats("resetbucketreplicationstatus", maxClients(gz(httpTraceAll(api.ResetBucketReplicationStatusHandler))))).Queries("replication-reset-status", "")
|
2018-05-10 00:02:26 -04:00
|
|
|
|
2019-02-08 19:18:13 -05:00
|
|
|
// Dummy Bucket Calls
|
2018-05-10 00:02:26 -04:00
|
|
|
// GetBucketACL -- this is a dummy call.
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getbucketacl", maxClients(gz(httpTraceAll(api.GetBucketACLHandler))))).Queries("acl", "")
|
2020-02-16 01:07:52 -05:00
|
|
|
// PutBucketACL -- this is a dummy call.
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPut).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("putbucketacl", maxClients(gz(httpTraceAll(api.PutBucketACLHandler))))).Queries("acl", "")
|
2019-02-08 19:18:13 -05:00
|
|
|
// GetBucketCors - this is a dummy call.
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getbucketcors", maxClients(gz(httpTraceAll(api.GetBucketCorsHandler))))).Queries("cors", "")
|
2019-02-08 19:18:13 -05:00
|
|
|
// GetBucketWebsiteHandler - this is a dummy call.
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getbucketwebsite", maxClients(gz(httpTraceAll(api.GetBucketWebsiteHandler))))).Queries("website", "")
|
2019-02-08 19:18:13 -05:00
|
|
|
// GetBucketAccelerateHandler - this is a dummy call.
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getbucketaccelerate", maxClients(gz(httpTraceAll(api.GetBucketAccelerateHandler))))).Queries("accelerate", "")
|
2019-02-08 19:18:13 -05:00
|
|
|
// GetBucketRequestPaymentHandler - this is a dummy call.
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getbucketrequestpayment", maxClients(gz(httpTraceAll(api.GetBucketRequestPaymentHandler))))).Queries("requestPayment", "")
|
2019-02-08 19:18:13 -05:00
|
|
|
// GetBucketLoggingHandler - this is a dummy call.
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getbucketlogging", maxClients(gz(httpTraceAll(api.GetBucketLoggingHandler))))).Queries("logging", "")
|
2020-05-05 17:18:13 -04:00
|
|
|
// GetBucketTaggingHandler
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getbuckettagging", maxClients(gz(httpTraceAll(api.GetBucketTaggingHandler))))).Queries("tagging", "")
|
2021-11-16 12:28:29 -05:00
|
|
|
// DeleteBucketWebsiteHandler
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodDelete).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("deletebucketwebsite", maxClients(gz(httpTraceAll(api.DeleteBucketWebsiteHandler))))).Queries("website", "")
|
2019-02-08 19:18:13 -05:00
|
|
|
// DeleteBucketTaggingHandler
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodDelete).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("deletebuckettagging", maxClients(gz(httpTraceAll(api.DeleteBucketTaggingHandler))))).Queries("tagging", "")
|
2018-05-10 00:02:26 -04:00
|
|
|
|
2017-11-14 19:56:24 -05:00
|
|
|
// ListMultipartUploads
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("listmultipartuploads", maxClients(gz(httpTraceAll(api.ListMultipartUploadsHandler))))).Queries("uploads", "")
|
2019-11-21 04:54:49 -05:00
|
|
|
// ListObjectsV2M
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("listobjectsv2M", maxClients(gz(httpTraceAll(api.ListObjectsV2MHandler))))).Queries("list-type", "2", "metadata", "true")
|
2017-11-14 19:56:24 -05:00
|
|
|
// ListObjectsV2
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("listobjectsv2", maxClients(gz(httpTraceAll(api.ListObjectsV2Handler))))).Queries("list-type", "2")
|
2020-06-12 23:04:01 -04:00
|
|
|
// ListObjectVersions
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("listobjectversions", maxClients(gz(httpTraceAll(api.ListObjectVersionsHandler))))).Queries("versions", "")
|
2021-03-02 02:10:33 -05:00
|
|
|
// GetBucketPolicyStatus
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getpolicystatus", maxClients(gz(httpTraceAll(api.GetBucketPolicyStatusHandler))))).Queries("policyStatus", "")
|
2019-07-19 16:20:33 -04:00
|
|
|
// PutBucketLifecycle
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPut).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("putbucketlifecycle", maxClients(gz(httpTraceAll(api.PutBucketLifecycleHandler))))).Queries("lifecycle", "")
|
2020-07-21 20:49:56 -04:00
|
|
|
// PutBucketReplicationConfig
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPut).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("putbucketreplicationconfiguration", maxClients(gz(httpTraceAll(api.PutBucketReplicationConfigHandler))))).Queries("replication", "")
|
2020-02-05 04:42:34 -05:00
|
|
|
// PutBucketEncryption
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPut).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("putbucketencryption", maxClients(gz(httpTraceAll(api.PutBucketEncryptionHandler))))).Queries("encryption", "")
|
2020-02-05 04:42:34 -05:00
|
|
|
|
2017-11-14 19:56:24 -05:00
|
|
|
// PutBucketPolicy
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPut).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("putbucketpolicy", maxClients(gz(httpTraceAll(api.PutBucketPolicyHandler))))).Queries("policy", "")
|
2019-07-19 16:20:33 -04:00
|
|
|
|
2019-11-12 17:50:18 -05:00
|
|
|
// PutBucketObjectLockConfig
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPut).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("putbucketobjectlockconfig", maxClients(gz(httpTraceAll(api.PutBucketObjectLockConfigHandler))))).Queries("object-lock", "")
|
2020-05-05 17:18:13 -04:00
|
|
|
// PutBucketTaggingHandler
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPut).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("putbuckettagging", maxClients(gz(httpTraceAll(api.PutBucketTaggingHandler))))).Queries("tagging", "")
|
2019-11-12 17:50:18 -05:00
|
|
|
// PutBucketVersioning
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPut).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("putbucketversioning", maxClients(gz(httpTraceAll(api.PutBucketVersioningHandler))))).Queries("versioning", "")
|
2017-11-14 19:56:24 -05:00
|
|
|
// PutBucketNotification
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPut).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("putbucketnotification", maxClients(gz(httpTraceAll(api.PutBucketNotificationHandler))))).Queries("notification", "")
|
2022-02-10 13:16:52 -05:00
|
|
|
// ResetBucketReplicationStart - MinIO extension API
|
2021-06-01 22:59:11 -04:00
|
|
|
router.Methods(http.MethodPut).HandlerFunc(
|
2022-02-10 13:16:52 -05:00
|
|
|
collectAPIStats("resetbucketreplicationstart", maxClients(gz(httpTraceAll(api.ResetBucketReplicationStartHandler))))).Queries("replication-reset", "")
|
|
|
|
|
2017-11-14 19:56:24 -05:00
|
|
|
// PutBucket
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPut).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("putbucket", maxClients(gz(httpTraceAll(api.PutBucketHandler)))))
|
2017-11-14 19:56:24 -05:00
|
|
|
// HeadBucket
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodHead).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("headbucket", maxClients(gz(httpTraceAll(api.HeadBucketHandler)))))
|
2017-11-14 19:56:24 -05:00
|
|
|
// PostPolicy
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPost).HeadersRegexp(xhttp.ContentType, "multipart/form-data*").HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("postpolicybucket", maxClients(gz(httpTraceHdrs(api.PostPolicyBucketHandler)))))
|
2017-11-14 19:56:24 -05:00
|
|
|
// DeleteMultipleObjects
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodPost).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("deletemultipleobjects", maxClients(gz(httpTraceAll(api.DeleteMultipleObjectsHandler))))).Queries("delete", "")
|
2017-11-14 19:56:24 -05:00
|
|
|
// DeleteBucketPolicy
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodDelete).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("deletebucketpolicy", maxClients(gz(httpTraceAll(api.DeleteBucketPolicyHandler))))).Queries("policy", "")
|
2020-07-21 20:49:56 -04:00
|
|
|
// DeleteBucketReplication
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodDelete).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("deletebucketreplicationconfiguration", maxClients(gz(httpTraceAll(api.DeleteBucketReplicationConfigHandler))))).Queries("replication", "")
|
2019-07-19 16:20:33 -04:00
|
|
|
// DeleteBucketLifecycle
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodDelete).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("deletebucketlifecycle", maxClients(gz(httpTraceAll(api.DeleteBucketLifecycleHandler))))).Queries("lifecycle", "")
|
2020-02-05 04:42:34 -05:00
|
|
|
// DeleteBucketEncryption
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodDelete).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("deletebucketencryption", maxClients(gz(httpTraceAll(api.DeleteBucketEncryptionHandler))))).Queries("encryption", "")
|
2017-11-14 19:56:24 -05:00
|
|
|
// DeleteBucket
|
2021-03-31 02:19:36 -04:00
|
|
|
router.Methods(http.MethodDelete).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("deletebucket", maxClients(gz(httpTraceAll(api.DeleteBucketHandler)))))
|
2021-05-19 12:21:34 -04:00
|
|
|
|
2021-04-03 12:03:42 -04:00
|
|
|
// MinIO extension API for replication.
|
|
|
|
//
|
|
|
|
// GetBucketReplicationMetrics
|
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("getbucketreplicationmetrics", maxClients(gz(httpTraceAll(api.GetBucketReplicationMetricsHandler))))).Queries("replication-metrics", "")
|
2021-04-05 16:36:39 -04:00
|
|
|
|
2021-05-19 12:21:34 -04:00
|
|
|
// Register rejected bucket APIs
|
|
|
|
for _, r := range rejectedBucketAPIs {
|
|
|
|
router.Methods(r.methods...).
|
|
|
|
HandlerFunc(collectAPIStats(r.api, httpTraceAll(notImplementedHandler))).
|
|
|
|
Queries(r.queries...)
|
|
|
|
}
|
|
|
|
|
2021-04-05 16:36:39 -04:00
|
|
|
// S3 ListObjectsV1 (Legacy)
|
|
|
|
router.Methods(http.MethodGet).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("listobjectsv1", maxClients(gz(httpTraceAll(api.ListObjectsV1Handler)))))
|
2017-11-14 19:56:24 -05:00
|
|
|
}
|
2016-03-27 15:37:21 -04:00
|
|
|
|
2021-11-16 12:28:29 -05:00
|
|
|
// Root operation
|
2016-03-27 15:37:21 -04:00
|
|
|
|
2020-07-20 15:52:49 -04:00
|
|
|
// ListenNotification
|
|
|
|
apiRouter.Methods(http.MethodGet).Path(SlashSeparator).HandlerFunc(
|
2022-06-05 17:29:12 -04:00
|
|
|
collectAPIStats("listennotification", gz(httpTraceAll(api.ListenNotificationHandler)))).Queries("events", "{events:.*}")
|
2020-07-20 15:52:49 -04:00
|
|
|
|
2016-03-27 15:37:21 -04:00
|
|
|
// ListBuckets
|
2020-03-24 15:43:40 -04:00
|
|
|
apiRouter.Methods(http.MethodGet).Path(SlashSeparator).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("listbuckets", maxClients(gz(httpTraceAll(api.ListBucketsHandler)))))
|
2017-11-14 19:56:24 -05:00
|
|
|
|
2020-05-21 21:51:23 -04:00
|
|
|
// S3 browser with signature v4 adds '//' for ListBuckets request, so rather
|
|
|
|
// than failing with UnknownAPIRequest we simply handle it for now.
|
|
|
|
apiRouter.Methods(http.MethodGet).Path(SlashSeparator + SlashSeparator).HandlerFunc(
|
2021-07-12 13:49:50 -04:00
|
|
|
collectAPIStats("listbuckets", maxClients(gz(httpTraceAll(api.ListBucketsHandler)))))
|
2020-05-21 21:51:23 -04:00
|
|
|
|
2019-11-04 12:30:59 -05:00
|
|
|
// If none of the routes match add default error handler routes
|
2020-09-28 16:33:49 -04:00
|
|
|
apiRouter.NotFoundHandler = collectAPIStats("notfound", httpTraceAll(errorResponseHandler))
|
2020-10-28 12:18:35 -04:00
|
|
|
apiRouter.MethodNotAllowedHandler = collectAPIStats("methodnotallowed", httpTraceAll(methodNotAllowedHandler("S3")))
|
2016-03-27 15:37:21 -04:00
|
|
|
}
|
2020-07-06 23:55:19 -04:00
|
|
|
|
2020-07-12 13:56:57 -04:00
|
|
|
// corsHandler handler for CORS (Cross Origin Resource Sharing)
|
|
|
|
func corsHandler(handler http.Handler) http.Handler {
|
2020-07-06 23:55:19 -04:00
|
|
|
commonS3Headers := []string{
|
|
|
|
xhttp.Date,
|
|
|
|
xhttp.ETag,
|
|
|
|
xhttp.ServerInfo,
|
|
|
|
xhttp.Connection,
|
|
|
|
xhttp.AcceptRanges,
|
|
|
|
xhttp.ContentRange,
|
|
|
|
xhttp.ContentEncoding,
|
|
|
|
xhttp.ContentLength,
|
|
|
|
xhttp.ContentType,
|
2020-07-27 12:03:38 -04:00
|
|
|
xhttp.ContentDisposition,
|
2020-07-24 03:46:51 -04:00
|
|
|
xhttp.LastModified,
|
|
|
|
xhttp.ContentLanguage,
|
|
|
|
xhttp.CacheControl,
|
|
|
|
xhttp.RetryAfter,
|
|
|
|
xhttp.AmzBucketRegion,
|
|
|
|
xhttp.Expires,
|
2020-07-06 23:55:19 -04:00
|
|
|
"X-Amz*",
|
|
|
|
"x-amz*",
|
|
|
|
"*",
|
|
|
|
}
|
|
|
|
|
2020-07-12 13:56:57 -04:00
|
|
|
return cors.New(cors.Options{
|
2020-07-06 23:55:19 -04:00
|
|
|
AllowOriginFunc: func(origin string) bool {
|
|
|
|
for _, allowedOrigin := range globalAPIConfig.getCorsAllowOrigins() {
|
|
|
|
if wildcard.MatchSimple(allowedOrigin, origin) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
},
|
|
|
|
AllowedMethods: []string{
|
|
|
|
http.MethodGet,
|
|
|
|
http.MethodPut,
|
|
|
|
http.MethodHead,
|
|
|
|
http.MethodPost,
|
|
|
|
http.MethodDelete,
|
|
|
|
http.MethodOptions,
|
|
|
|
http.MethodPatch,
|
|
|
|
},
|
|
|
|
AllowedHeaders: commonS3Headers,
|
|
|
|
ExposedHeaders: commonS3Headers,
|
|
|
|
AllowCredentials: true,
|
2020-07-12 13:56:57 -04:00
|
|
|
}).Handler(handler)
|
2020-07-06 23:55:19 -04:00
|
|
|
}
|