diff --git a/cmd/api-router.go b/cmd/api-router.go index f7f5d672d..a7e2dc5e8 100644 --- a/cmd/api-router.go +++ b/cmd/api-router.go @@ -23,7 +23,7 @@ import ( "github.com/gorilla/mux" xhttp "github.com/minio/minio/cmd/http" - "github.com/minio/minio/pkg/wildcard" + "github.com/minio/pkg/wildcard" "github.com/rs/cors" ) diff --git a/cmd/background-newdisks-heal-ops.go b/cmd/background-newdisks-heal-ops.go index a38a0cf6f..95a5354d9 100644 --- a/cmd/background-newdisks-heal-ops.go +++ b/cmd/background-newdisks-heal-ops.go @@ -34,7 +34,7 @@ import ( "github.com/minio/minio-go/v7/pkg/set" "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/color" - "github.com/minio/minio/pkg/console" + "github.com/minio/pkg/console" ) const ( diff --git a/cmd/common-main.go b/cmd/common-main.go index 1262fcd9e..5403aa553 100644 --- a/cmd/common-main.go +++ b/cmd/common-main.go @@ -44,12 +44,12 @@ import ( xhttp "github.com/minio/minio/cmd/http" "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/auth" - "github.com/minio/minio/pkg/certs" - "github.com/minio/minio/pkg/console" - "github.com/minio/minio/pkg/ellipses" - "github.com/minio/minio/pkg/env" "github.com/minio/minio/pkg/handlers" "github.com/minio/minio/pkg/kms" + "github.com/minio/pkg/certs" + "github.com/minio/pkg/console" + "github.com/minio/pkg/ellipses" + "github.com/minio/pkg/env" ) // serverDebugLog will enable debug printing diff --git a/cmd/config-current.go b/cmd/config-current.go index f3645da94..56b7851d6 100644 --- a/cmd/config-current.go +++ b/cmd/config-current.go @@ -42,8 +42,8 @@ import ( xhttp "github.com/minio/minio/cmd/http" "github.com/minio/minio/cmd/logger" "github.com/minio/minio/cmd/logger/target/http" - "github.com/minio/minio/pkg/env" "github.com/minio/minio/pkg/kms" + "github.com/minio/pkg/env" ) func initHelp() { diff --git a/cmd/config-migrate.go b/cmd/config-migrate.go index 5b5490b36..1281e5bee 100644 --- a/cmd/config-migrate.go +++ b/cmd/config-migrate.go @@ -42,7 +42,7 @@ import ( "github.com/minio/minio/pkg/event/target" "github.com/minio/minio/pkg/kms" xnet "github.com/minio/minio/pkg/net" - "github.com/minio/minio/pkg/quick" + "github.com/minio/pkg/quick" ) // DO NOT EDIT following message template, please open a GitHub issue to discuss instead. diff --git a/cmd/config-versions.go b/cmd/config-versions.go index 5620cc1bd..2cdc833b2 100644 --- a/cmd/config-versions.go +++ b/cmd/config-versions.go @@ -31,7 +31,7 @@ import ( "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/auth" "github.com/minio/minio/pkg/event/target" - "github.com/minio/minio/pkg/quick" + "github.com/minio/pkg/quick" ) /////////////////// Config V1 /////////////////// diff --git a/cmd/config/api/api.go b/cmd/config/api/api.go index 6cf300b16..1f32cdbc1 100644 --- a/cmd/config/api/api.go +++ b/cmd/config/api/api.go @@ -25,7 +25,7 @@ import ( "time" "github.com/minio/minio/cmd/config" - "github.com/minio/minio/pkg/env" + "github.com/minio/pkg/env" ) // API sub-system constants diff --git a/cmd/config/cache/config.go b/cmd/config/cache/config.go index f170423b8..4e32aa1c0 100644 --- a/cmd/config/cache/config.go +++ b/cmd/config/cache/config.go @@ -24,7 +24,7 @@ import ( "strings" "github.com/minio/minio/cmd/config" - "github.com/minio/minio/pkg/ellipses" + "github.com/minio/pkg/ellipses" ) // Config represents cache config settings diff --git a/cmd/config/cache/lookup.go b/cmd/config/cache/lookup.go index bc27fc254..eedb143f9 100644 --- a/cmd/config/cache/lookup.go +++ b/cmd/config/cache/lookup.go @@ -22,7 +22,7 @@ import ( "strconv" "github.com/minio/minio/cmd/config" - "github.com/minio/minio/pkg/env" + "github.com/minio/pkg/env" ) // Cache ENVs diff --git a/cmd/config/certs.go b/cmd/config/certs.go index 2915309dd..ec7e35683 100644 --- a/cmd/config/certs.go +++ b/cmd/config/certs.go @@ -27,7 +27,7 @@ import ( "errors" "io/ioutil" - "github.com/minio/minio/pkg/env" + "github.com/minio/pkg/env" ) // EnvCertPassword is the environment variable which contains the password used diff --git a/cmd/config/compress/compress.go b/cmd/config/compress/compress.go index 7e39fb24b..c7481c7ab 100644 --- a/cmd/config/compress/compress.go +++ b/cmd/config/compress/compress.go @@ -22,7 +22,7 @@ import ( "strings" "github.com/minio/minio/cmd/config" - "github.com/minio/minio/pkg/env" + "github.com/minio/pkg/env" ) // Config represents the compression settings. diff --git a/cmd/config/config.go b/cmd/config/config.go index c3d14c011..9f76cc7fa 100644 --- a/cmd/config/config.go +++ b/cmd/config/config.go @@ -27,7 +27,7 @@ import ( "github.com/minio/madmin-go" "github.com/minio/minio-go/v7/pkg/set" "github.com/minio/minio/pkg/auth" - "github.com/minio/minio/pkg/env" + "github.com/minio/pkg/env" ) // Error config error type diff --git a/cmd/config/etcd/etcd.go b/cmd/config/etcd/etcd.go index 37f740852..0f8100cc1 100644 --- a/cmd/config/etcd/etcd.go +++ b/cmd/config/etcd/etcd.go @@ -24,8 +24,8 @@ import ( "time" "github.com/minio/minio/cmd/config" - "github.com/minio/minio/pkg/env" xnet "github.com/minio/minio/pkg/net" + "github.com/minio/pkg/env" clientv3 "go.etcd.io/etcd/client/v3" "go.etcd.io/etcd/client/v3/namespace" "go.uber.org/zap" diff --git a/cmd/config/heal/heal.go b/cmd/config/heal/heal.go index f18a218f3..be32c5d24 100644 --- a/cmd/config/heal/heal.go +++ b/cmd/config/heal/heal.go @@ -23,7 +23,7 @@ import ( "time" "github.com/minio/minio/cmd/config" - "github.com/minio/minio/pkg/env" + "github.com/minio/pkg/env" ) // Compression environment variables diff --git a/cmd/config/identity/ldap/config.go b/cmd/config/identity/ldap/config.go index f962cecec..fca835df2 100644 --- a/cmd/config/identity/ldap/config.go +++ b/cmd/config/identity/ldap/config.go @@ -29,7 +29,7 @@ import ( ldap "github.com/go-ldap/ldap/v3" "github.com/minio/minio/cmd/config" - "github.com/minio/minio/pkg/env" + "github.com/minio/pkg/env" ) const ( diff --git a/cmd/config/identity/openid/jwt.go b/cmd/config/identity/openid/jwt.go index ccf50d52e..03773e3f6 100644 --- a/cmd/config/identity/openid/jwt.go +++ b/cmd/config/identity/openid/jwt.go @@ -32,9 +32,9 @@ import ( jwtgo "github.com/dgrijalva/jwt-go" "github.com/minio/minio/cmd/config" "github.com/minio/minio/pkg/auth" - "github.com/minio/minio/pkg/env" iampolicy "github.com/minio/minio/pkg/iam/policy" xnet "github.com/minio/minio/pkg/net" + "github.com/minio/pkg/env" ) // Config - OpenID Config diff --git a/cmd/config/notify/parse.go b/cmd/config/notify/parse.go index fe8661906..83b4ae3e4 100644 --- a/cmd/config/notify/parse.go +++ b/cmd/config/notify/parse.go @@ -29,10 +29,10 @@ import ( "github.com/minio/minio/cmd/config" "github.com/minio/minio/cmd/logger" - "github.com/minio/minio/pkg/env" "github.com/minio/minio/pkg/event" "github.com/minio/minio/pkg/event/target" xnet "github.com/minio/minio/pkg/net" + "github.com/minio/pkg/env" ) const ( diff --git a/cmd/config/policy/opa/config.go b/cmd/config/policy/opa/config.go index e5a3cfaa7..cf478a161 100644 --- a/cmd/config/policy/opa/config.go +++ b/cmd/config/policy/opa/config.go @@ -25,9 +25,9 @@ import ( "net/http" "github.com/minio/minio/cmd/config" - "github.com/minio/minio/pkg/env" iampolicy "github.com/minio/minio/pkg/iam/policy" xnet "github.com/minio/minio/pkg/net" + "github.com/minio/pkg/env" ) // Env IAM OPA URL diff --git a/cmd/config/scanner/scanner.go b/cmd/config/scanner/scanner.go index 6649f4bf9..5db137250 100644 --- a/cmd/config/scanner/scanner.go +++ b/cmd/config/scanner/scanner.go @@ -22,7 +22,7 @@ import ( "time" "github.com/minio/minio/cmd/config" - "github.com/minio/minio/pkg/env" + "github.com/minio/pkg/env" ) // Compression environment variables diff --git a/cmd/config/storageclass/storage-class.go b/cmd/config/storageclass/storage-class.go index 180f390a2..fbe19ff94 100644 --- a/cmd/config/storageclass/storage-class.go +++ b/cmd/config/storageclass/storage-class.go @@ -26,7 +26,7 @@ import ( "sync" "github.com/minio/minio/cmd/config" - "github.com/minio/minio/pkg/env" + "github.com/minio/pkg/env" ) // Standard constants for all storage class diff --git a/cmd/crypto/auto-encryption.go b/cmd/crypto/auto-encryption.go index 103011ca7..7606bcb35 100644 --- a/cmd/crypto/auto-encryption.go +++ b/cmd/crypto/auto-encryption.go @@ -19,7 +19,7 @@ package crypto import ( "github.com/minio/minio/cmd/config" - "github.com/minio/minio/pkg/env" + "github.com/minio/pkg/env" ) const ( diff --git a/cmd/data-scanner.go b/cmd/data-scanner.go index b70342e50..7b775c764 100644 --- a/cmd/data-scanner.go +++ b/cmd/data-scanner.go @@ -39,9 +39,9 @@ import ( "github.com/minio/minio/pkg/bucket/lifecycle" "github.com/minio/minio/pkg/bucket/replication" "github.com/minio/minio/pkg/color" - "github.com/minio/minio/pkg/console" "github.com/minio/minio/pkg/event" "github.com/minio/minio/pkg/hash" + "github.com/minio/pkg/console" ) const ( diff --git a/cmd/data-update-tracker.go b/cmd/data-update-tracker.go index add8d9c97..774ad3dd8 100644 --- a/cmd/data-update-tracker.go +++ b/cmd/data-update-tracker.go @@ -35,7 +35,7 @@ import ( "github.com/bits-and-blooms/bloom/v3" "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/color" - "github.com/minio/minio/pkg/console" + "github.com/minio/pkg/console" ) const ( diff --git a/cmd/disk-cache.go b/cmd/disk-cache.go index e8767eec2..7b91d17c9 100644 --- a/cmd/disk-cache.go +++ b/cmd/disk-cache.go @@ -36,7 +36,7 @@ import ( "github.com/minio/minio/pkg/color" "github.com/minio/minio/pkg/hash" "github.com/minio/minio/pkg/sync/errgroup" - "github.com/minio/minio/pkg/wildcard" + "github.com/minio/pkg/wildcard" ) const ( diff --git a/cmd/endpoint-ellipses.go b/cmd/endpoint-ellipses.go index 5116afc23..fc8a49ca9 100644 --- a/cmd/endpoint-ellipses.go +++ b/cmd/endpoint-ellipses.go @@ -25,8 +25,8 @@ import ( "github.com/minio/minio-go/v7/pkg/set" "github.com/minio/minio/cmd/config" - "github.com/minio/minio/pkg/ellipses" - "github.com/minio/minio/pkg/env" + "github.com/minio/pkg/ellipses" + "github.com/minio/pkg/env" ) // This file implements and supports ellipses pattern for diff --git a/cmd/endpoint-ellipses_test.go b/cmd/endpoint-ellipses_test.go index 423c307bd..c4cc76f94 100644 --- a/cmd/endpoint-ellipses_test.go +++ b/cmd/endpoint-ellipses_test.go @@ -22,7 +22,7 @@ import ( "reflect" "testing" - "github.com/minio/minio/pkg/ellipses" + "github.com/minio/pkg/ellipses" ) // Tests create endpoints with ellipses and without. diff --git a/cmd/endpoint.go b/cmd/endpoint.go index 0e28e0b40..6fec355a2 100644 --- a/cmd/endpoint.go +++ b/cmd/endpoint.go @@ -38,9 +38,9 @@ import ( "github.com/minio/minio/cmd/config" xhttp "github.com/minio/minio/cmd/http" "github.com/minio/minio/cmd/logger" - "github.com/minio/minio/pkg/env" "github.com/minio/minio/pkg/mountinfo" xnet "github.com/minio/minio/pkg/net" + "github.com/minio/pkg/env" ) // EndpointType - enum for endpoint type. diff --git a/cmd/erasure-multipart.go b/cmd/erasure-multipart.go index b4088d9ef..76ebb6444 100644 --- a/cmd/erasure-multipart.go +++ b/cmd/erasure-multipart.go @@ -32,8 +32,8 @@ import ( "github.com/minio/minio-go/v7/pkg/set" xhttp "github.com/minio/minio/cmd/http" "github.com/minio/minio/cmd/logger" - "github.com/minio/minio/pkg/mimedb" "github.com/minio/minio/pkg/sync/errgroup" + "github.com/minio/pkg/mimedb" ) func (er erasureObjects) getUploadIDDir(bucket, object, uploadID string) string { diff --git a/cmd/erasure-object.go b/cmd/erasure-object.go index edf65cd8e..594e9a721 100644 --- a/cmd/erasure-object.go +++ b/cmd/erasure-object.go @@ -38,8 +38,8 @@ import ( "github.com/minio/minio/pkg/event" "github.com/minio/minio/pkg/hash" xioutil "github.com/minio/minio/pkg/ioutil" - "github.com/minio/minio/pkg/mimedb" "github.com/minio/minio/pkg/sync/errgroup" + "github.com/minio/pkg/mimedb" ) // list all errors which can be ignored in object operations. diff --git a/cmd/erasure-server-pool.go b/cmd/erasure-server-pool.go index 17c6b1828..3435f0caf 100644 --- a/cmd/erasure-server-pool.go +++ b/cmd/erasure-server-pool.go @@ -36,7 +36,7 @@ import ( "github.com/minio/minio/cmd/config/storageclass" "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/sync/errgroup" - "github.com/minio/minio/pkg/wildcard" + "github.com/minio/pkg/wildcard" ) type erasureServerPools struct { diff --git a/cmd/erasure-sets.go b/cmd/erasure-sets.go index 5b46ddbd9..59da06421 100644 --- a/cmd/erasure-sets.go +++ b/cmd/erasure-sets.go @@ -37,10 +37,10 @@ import ( "github.com/minio/minio-go/v7/pkg/tags" "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/bpool" - "github.com/minio/minio/pkg/console" "github.com/minio/minio/pkg/dsync" - "github.com/minio/minio/pkg/env" "github.com/minio/minio/pkg/sync/errgroup" + "github.com/minio/pkg/console" + "github.com/minio/pkg/env" ) // setsDsyncLockers is encapsulated type for Close() diff --git a/cmd/erasure.go b/cmd/erasure.go index 1c3e9e696..b5772e8be 100644 --- a/cmd/erasure.go +++ b/cmd/erasure.go @@ -31,9 +31,9 @@ import ( "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/bpool" "github.com/minio/minio/pkg/color" - "github.com/minio/minio/pkg/console" "github.com/minio/minio/pkg/dsync" "github.com/minio/minio/pkg/sync/errgroup" + "github.com/minio/pkg/console" ) // OfflineDisk represents an unavailable disk. diff --git a/cmd/fs-v1-metadata.go b/cmd/fs-v1-metadata.go index a36c6dddf..474abfbc1 100644 --- a/cmd/fs-v1-metadata.go +++ b/cmd/fs-v1-metadata.go @@ -32,7 +32,7 @@ import ( xhttp "github.com/minio/minio/cmd/http" "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/lock" - "github.com/minio/minio/pkg/mimedb" + "github.com/minio/pkg/mimedb" ) // FS format, and object metadata. diff --git a/cmd/fs-v1-multipart.go b/cmd/fs-v1-multipart.go index 4e0b40f5e..358b4d931 100644 --- a/cmd/fs-v1-multipart.go +++ b/cmd/fs-v1-multipart.go @@ -33,7 +33,7 @@ import ( jsoniter "github.com/json-iterator/go" "github.com/minio/minio/cmd/logger" xioutil "github.com/minio/minio/pkg/ioutil" - "github.com/minio/minio/pkg/trie" + "github.com/minio/pkg/trie" ) // Returns EXPORT/.minio.sys/multipart/SHA256/UPLOADID diff --git a/cmd/fs-v1.go b/cmd/fs-v1.go index 1993b78b8..91f374e49 100644 --- a/cmd/fs-v1.go +++ b/cmd/fs-v1.go @@ -44,8 +44,8 @@ import ( "github.com/minio/minio/pkg/color" xioutil "github.com/minio/minio/pkg/ioutil" "github.com/minio/minio/pkg/lock" - "github.com/minio/minio/pkg/mimedb" "github.com/minio/minio/pkg/mountinfo" + "github.com/minio/pkg/mimedb" ) // Default etag is used for pre-existing objects. diff --git a/cmd/gateway-common.go b/cmd/gateway-common.go index 653c93bcd..a0f3eff89 100644 --- a/cmd/gateway-common.go +++ b/cmd/gateway-common.go @@ -27,9 +27,9 @@ import ( "github.com/minio/minio/cmd/config" xhttp "github.com/minio/minio/cmd/http" "github.com/minio/minio/cmd/logger" - "github.com/minio/minio/pkg/env" "github.com/minio/minio/pkg/hash" xnet "github.com/minio/minio/pkg/net" + "github.com/minio/pkg/env" minio "github.com/minio/minio-go/v7" ) diff --git a/cmd/gateway-main.go b/cmd/gateway-main.go index 01e828761..6a425732b 100644 --- a/cmd/gateway-main.go +++ b/cmd/gateway-main.go @@ -31,9 +31,9 @@ import ( "github.com/minio/cli" xhttp "github.com/minio/minio/cmd/http" "github.com/minio/minio/cmd/logger" - "github.com/minio/minio/pkg/certs" "github.com/minio/minio/pkg/color" - "github.com/minio/minio/pkg/env" + "github.com/minio/pkg/certs" + "github.com/minio/pkg/env" ) var ( diff --git a/cmd/gateway/azure/gateway-azure.go b/cmd/gateway/azure/gateway-azure.go index 860cea375..3901aa85c 100644 --- a/cmd/gateway/azure/gateway-azure.go +++ b/cmd/gateway/azure/gateway-azure.go @@ -47,7 +47,7 @@ import ( "github.com/minio/minio/pkg/auth" "github.com/minio/minio/pkg/bucket/policy" "github.com/minio/minio/pkg/bucket/policy/condition" - "github.com/minio/minio/pkg/env" + "github.com/minio/pkg/env" ) const ( diff --git a/cmd/gateway/gcs/gateway-gcs.go b/cmd/gateway/gcs/gateway-gcs.go index 1ea9dc135..724af2750 100644 --- a/cmd/gateway/gcs/gateway-gcs.go +++ b/cmd/gateway/gcs/gateway-gcs.go @@ -44,7 +44,7 @@ import ( "github.com/minio/minio/pkg/auth" "github.com/minio/minio/pkg/bucket/policy" "github.com/minio/minio/pkg/bucket/policy/condition" - "github.com/minio/minio/pkg/env" + "github.com/minio/pkg/env" "google.golang.org/api/googleapi" "google.golang.org/api/iterator" "google.golang.org/api/option" diff --git a/cmd/gateway/hdfs/gateway-hdfs.go b/cmd/gateway/hdfs/gateway-hdfs.go index 4e37b49db..980d37455 100644 --- a/cmd/gateway/hdfs/gateway-hdfs.go +++ b/cmd/gateway/hdfs/gateway-hdfs.go @@ -43,8 +43,8 @@ import ( minio "github.com/minio/minio/cmd" "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/auth" - "github.com/minio/minio/pkg/env" xnet "github.com/minio/minio/pkg/net" + "github.com/minio/pkg/env" ) const ( diff --git a/cmd/global-heal.go b/cmd/global-heal.go index 25640facd..eea41d4a3 100644 --- a/cmd/global-heal.go +++ b/cmd/global-heal.go @@ -27,8 +27,8 @@ import ( "github.com/minio/madmin-go" "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/color" - "github.com/minio/minio/pkg/console" - "github.com/minio/minio/pkg/wildcard" + "github.com/minio/pkg/console" + "github.com/minio/pkg/wildcard" ) const ( diff --git a/cmd/globals.go b/cmd/globals.go index 075b9a1b3..c617a621b 100644 --- a/cmd/globals.go +++ b/cmd/globals.go @@ -42,9 +42,9 @@ import ( "github.com/minio/minio/pkg/auth" etcd "go.etcd.io/etcd/client/v3" - "github.com/minio/minio/pkg/certs" "github.com/minio/minio/pkg/event" "github.com/minio/minio/pkg/pubsub" + "github.com/minio/pkg/certs" ) // minio configuration related constants. diff --git a/cmd/handler-api.go b/cmd/handler-api.go index 7049f0252..5f80b694a 100644 --- a/cmd/handler-api.go +++ b/cmd/handler-api.go @@ -24,7 +24,7 @@ import ( "github.com/minio/minio/cmd/config/api" "github.com/minio/minio/cmd/logger" - "github.com/minio/minio/pkg/sys" + "github.com/minio/pkg/sys" ) type apiConfig struct { diff --git a/cmd/http/server.go b/cmd/http/server.go index 7df60335c..cab87b251 100644 --- a/cmd/http/server.go +++ b/cmd/http/server.go @@ -32,9 +32,9 @@ import ( "github.com/minio/minio-go/v7/pkg/set" "github.com/minio/minio/cmd/config" "github.com/minio/minio/cmd/config/api" - "github.com/minio/minio/pkg/certs" - "github.com/minio/minio/pkg/env" "github.com/minio/minio/pkg/fips" + "github.com/minio/pkg/certs" + "github.com/minio/pkg/env" ) const ( diff --git a/cmd/http/server_test.go b/cmd/http/server_test.go index 2a80b6d1c..97363d895 100644 --- a/cmd/http/server_test.go +++ b/cmd/http/server_test.go @@ -23,7 +23,7 @@ import ( "reflect" "testing" - "github.com/minio/minio/pkg/certs" + "github.com/minio/pkg/certs" ) func TestNewServer(t *testing.T) { diff --git a/cmd/logger/config.go b/cmd/logger/config.go index c212b2d0d..62db81f11 100644 --- a/cmd/logger/config.go +++ b/cmd/logger/config.go @@ -21,7 +21,7 @@ import ( "strings" "github.com/minio/minio/cmd/config" - "github.com/minio/minio/pkg/env" + "github.com/minio/pkg/env" ) // Console logger target diff --git a/cmd/logger/console.go b/cmd/logger/console.go index 7337231d3..fca9864c4 100644 --- a/cmd/logger/console.go +++ b/cmd/logger/console.go @@ -26,7 +26,7 @@ import ( "github.com/minio/minio/cmd/logger/message/log" "github.com/minio/minio/pkg/color" - c "github.com/minio/minio/pkg/console" + c "github.com/minio/pkg/console" ) // Logger interface describes the methods that need to be implemented to satisfy the interface requirements. diff --git a/cmd/logger/target/console/console.go b/cmd/logger/target/console/console.go index e3c7b1f74..fa55204e1 100644 --- a/cmd/logger/target/console/console.go +++ b/cmd/logger/target/console/console.go @@ -26,7 +26,7 @@ import ( "github.com/minio/minio/cmd/logger" "github.com/minio/minio/cmd/logger/message/log" "github.com/minio/minio/pkg/color" - "github.com/minio/minio/pkg/console" + "github.com/minio/pkg/console" ) // Target implements loggerTarget to send log diff --git a/cmd/main.go b/cmd/main.go index 7b86faf3c..26b1a2f39 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -23,9 +23,9 @@ import ( "sort" "github.com/minio/cli" - "github.com/minio/minio/pkg/console" - "github.com/minio/minio/pkg/trie" - "github.com/minio/minio/pkg/words" + "github.com/minio/pkg/console" + "github.com/minio/pkg/trie" + "github.com/minio/pkg/words" ) // GlobalFlags - global flags for minio. diff --git a/cmd/metacache-bucket.go b/cmd/metacache-bucket.go index 1df41bd4c..3123efd92 100644 --- a/cmd/metacache-bucket.go +++ b/cmd/metacache-bucket.go @@ -32,8 +32,8 @@ import ( "github.com/klauspost/compress/s2" "github.com/minio/minio/cmd/logger" - "github.com/minio/minio/pkg/console" "github.com/minio/minio/pkg/hash" + "github.com/minio/pkg/console" "github.com/tinylib/msgp/msgp" ) diff --git a/cmd/metacache-set.go b/cmd/metacache-set.go index 7750a45aa..6cade820c 100644 --- a/cmd/metacache-set.go +++ b/cmd/metacache-set.go @@ -33,8 +33,8 @@ import ( jsoniter "github.com/json-iterator/go" "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/color" - "github.com/minio/minio/pkg/console" "github.com/minio/minio/pkg/hash" + "github.com/minio/pkg/console" ) type listPathOptions struct { diff --git a/cmd/object-api-utils.go b/cmd/object-api-utils.go index b1efd1193..5df429935 100644 --- a/cmd/object-api-utils.go +++ b/cmd/object-api-utils.go @@ -47,8 +47,8 @@ import ( "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/hash" "github.com/minio/minio/pkg/ioutil" - "github.com/minio/minio/pkg/trie" - "github.com/minio/minio/pkg/wildcard" + "github.com/minio/pkg/trie" + "github.com/minio/pkg/wildcard" ) const ( diff --git a/cmd/object-api-utils_test.go b/cmd/object-api-utils_test.go index 84d5a6240..ffd12f787 100644 --- a/cmd/object-api-utils_test.go +++ b/cmd/object-api-utils_test.go @@ -29,7 +29,7 @@ import ( "github.com/klauspost/compress/s2" "github.com/minio/minio/cmd/config/compress" "github.com/minio/minio/cmd/crypto" - "github.com/minio/minio/pkg/trie" + "github.com/minio/pkg/trie" ) // Tests validate bucket name. diff --git a/cmd/server-main.go b/cmd/server-main.go index eaeefd41c..37662af8d 100644 --- a/cmd/server-main.go +++ b/cmd/server-main.go @@ -40,11 +40,11 @@ import ( "github.com/minio/minio/cmd/rest" "github.com/minio/minio/pkg/auth" "github.com/minio/minio/pkg/bucket/bandwidth" - "github.com/minio/minio/pkg/certs" "github.com/minio/minio/pkg/color" - "github.com/minio/minio/pkg/env" "github.com/minio/minio/pkg/fips" "github.com/minio/minio/pkg/sync/errgroup" + "github.com/minio/pkg/certs" + "github.com/minio/pkg/env" ) // ServerFlags - server command specific flags diff --git a/cmd/server-rlimit.go b/cmd/server-rlimit.go index f1d8f157d..c275898f3 100644 --- a/cmd/server-rlimit.go +++ b/cmd/server-rlimit.go @@ -20,7 +20,7 @@ package cmd import ( "runtime/debug" - "github.com/minio/minio/pkg/sys" + "github.com/minio/pkg/sys" ) func setMaxResources() (err error) { diff --git a/cmd/sts-handlers.go b/cmd/sts-handlers.go index 5010b955f..bb11c172f 100644 --- a/cmd/sts-handlers.go +++ b/cmd/sts-handlers.go @@ -32,7 +32,7 @@ import ( "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/auth" iampolicy "github.com/minio/minio/pkg/iam/policy" - "github.com/minio/minio/pkg/wildcard" + "github.com/minio/pkg/wildcard" ) const ( diff --git a/cmd/update.go b/cmd/update.go index 8458e1063..e29ff81ac 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -37,8 +37,8 @@ import ( xhttp "github.com/minio/minio/cmd/http" "github.com/minio/minio/cmd/logger" - "github.com/minio/minio/pkg/env" xnet "github.com/minio/minio/pkg/net" + "github.com/minio/pkg/env" "github.com/minio/selfupdate" ) diff --git a/cmd/utils.go b/cmd/utils.go index be2bede19..63289a546 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -47,8 +47,8 @@ import ( xhttp "github.com/minio/minio/cmd/http" "github.com/minio/minio/cmd/logger" "github.com/minio/minio/cmd/rest" - "github.com/minio/minio/pkg/certs" "github.com/minio/minio/pkg/handlers" + "github.com/minio/pkg/certs" ) const ( diff --git a/cmd/xl-storage.go b/cmd/xl-storage.go index dca22cd5b..44c8fac49 100644 --- a/cmd/xl-storage.go +++ b/cmd/xl-storage.go @@ -45,10 +45,10 @@ import ( "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/bucket/lifecycle" "github.com/minio/minio/pkg/color" - "github.com/minio/minio/pkg/console" "github.com/minio/minio/pkg/disk" - "github.com/minio/minio/pkg/env" xioutil "github.com/minio/minio/pkg/ioutil" + "github.com/minio/pkg/console" + "github.com/minio/pkg/env" ) const ( diff --git a/go.mod b/go.mod index a2d183277..d06e4f257 100644 --- a/go.mod +++ b/go.mod @@ -23,8 +23,7 @@ require ( github.com/dustin/go-humanize v1.0.0 github.com/eclipse/paho.mqtt.golang v1.3.0 github.com/elastic/go-elasticsearch/v7 v7.12.0 - github.com/fatih/color v1.10.0 - github.com/fatih/structs v1.1.0 + github.com/fatih/color v1.12.0 github.com/go-ldap/ldap/v3 v3.2.4 github.com/go-sql-driver/mysql v1.5.0 github.com/gomodule/redigo v2.0.0+incompatible @@ -40,8 +39,6 @@ require ( github.com/klauspost/readahead v1.3.1 github.com/klauspost/reedsolomon v1.9.11 github.com/lib/pq v1.9.0 - github.com/mattn/go-colorable v0.1.8 - github.com/mattn/go-isatty v0.0.12 github.com/miekg/dns v1.1.35 github.com/minio/cli v1.22.0 github.com/minio/csvparser v1.0.0 @@ -50,6 +47,7 @@ require ( github.com/minio/madmin-go v1.0.2 github.com/minio/minio-go/v7 v7.0.11-0.20210302210017-6ae69c73ce78 github.com/minio/parquet-go v1.0.0 + github.com/minio/pkg v1.0.2 github.com/minio/rpc v1.0.0 github.com/minio/selfupdate v0.3.1 github.com/minio/sha256-simd v1.0.0 @@ -69,7 +67,6 @@ require ( github.com/prometheus/client_golang v1.8.0 github.com/prometheus/client_model v0.2.0 github.com/prometheus/procfs v0.6.0 - github.com/rjeczalik/notify v0.9.2 github.com/rs/cors v1.7.0 github.com/secure-io/sio-go v0.3.1 github.com/shirou/gopsutil/v3 v3.21.3 @@ -85,7 +82,7 @@ require ( golang.org/x/sys v0.0.0-20210510120138-977fb7262007 golang.org/x/tools v0.1.1 // indirect google.golang.org/api v0.31.0 - gopkg.in/yaml.v2 v2.3.0 + gopkg.in/yaml.v2 v2.4.0 ) replace google.golang.org/grpc => google.golang.org/grpc v1.29.1 diff --git a/go.sum b/go.sum index 5699227b4..a4f1c7f70 100644 --- a/go.sum +++ b/go.sum @@ -148,6 +148,10 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dchest/siphash v1.2.1 h1:4cLinnzVJDKxTCl9B01807Yiy+W7ZzVHj/KIroQRvT4= github.com/dchest/siphash v1.2.1/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4= +github.com/decred/dcrd/chaincfg/chainhash v1.0.2/go.mod h1:BpbrGgrPTr3YJYRN3Bm+D9NuaFd+zGyNeIKgrhCXK60= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0 h1:sgNeV1VRMDzs6rzyPpxyM0jp317hnwiq58Filgag2xw= +github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0/go.mod h1:J70FGZSbzsjecRTiTzER+3f1KZLNaXkuv+yeFTKoxM8= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/djherbis/atime v1.0.0 h1:ySLvBAM0EvOGaX7TI4dAM5lWj+RdJUCKtGSEHN8SGBg= @@ -173,8 +177,9 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= +github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= @@ -211,6 +216,8 @@ github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gG github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/goccy/go-json v0.4.8 h1:TfwOxfSp8hXH+ivoOk36RyDNmXATUETRdaNWDaZglf8= +github.com/goccy/go-json v0.4.8/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -428,6 +435,22 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lestrrat-go/backoff/v2 v2.0.7 h1:i2SeK33aOFJlUNJZzf2IpXRBvqBBnaGXfY5Xaop/GsE= +github.com/lestrrat-go/backoff/v2 v2.0.7/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= +github.com/lestrrat-go/blackmagic v1.0.0 h1:XzdxDbuQTz0RZZEmdU7cnQxUtFUzgCSPq8RCz4BxIi4= +github.com/lestrrat-go/blackmagic v1.0.0/go.mod h1:TNgH//0vYSs8VXDCfkZLgIrVTTXQELZffUV0tz3MtdQ= +github.com/lestrrat-go/codegen v1.0.0/go.mod h1:JhJw6OQAuPEfVKUCLItpaVLumDGWQznd1VaXrBk9TdM= +github.com/lestrrat-go/httpcc v1.0.0 h1:FszVC6cKfDvBKcJv646+lkh4GydQg2Z29scgUfkOpYc= +github.com/lestrrat-go/httpcc v1.0.0/go.mod h1:tGS/u00Vh5N6FHNkExqGGNId8e0Big+++0Gf8MBnAvE= +github.com/lestrrat-go/iter v1.0.1 h1:q8faalr2dY6o8bV45uwrxq12bRa1ezKrB6oM9FUgN4A= +github.com/lestrrat-go/iter v1.0.1/go.mod h1:zIdgO1mRKhn8l9vrZJZz9TUMMFbQbLeTsbqPDrJ/OJc= +github.com/lestrrat-go/jwx v1.2.0 h1:n08WEu8cJy3uzuQ39KWAOIhM4XfeozgaEGA8mTiioZ8= +github.com/lestrrat-go/jwx v1.2.0/go.mod h1:Tg2uP7bpxEHUDtuWjap/PxroJ4okxGzkQznXiG+a5Dc= +github.com/lestrrat-go/option v0.0.0-20210103042652-6f1ecfceda35/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/lestrrat-go/option v1.0.0 h1:WqAWL8kh8VcSoD6xjSH34/1m8yxluXQbDeKNfvFeEO4= +github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/lestrrat-go/pdebug/v3 v3.0.1 h1:3G5sX/aw/TbMTtVc9U7IHBWRZtMvwvBziF1e4HoQtv8= +github.com/lestrrat-go/pdebug/v3 v3.0.1/go.mod h1:za+m+Ve24yCxTEhR59N7UlnJomWwCiIqbJRmKeiADU4= github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8= github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= @@ -448,8 +471,9 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= +github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54= @@ -480,6 +504,8 @@ github.com/minio/minio-go/v7 v7.0.11-0.20210302210017-6ae69c73ce78 h1:v7OMbUnWky github.com/minio/minio-go/v7 v7.0.11-0.20210302210017-6ae69c73ce78/go.mod h1:mTh2uJuAbEqdhMVl6CMIIZLUeiMiWtJR4JB8/5g2skw= github.com/minio/parquet-go v1.0.0 h1:fcWsEvub04Nsl/4hiRBDWlbqd6jhacQieV07a+nhiIk= github.com/minio/parquet-go v1.0.0/go.mod h1:aQlkSOfOq2AtQKkuou3mosNVMwNokd+faTacxxk/oHA= +github.com/minio/pkg v1.0.2 h1:vUlNMJbOgP/Hi/ekN+tl1xTOm3Q39gPr5XurDVOgvBA= +github.com/minio/pkg v1.0.2/go.mod h1:e9WOU0bav8jd8AzloFjCTSiXSNqnXqxbzGwlH+2rQnI= github.com/minio/rpc v1.0.0 h1:tJCHyLfQF6k6HlMQFpKy2FO/7lc2WP8gLDGMZp18E70= github.com/minio/rpc v1.0.0/go.mod h1:b9xqF7J0xeMXr0cM4pnBlP7Te7PDsG5JrRxl5dG6Ldk= github.com/minio/selfupdate v0.3.1 h1:BWEFSNnrZVMUWXbXIgLDNDjbejkmpAmZvy/nCz1HlEs= @@ -671,8 +697,9 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tidwall/gjson v1.6.8/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= github.com/tidwall/gjson v1.7.4/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk= github.com/tidwall/gjson v1.7.5 h1:zmAN/xmX7OtpAkv4Ovfso60r/BiCi5IErCDYGNJu+uc= @@ -764,6 +791,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201217014255-9d1352758620/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210415154028-4f45737414dc/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg= @@ -798,6 +826,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -986,9 +1015,11 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200828161849-5deb26317202/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201105001634-bc3cf281b174/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210114065538-d78b04bdf963/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1 h1:wGiQel/hW0NnEkJUk8lbzkX2gFJU6PFxf1v5OlCfuOs= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -1110,8 +1141,9 @@ gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/bucket/object/lock/lock.go b/pkg/bucket/object/lock/lock.go index 3074aec26..449ef5b08 100644 --- a/pkg/bucket/object/lock/lock.go +++ b/pkg/bucket/object/lock/lock.go @@ -29,7 +29,7 @@ import ( "github.com/beevik/ntp" "github.com/minio/minio/cmd/logger" - "github.com/minio/minio/pkg/env" + "github.com/minio/pkg/env" ) // RetMode - object retention mode. diff --git a/pkg/bucket/policy/condition/stringlikefunc.go b/pkg/bucket/policy/condition/stringlikefunc.go index d0f2045c8..4d950c953 100644 --- a/pkg/bucket/policy/condition/stringlikefunc.go +++ b/pkg/bucket/policy/condition/stringlikefunc.go @@ -24,7 +24,7 @@ import ( "github.com/minio/minio-go/v7/pkg/s3utils" "github.com/minio/minio-go/v7/pkg/set" - "github.com/minio/minio/pkg/wildcard" + "github.com/minio/pkg/wildcard" ) func toStringLikeFuncString(n name, key Key, values set.StringSet) string { diff --git a/pkg/bucket/policy/principal.go b/pkg/bucket/policy/principal.go index 503bc9d36..732df7433 100644 --- a/pkg/bucket/policy/principal.go +++ b/pkg/bucket/policy/principal.go @@ -21,7 +21,7 @@ import ( "encoding/json" "github.com/minio/minio-go/v7/pkg/set" - "github.com/minio/minio/pkg/wildcard" + "github.com/minio/pkg/wildcard" ) // Principal - policy principal. diff --git a/pkg/bucket/policy/resource.go b/pkg/bucket/policy/resource.go index 347f7ee34..07df24276 100644 --- a/pkg/bucket/policy/resource.go +++ b/pkg/bucket/policy/resource.go @@ -22,7 +22,7 @@ import ( "strings" "github.com/minio/minio/pkg/bucket/policy/condition" - "github.com/minio/minio/pkg/wildcard" + "github.com/minio/pkg/wildcard" ) // ResourceARNPrefix - resource ARN prefix as per AWS S3 specification. diff --git a/pkg/bucket/replication/destination.go b/pkg/bucket/replication/destination.go index 68cc2c954..395a24e51 100644 --- a/pkg/bucket/replication/destination.go +++ b/pkg/bucket/replication/destination.go @@ -22,7 +22,7 @@ import ( "fmt" "strings" - "github.com/minio/minio/pkg/wildcard" + "github.com/minio/pkg/wildcard" ) // DestinationARNPrefix - destination ARN prefix as per AWS S3 specification. diff --git a/pkg/certs/ca-certs.go b/pkg/certs/ca-certs.go deleted file mode 100644 index aacdb7478..000000000 --- a/pkg/certs/ca-certs.go +++ /dev/null @@ -1,93 +0,0 @@ -// 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 . - -package certs - -import ( - "crypto/x509" - "errors" - "fmt" - "io/ioutil" - "os" - "path/filepath" -) - -// GetRootCAs loads all X.509 certificates at the given path and adds them -// to the list of system root CAs, if available. The returned CA pool -// is a conjunction of the system root CAs and the certificate(s) at -// the given path. -// -// If path is a regular file, LoadCAs simply adds it to the CA pool -// if the file contains a valid X.509 certificate -// -// If the path points to a directory, LoadCAs iterates over all top-level -// files within the directory and adds them to the CA pool if they contain -// a valid X.509 certificate. -func GetRootCAs(path string) (*x509.CertPool, error) { - rootCAs, _ := loadSystemRoots() - if rootCAs == nil { - // In some systems system cert pool is not supported - // or no certificates are present on the - // system - so we create a new cert pool. - rootCAs = x509.NewCertPool() - } - - // Open the file path and check whether its a regular file - // or a directory. - f, err := os.Open(path) - if errors.Is(err, os.ErrNotExist) { - return rootCAs, nil - } - if errors.Is(err, os.ErrPermission) { - return rootCAs, nil - } - if err != nil { - return rootCAs, err - } - defer f.Close() - - stat, err := f.Stat() - if err != nil { - return rootCAs, err - } - - // In case of a file add it to the root CAs. - if !stat.IsDir() { - bytes, err := ioutil.ReadAll(f) - if err != nil { - return rootCAs, err - } - if !rootCAs.AppendCertsFromPEM(bytes) { - return rootCAs, fmt.Errorf("cert: %q does not contain a valid X.509 PEM-encoded certificate", path) - } - return rootCAs, nil - } - - // Otherwise iterate over the files in the directory - // and add each on to the root CAs. - files, err := f.Readdirnames(0) - if err != nil { - return rootCAs, err - } - for _, file := range files { - bytes, err := ioutil.ReadFile(filepath.Join(path, file)) - if err == nil { // ignore files which are not readable. - rootCAs.AppendCertsFromPEM(bytes) - } - } - return rootCAs, nil -} diff --git a/pkg/certs/ca-certs_test.go b/pkg/certs/ca-certs_test.go deleted file mode 100644 index eaa1115b4..000000000 --- a/pkg/certs/ca-certs_test.go +++ /dev/null @@ -1,79 +0,0 @@ -// 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 . - -package certs - -import ( - "io/ioutil" - "os" - "path/filepath" - "testing" -) - -func TestGetRootCAs(t *testing.T) { - emptydir, err := ioutil.TempDir("", "test-get-root-cas") - if err != nil { - t.Fatalf("Unable create temp directory. %v", emptydir) - } - defer os.RemoveAll(emptydir) - - dir1, err := ioutil.TempDir("", "test-get-root-cas") - if err != nil { - t.Fatalf("Unable create temp directory. %v", dir1) - } - defer os.RemoveAll(dir1) - if err = os.Mkdir(filepath.Join(dir1, "empty-dir"), 0755); err != nil { - t.Fatalf("Unable create empty dir. %v", err) - } - - dir2, err := ioutil.TempDir("", "test-get-root-cas") - if err != nil { - t.Fatalf("Unable create temp directory. %v", dir2) - } - defer os.RemoveAll(dir2) - if err = ioutil.WriteFile(filepath.Join(dir2, "empty-file"), []byte{}, 0644); err != nil { - t.Fatalf("Unable create test file. %v", err) - } - - testCases := []struct { - certCAsDir string - expectedErr error - }{ - // ignores non-existent directories. - {"nonexistent-dir", nil}, - // Ignores directories. - {dir1, nil}, - // Ignore empty directory. - {emptydir, nil}, - // Loads the cert properly. - {dir2, nil}, - } - - for _, testCase := range testCases { - _, err := GetRootCAs(testCase.certCAsDir) - - if testCase.expectedErr == nil { - if err != nil { - t.Fatalf("error: expected = , got = %v", err) - } - } else if err == nil { - t.Fatalf("error: expected = %v, got = ", testCase.expectedErr) - } else if testCase.expectedErr.Error() != err.Error() { - t.Fatalf("error: expected = %v, got = %v", testCase.expectedErr, err) - } - } -} diff --git a/pkg/certs/cert_pool_nix.go b/pkg/certs/cert_pool_nix.go deleted file mode 100644 index a78140fac..000000000 --- a/pkg/certs/cert_pool_nix.go +++ /dev/null @@ -1,85 +0,0 @@ -// +build !windows - -// 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 . - -package certs - -import ( - "crypto/x509" - "io/ioutil" - "os" - "path/filepath" - "strings" -) - -// Possible directories with certificate files, this is an extended -// list from https://golang.org/src/crypto/x509/root_unix.go?#L18 -// for k8s platform -var certDirectories = []string{ - "/var/run/secrets/kubernetes.io/serviceaccount", -} - -// readUniqueDirectoryEntries is like ioutil.ReadDir but omits -// symlinks that point within the directory. -func readUniqueDirectoryEntries(dir string) ([]os.FileInfo, error) { - fis, err := ioutil.ReadDir(dir) - if err != nil { - return nil, err - } - uniq := fis[:0] - for _, fi := range fis { - if !isSameDirSymlink(fi, dir) { - uniq = append(uniq, fi) - } - } - return uniq, nil -} - -// isSameDirSymlink reports whether fi in dir is a symlink with a -// target not containing a slash. -func isSameDirSymlink(fi os.FileInfo, dir string) bool { - if fi.Mode()&os.ModeSymlink == 0 { - return false - } - target, err := os.Readlink(filepath.Join(dir, fi.Name())) - return err == nil && !strings.Contains(target, "/") -} - -func loadSystemRoots() (*x509.CertPool, error) { - caPool, err := x509.SystemCertPool() - if err != nil { - return caPool, err - } - - for _, directory := range certDirectories { - fis, err := readUniqueDirectoryEntries(directory) - if err != nil { - if os.IsNotExist(err) || os.IsPermission(err) { - return caPool, nil - } - return caPool, err - } - for _, fi := range fis { - data, err := ioutil.ReadFile(directory + "/" + fi.Name()) - if err == nil { - caPool.AppendCertsFromPEM(data) - } - } - } - return caPool, nil -} diff --git a/pkg/certs/cert_pool_windows.go b/pkg/certs/cert_pool_windows.go deleted file mode 100644 index db9c8f9ff..000000000 --- a/pkg/certs/cert_pool_windows.go +++ /dev/null @@ -1,61 +0,0 @@ -// +build windows - -// 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 . - -package certs - -import ( - "crypto/x509" - "syscall" - "unsafe" -) - -func loadSystemRoots() (*x509.CertPool, error) { - const CRYPTENOTFOUND = 0x80092004 - - store, err := syscall.CertOpenSystemStore(0, syscall.StringToUTF16Ptr("ROOT")) - if err != nil { - return nil, err - } - defer syscall.CertCloseStore(store, 0) - - roots := x509.NewCertPool() - var cert *syscall.CertContext - for { - cert, err = syscall.CertEnumCertificatesInStore(store, cert) - if err != nil { - if errno, ok := err.(syscall.Errno); ok { - if errno == CRYPTENOTFOUND { - break - } - } - return nil, err - } - if cert == nil { - break - } - // Copy the buf, since ParseCertificate does not create its own copy. - buf := (*[1 << 20]byte)(unsafe.Pointer(cert.EncodedCert))[:] - buf2 := make([]byte, cert.Length) - copy(buf2, buf) - if c, err := x509.ParseCertificate(buf2); err == nil { - roots.AddCert(c) - } - } - return roots, nil -} diff --git a/pkg/certs/certs.go b/pkg/certs/certs.go deleted file mode 100644 index aecd7e6d3..000000000 --- a/pkg/certs/certs.go +++ /dev/null @@ -1,347 +0,0 @@ -// 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 . - -package certs - -import ( - "context" - "crypto/tls" - "crypto/x509" - "errors" - "fmt" - "os" - "path/filepath" - "sync" - "time" - - "github.com/rjeczalik/notify" -) - -// LoadX509KeyPairFunc is a function that parses a private key and -// certificate file and returns a TLS certificate on success. -type LoadX509KeyPairFunc func(certFile, keyFile string) (tls.Certificate, error) - -// GetCertificateFunc is a callback that allows a TLS stack deliver different -// certificates based on the client trying to establish a TLS connection. -// -// For example, a GetCertificateFunc can return different TLS certificates depending -// upon the TLS SNI sent by the client. -type GetCertificateFunc func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) - -// Manager is a TLS certificate manager that can handle multiple certificates. -// When a client tries to establish a TLS connection, Manager will try to -// pick a certificate that can be validated by the client. -// -// For instance, if the client specifies a TLS SNI then Manager will try to -// find the corresponding certificate. If there is no such certificate it -// will fallback to the certificate named public.crt. -// -// Manager will automatically reload certificates if the corresponding file changes. -type Manager struct { - lock sync.RWMutex - certificates map[pair]*tls.Certificate // Mapping: certificate file name => TLS certificates - defaultCert pair - - loadX509KeyPair LoadX509KeyPairFunc - events chan notify.EventInfo - ctx context.Context -} - -// pair represents a certificate and private key file tuple. -type pair struct { - KeyFile string - CertFile string -} - -// NewManager returns a new Manager that handles one certificate specified via -// the certFile and keyFile. It will use the loadX509KeyPair function to (re)load -// certificates. -// -// The certificate loaded from certFile is considered the default certificate. -// If a client does not send the TLS SNI extension then Manager will return -// this certificate. -func NewManager(ctx context.Context, certFile, keyFile string, loadX509KeyPair LoadX509KeyPairFunc) (manager *Manager, err error) { - certFile, err = filepath.Abs(certFile) - if err != nil { - return nil, err - } - keyFile, err = filepath.Abs(keyFile) - if err != nil { - return nil, err - } - - manager = &Manager{ - certificates: map[pair]*tls.Certificate{}, - defaultCert: pair{ - KeyFile: keyFile, - CertFile: certFile, - }, - loadX509KeyPair: loadX509KeyPair, - events: make(chan notify.EventInfo, 1), - ctx: ctx, - } - if err := manager.AddCertificate(certFile, keyFile); err != nil { - return nil, err - } - go manager.watchFileEvents() - return manager, nil -} - -// AddCertificate adds the TLS certificate in certFile resp. keyFile -// to the Manager. -// -// If there is already a certificate with the same base name it will be -// replaced by the newly added one. -func (m *Manager) AddCertificate(certFile, keyFile string) (err error) { - certFile, err = filepath.Abs(certFile) - if err != nil { - return err - } - keyFile, err = filepath.Abs(keyFile) - if err != nil { - return err - } - certFileIsLink, err := isSymlink(certFile) - if err != nil { - return err - } - keyFileIsLink, err := isSymlink(keyFile) - if err != nil { - return err - } - if certFileIsLink && !keyFileIsLink { - return fmt.Errorf("certs: '%s' is a symlink but '%s' is a regular file", certFile, keyFile) - } - if keyFileIsLink && !certFileIsLink { - return fmt.Errorf("certs: '%s' is a symlink but '%s' is a regular file", keyFile, certFile) - } - - certificate, err := m.loadX509KeyPair(certFile, keyFile) - if err != nil { - return err - } - // We set the certificate leaf to the actual certificate such that - // we don't have to do the parsing (multiple times) when matching the - // certificate to the client hello. This a performance optimisation. - if certificate.Leaf == nil { - certificate.Leaf, err = x509.ParseCertificate(certificate.Certificate[0]) - if err != nil { - return err - } - } - - p := pair{ - CertFile: certFile, - KeyFile: keyFile, - } - m.lock.Lock() - defer m.lock.Unlock() - - // We don't allow IP SANs in certificates - except for the "default" certificate - // which is, by convention, the first certificate added to the manager. The problem - // with allowing IP SANs in more than one certificate is that the manager usually can't - // match the client SNI to a SAN since the SNI is meant to communicate the destination - // host name and clients will not set the SNI to an IP address. - // Allowing multiple certificates with IP SANs lead to errors that confuses users - like: - // "It works for `https://instance.minio.local` but not for `https://10.0.2.1`" - if len(m.certificates) > 0 && len(certificate.Leaf.IPAddresses) > 0 { - return errors.New("cert: certificate must not contain any IP SANs: only the default certificate may contain IP SANs") - } - m.certificates[p] = &certificate - - if certFileIsLink && keyFileIsLink { - go m.watchSymlinks(certFile, keyFile) - } else { - // Windows doesn't allow for watching file changes but instead allows - // for directory changes only, while we can still watch for changes - // on files on other platforms. Watch parent directory on all platforms - // for simplicity. - if err = notify.Watch(filepath.Dir(certFile), m.events, eventWrite...); err != nil { - return err - } - if err = notify.Watch(filepath.Dir(keyFile), m.events, eventWrite...); err != nil { - return err - } - } - return nil -} - -// watchSymlinks starts an endless loop reloading the -// certFile and keyFile periodically. -func (m *Manager) watchSymlinks(certFile, keyFile string) { - for { - select { - case <-m.ctx.Done(): - return // Once stopped exits this routine. - case <-time.After(24 * time.Hour): - certificate, err := m.loadX509KeyPair(certFile, keyFile) - if err != nil { - continue - } - if certificate.Leaf == nil { // This is a performance optimisation - certificate.Leaf, err = x509.ParseCertificate(certificate.Certificate[0]) - if err != nil { - continue - } - } - - p := pair{ - CertFile: certFile, - KeyFile: keyFile, - } - m.lock.Lock() - m.certificates[p] = &certificate - m.lock.Unlock() - } - } -} - -// watchFileEvents starts an endless loop waiting for file systems events. -// Once an event occurs it reloads the private key and certificate that -// has changed, if any. -func (m *Manager) watchFileEvents() { - for { - select { - case <-m.ctx.Done(): - return - case event := <-m.events: - if !isWriteEvent(event.Event()) { - continue - } - - for pair := range m.certificates { - if p := event.Path(); pair.KeyFile == p || pair.CertFile == p { - certificate, err := m.loadX509KeyPair(pair.CertFile, pair.KeyFile) - if err != nil { - continue - } - if certificate.Leaf == nil { // This is performance optimisation - certificate.Leaf, err = x509.ParseCertificate(certificate.Certificate[0]) - if err != nil { - continue - } - } - m.lock.Lock() - m.certificates[pair] = &certificate - m.lock.Unlock() - } - } - } - } -} - -// GetCertificate returns a TLS certificate based on the client hello. -// -// It tries to find a certificate that would be accepted by the client -// according to the client hello. However, if no certificate can be -// found GetCertificate returns the certificate loaded from the -// Public file. -func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) { - m.lock.RLock() - defer m.lock.RUnlock() - - // If the client does not send a SNI we return the "default" - // certificate. A client may not send a SNI - e.g. when trying - // to connect to an IP directly (https://:). - // - // In this case we don't know which the certificate the client - // asks for. It may be a public-facing certificate issued by a - // public CA or an internal certificate containing internal domain - // names. - // Now, we should not serve "the first" certificate that would be - // accepted by the client based on the Client Hello. Otherwise, we - // may expose an internal certificate to the client that contains - // internal domain names. That way we would disclose internal - // infrastructure details. - // - // Therefore, we serve the "default" certificate - which by convention - // is the first certificate added to the Manager. It's the calling code's - // responsibility to ensure that the "public-facing" certificate is used - // when creating a Manager instance. - if hello.ServerName == "" { - certificate := m.certificates[m.defaultCert] - return certificate, nil - } - - // Optimization: If there is just one certificate, always serve that one. - if len(m.certificates) == 1 { - for _, certificate := range m.certificates { - return certificate, nil - } - } - - // Iterate over all certificates and return the first one that would - // be accepted by the peer (TLS client) based on the client hello. - // In particular, the client usually specifies the requested host/domain - // via SNI. - // - // Note: The certificate.Leaf should be non-nil and contain the actual - // client certificate of MinIO that should be presented to the peer (TLS client). - // Otherwise, the leaf certificate has to be parsed again - which is kind of - // expensive and may cause a performance issue. For more information, check the - // docs of tls.ClientHelloInfo.SupportsCertificate. - for _, certificate := range m.certificates { - if err := hello.SupportsCertificate(certificate); err == nil { - return certificate, nil - } - } - return nil, errors.New("certs: no server certificate is supported by peer") -} - -// GetClientCertificate returns a TLS certificate for mTLS based on the -// certificate request. -// -// It tries to find a certificate that would be accepted by the server -// according to the certificate request. However, if no certificate can be -// found GetClientCertificate returns the certificate loaded from the -// Public file. -func (m *Manager) GetClientCertificate(reqInfo *tls.CertificateRequestInfo) (*tls.Certificate, error) { - m.lock.RLock() - defer m.lock.RUnlock() - - // Optimization: If there is just one certificate, always serve that one. - if len(m.certificates) == 1 { - for _, certificate := range m.certificates { - return certificate, nil - } - } - - // Iterate over all certificates and return the first one that would - // be accepted by the peer (TLS server) based on reqInfo. - // - // Note: The certificate.Leaf should be non-nil and contain the actual - // client certificate of MinIO that should be presented to the peer (TLS server). - // Otherwise, the leaf certificate has to be parsed again - which is kind of - // expensive and may cause a performance issue. For more information, check the - // docs of tls.CertificateRequestInfo.SupportsCertificate. - for _, certificate := range m.certificates { - if err := reqInfo.SupportsCertificate(certificate); err == nil { - return certificate, nil - } - } - return nil, errors.New("certs: no client certificate is supported by peer") -} - -// isSymlink returns true if the given file -// is a symbolic link. -func isSymlink(file string) (bool, error) { - st, err := os.Lstat(file) - if err != nil { - return false, err - } - return st.Mode()&os.ModeSymlink == os.ModeSymlink, nil -} diff --git a/pkg/certs/certs_test.go b/pkg/certs/certs_test.go deleted file mode 100644 index cc460066a..000000000 --- a/pkg/certs/certs_test.go +++ /dev/null @@ -1,110 +0,0 @@ -// 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 . - -package certs_test - -import ( - "context" - "crypto/tls" - "io" - "os" - "reflect" - "testing" - "time" - - "github.com/minio/minio/pkg/certs" -) - -func updateCerts(crt, key string) { - // ignore error handling - crtSource, _ := os.Open(crt) - defer crtSource.Close() - crtDest, _ := os.Create("public.crt") - defer crtDest.Close() - io.Copy(crtDest, crtSource) - - keySource, _ := os.Open(key) - defer keySource.Close() - keyDest, _ := os.Create("private.key") - defer keyDest.Close() - io.Copy(keyDest, keySource) -} - -func TestNewManager(t *testing.T) { - ctx, cancelFn := context.WithCancel(context.Background()) - defer cancelFn() - c, err := certs.NewManager(ctx, "public.crt", "private.key", tls.LoadX509KeyPair) - if err != nil { - t.Fatal(err) - } - hello := &tls.ClientHelloInfo{} - gcert, err := c.GetCertificate(hello) - if err != nil { - t.Fatal(err) - } - expectedCert, err := tls.LoadX509KeyPair("public.crt", "private.key") - if err != nil { - t.Fatal(err) - } - if !reflect.DeepEqual(gcert.Certificate, expectedCert.Certificate) { - t.Error("certificate doesn't match expected certificate") - } - _, err = certs.NewManager(ctx, "public.crt", "new-private.key", tls.LoadX509KeyPair) - if err == nil { - t.Fatal("Expected to fail but got success") - } -} - -func TestValidPairAfterWrite(t *testing.T) { - ctx, cancelFn := context.WithCancel(context.Background()) - defer cancelFn() - expectedCert, err := tls.LoadX509KeyPair("new-public.crt", "new-private.key") - if err != nil { - t.Fatal(err) - } - - c, err := certs.NewManager(ctx, "public.crt", "private.key", tls.LoadX509KeyPair) - if err != nil { - t.Fatal(err) - } - - updateCerts("new-public.crt", "new-private.key") - defer updateCerts("original-public.crt", "original-private.key") - - // Wait for the write event.. - time.Sleep(200 * time.Millisecond) - - hello := &tls.ClientHelloInfo{} - gcert, err := c.GetCertificate(hello) - if err != nil { - t.Fatal(err) - } - - if !reflect.DeepEqual(gcert.Certificate, expectedCert.Certificate) { - t.Error("certificate doesn't match expected certificate") - } - - rInfo := &tls.CertificateRequestInfo{} - gcert, err = c.GetClientCertificate(rInfo) - if err != nil { - t.Fatal(err) - } - - if !reflect.DeepEqual(gcert.Certificate, expectedCert.Certificate) { - t.Error("client certificate doesn't match expected certificate") - } -} diff --git a/pkg/certs/event.go b/pkg/certs/event.go deleted file mode 100644 index 7d69d0824..000000000 --- a/pkg/certs/event.go +++ /dev/null @@ -1,32 +0,0 @@ -// 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 . - -package certs - -import ( - "github.com/rjeczalik/notify" -) - -// isWriteEvent checks if the event returned is a write event -func isWriteEvent(event notify.Event) bool { - for _, ev := range eventWrite { - if event&ev != 0 { - return true - } - } - return false -} diff --git a/pkg/certs/event_linux.go b/pkg/certs/event_linux.go deleted file mode 100644 index 6134c99ae..000000000 --- a/pkg/certs/event_linux.go +++ /dev/null @@ -1,27 +0,0 @@ -// +build linux - -// 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 . - -package certs - -import "github.com/rjeczalik/notify" - -var ( - // eventWrite contains the notify events that will cause a write - eventWrite = []notify.Event{notify.InCloseWrite} -) diff --git a/pkg/certs/event_others.go b/pkg/certs/event_others.go deleted file mode 100644 index 12e57aae3..000000000 --- a/pkg/certs/event_others.go +++ /dev/null @@ -1,27 +0,0 @@ -// +build !linux - -// 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 . - -package certs - -import "github.com/rjeczalik/notify" - -var ( - // eventWrite contains the notify events that will cause a write - eventWrite = []notify.Event{notify.Create, notify.Write} -) diff --git a/pkg/certs/new-private.key b/pkg/certs/new-private.key deleted file mode 100644 index 89a196850..000000000 --- a/pkg/certs/new-private.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD4tnz56oMfKgK3 -scZAiFkr5lqAPFfMnrtrZXzyz+scHfOGLV3qFrqrmxyWOYI2qPbnR+NJakNDiGyx -+rI0OZj8hRqmGdP14wE9lfpFdlUVca2lRQW8aKTmF53aDuPkmHL6W7PlAef3NHoT -uuSpM+XdYlnZ97gsR+KPr9vNnYIxQWsrK3+6qfiVpOWbgM77COg5QYAeZoduSmSF -hNv+ptbNXSoyHRnLiBC4VhwFVsBNx0CNXhtE2Qd3QIsSR3cD1p7llp46uDYeQ9Vy -KfGDWWfmMF7YsGoMWoqRa53ObqN43D6gTiUorEN8cfwAPTw3yoVt+zVjFkCMvfAq -lxhXDanNAgMBAAECggEBAIGAI5rNbPCxIzEas6uuUx/0lXLn+J9mlxfYhDK56CV/ -wuk+fgQBSblIzp252/8yAz1xxPrZBaUIR/B0JI3k36+8bp/GGwOQ63hxuxqn/q1n -v46qXc44foQAEAUWc7r3Vgbd8NFxKKMjA916Fs2zZCDdsQM5ZQBJfcJrQvvQ45VY -//UtXdNeIBQOb5Wg4o9fHJolKzCHWRaD2ExoIHZ5Fa6JpBmk9JBHcUbrHrlbOeep -/SkbSa0ma9j3k3jqV970XRoQUCJf+K1Li49jmaYPPGXBUAp6AfU+yiAJ1aups38m -BClLAV9g6vgE3xK2xozGPI1+j9lkruYbvGbPNkXexdECgYEA/47XnKITSnxtV+NK -nDbWNOgpeaRbxAdjp1P0b4VI0S0SuRvKUOCp1UlPg5BjGL0JLPQpGlPzEfLlGWAa -68vhyj0V6HL2+PAJNib1eu6yyRBsSbPdrAD5nydHpbxRcdShhVwb2MHMyBeYH5Al -kL+ed5wCF32kXOOGzhoGzJEKNEcCgYEA+SSdcdbuVpQFkAecIoABwdx/qeOAeS19 -FsvVSTmWlhal8m2Mn8RWZ0IKXT9AoZJ0KQBIKHViPtyV7UQey05uRgLRHZapHpe8 -dhm6SsGYtU3BhLdHJBP0kI79qm2kzqsHp6ghSzaxT9CkRfMniN+TD+w8p7lrOaxv -vV46UHoGX0sCgYB4LlCvVHkF+mXhgv4/YHpz/woiLm0JTwBKXG0DVQbdd/jqHGuU -hVLY/tTp5ij0JVH/VgNOYlRZCIU83blLUmIonXmECyyh/SAX21JuMXram2KRdoi0 -rvC1K9/BzUHv6jLbaGmgEeOf5Zign0VLQRHg5fkF2wxEsqtemVbBNSQ7WQKBgBFk -Y/VRervig2zlixnBc93zpZnXft12tnfD7PS6p298z0LYMOvqSdnVe2G9C6b70U4X -bfIdF6mpvnGcwsWQiRQsGCsHnHC9SPO5og6b6ywk7HB2VuoG1pjM0pp2Iv4mZFdo -3kIg5EndF8qmSck9SkffRvCyefDBv98pV8rMaet3AoGBALjlN2hLoNE5Cs5vTYH8 -W0AN4lEOaTlBRKG8a1h7Fm2vPgzGGkiwU6bVzsh0oTfytc8v8MW9lNQZpE3dBKne -ms3FrNsnBbTczX+xJmndRnVRocdyON6u476VxAuz/dHSFFnZGXX+2lJse9xnWHUz -OpSHUPq3TrUzhgZClE2ZKpNm ------END PRIVATE KEY----- diff --git a/pkg/certs/new-public.crt b/pkg/certs/new-public.crt deleted file mode 100644 index aa988c0c5..000000000 --- a/pkg/certs/new-public.crt +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDYDCCAkigAwIBAgIJALIHkFXjtZ2yMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQwHhcNMTgwNTIwMDg1MzI3WhcNMTkwNTIwMDg1MzI3WjBF -MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 -ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEA+LZ8+eqDHyoCt7HGQIhZK+ZagDxXzJ67a2V88s/rHB3zhi1d6ha6q5sc -ljmCNqj250fjSWpDQ4hssfqyNDmY/IUaphnT9eMBPZX6RXZVFXGtpUUFvGik5hed -2g7j5Jhy+luz5QHn9zR6E7rkqTPl3WJZ2fe4LEfij6/bzZ2CMUFrKyt/uqn4laTl -m4DO+wjoOUGAHmaHbkpkhYTb/qbWzV0qMh0Zy4gQuFYcBVbATcdAjV4bRNkHd0CL -Ekd3A9ae5ZaeOrg2HkPVcinxg1ln5jBe2LBqDFqKkWudzm6jeNw+oE4lKKxDfHH8 -AD08N8qFbfs1YxZAjL3wKpcYVw2pzQIDAQABo1MwUTAdBgNVHQ4EFgQU2Yywgv8p -WfyZxYVx+MnH+VQ5TTUwHwYDVR0jBBgwFoAU2Yywgv8pWfyZxYVx+MnH+VQ5TTUw -DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA2maF7DQ7CMpCho9B -9gjGxvt8HqY1pCyuQwcSPb4PTyoKUZ/ZuIDhVOaBX+ox1RzlfGtYs2BUM63/QUDs -dP0GO7/IL/XEqJi1flrFvM7LNSs89qAbPJ440m6jJDzsuL2VeyUX/M72IEsBK2uS -ajtS1+HFQjPMvt7wR6fDPCP7wHPOrkTN4hcHlgzVJShKUnFaHtb2lOnWaoM/Sk91 -IsiyAhKRuCM9et7/bnOj7G8448QDVtQNniT8V/HpqQ7ltSuIGvs3QYTLDTege/74 -Q8Ph1oH7shyRE/PqPfyIuLq3p0N9Sah3oRMHLohYjJL0zAGt0jxSsnhrBSNUUD/v -bAd5VQ== ------END CERTIFICATE----- diff --git a/pkg/certs/original-private.key b/pkg/certs/original-private.key deleted file mode 100644 index 25c46cefd..000000000 --- a/pkg/certs/original-private.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDPszxaYwn+mIz6 -IGuUlmvWwUs/yWTH4MC17qey2N5MqcxlfIWHUugcBsbGhi/e1druFW0s7YGMxp+G -+Q1IezxX+VmVaJCN8AgSowbYgpRdpRQ+mhGeQby0JcvO16fyPnUJBz3GGel2bcK8 -fcQyT0TVapCiD9oURVmdvDSsRXz+EoPlOve8AWciHHgm1ItO5qdPRP5YtcJfLiwK -noYnpda2d9SzmYk+Q2JFArooF7/A1DYz9bXCMo3qp0gQlMpSMDR+MCbxHBzBBr+f -QG8QdDrzWQ2slhniBhFDk0LuPCBLlSeIzkp+DoAGDXf3hWYhechlabZ7nfngg5er -Ez776WCFAgMBAAECggEBAJcHRyCWmcLm3MRY5MF0K9BKV9R3NnBdTuQ8OPdE2Ui3 -w6gcRuBi+eK/TrU3CAIqUXsEW5Hq1mQuXfwAh5cn/XYfG/QXx91eKBCdOTIgqY/6 -pODsmVkRhg0c2rl6eWYd4m6BNHsjhm8WWx9C+HJ4z528UpV1n2dUElkvbMHD+aKp -Ndwd0W+0PCn/BjMn/sdyy01f8sfaK2Zoy7HBw/fGeBDNLFFj3Iz7BqXYeS+OyfLN -B4xD5I5fFqt1iJeyqVPzGkOAYSqisijbM1GtZJCeVp37/+IDylCKTO3l8Xd8x73U -qTYcYT3heSHyUC2xCM6Va2YkSrOHeqbq91QgHh9LVrUCgYEA9t/wE2S8TE2l1IG9 -68SXdhyaXTnB2qSL7ggY0uazPzBNLQpNMOxicZ6/4QGEi3hSuCqGxxGo9UEoTsVd -pk8oIeDULdPVi4NQxSmkxUyArs/dzOMygUPyosOiEc8z6jWFFKDcQ7mnZnay8dZ4 -e4j+/hZDONtDrJ+zH2xu98ZrJPcCgYEA12CbSRbCkTiRj/dq8Qvgp6+ceTVcAbnk -MWpAhZQaXHrG3XP0L7QTIHG/7a09Mln92zjuAFXDp/Vc5NdxeXcnj9j6oUAxq+0I -dq+vibzjROemmvnmQvXGY9tc0ns6u7GjM0+Sicmas+IH4vuum/aRasABfVe2XBwe -4fVs0n7yU2MCgYA7KevFGg0uVCV7yiQTzqdlvPEZim/00B5gyzv3vyYR7KdyNdfN -87ib9imR6OU0738Td82ZA5h0PktEpXQOGUZK6DCxUuUIbE39Ej/UsMLeIh7LrV87 -L2eErlG25utQI8di7DIdYO7HVYcJAhcZs/k4N2mgxJtxUUyCKWBmrPycfQKBgAo7 -0uUUKcaQs4ntra0qbVBKbdrsiCSk2ozmiY5PTTlbtBtNqSqjGc2O2hnHA4Ni90b1 -W4m0iYlvhSxyeDfXS4/wNWh4DmQm7SIGkwaubPYXM7llamWAHB8eiziNFmtYs3J6 -s3HMnIczlEBayR8sBhjWaruz8TxLMcR2zubplUYVAoGBAItxeC9IT8BGJoZB++qM -f2LXCqJ383x0sDHhwPMFPtwUTzAwc5BJgQe9zFktW5CBxsER+MnUZjlrarT1HQfH -1Y1mJQXtwuBKG4pPPZphH0yoVlYcWkBTMw/KmlVlwRclEzRQwV3TPD+i6ieKeZhz -9eZwhS3H+Zb/693WbBDyH8L+ ------END PRIVATE KEY----- diff --git a/pkg/certs/original-public.crt b/pkg/certs/original-public.crt deleted file mode 100644 index f0d8d2d91..000000000 --- a/pkg/certs/original-public.crt +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDqjCCApKgAwIBAgIJAOcv4FsrflS4MA0GCSqGSIb3DQEBCwUAMGoxCzAJBgNV -BAYTAlVTMQswCQYDVQQIDAJDQTEVMBMGA1UEBwwMUmVkd29vZCBDaXR5MQ4wDAYD -VQQKDAVNaW5pbzEUMBIGA1UECwwLRW5naW5lZXJpbmcxETAPBgNVBAMMCG1pbmlv -LmlvMB4XDTE4MDUyMDA4NDc0MFoXDTE5MDUyMDA4NDc0MFowajELMAkGA1UEBhMC -VVMxCzAJBgNVBAgMAkNBMRUwEwYDVQQHDAxSZWR3b29kIENpdHkxDjAMBgNVBAoM -BU1pbmlvMRQwEgYDVQQLDAtFbmdpbmVlcmluZzERMA8GA1UEAwwIbWluaW8uaW8w -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPszxaYwn+mIz6IGuUlmvW -wUs/yWTH4MC17qey2N5MqcxlfIWHUugcBsbGhi/e1druFW0s7YGMxp+G+Q1IezxX -+VmVaJCN8AgSowbYgpRdpRQ+mhGeQby0JcvO16fyPnUJBz3GGel2bcK8fcQyT0TV -apCiD9oURVmdvDSsRXz+EoPlOve8AWciHHgm1ItO5qdPRP5YtcJfLiwKnoYnpda2 -d9SzmYk+Q2JFArooF7/A1DYz9bXCMo3qp0gQlMpSMDR+MCbxHBzBBr+fQG8QdDrz -WQ2slhniBhFDk0LuPCBLlSeIzkp+DoAGDXf3hWYhechlabZ7nfngg5erEz776WCF -AgMBAAGjUzBRMB0GA1UdDgQWBBRzC09a+3AlbFDg6BsvELolmO8jYjAfBgNVHSME -GDAWgBRzC09a+3AlbFDg6BsvELolmO8jYjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG -SIb3DQEBCwUAA4IBAQBl0cx7qbidKjhoZ1Iv4pCD8xHZgtuWEDApPoGuMtVS66jJ -+oj0ncD5xCtv9XqXtshE65FIsEWnDOIwa+kyjMnxHbFwxveWBT4W0twtqwbVs7NE -I0So6cEmSx4+rB0XorY6mIbD3O9YAStelNhB1jVfQfIMSByYkcGq2Fh+B1LHlOrz -06LJdwYMiILzK0c5fvjZvsDq/9EK+Xo66hphKjs5cl1t9WK7wKOCoZDt2lOTZqEq -UWYGPWlTAxSWQxO4WnvSKqFdsRi8fOO3KlDq1eNqeDSGGCI0DTGgJxidHIpfOPEF -s/zojgc5npE32/1n8og6gLcv7LIKelBfMhUrFTp7 ------END CERTIFICATE----- diff --git a/pkg/certs/private.key b/pkg/certs/private.key deleted file mode 100644 index 25c46cefd..000000000 --- a/pkg/certs/private.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDPszxaYwn+mIz6 -IGuUlmvWwUs/yWTH4MC17qey2N5MqcxlfIWHUugcBsbGhi/e1druFW0s7YGMxp+G -+Q1IezxX+VmVaJCN8AgSowbYgpRdpRQ+mhGeQby0JcvO16fyPnUJBz3GGel2bcK8 -fcQyT0TVapCiD9oURVmdvDSsRXz+EoPlOve8AWciHHgm1ItO5qdPRP5YtcJfLiwK -noYnpda2d9SzmYk+Q2JFArooF7/A1DYz9bXCMo3qp0gQlMpSMDR+MCbxHBzBBr+f -QG8QdDrzWQ2slhniBhFDk0LuPCBLlSeIzkp+DoAGDXf3hWYhechlabZ7nfngg5er -Ez776WCFAgMBAAECggEBAJcHRyCWmcLm3MRY5MF0K9BKV9R3NnBdTuQ8OPdE2Ui3 -w6gcRuBi+eK/TrU3CAIqUXsEW5Hq1mQuXfwAh5cn/XYfG/QXx91eKBCdOTIgqY/6 -pODsmVkRhg0c2rl6eWYd4m6BNHsjhm8WWx9C+HJ4z528UpV1n2dUElkvbMHD+aKp -Ndwd0W+0PCn/BjMn/sdyy01f8sfaK2Zoy7HBw/fGeBDNLFFj3Iz7BqXYeS+OyfLN -B4xD5I5fFqt1iJeyqVPzGkOAYSqisijbM1GtZJCeVp37/+IDylCKTO3l8Xd8x73U -qTYcYT3heSHyUC2xCM6Va2YkSrOHeqbq91QgHh9LVrUCgYEA9t/wE2S8TE2l1IG9 -68SXdhyaXTnB2qSL7ggY0uazPzBNLQpNMOxicZ6/4QGEi3hSuCqGxxGo9UEoTsVd -pk8oIeDULdPVi4NQxSmkxUyArs/dzOMygUPyosOiEc8z6jWFFKDcQ7mnZnay8dZ4 -e4j+/hZDONtDrJ+zH2xu98ZrJPcCgYEA12CbSRbCkTiRj/dq8Qvgp6+ceTVcAbnk -MWpAhZQaXHrG3XP0L7QTIHG/7a09Mln92zjuAFXDp/Vc5NdxeXcnj9j6oUAxq+0I -dq+vibzjROemmvnmQvXGY9tc0ns6u7GjM0+Sicmas+IH4vuum/aRasABfVe2XBwe -4fVs0n7yU2MCgYA7KevFGg0uVCV7yiQTzqdlvPEZim/00B5gyzv3vyYR7KdyNdfN -87ib9imR6OU0738Td82ZA5h0PktEpXQOGUZK6DCxUuUIbE39Ej/UsMLeIh7LrV87 -L2eErlG25utQI8di7DIdYO7HVYcJAhcZs/k4N2mgxJtxUUyCKWBmrPycfQKBgAo7 -0uUUKcaQs4ntra0qbVBKbdrsiCSk2ozmiY5PTTlbtBtNqSqjGc2O2hnHA4Ni90b1 -W4m0iYlvhSxyeDfXS4/wNWh4DmQm7SIGkwaubPYXM7llamWAHB8eiziNFmtYs3J6 -s3HMnIczlEBayR8sBhjWaruz8TxLMcR2zubplUYVAoGBAItxeC9IT8BGJoZB++qM -f2LXCqJ383x0sDHhwPMFPtwUTzAwc5BJgQe9zFktW5CBxsER+MnUZjlrarT1HQfH -1Y1mJQXtwuBKG4pPPZphH0yoVlYcWkBTMw/KmlVlwRclEzRQwV3TPD+i6ieKeZhz -9eZwhS3H+Zb/693WbBDyH8L+ ------END PRIVATE KEY----- diff --git a/pkg/certs/public.crt b/pkg/certs/public.crt deleted file mode 100644 index f0d8d2d91..000000000 --- a/pkg/certs/public.crt +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDqjCCApKgAwIBAgIJAOcv4FsrflS4MA0GCSqGSIb3DQEBCwUAMGoxCzAJBgNV -BAYTAlVTMQswCQYDVQQIDAJDQTEVMBMGA1UEBwwMUmVkd29vZCBDaXR5MQ4wDAYD -VQQKDAVNaW5pbzEUMBIGA1UECwwLRW5naW5lZXJpbmcxETAPBgNVBAMMCG1pbmlv -LmlvMB4XDTE4MDUyMDA4NDc0MFoXDTE5MDUyMDA4NDc0MFowajELMAkGA1UEBhMC -VVMxCzAJBgNVBAgMAkNBMRUwEwYDVQQHDAxSZWR3b29kIENpdHkxDjAMBgNVBAoM -BU1pbmlvMRQwEgYDVQQLDAtFbmdpbmVlcmluZzERMA8GA1UEAwwIbWluaW8uaW8w -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPszxaYwn+mIz6IGuUlmvW -wUs/yWTH4MC17qey2N5MqcxlfIWHUugcBsbGhi/e1druFW0s7YGMxp+G+Q1IezxX -+VmVaJCN8AgSowbYgpRdpRQ+mhGeQby0JcvO16fyPnUJBz3GGel2bcK8fcQyT0TV -apCiD9oURVmdvDSsRXz+EoPlOve8AWciHHgm1ItO5qdPRP5YtcJfLiwKnoYnpda2 -d9SzmYk+Q2JFArooF7/A1DYz9bXCMo3qp0gQlMpSMDR+MCbxHBzBBr+fQG8QdDrz -WQ2slhniBhFDk0LuPCBLlSeIzkp+DoAGDXf3hWYhechlabZ7nfngg5erEz776WCF -AgMBAAGjUzBRMB0GA1UdDgQWBBRzC09a+3AlbFDg6BsvELolmO8jYjAfBgNVHSME -GDAWgBRzC09a+3AlbFDg6BsvELolmO8jYjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG -SIb3DQEBCwUAA4IBAQBl0cx7qbidKjhoZ1Iv4pCD8xHZgtuWEDApPoGuMtVS66jJ -+oj0ncD5xCtv9XqXtshE65FIsEWnDOIwa+kyjMnxHbFwxveWBT4W0twtqwbVs7NE -I0So6cEmSx4+rB0XorY6mIbD3O9YAStelNhB1jVfQfIMSByYkcGq2Fh+B1LHlOrz -06LJdwYMiILzK0c5fvjZvsDq/9EK+Xo66hphKjs5cl1t9WK7wKOCoZDt2lOTZqEq -UWYGPWlTAxSWQxO4WnvSKqFdsRi8fOO3KlDq1eNqeDSGGCI0DTGgJxidHIpfOPEF -s/zojgc5npE32/1n8og6gLcv7LIKelBfMhUrFTp7 ------END CERTIFICATE----- diff --git a/pkg/certs/server.crt b/pkg/certs/server.crt deleted file mode 100644 index f0d8d2d91..000000000 --- a/pkg/certs/server.crt +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDqjCCApKgAwIBAgIJAOcv4FsrflS4MA0GCSqGSIb3DQEBCwUAMGoxCzAJBgNV -BAYTAlVTMQswCQYDVQQIDAJDQTEVMBMGA1UEBwwMUmVkd29vZCBDaXR5MQ4wDAYD -VQQKDAVNaW5pbzEUMBIGA1UECwwLRW5naW5lZXJpbmcxETAPBgNVBAMMCG1pbmlv -LmlvMB4XDTE4MDUyMDA4NDc0MFoXDTE5MDUyMDA4NDc0MFowajELMAkGA1UEBhMC -VVMxCzAJBgNVBAgMAkNBMRUwEwYDVQQHDAxSZWR3b29kIENpdHkxDjAMBgNVBAoM -BU1pbmlvMRQwEgYDVQQLDAtFbmdpbmVlcmluZzERMA8GA1UEAwwIbWluaW8uaW8w -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPszxaYwn+mIz6IGuUlmvW -wUs/yWTH4MC17qey2N5MqcxlfIWHUugcBsbGhi/e1druFW0s7YGMxp+G+Q1IezxX -+VmVaJCN8AgSowbYgpRdpRQ+mhGeQby0JcvO16fyPnUJBz3GGel2bcK8fcQyT0TV -apCiD9oURVmdvDSsRXz+EoPlOve8AWciHHgm1ItO5qdPRP5YtcJfLiwKnoYnpda2 -d9SzmYk+Q2JFArooF7/A1DYz9bXCMo3qp0gQlMpSMDR+MCbxHBzBBr+fQG8QdDrz -WQ2slhniBhFDk0LuPCBLlSeIzkp+DoAGDXf3hWYhechlabZ7nfngg5erEz776WCF -AgMBAAGjUzBRMB0GA1UdDgQWBBRzC09a+3AlbFDg6BsvELolmO8jYjAfBgNVHSME -GDAWgBRzC09a+3AlbFDg6BsvELolmO8jYjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG -SIb3DQEBCwUAA4IBAQBl0cx7qbidKjhoZ1Iv4pCD8xHZgtuWEDApPoGuMtVS66jJ -+oj0ncD5xCtv9XqXtshE65FIsEWnDOIwa+kyjMnxHbFwxveWBT4W0twtqwbVs7NE -I0So6cEmSx4+rB0XorY6mIbD3O9YAStelNhB1jVfQfIMSByYkcGq2Fh+B1LHlOrz -06LJdwYMiILzK0c5fvjZvsDq/9EK+Xo66hphKjs5cl1t9WK7wKOCoZDt2lOTZqEq -UWYGPWlTAxSWQxO4WnvSKqFdsRi8fOO3KlDq1eNqeDSGGCI0DTGgJxidHIpfOPEF -s/zojgc5npE32/1n8og6gLcv7LIKelBfMhUrFTp7 ------END CERTIFICATE----- diff --git a/pkg/certs/server.key b/pkg/certs/server.key deleted file mode 100644 index 25c46cefd..000000000 --- a/pkg/certs/server.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDPszxaYwn+mIz6 -IGuUlmvWwUs/yWTH4MC17qey2N5MqcxlfIWHUugcBsbGhi/e1druFW0s7YGMxp+G -+Q1IezxX+VmVaJCN8AgSowbYgpRdpRQ+mhGeQby0JcvO16fyPnUJBz3GGel2bcK8 -fcQyT0TVapCiD9oURVmdvDSsRXz+EoPlOve8AWciHHgm1ItO5qdPRP5YtcJfLiwK -noYnpda2d9SzmYk+Q2JFArooF7/A1DYz9bXCMo3qp0gQlMpSMDR+MCbxHBzBBr+f -QG8QdDrzWQ2slhniBhFDk0LuPCBLlSeIzkp+DoAGDXf3hWYhechlabZ7nfngg5er -Ez776WCFAgMBAAECggEBAJcHRyCWmcLm3MRY5MF0K9BKV9R3NnBdTuQ8OPdE2Ui3 -w6gcRuBi+eK/TrU3CAIqUXsEW5Hq1mQuXfwAh5cn/XYfG/QXx91eKBCdOTIgqY/6 -pODsmVkRhg0c2rl6eWYd4m6BNHsjhm8WWx9C+HJ4z528UpV1n2dUElkvbMHD+aKp -Ndwd0W+0PCn/BjMn/sdyy01f8sfaK2Zoy7HBw/fGeBDNLFFj3Iz7BqXYeS+OyfLN -B4xD5I5fFqt1iJeyqVPzGkOAYSqisijbM1GtZJCeVp37/+IDylCKTO3l8Xd8x73U -qTYcYT3heSHyUC2xCM6Va2YkSrOHeqbq91QgHh9LVrUCgYEA9t/wE2S8TE2l1IG9 -68SXdhyaXTnB2qSL7ggY0uazPzBNLQpNMOxicZ6/4QGEi3hSuCqGxxGo9UEoTsVd -pk8oIeDULdPVi4NQxSmkxUyArs/dzOMygUPyosOiEc8z6jWFFKDcQ7mnZnay8dZ4 -e4j+/hZDONtDrJ+zH2xu98ZrJPcCgYEA12CbSRbCkTiRj/dq8Qvgp6+ceTVcAbnk -MWpAhZQaXHrG3XP0L7QTIHG/7a09Mln92zjuAFXDp/Vc5NdxeXcnj9j6oUAxq+0I -dq+vibzjROemmvnmQvXGY9tc0ns6u7GjM0+Sicmas+IH4vuum/aRasABfVe2XBwe -4fVs0n7yU2MCgYA7KevFGg0uVCV7yiQTzqdlvPEZim/00B5gyzv3vyYR7KdyNdfN -87ib9imR6OU0738Td82ZA5h0PktEpXQOGUZK6DCxUuUIbE39Ej/UsMLeIh7LrV87 -L2eErlG25utQI8di7DIdYO7HVYcJAhcZs/k4N2mgxJtxUUyCKWBmrPycfQKBgAo7 -0uUUKcaQs4ntra0qbVBKbdrsiCSk2ozmiY5PTTlbtBtNqSqjGc2O2hnHA4Ni90b1 -W4m0iYlvhSxyeDfXS4/wNWh4DmQm7SIGkwaubPYXM7llamWAHB8eiziNFmtYs3J6 -s3HMnIczlEBayR8sBhjWaruz8TxLMcR2zubplUYVAoGBAItxeC9IT8BGJoZB++qM -f2LXCqJ383x0sDHhwPMFPtwUTzAwc5BJgQe9zFktW5CBxsER+MnUZjlrarT1HQfH -1Y1mJQXtwuBKG4pPPZphH0yoVlYcWkBTMw/KmlVlwRclEzRQwV3TPD+i6ieKeZhz -9eZwhS3H+Zb/693WbBDyH8L+ ------END PRIVATE KEY----- diff --git a/pkg/cgroup/linux.go b/pkg/cgroup/linux.go deleted file mode 100644 index a6da2d01b..000000000 --- a/pkg/cgroup/linux.go +++ /dev/null @@ -1,178 +0,0 @@ -// +build linux - -// 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 . - -// Package cgroup implements parsing for all the cgroup -// categories and functionality in a simple way. -package cgroup - -import ( - "bufio" - "bytes" - "fmt" - "io" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "strconv" - "strings" -) - -// DO NOT EDIT following constants are chosen defaults for any kernel -// after 3.x, please open a GitHub issue https://github.com/minio/minio/issues -// and discuss first if you wish to change this. -const ( - // Default string for looking for kernel memory param. - memoryLimitKernelParam = "memory.limit_in_bytes" - - // Points to sys path memory path. - cgroupMemSysPath = "/sys/fs/cgroup/memory" - - // Default docker prefix. - dockerPrefixName = "/docker/" - - // Proc controller group path. - cgroupFileTemplate = "/proc/%d/cgroup" -) - -// CGEntries - represents all the entries in a process cgroup file -// at /proc//cgroup as key value pairs. -type CGEntries map[string]string - -// GetEntries reads and parses all the cgroup entries for a given process. -func GetEntries(pid int) (CGEntries, error) { - r, err := os.Open(fmt.Sprintf(cgroupFileTemplate, pid)) - if err != nil { - return nil, err - } - defer r.Close() - return parseProcCGroup(r) -} - -// parseProcCGroup - cgroups are always in the following -// format once enabled you need to know the pid of the -// application you are looking for so that the the -// following parsing logic only parses the file located -// at /proc//cgroup. -// -// CGROUP entries id, component and path are always in -// the following format. ``ID:COMPONENT:PATH`` -// -// Following code block parses this information and -// returns a procCGroup which is a parsed list of all -// the line by line entires from /proc//cgroup. -func parseProcCGroup(r io.Reader) (CGEntries, error) { - var cgEntries = CGEntries{} - - // Start reading cgroup categories line by line - // and process them into procCGroup structure. - scanner := bufio.NewScanner(r) - for scanner.Scan() { - line := scanner.Text() - - tokens := strings.SplitN(line, ":", 3) - if len(tokens) < 3 { - continue - } - - name, path := tokens[1], tokens[2] - for _, token := range strings.Split(name, ",") { - name = strings.TrimPrefix(token, "name=") - cgEntries[name] = path - } - } - - // Return upon any error while reading the cgroup categories. - if err := scanner.Err(); err != nil { - return nil, err - } - - return cgEntries, nil -} - -// Fetch value of the cgroup kernel param from the cgroup manager, -// if cgroup manager is configured we should just rely on `cgm` cli -// to fetch all the values for us. -func getManagerKernValue(cname, path, kernParam string) (limit uint64, err error) { - - cmd := exec.Command("cgm", "getvalue", cname, path, kernParam) - var out bytes.Buffer - cmd.Stdout = &out - if err = cmd.Run(); err != nil { - return 0, err - } - - // Parse the cgm output. - limit, err = strconv.ParseUint(strings.TrimSpace(out.String()), 10, 64) - return limit, err -} - -// Get cgroup memory limit file path. -func getMemoryLimitFilePath(cgPath string) string { - path := cgroupMemSysPath - - // Docker generates weird cgroup paths that don't - // really exist on the file system. - // - // For example on regular Linux OS : - // `/user.slice/user-1000.slice/session-1.scope` - // - // But they exist as a bind mount on Docker and - // are not accessible : `/docker/` - // - // We we will just ignore if there is `/docker` in the - // path ignore and fall back to : - // `/sys/fs/cgroup/memory/memory.limit_in_bytes` - if !strings.HasPrefix(cgPath, dockerPrefixName) { - path = filepath.Join(path, cgPath) - } - - // Final path. - return filepath.Join(path, memoryLimitKernelParam) -} - -// GetMemoryLimit - Fetches cgroup memory limit either from -// a file path at '/sys/fs/cgroup/memory', if path fails then -// fallback to querying cgroup manager. -func GetMemoryLimit(pid int) (limit uint64, err error) { - var cg CGEntries - cg, err = GetEntries(pid) - if err != nil { - return 0, err - } - - path := cg["memory"] - - limit, err = getManagerKernValue("memory", path, memoryLimitKernelParam) - if err != nil { - - // Upon any failure returned from `cgm`, on some systems cgm - // might not be installed. We fallback to using the the sysfs - // path instead to lookup memory limits. - var b []byte - b, err = ioutil.ReadFile(getMemoryLimitFilePath(path)) - if err != nil { - return 0, err - } - - limit, err = strconv.ParseUint(strings.TrimSpace(string(b)), 10, 64) - } - - return limit, err -} diff --git a/pkg/cgroup/linux_test.go b/pkg/cgroup/linux_test.go deleted file mode 100644 index 5b9dc4c53..000000000 --- a/pkg/cgroup/linux_test.go +++ /dev/null @@ -1,141 +0,0 @@ -// +build linux - -// 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 . - -package cgroup - -import ( - "io/ioutil" - "os" - "testing" -) - -// Testing parsing correctness for various process cgroup files. -func TestProcCGroup(t *testing.T) { - tmpPath, err := ioutil.TempFile("", "cgroup") - if err != nil { - t.Fatal(err) - } - defer os.Remove(tmpPath.Name()) - - cgroup := ` -11:memory:/user.slice -10:blkio:/user.slice -9:hugetlb:/ -8:net_cls,net_prio:/ -7:perf_event:/ -6:pids:/user.slice/user-1000.slice -5:devices:/user.slice -4:cpuset:/ -3:cpu,cpuacct:/user.slice -2:freezer:/ -1:name=systemd:/user.slice/user-1000.slice/session-1.scope -` - _, err = tmpPath.WriteString(cgroup) - if err != nil { - t.Fatal(err) - } - - // Seek back to read from the beginning. - tmpPath.Seek(0, 0) - - cg, err := parseProcCGroup(tmpPath) - if err != nil { - t.Fatal(err) - } - - path := cg["memory"] - if len(path) == 0 { - t.Fatal("Path component cannot be empty") - } - - if path != "/user.slice" { - t.Fatal("Path component cannot be empty") - } - - path = cg["systemd"] - if path != "/user.slice/user-1000.slice/session-1.scope" { - t.Fatal("Path component cannot be empty") - } - - // Mixed cgroups with different group names. - cgroup = ` -11:memory:/newtest/newtest -10:blkio:/user.slice -9:hugetlb:/ -8:net_cls,net_prio:/ -7:perf_event:/ -6:pids:/user.slice/user-1000.slice -5:devices:/user.slice -4:cpuset:/ -3:cpu,cpuacct:/newtest/newtest -2:freezer:/ -1:name=systemd:/user.slice/user-1000.slice/session-1.scope -` - - // Seek back to read from the beginning. - tmpPath.Seek(0, 0) - - _, err = tmpPath.WriteString(cgroup) - if err != nil { - t.Fatal(err) - } - - // Seek back to read from the beginning. - tmpPath.Seek(0, 0) - - cg, err = parseProcCGroup(tmpPath) - if err != nil { - t.Fatal(err) - } - - path = cg["memory"] - if path != "/newtest/newtest" { - t.Fatal("Path component cannot be empty") - } - - path = cg["systemd"] - if path != "/user.slice/user-1000.slice/session-1.scope" { - t.Fatal("Path component cannot be empty") - } - -} - -// Tests cgroup memory limit path construction. -func TestMemoryLimitPath(t *testing.T) { - testCases := []struct { - cgroupPath string - expectedPath string - }{ - { - cgroupPath: "/user.slice", - expectedPath: "/sys/fs/cgroup/memory/user.slice/memory.limit_in_bytes", - }, - { - cgroupPath: "/docker/testing", - expectedPath: "/sys/fs/cgroup/memory/memory.limit_in_bytes", - }, - } - - for i, testCase := range testCases { - actualPath := getMemoryLimitFilePath(testCase.cgroupPath) - if actualPath != testCase.expectedPath { - t.Fatalf("Test: %d: Expected: %s, got %s", i+1, testCase.expectedPath, actualPath) - } - } -} diff --git a/pkg/cgroup/others.go b/pkg/cgroup/others.go deleted file mode 100644 index 968eb5f8c..000000000 --- a/pkg/cgroup/others.go +++ /dev/null @@ -1,20 +0,0 @@ -// +build !linux - -// 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 . - -package cgroup diff --git a/pkg/console/console.go b/pkg/console/console.go deleted file mode 100644 index f3be31abe..000000000 --- a/pkg/console/console.go +++ /dev/null @@ -1,436 +0,0 @@ -// 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 . - -// Package console implements console printing helpers -package console - -import ( - "fmt" - "os" - "path/filepath" - "strings" - "sync" - - "github.com/fatih/color" - "github.com/mattn/go-colorable" - "github.com/mattn/go-isatty" -) - -var ( - // Used by the caller to print multiple lines atomically. Exposed by Lock/Unlock methods. - publicMutex sync.Mutex - - // Used internally by console. - privateMutex sync.Mutex - - stderrColoredOutput = colorable.NewColorableStderr() - - // Print prints a message. - Print = func(data ...interface{}) { - consolePrint("Print", Theme["Print"], data...) - } - - // PrintC prints a message with color. - PrintC = func(data ...interface{}) { - consolePrint("PrintC", Theme["PrintC"], data...) - } - - // Printf prints a formatted message. - Printf = func(format string, data ...interface{}) { - consolePrintf("Print", Theme["Print"], format, data...) - } - - // Println prints a message with a newline. - Println = func(data ...interface{}) { - consolePrintln("Print", Theme["Print"], data...) - } - - // Fatal print a error message and exit. - Fatal = func(data ...interface{}) { - consolePrint("Fatal", Theme["Fatal"], data...) - os.Exit(1) - } - - // Fatalf print a error message with a format specified and exit. - Fatalf = func(format string, data ...interface{}) { - consolePrintf("Fatal", Theme["Fatal"], format, data...) - os.Exit(1) - } - - // Fatalln print a error message with a new line and exit. - Fatalln = func(data ...interface{}) { - consolePrintln("Fatal", Theme["Fatal"], data...) - os.Exit(1) - } - - // Error prints a error message. - Error = func(data ...interface{}) { - consolePrint("Error", Theme["Error"], data...) - } - - // Errorf print a error message with a format specified. - Errorf = func(format string, data ...interface{}) { - consolePrintf("Error", Theme["Error"], format, data...) - } - - // Errorln prints a error message with a new line. - Errorln = func(data ...interface{}) { - consolePrintln("Error", Theme["Error"], data...) - } - - // Info prints a informational message. - Info = func(data ...interface{}) { - consolePrint("Info", Theme["Info"], data...) - } - - // Infof prints a informational message in custom format. - Infof = func(format string, data ...interface{}) { - consolePrintf("Info", Theme["Info"], format, data...) - } - - // Infoln prints a informational message with a new line. - Infoln = func(data ...interface{}) { - consolePrintln("Info", Theme["Info"], data...) - } - - // Debug prints a debug message without a new line - // Debug prints a debug message. - Debug = func(data ...interface{}) { - consolePrint("Debug", Theme["Debug"], data...) - } - - // Debugf prints a debug message with a new line. - Debugf = func(format string, data ...interface{}) { - consolePrintf("Debug", Theme["Debug"], format, data...) - } - - // Debugln prints a debug message with a new line. - Debugln = func(data ...interface{}) { - consolePrintln("Debug", Theme["Debug"], data...) - } - - // Colorize prints message in a colorized form, dictated by the corresponding tag argument. - Colorize = func(tag string, data interface{}) string { - if isatty.IsTerminal(os.Stdout.Fd()) { - colorized, ok := Theme[tag] - if ok { - return colorized.SprintFunc()(data) - } // else: No theme found. Return as string. - } - return fmt.Sprint(data) - } - - // Eraseline Print in new line and adjust to top so that we don't print over the ongoing progress bar. - Eraseline = func() { - consolePrintf("Print", Theme["Print"], "%c[2K\n", 27) - consolePrintf("Print", Theme["Print"], "%c[A", 27) - } -) - -// wrap around standard fmt functions. -// consolePrint prints a message prefixed with message type and program name. -func consolePrint(tag string, c *color.Color, a ...interface{}) { - privateMutex.Lock() - defer privateMutex.Unlock() - - switch tag { - case "Debug": - // if no arguments are given do not invoke debug printer. - if len(a) == 0 { - return - } - output := color.Output - color.Output = stderrColoredOutput - if isatty.IsTerminal(os.Stderr.Fd()) { - c.Print(ProgramName() + ": ") - c.Print(a...) - } else { - fmt.Fprint(color.Output, ProgramName()+": ") - fmt.Fprint(color.Output, a...) - } - color.Output = output - case "Fatal": - fallthrough - case "Error": - // if no arguments are given do not invoke fatal and error printer. - if len(a) == 0 { - return - } - output := color.Output - color.Output = stderrColoredOutput - if isatty.IsTerminal(os.Stderr.Fd()) { - c.Print(ProgramName() + ": ") - c.Print(a...) - } else { - fmt.Fprint(color.Output, ProgramName()+": ") - fmt.Fprint(color.Output, a...) - } - color.Output = output - case "Info": - // if no arguments are given do not invoke info printer. - if len(a) == 0 { - return - } - if isatty.IsTerminal(os.Stdout.Fd()) { - c.Print(ProgramName() + ": ") - c.Print(a...) - } else { - fmt.Fprint(color.Output, ProgramName()+": ") - fmt.Fprint(color.Output, a...) - } - default: - if isatty.IsTerminal(os.Stdout.Fd()) { - c.Print(a...) - } else { - fmt.Fprint(color.Output, a...) - } - } -} - -// consolePrintf - same as print with a new line. -func consolePrintf(tag string, c *color.Color, format string, a ...interface{}) { - privateMutex.Lock() - defer privateMutex.Unlock() - - switch tag { - case "Debug": - // if no arguments are given do not invoke debug printer. - if len(a) == 0 { - return - } - output := color.Output - color.Output = stderrColoredOutput - if isatty.IsTerminal(os.Stderr.Fd()) { - c.Print(ProgramName() + ": ") - c.Printf(format, a...) - } else { - fmt.Fprint(color.Output, ProgramName()+": ") - fmt.Fprintf(color.Output, format, a...) - } - color.Output = output - case "Fatal": - fallthrough - case "Error": - // if no arguments are given do not invoke fatal and error printer. - if len(a) == 0 { - return - } - output := color.Output - color.Output = stderrColoredOutput - if isatty.IsTerminal(os.Stderr.Fd()) { - c.Print(ProgramName() + ": ") - c.Printf(format, a...) - } else { - fmt.Fprint(color.Output, ProgramName()+": ") - fmt.Fprintf(color.Output, format, a...) - } - color.Output = output - case "Info": - // if no arguments are given do not invoke info printer. - if len(a) == 0 { - return - } - if isatty.IsTerminal(os.Stdout.Fd()) { - c.Print(ProgramName() + ": ") - c.Printf(format, a...) - } else { - fmt.Fprint(color.Output, ProgramName()+": ") - fmt.Fprintf(color.Output, format, a...) - } - default: - if isatty.IsTerminal(os.Stdout.Fd()) { - c.Printf(format, a...) - } else { - fmt.Fprintf(color.Output, format, a...) - } - } -} - -// consolePrintln - same as print with a new line. -func consolePrintln(tag string, c *color.Color, a ...interface{}) { - privateMutex.Lock() - defer privateMutex.Unlock() - - switch tag { - case "Debug": - // if no arguments are given do not invoke debug printer. - if len(a) == 0 { - return - } - output := color.Output - color.Output = stderrColoredOutput - if isatty.IsTerminal(os.Stderr.Fd()) { - c.Print(ProgramName() + ": ") - c.Println(a...) - } else { - fmt.Fprint(color.Output, ProgramName()+": ") - fmt.Fprintln(color.Output, a...) - } - color.Output = output - case "Fatal": - fallthrough - case "Error": - // if no arguments are given do not invoke fatal and error printer. - if len(a) == 0 { - return - } - output := color.Output - color.Output = stderrColoredOutput - if isatty.IsTerminal(os.Stderr.Fd()) { - c.Print(ProgramName() + ": ") - c.Println(a...) - } else { - fmt.Fprint(color.Output, ProgramName()+": ") - fmt.Fprintln(color.Output, a...) - } - color.Output = output - case "Info": - // if no arguments are given do not invoke info printer. - if len(a) == 0 { - return - } - if isatty.IsTerminal(os.Stdout.Fd()) { - c.Print(ProgramName() + ": ") - c.Println(a...) - } else { - fmt.Fprint(color.Output, ProgramName()+": ") - fmt.Fprintln(color.Output, a...) - } - default: - if isatty.IsTerminal(os.Stdout.Fd()) { - c.Println(a...) - } else { - fmt.Fprintln(color.Output, a...) - } - } -} - -// Lock console. -func Lock() { - publicMutex.Lock() -} - -// Unlock locked console. -func Unlock() { - publicMutex.Unlock() -} - -// ProgramName - return the name of the executable program. -func ProgramName() string { - _, progName := filepath.Split(os.Args[0]) - return progName -} - -// Table - data to print in table format with fixed row widths. -type Table struct { - // per-row colors - RowColors []*color.Color - - // per-column align-right flag (aligns left by default) - AlignRight []bool - - // Left margin width for table - TableIndentWidth int - - // Flag to print separator under heading. Row 0 is considered heading - HeaderRowSeparator bool -} - -// NewTable - create a new Table instance. Takes per-row colors and -// per-column right-align flags and table indentation width (i.e. left -// margin width) -func NewTable(rowColors []*color.Color, alignRight []bool, indentWidth int) *Table { - return &Table{rowColors, alignRight, indentWidth, false} -} - -// DisplayTable - prints the table -func (t *Table) DisplayTable(rows [][]string) error { - numRows := len(rows) - numCols := len(rows[0]) - if numRows != len(t.RowColors) { - return fmt.Errorf("row count and row-colors mismatch") - } - - // Compute max. column widths - maxColWidths := make([]int, numCols) - for _, row := range rows { - if len(row) != len(t.AlignRight) { - return fmt.Errorf("col count and align-right mismatch") - } - for i, v := range row { - if len([]rune(v)) > maxColWidths[i] { - maxColWidths[i] = len([]rune(v)) - } - } - } - - // Compute per-cell text with padding and alignment applied. - paddedText := make([][]string, numRows) - for r, row := range rows { - paddedText[r] = make([]string, numCols) - for c, cell := range row { - if t.AlignRight[c] { - fmtStr := fmt.Sprintf("%%%ds", maxColWidths[c]) - paddedText[r][c] = fmt.Sprintf(fmtStr, cell) - } else { - extraWidth := maxColWidths[c] - len([]rune(cell)) - fmtStr := fmt.Sprintf("%%s%%%ds", extraWidth) - paddedText[r][c] = fmt.Sprintf(fmtStr, cell, "") - } - } - } - - // Draw table top border - segments := make([]string, numCols) - for i, c := range maxColWidths { - segments[i] = strings.Repeat("─", c+2) - } - indentText := strings.Repeat(" ", t.TableIndentWidth) - border := fmt.Sprintf("%s┌%s┐", indentText, strings.Join(segments, "┬")) - fmt.Println(border) - - // Print the table with colors - for r, row := range paddedText { - if t.HeaderRowSeparator && r == 1 { - // Draw table header-row border - border = fmt.Sprintf("%s├%s┤", indentText, strings.Join(segments, "┼")) - fmt.Println(border) - } - fmt.Print(indentText + "│ ") - for c, text := range row { - t.RowColors[r].Print(text) - if c != numCols-1 { - fmt.Print(" │ ") - } - } - fmt.Println(" │") - } - - // Draw table bottom border - border = fmt.Sprintf("%s└%s┘", indentText, strings.Join(segments, "┴")) - fmt.Println(border) - - return nil -} - -// RewindLines - uses terminal escape symbols to clear and rewind -// upwards on the console for `n` lines. -func RewindLines(n int) { - for i := 0; i < n; i++ { - fmt.Printf("\033[1A\033[K") - } -} diff --git a/pkg/console/console_test.go b/pkg/console/console_test.go deleted file mode 100644 index dda1ccbbf..000000000 --- a/pkg/console/console_test.go +++ /dev/null @@ -1,38 +0,0 @@ -// 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 . - -package console - -import ( - "testing" - - "github.com/fatih/color" -) - -func TestSetColor(t *testing.T) { - SetColor("unknown", color.New(color.FgWhite)) - _, ok := Theme["unknown"] - if !ok { - t.Fatal("missing theme") - } -} - -func TestColorLock(t *testing.T) { - Lock() - Print("") // Test for deadlocks. - Unlock() -} diff --git a/pkg/console/themes.go b/pkg/console/themes.go deleted file mode 100644 index 9ee14a1f0..000000000 --- a/pkg/console/themes.go +++ /dev/null @@ -1,55 +0,0 @@ -// 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 . - -package console - -import "github.com/fatih/color" - -var ( - // Theme contains default color mapping. - Theme = map[string]*color.Color{ - "Debug": color.New(color.FgWhite, color.Faint, color.Italic), - "Fatal": color.New(color.FgRed, color.Italic, color.Bold), - "Error": color.New(color.FgYellow, color.Italic), - "Info": color.New(color.FgGreen, color.Bold), - "Print": color.New(), - "PrintB": color.New(color.FgBlue, color.Bold), - "PrintC": color.New(color.FgGreen, color.Bold), - } -) - -// SetColorOff disables coloring for the entire session. -func SetColorOff() { - privateMutex.Lock() - defer privateMutex.Unlock() - color.NoColor = true -} - -// SetColorOn enables coloring for the entire session. -func SetColorOn() { - privateMutex.Lock() - defer privateMutex.Unlock() - color.NoColor = false -} - -// SetColor sets a color for a particular tag. -func SetColor(tag string, cl *color.Color) { - privateMutex.Lock() - defer privateMutex.Unlock() - // add new theme - Theme[tag] = cl -} diff --git a/pkg/dsync/drwmutex.go b/pkg/dsync/drwmutex.go index 9d9a5b75a..730944cc5 100644 --- a/pkg/dsync/drwmutex.go +++ b/pkg/dsync/drwmutex.go @@ -25,7 +25,7 @@ import ( "sync" "time" - "github.com/minio/minio/pkg/console" + "github.com/minio/pkg/console" ) // Indicator if logging is enabled. diff --git a/pkg/ellipses/ellipses.go b/pkg/ellipses/ellipses.go deleted file mode 100644 index 90dbe216a..000000000 --- a/pkg/ellipses/ellipses.go +++ /dev/null @@ -1,227 +0,0 @@ -// 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 . - -package ellipses - -import ( - "errors" - "fmt" - "regexp" - "strconv" - "strings" -) - -var ( - // Regex to extract ellipses syntax inputs. - regexpEllipses = regexp.MustCompile(`(.*)({[0-9a-z]*\.\.\.[0-9a-z]*})(.*)`) - - // Ellipses constants - openBraces = "{" - closeBraces = "}" - ellipses = "..." -) - -// Parses an ellipses range pattern of following style -// `{1...64}` -// `{33...64}` -func parseEllipsesRange(pattern string) (seq []string, err error) { - if !strings.Contains(pattern, openBraces) { - return nil, errors.New("Invalid argument") - } - if !strings.Contains(pattern, closeBraces) { - return nil, errors.New("Invalid argument") - } - - pattern = strings.TrimPrefix(pattern, openBraces) - pattern = strings.TrimSuffix(pattern, closeBraces) - - ellipsesRange := strings.Split(pattern, ellipses) - if len(ellipsesRange) != 2 { - return nil, errors.New("Invalid argument") - } - - var hexadecimal bool - var start, end uint64 - if start, err = strconv.ParseUint(ellipsesRange[0], 10, 64); err != nil { - // Look for hexadecimal conversions if any. - start, err = strconv.ParseUint(ellipsesRange[0], 16, 64) - if err != nil { - return nil, err - } - hexadecimal = true - } - - if end, err = strconv.ParseUint(ellipsesRange[1], 10, 64); err != nil { - // Look for hexadecimal conversions if any. - end, err = strconv.ParseUint(ellipsesRange[1], 16, 64) - if err != nil { - return nil, err - } - hexadecimal = true - } - - if start > end { - return nil, fmt.Errorf("Incorrect range start %d cannot be bigger than end %d", start, end) - } - - for i := start; i <= end; i++ { - if strings.HasPrefix(ellipsesRange[0], "0") && len(ellipsesRange[0]) > 1 || strings.HasPrefix(ellipsesRange[1], "0") { - if hexadecimal { - seq = append(seq, fmt.Sprintf(fmt.Sprintf("%%0%dx", len(ellipsesRange[1])), i)) - } else { - seq = append(seq, fmt.Sprintf(fmt.Sprintf("%%0%dd", len(ellipsesRange[1])), i)) - } - } else { - if hexadecimal { - seq = append(seq, fmt.Sprintf("%x", i)) - } else { - seq = append(seq, fmt.Sprintf("%d", i)) - } - } - } - - return seq, nil -} - -// Pattern - ellipses pattern, describes the range and also the -// associated prefix and suffixes. -type Pattern struct { - Prefix string - Suffix string - Seq []string -} - -// argExpander - recursively expands labels into its respective forms. -func argExpander(labels [][]string) (out [][]string) { - if len(labels) == 1 { - for _, v := range labels[0] { - out = append(out, []string{v}) - } - return out - } - for _, lbl := range labels[0] { - rs := argExpander(labels[1:]) - for _, rlbls := range rs { - r := append(rlbls, []string{lbl}...) - out = append(out, r) - } - } - return out -} - -// ArgPattern contains a list of patterns provided in the input. -type ArgPattern []Pattern - -// Expand - expands all the ellipses patterns in -// the given argument. -func (a ArgPattern) Expand() [][]string { - labels := make([][]string, len(a)) - for i := range labels { - labels[i] = a[i].Expand() - } - return argExpander(labels) -} - -// Expand - expands a ellipses pattern. -func (p Pattern) Expand() []string { - var labels []string - for i := range p.Seq { - switch { - case p.Prefix != "" && p.Suffix == "": - labels = append(labels, fmt.Sprintf("%s%s", p.Prefix, p.Seq[i])) - case p.Suffix != "" && p.Prefix == "": - labels = append(labels, fmt.Sprintf("%s%s", p.Seq[i], p.Suffix)) - case p.Suffix == "" && p.Prefix == "": - labels = append(labels, p.Seq[i]) - default: - labels = append(labels, fmt.Sprintf("%s%s%s", p.Prefix, p.Seq[i], p.Suffix)) - } - } - return labels -} - -// HasEllipses - returns true if input arg has ellipses type pattern. -func HasEllipses(args ...string) bool { - var ok = true - for _, arg := range args { - ok = ok && (strings.Count(arg, ellipses) > 0 || (strings.Count(arg, openBraces) > 0 && strings.Count(arg, closeBraces) > 0)) - } - return ok -} - -// ErrInvalidEllipsesFormatFn error returned when invalid ellipses format is detected. -var ErrInvalidEllipsesFormatFn = func(arg string) error { - return fmt.Errorf("Invalid ellipsis format in (%s), Ellipsis range must be provided in format {N...M} where N and M are positive integers, M must be greater than N, with an allowed minimum range of 4", arg) -} - -// FindEllipsesPatterns - finds all ellipses patterns, recursively and parses the ranges numerically. -func FindEllipsesPatterns(arg string) (ArgPattern, error) { - var patterns []Pattern - parts := regexpEllipses.FindStringSubmatch(arg) - if len(parts) == 0 { - // We throw an error if arg doesn't have any recognizable ellipses pattern. - return nil, ErrInvalidEllipsesFormatFn(arg) - } - - parts = parts[1:] - patternFound := regexpEllipses.MatchString(parts[0]) - for patternFound { - seq, err := parseEllipsesRange(parts[1]) - if err != nil { - return patterns, err - } - patterns = append(patterns, Pattern{ - Prefix: "", - Suffix: parts[2], - Seq: seq, - }) - parts = regexpEllipses.FindStringSubmatch(parts[0]) - if len(parts) > 0 { - parts = parts[1:] - patternFound = HasEllipses(parts[0]) - continue - } - break - } - - if len(parts) > 0 { - seq, err := parseEllipsesRange(parts[1]) - if err != nil { - return patterns, err - } - - patterns = append(patterns, Pattern{ - Prefix: parts[0], - Suffix: parts[2], - Seq: seq, - }) - } - - // Check if any of the prefix or suffixes now have flower braces - // left over, in such a case we generally think that there is - // perhaps a typo in users input and error out accordingly. - for _, pattern := range patterns { - if strings.Count(pattern.Prefix, openBraces) > 0 || strings.Count(pattern.Prefix, closeBraces) > 0 { - return nil, ErrInvalidEllipsesFormatFn(arg) - } - if strings.Count(pattern.Suffix, openBraces) > 0 || strings.Count(pattern.Suffix, closeBraces) > 0 { - return nil, ErrInvalidEllipsesFormatFn(arg) - } - } - - return patterns, nil -} diff --git a/pkg/ellipses/ellipses_test.go b/pkg/ellipses/ellipses_test.go deleted file mode 100644 index c37fcaa42..000000000 --- a/pkg/ellipses/ellipses_test.go +++ /dev/null @@ -1,256 +0,0 @@ -// 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 . - -package ellipses - -import ( - "fmt" - "testing" -) - -// Test tests args with ellipses. -func TestHasEllipses(t *testing.T) { - testCases := []struct { - args []string - expectedOk bool - }{ - // Tests for all args without ellipses. - { - []string{"64"}, - false, - }, - // Found flower braces, still attempt to parse and throw an error. - { - []string{"{1..64}"}, - true, - }, - { - []string{"{1..2..}"}, - true, - }, - // Test for valid input. - { - []string{"1...64"}, - true, - }, - { - []string{"{1...2O}"}, - true, - }, - { - []string{"..."}, - true, - }, - { - []string{"{-1...1}"}, - true, - }, - { - []string{"{0...-1}"}, - true, - }, - { - []string{"{1....4}"}, - true, - }, - { - []string{"{1...64}"}, - true, - }, - { - []string{"{...}"}, - true, - }, - { - []string{"{1...64}", "{65...128}"}, - true, - }, - { - []string{"http://minio{2...3}/export/set{1...64}"}, - true, - }, - { - []string{ - "http://minio{2...3}/export/set{1...64}", - "http://minio{2...3}/export/set{65...128}", - }, - true, - }, - { - []string{ - "mydisk-{a...z}{1...20}", - }, - true, - }, - { - - []string{ - "mydisk-{1...4}{1..2.}", - }, - true, - }, - } - - for i, testCase := range testCases { - t.Run(fmt.Sprintf("Test%d", i+1), func(t *testing.T) { - gotOk := HasEllipses(testCase.args...) - if gotOk != testCase.expectedOk { - t.Errorf("Expected %t, got %t", testCase.expectedOk, gotOk) - } - }) - } -} - -// Test tests find ellipses patterns. -func TestFindEllipsesPatterns(t *testing.T) { - testCases := []struct { - pattern string - success bool - expectedCount int - }{ - // Tests for all invalid inputs - { - "{1..64}", - false, - 0, - }, - { - "1...64", - false, - 0, - }, - { - "...", - false, - 0, - }, - { - "{1...", - false, - 0, - }, - { - "...64}", - false, - 0, - }, - { - "{...}", - false, - 0, - }, - { - "{-1...1}", - false, - 0, - }, - { - "{0...-1}", - false, - 0, - }, - { - "{1...2O}", - false, - 0, - }, - { - "{64...1}", - false, - 0, - }, - { - "{1....4}", - false, - 0, - }, - { - "mydisk-{a...z}{1...20}", - false, - 0, - }, - { - "mydisk-{1...4}{1..2.}", - false, - 0, - }, - { - "{1..2.}-mydisk-{1...4}", - false, - 0, - }, - { - "{{1...4}}", - false, - 0, - }, - { - "{4...02}", - false, - 0, - }, - { - "{f...z}", - false, - 0, - }, - // Test for valid input. - { - "{1...64}", - true, - 64, - }, - { - "{1...64} {65...128}", - true, - 4096, - }, - { - "{01...036}", - true, - 36, - }, - { - "{001...036}", - true, - 36, - }, - { - "{1...a}", - true, - 10, - }, - } - - for i, testCase := range testCases { - t.Run(fmt.Sprintf("Test%d", i+1), func(t *testing.T) { - argP, err := FindEllipsesPatterns(testCase.pattern) - if err != nil && testCase.success { - t.Errorf("Expected success but failed instead %s", err) - } - if err == nil && !testCase.success { - t.Errorf("Expected failure but passed instead") - } - if err == nil { - gotCount := len(argP.Expand()) - if gotCount != testCase.expectedCount { - t.Errorf("Expected %d, got %d", testCase.expectedCount, gotCount) - } - } - }) - } -} diff --git a/pkg/env/env.go b/pkg/env/env.go deleted file mode 100644 index d663d6ba7..000000000 --- a/pkg/env/env.go +++ /dev/null @@ -1,100 +0,0 @@ -// 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 . - -package env - -import ( - "strconv" - "strings" - "sync" -) - -var ( - privateMutex sync.RWMutex - lockEnvMutex sync.Mutex - envOff bool -) - -// LockSetEnv locks modifications to environment. -// Call returned function to unlock. -func LockSetEnv() func() { - lockEnvMutex.Lock() - return lockEnvMutex.Unlock -} - -// SetEnvOff - turns off env lookup -// A global lock above this MUST ensure that -func SetEnvOff() { - privateMutex.Lock() - defer privateMutex.Unlock() - - envOff = true -} - -// SetEnvOn - turns on env lookup -func SetEnvOn() { - privateMutex.Lock() - defer privateMutex.Unlock() - - envOff = false -} - -// IsSet returns if the given env key is set. -func IsSet(key string) bool { - _, _, _, ok := LookupEnv(key) - return ok -} - -// Get retrieves the value of the environment variable named -// by the key. If the variable is present in the environment the -// value (which may be empty) is returned. Otherwise it returns -// the specified default value. -func Get(key, defaultValue string) string { - privateMutex.RLock() - ok := envOff - privateMutex.RUnlock() - if ok { - return defaultValue - } - if v, _, _, ok := LookupEnv(key); ok { - return v - } - return defaultValue -} - -// GetInt returns an integer if found in the environment -// and returns the default value otherwise. -func GetInt(key string, defaultValue int) (int, error) { - v := Get(key, "") - if v == "" { - return defaultValue, nil - } - return strconv.Atoi(v) -} - -// List all envs with a given prefix. -func List(prefix string) (envs []string) { - for _, env := range Environ() { - if strings.HasPrefix(env, prefix) { - values := strings.SplitN(env, "=", 2) - if len(values) == 2 { - envs = append(envs, values[0]) - } - } - } - return envs -} diff --git a/pkg/env/web_env.go b/pkg/env/web_env.go deleted file mode 100644 index dfa2b78df..000000000 --- a/pkg/env/web_env.go +++ /dev/null @@ -1,187 +0,0 @@ -// 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 . - -package env - -import ( - "context" - "crypto/tls" - "crypto/x509" - "errors" - "fmt" - "io/ioutil" - "net" - "net/http" - "net/url" - "os" - "regexp" - "strings" - "time" - - "github.com/dgrijalva/jwt-go" -) - -const ( - webEnvScheme = "env" - webEnvSchemeSecure = "env+tls" -) - -var ( - globalRootCAs *x509.CertPool -) - -// RegisterGlobalCAs register the global root CAs -func RegisterGlobalCAs(CAs *x509.CertPool) { - globalRootCAs = CAs -} - -var ( - hostKeys = regexp.MustCompile("^(https?://)(.*?):(.*?)@(.*?)$") -) - -func fetchHTTPConstituentParts(u *url.URL) (username string, password string, envURL string, err error) { - envURL = u.String() - if hostKeys.MatchString(envURL) { - parts := hostKeys.FindStringSubmatch(envURL) - if len(parts) != 5 { - return "", "", "", errors.New("invalid arguments") - } - username = parts[2] - password = parts[3] - envURL = fmt.Sprintf("%s%s", parts[1], parts[4]) - } - - if username == "" && password == "" && u.User != nil { - username = u.User.Username() - password, _ = u.User.Password() - } - return username, password, envURL, nil -} - -func getEnvValueFromHTTP(urlStr, envKey string) (string, string, string, error) { - u, err := url.Parse(urlStr) - if err != nil { - return "", "", "", err - } - - switch u.Scheme { - case webEnvScheme: - u.Scheme = "http" - case webEnvSchemeSecure: - u.Scheme = "https" - default: - return "", "", "", errors.New("invalid arguments") - } - - username, password, envURL, err := fetchHTTPConstituentParts(u) - if err != nil { - return "", "", "", err - } - - ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) - defer cancel() - - req, err := http.NewRequestWithContext(ctx, http.MethodGet, envURL+"?key="+envKey, nil) - if err != nil { - return "", "", "", err - } - - claims := &jwt.StandardClaims{ - ExpiresAt: int64(15 * time.Minute), - Issuer: username, - Subject: envKey, - } - - token := jwt.NewWithClaims(jwt.SigningMethodHS512, claims) - ss, err := token.SignedString([]byte(password)) - if err != nil { - return "", "", "", err - } - - req.Header.Set("Authorization", "Bearer "+ss) - - clnt := &http.Client{ - Transport: &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: (&net.Dialer{ - Timeout: 3 * time.Second, - KeepAlive: 5 * time.Second, - }).DialContext, - ResponseHeaderTimeout: 3 * time.Second, - TLSHandshakeTimeout: 3 * time.Second, - ExpectContinueTimeout: 3 * time.Second, - TLSClientConfig: &tls.Config{ - RootCAs: globalRootCAs, - }, - // Go net/http automatically unzip if content-type is - // gzip disable this feature, as we are always interested - // in raw stream. - DisableCompression: true, - }, - } - - resp, err := clnt.Do(req) - if err != nil { - return "", "", "", err - } - - envValueBytes, err := ioutil.ReadAll(resp.Body) - if err != nil { - return "", "", "", err - } - - return string(envValueBytes), username, password, nil -} - -// Environ returns a copy of strings representing the -// environment, in the form "key=value". -func Environ() []string { - return os.Environ() -} - -// LookupEnv retrieves the value of the environment variable -// named by the key. If the variable is present in the -// environment the value (which may be empty) is returned -// and the boolean is true. Otherwise the returned value -// will be empty and the boolean will be false. -// -// Additionally if the input is env://username:password@remote:port/ -// to fetch ENV values for the env value from a remote server. -// In this case, it also returns the credentials username and password -func LookupEnv(key string) (string, string, string, bool) { - v, ok := os.LookupEnv(key) - if ok && strings.HasPrefix(v, webEnvScheme) { - // If env value starts with `env*://` - // continue to parse and fetch from remote - var err error - v, user, pwd, err := getEnvValueFromHTTP(strings.TrimSpace(v), key) - if err != nil { - env, eok := os.LookupEnv("_" + key) - if eok { - // fallback to cached value if-any. - return env, user, pwd, eok - } - } - // Set the ENV value to _env value, - // this value is a fallback in-case of - // server restarts when webhook server - // is down. - os.Setenv("_"+key, v) - return v, user, pwd, true - } - return v, "", "", ok -} diff --git a/pkg/env/web_env_test.go b/pkg/env/web_env_test.go deleted file mode 100644 index 5d8c14905..000000000 --- a/pkg/env/web_env_test.go +++ /dev/null @@ -1,89 +0,0 @@ -// 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 . - -package env - -import ( - "fmt" - "net/http" - "net/http/httptest" - "net/url" - "testing" - - "github.com/gorilla/mux" -) - -func GetenvHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - if vars["namespace"] != "default" { - http.Error(w, "namespace not found", http.StatusNotFound) - return - } - if vars["name"] != "minio" { - http.Error(w, "tenant not found", http.StatusNotFound) - return - } - if vars["key"] != "MINIO_ARGS" { - http.Error(w, "key not found", http.StatusNotFound) - return - } - w.Write([]byte("http://127.0.0.{1..4}:9000/data{1...4}")) - w.(http.Flusher).Flush() -} - -func startTestServer(t *testing.T) *httptest.Server { - router := mux.NewRouter().SkipClean(true).UseEncodedPath() - router.Methods(http.MethodGet). - Path("/webhook/v1/getenv/{namespace}/{name}"). - HandlerFunc(GetenvHandler).Queries("key", "{key:.*}") - - ts := httptest.NewServer(router) - t.Cleanup(func() { - ts.Close() - }) - - return ts -} - -func TestWebEnv(t *testing.T) { - ts := startTestServer(t) - - u, err := url.Parse(ts.URL) - if err != nil { - t.Fatal(err) - } - - v, user, pwd, err := getEnvValueFromHTTP( - fmt.Sprintf("env://minio:minio123@%s/webhook/v1/getenv/default/minio", - u.Host), - "MINIO_ARGS") - if err != nil { - t.Fatal(err) - } - - if v != "http://127.0.0.{1..4}:9000/data{1...4}" { - t.Fatalf("Unexpected value %s", v) - } - - if user != "minio" { - t.Fatalf("Unexpected value %s", v) - } - - if pwd != "minio123" { - t.Fatalf("Unexpected value %s", v) - } -} diff --git a/pkg/event/rules.go b/pkg/event/rules.go index d6e90fd2c..b7a59cd1a 100644 --- a/pkg/event/rules.go +++ b/pkg/event/rules.go @@ -20,7 +20,7 @@ package event import ( "strings" - "github.com/minio/minio/pkg/wildcard" + "github.com/minio/pkg/wildcard" ) // NewPattern - create new pattern for prefix/suffix. diff --git a/pkg/event/target/queuestore.go b/pkg/event/target/queuestore.go index 9d4504a4a..f85aefde4 100644 --- a/pkg/event/target/queuestore.go +++ b/pkg/event/target/queuestore.go @@ -27,7 +27,7 @@ import ( "sync" "github.com/minio/minio/pkg/event" - "github.com/minio/minio/pkg/sys" + "github.com/minio/pkg/sys" ) const ( diff --git a/pkg/event/target/webhook.go b/pkg/event/target/webhook.go index 86b59cf62..597616bb5 100644 --- a/pkg/event/target/webhook.go +++ b/pkg/event/target/webhook.go @@ -32,9 +32,9 @@ import ( "path/filepath" "time" - "github.com/minio/minio/pkg/certs" "github.com/minio/minio/pkg/event" xnet "github.com/minio/minio/pkg/net" + "github.com/minio/pkg/certs" ) // Webhook constants diff --git a/pkg/iam/policy/action.go b/pkg/iam/policy/action.go index 5d390fed5..af2652565 100644 --- a/pkg/iam/policy/action.go +++ b/pkg/iam/policy/action.go @@ -19,7 +19,7 @@ package iampolicy import ( "github.com/minio/minio/pkg/bucket/policy/condition" - "github.com/minio/minio/pkg/wildcard" + "github.com/minio/pkg/wildcard" ) // Action - policy action. diff --git a/pkg/iam/policy/resource.go b/pkg/iam/policy/resource.go index 712770164..8d8ea337f 100644 --- a/pkg/iam/policy/resource.go +++ b/pkg/iam/policy/resource.go @@ -23,7 +23,7 @@ import ( "strings" "github.com/minio/minio/pkg/bucket/policy/condition" - "github.com/minio/minio/pkg/wildcard" + "github.com/minio/pkg/wildcard" ) // ResourceARNPrefix - resource ARN prefix as per AWS S3 specification. diff --git a/pkg/licverifier/verifier.go b/pkg/licverifier/verifier.go deleted file mode 100644 index 36bc435f8..000000000 --- a/pkg/licverifier/verifier.go +++ /dev/null @@ -1,118 +0,0 @@ -// 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 . - -// Package licverifier implements a simple library to verify MinIO Subnet license keys. -package licverifier - -import ( - "crypto/ecdsa" - "errors" - "fmt" - "time" - - "github.com/dgrijalva/jwt-go" -) - -// LicenseVerifier needs an ECDSA public key in PEM format for initialization. -type LicenseVerifier struct { - ecPubKey *ecdsa.PublicKey -} - -// LicenseInfo holds customer metadata present in the license key. -type LicenseInfo struct { - Email string // Email of the license key requestor - Organization string // Subnet organization name - AccountID int64 // Subnet account id - StorageCapacity int64 // Storage capacity used in TB - Plan string // Subnet plan - ExpiresAt time.Time // Time of license expiry -} - -// license key JSON field names -const ( - accountID = "aid" - sub = "sub" - expiresAt = "exp" - organization = "org" - capacity = "cap" - plan = "plan" -) - -// NewLicenseVerifier returns an initialized license verifier with the given -// ECDSA public key in PEM format. -func NewLicenseVerifier(pemBytes []byte) (*LicenseVerifier, error) { - pbKey, err := jwt.ParseECPublicKeyFromPEM(pemBytes) - if err != nil { - return nil, fmt.Errorf("Failed to parse public key: %s", err) - } - return &LicenseVerifier{ - ecPubKey: pbKey, - }, nil -} - -// toLicenseInfo extracts LicenseInfo from claims. It returns an error if any of -// the claim values are invalid. -func toLicenseInfo(claims jwt.MapClaims) (LicenseInfo, error) { - accID, ok := claims[accountID].(float64) - if !ok || ok && accID <= 0 { - return LicenseInfo{}, errors.New("Invalid accountId in claims") - } - email, ok := claims[sub].(string) - if !ok { - return LicenseInfo{}, errors.New("Invalid email in claims") - } - expiryTS, ok := claims[expiresAt].(float64) - if !ok { - return LicenseInfo{}, errors.New("Invalid time of expiry in claims") - } - expiresAt := time.Unix(int64(expiryTS), 0) - orgName, ok := claims[organization].(string) - if !ok { - return LicenseInfo{}, errors.New("Invalid organization in claims") - } - storageCap, ok := claims[capacity].(float64) - if !ok { - return LicenseInfo{}, errors.New("Invalid storage capacity in claims") - } - plan, ok := claims[plan].(string) - if !ok { - return LicenseInfo{}, errors.New("Invalid plan in claims") - } - return LicenseInfo{ - Email: email, - Organization: orgName, - AccountID: int64(accID), - StorageCapacity: int64(storageCap), - Plan: plan, - ExpiresAt: expiresAt, - }, nil - -} - -// Verify verifies the license key and validates the claims present in it. -func (lv *LicenseVerifier) Verify(license string) (LicenseInfo, error) { - token, err := jwt.ParseWithClaims(license, &jwt.MapClaims{}, func(token *jwt.Token) (interface{}, error) { - return lv.ecPubKey, nil - }) - if err != nil { - return LicenseInfo{}, fmt.Errorf("Failed to verify license: %s", err) - } - if claims, ok := token.Claims.(*jwt.MapClaims); ok && token.Valid { - return toLicenseInfo(*claims) - } - return LicenseInfo{}, errors.New("Invalid claims found in license") -} diff --git a/pkg/licverifier/verifier_test.go b/pkg/licverifier/verifier_test.go deleted file mode 100644 index 51af1beb5..000000000 --- a/pkg/licverifier/verifier_test.go +++ /dev/null @@ -1,111 +0,0 @@ -// 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 . - -package licverifier - -import ( - "fmt" - "testing" - "time" - - "github.com/dgrijalva/jwt-go" -) - -// at fixes the jwt.TimeFunc at t and calls f in that context. -func at(t time.Time, f func()) { - jwt.TimeFunc = func() time.Time { return t } - f() - jwt.TimeFunc = time.Now -} - -func areEqLicenseInfo(a, b LicenseInfo) bool { - if a.Email == b.Email && a.Organization == b.Organization && a.AccountID == b.AccountID && a.Plan == b.Plan && a.StorageCapacity == b.StorageCapacity && a.ExpiresAt.Equal(b.ExpiresAt) { - return true - } - return false -} - -// TestLicenseVerify tests the license key verification process with a valid and -// an invalid key. -func TestLicenseVerify(t *testing.T) { - pemBytes := []byte(`-----BEGIN PUBLIC KEY----- -MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEbo+e1wpBY4tBq9AONKww3Kq7m6QP/TBQ -mr/cKCUyBL7rcAvg0zNq1vcSrUSGlAmY3SEDCu3GOKnjG/U4E7+p957ocWSV+mQU -9NKlTdQFGF3+aO6jbQ4hX/S5qPyF+a3z ------END PUBLIC KEY-----`) - lv, err := NewLicenseVerifier(pemBytes) - if err != nil { - t.Fatalf("Failed to create license verifier: %s", err) - } - testCases := []struct { - lic string - expectedLicInfo LicenseInfo - shouldPass bool - }{{"", LicenseInfo{}, false}, - {"eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJrYW5hZ2FyYWorYzFAbWluaW8uaW8iLCJjYXAiOjUwLCJvcmciOiJHcmluZ290dHMgSW5jLiIsImV4cCI6MS42NDE0NDYxNjkwMDExOTg4OTRlOSwicGxhbiI6IlNUQU5EQVJEIiwiaXNzIjoic3VibmV0QG1pbi5pbyIsImFpZCI6MSwiaWF0IjoxLjYwOTkxMDE2OTAwMTE5ODg5NGU5fQ.EhTL2xwMHnUoLQF4UR-5bjUCja3whseLU5mb9XEj7PvAae6HEIDCOMEF8Hhh20DN_v_LRE283j2ZlA5zulcXSZXS0CLcrKqbVy6QLvZfvvLuerOjJI-NBa9dSJWJ0WoN", LicenseInfo{ - Email: "kanagaraj+c1@minio.io", - Organization: "Gringotts Inc.", - AccountID: 1, - StorageCapacity: 50, - Plan: "STANDARD", - ExpiresAt: time.Date(2022, time.January, 6, 5, 16, 9, 0, time.UTC), - }, true}, - } - - for i, tc := range testCases { - // Fixing the jwt.TimeFunc at 2021-01-06 05:16:09 +0000 UTC to - // ensure that the license JWT doesn't expire ever. - at(time.Unix(int64(1609910169), 0), func() { - licInfo, err := lv.Verify(tc.lic) - if err != nil && tc.shouldPass { - t.Fatalf("%d: Expected license to pass verification but failed with %s", i+1, err) - } - if err == nil { - if !tc.shouldPass { - t.Fatalf("%d: Expected license to fail verification but passed", i+1) - } - if !areEqLicenseInfo(tc.expectedLicInfo, licInfo) { - t.Fatalf("%d: Expected license info %v but got %v", i+1, tc.expectedLicInfo, licInfo) - } - } - }) - } -} - -// Example creates a LicenseVerifier using the ECDSA public key in pemBytes. It -// uses the Verify method of the LicenseVerifier to verify and extract the -// claims present in the license key. -func Example() { - pemBytes := []byte(`-----BEGIN PUBLIC KEY----- -MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEbo+e1wpBY4tBq9AONKww3Kq7m6QP/TBQ -mr/cKCUyBL7rcAvg0zNq1vcSrUSGlAmY3SEDCu3GOKnjG/U4E7+p957ocWSV+mQU -9NKlTdQFGF3+aO6jbQ4hX/S5qPyF+a3z ------END PUBLIC KEY-----`) - - lv, err := NewLicenseVerifier(pemBytes) - if err != nil { - fmt.Println("Failed to create license verifier", err) - } - - licenseKey := "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJrYW5hZ2FyYWorYzFAbWluaW8uaW8iLCJjYXAiOjUwLCJvcmciOiJHcmluZ290dHMgSW5jLiIsImV4cCI6MS42NDE0NDYxNjkwMDExOTg4OTRlOSwicGxhbiI6IlNUQU5EQVJEIiwiaXNzIjoic3VibmV0QG1pbi5pbyIsImFpZCI6MSwiaWF0IjoxLjYwOTkxMDE2OTAwMTE5ODg5NGU5fQ.EhTL2xwMHnUoLQF4UR-5bjUCja3whseLU5mb9XEj7PvAae6HEIDCOMEF8Hhh20DN_v_LRE283j2ZlA5zulcXSZXS0CLcrKqbVy6QLvZfvvLuerOjJI-NBa9dSJWJ0WoN" - licInfo, err := lv.Verify(licenseKey) - if err != nil { - fmt.Println("Failed to verify license key", err) - } - - fmt.Println("License metadata", licInfo) -} diff --git a/pkg/mimedb/Makefile b/pkg/mimedb/Makefile deleted file mode 100644 index 537bf1f76..000000000 --- a/pkg/mimedb/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# Generate db.go from db.json downloaded nodejs mime-db project. -# NOTE: Autogenerated db.go needs to be vet proofed. \ - Manually edit json -> JSON for all variable names -all: download build - -# Download db.json from NodeJS's mime-db project. It is under MIT license. -download: - @mkdir db - @wget -nv -q https://cdn.rawgit.com/jshttp/mime-db/master/db.json -O db/db.json - - -# After generating db.go, clean up downloaded db.json. -build: download - @go run util/gen-db.go db/db.json > db.go - @rm -f db/db.json - @rm -rf db - @echo Generated \"db.go\". diff --git a/pkg/mimedb/db.go b/pkg/mimedb/db.go deleted file mode 100644 index e7ea19fa5..000000000 --- a/pkg/mimedb/db.go +++ /dev/null @@ -1,4411 +0,0 @@ -// 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 . - -// Package mimedb is a database of file extension to mime content-type. -// Definitions are imported from NodeJS mime-db project under MIT license. -package mimedb - -// DB - Mime is a collection of mime types with extension as key and content-type as value. -var DB = map[string]struct { - ContentType string - Compressible bool -}{ - "123": { - ContentType: "application/vnd.lotus-1-2-3", - Compressible: false, - }, - "3dml": { - ContentType: "text/vnd.in3d.3dml", - Compressible: false, - }, - "3ds": { - ContentType: "image/x-3ds", - Compressible: false, - }, - "3g2": { - ContentType: "video/3gpp2", - Compressible: false, - }, - "3gp": { - ContentType: "video/3gpp", - Compressible: false, - }, - "3gpp": { - ContentType: "video/3gpp", - Compressible: false, - }, - "7z": { - ContentType: "application/x-7z-compressed", - Compressible: false, - }, - "aab": { - ContentType: "application/x-authorware-bin", - Compressible: false, - }, - "aac": { - ContentType: "audio/x-aac", - Compressible: false, - }, - "aam": { - ContentType: "application/x-authorware-map", - Compressible: false, - }, - "aas": { - ContentType: "application/x-authorware-seg", - Compressible: false, - }, - "abw": { - ContentType: "application/x-abiword", - Compressible: false, - }, - "ac": { - ContentType: "application/pkix-attr-cert", - Compressible: false, - }, - "acc": { - ContentType: "application/vnd.americandynamics.acc", - Compressible: false, - }, - "ace": { - ContentType: "application/x-ace-compressed", - Compressible: false, - }, - "acu": { - ContentType: "application/vnd.acucobol", - Compressible: false, - }, - "acutc": { - ContentType: "application/vnd.acucorp", - Compressible: false, - }, - "adp": { - ContentType: "audio/adpcm", - Compressible: false, - }, - "aep": { - ContentType: "application/vnd.audiograph", - Compressible: false, - }, - "afm": { - ContentType: "application/x-font-type1", - Compressible: false, - }, - "afp": { - ContentType: "application/vnd.ibm.modcap", - Compressible: false, - }, - "ahead": { - ContentType: "application/vnd.ahead.space", - Compressible: false, - }, - "ai": { - ContentType: "application/postscript", - Compressible: false, - }, - "aif": { - ContentType: "audio/x-aiff", - Compressible: false, - }, - "aifc": { - ContentType: "audio/x-aiff", - Compressible: false, - }, - "aiff": { - ContentType: "audio/x-aiff", - Compressible: false, - }, - "air": { - ContentType: "application/vnd.adobe.air-application-installer-package+zip", - Compressible: false, - }, - "ait": { - ContentType: "application/vnd.dvb.ait", - Compressible: false, - }, - "ami": { - ContentType: "application/vnd.amiga.ami", - Compressible: false, - }, - "apk": { - ContentType: "application/vnd.android.package-archive", - Compressible: false, - }, - "apng": { - ContentType: "image/apng", - Compressible: false, - }, - "appcache": { - ContentType: "text/cache-manifest", - Compressible: false, - }, - "application": { - ContentType: "application/x-ms-application", - Compressible: false, - }, - "apr": { - ContentType: "application/vnd.lotus-approach", - Compressible: false, - }, - "arc": { - ContentType: "application/x-freearc", - Compressible: false, - }, - "arj": { - ContentType: "application/x-arj", - Compressible: false, - }, - "asc": { - ContentType: "application/pgp-signature", - Compressible: false, - }, - "asf": { - ContentType: "video/x-ms-asf", - Compressible: false, - }, - "asm": { - ContentType: "text/x-asm", - Compressible: false, - }, - "aso": { - ContentType: "application/vnd.accpac.simply.aso", - Compressible: false, - }, - "asx": { - ContentType: "video/x-ms-asf", - Compressible: false, - }, - "atc": { - ContentType: "application/vnd.acucorp", - Compressible: false, - }, - "atom": { - ContentType: "application/atom+xml", - Compressible: false, - }, - "atomcat": { - ContentType: "application/atomcat+xml", - Compressible: false, - }, - "atomsvc": { - ContentType: "application/atomsvc+xml", - Compressible: false, - }, - "atx": { - ContentType: "application/vnd.antix.game-component", - Compressible: false, - }, - "au": { - ContentType: "audio/basic", - Compressible: false, - }, - "avi": { - ContentType: "video/x-msvideo", - Compressible: false, - }, - "aw": { - ContentType: "application/applixware", - Compressible: false, - }, - "azf": { - ContentType: "application/vnd.airzip.filesecure.azf", - Compressible: false, - }, - "azs": { - ContentType: "application/vnd.airzip.filesecure.azs", - Compressible: false, - }, - "azv": { - ContentType: "image/vnd.airzip.accelerator.azv", - Compressible: false, - }, - "azw": { - ContentType: "application/vnd.amazon.ebook", - Compressible: false, - }, - "bat": { - ContentType: "application/x-msdownload", - Compressible: false, - }, - "bcpio": { - ContentType: "application/x-bcpio", - Compressible: false, - }, - "bdf": { - ContentType: "application/x-font-bdf", - Compressible: false, - }, - "bdm": { - ContentType: "application/vnd.syncml.dm+wbxml", - Compressible: false, - }, - "bdoc": { - ContentType: "application/x-bdoc", - Compressible: false, - }, - "bed": { - ContentType: "application/vnd.realvnc.bed", - Compressible: false, - }, - "bh2": { - ContentType: "application/vnd.fujitsu.oasysprs", - Compressible: false, - }, - "bin": { - ContentType: "application/octet-stream", - Compressible: false, - }, - "blb": { - ContentType: "application/x-blorb", - Compressible: false, - }, - "blorb": { - ContentType: "application/x-blorb", - Compressible: false, - }, - "bmi": { - ContentType: "application/vnd.bmi", - Compressible: false, - }, - "bmp": { - ContentType: "image/x-ms-bmp", - Compressible: false, - }, - "book": { - ContentType: "application/vnd.framemaker", - Compressible: false, - }, - "box": { - ContentType: "application/vnd.previewsystems.box", - Compressible: false, - }, - "boz": { - ContentType: "application/x-bzip2", - Compressible: false, - }, - "bpk": { - ContentType: "application/octet-stream", - Compressible: false, - }, - "btif": { - ContentType: "image/prs.btif", - Compressible: false, - }, - "buffer": { - ContentType: "application/octet-stream", - Compressible: false, - }, - "bz": { - ContentType: "application/x-bzip", - Compressible: false, - }, - "bz2": { - ContentType: "application/x-bzip2", - Compressible: false, - }, - "c": { - ContentType: "text/x-c", - Compressible: false, - }, - "c11amc": { - ContentType: "application/vnd.cluetrust.cartomobile-config", - Compressible: false, - }, - "c11amz": { - ContentType: "application/vnd.cluetrust.cartomobile-config-pkg", - Compressible: false, - }, - "c4d": { - ContentType: "application/vnd.clonk.c4group", - Compressible: false, - }, - "c4f": { - ContentType: "application/vnd.clonk.c4group", - Compressible: false, - }, - "c4g": { - ContentType: "application/vnd.clonk.c4group", - Compressible: false, - }, - "c4p": { - ContentType: "application/vnd.clonk.c4group", - Compressible: false, - }, - "c4u": { - ContentType: "application/vnd.clonk.c4group", - Compressible: false, - }, - "cab": { - ContentType: "application/vnd.ms-cab-compressed", - Compressible: false, - }, - "caf": { - ContentType: "audio/x-caf", - Compressible: false, - }, - "cap": { - ContentType: "application/vnd.tcpdump.pcap", - Compressible: false, - }, - "car": { - ContentType: "application/vnd.curl.car", - Compressible: false, - }, - "cat": { - ContentType: "application/vnd.ms-pki.seccat", - Compressible: false, - }, - "cb7": { - ContentType: "application/x-cbr", - Compressible: false, - }, - "cba": { - ContentType: "application/x-cbr", - Compressible: false, - }, - "cbr": { - ContentType: "application/x-cbr", - Compressible: false, - }, - "cbt": { - ContentType: "application/x-cbr", - Compressible: false, - }, - "cbz": { - ContentType: "application/x-cbr", - Compressible: false, - }, - "cc": { - ContentType: "text/x-c", - Compressible: false, - }, - "cco": { - ContentType: "application/x-cocoa", - Compressible: false, - }, - "cct": { - ContentType: "application/x-director", - Compressible: false, - }, - "ccxml": { - ContentType: "application/ccxml+xml", - Compressible: false, - }, - "cdbcmsg": { - ContentType: "application/vnd.contact.cmsg", - Compressible: false, - }, - "cdf": { - ContentType: "application/x-netcdf", - Compressible: false, - }, - "cdkey": { - ContentType: "application/vnd.mediastation.cdkey", - Compressible: false, - }, - "cdmia": { - ContentType: "application/cdmi-capability", - Compressible: false, - }, - "cdmic": { - ContentType: "application/cdmi-container", - Compressible: false, - }, - "cdmid": { - ContentType: "application/cdmi-domain", - Compressible: false, - }, - "cdmio": { - ContentType: "application/cdmi-object", - Compressible: false, - }, - "cdmiq": { - ContentType: "application/cdmi-queue", - Compressible: false, - }, - "cdx": { - ContentType: "chemical/x-cdx", - Compressible: false, - }, - "cdxml": { - ContentType: "application/vnd.chemdraw+xml", - Compressible: false, - }, - "cdy": { - ContentType: "application/vnd.cinderella", - Compressible: false, - }, - "cer": { - ContentType: "application/pkix-cert", - Compressible: false, - }, - "cfs": { - ContentType: "application/x-cfs-compressed", - Compressible: false, - }, - "cgm": { - ContentType: "image/cgm", - Compressible: false, - }, - "chat": { - ContentType: "application/x-chat", - Compressible: false, - }, - "chm": { - ContentType: "application/vnd.ms-htmlhelp", - Compressible: false, - }, - "chrt": { - ContentType: "application/vnd.kde.kchart", - Compressible: false, - }, - "cif": { - ContentType: "chemical/x-cif", - Compressible: false, - }, - "cii": { - ContentType: "application/vnd.anser-web-certificate-issue-initiation", - Compressible: false, - }, - "cil": { - ContentType: "application/vnd.ms-artgalry", - Compressible: false, - }, - "cla": { - ContentType: "application/vnd.claymore", - Compressible: false, - }, - "class": { - ContentType: "application/java-vm", - Compressible: false, - }, - "clkk": { - ContentType: "application/vnd.crick.clicker.keyboard", - Compressible: false, - }, - "clkp": { - ContentType: "application/vnd.crick.clicker.palette", - Compressible: false, - }, - "clkt": { - ContentType: "application/vnd.crick.clicker.template", - Compressible: false, - }, - "clkw": { - ContentType: "application/vnd.crick.clicker.wordbank", - Compressible: false, - }, - "clkx": { - ContentType: "application/vnd.crick.clicker", - Compressible: false, - }, - "clp": { - ContentType: "application/x-msclip", - Compressible: false, - }, - "cmc": { - ContentType: "application/vnd.cosmocaller", - Compressible: false, - }, - "cmdf": { - ContentType: "chemical/x-cmdf", - Compressible: false, - }, - "cml": { - ContentType: "chemical/x-cml", - Compressible: false, - }, - "cmp": { - ContentType: "application/vnd.yellowriver-custom-menu", - Compressible: false, - }, - "cmx": { - ContentType: "image/x-cmx", - Compressible: false, - }, - "cod": { - ContentType: "application/vnd.rim.cod", - Compressible: false, - }, - "coffee": { - ContentType: "text/coffeescript", - Compressible: false, - }, - "com": { - ContentType: "application/x-msdownload", - Compressible: false, - }, - "conf": { - ContentType: "text/plain", - Compressible: false, - }, - "cpio": { - ContentType: "application/x-cpio", - Compressible: false, - }, - "cpp": { - ContentType: "text/x-c", - Compressible: false, - }, - "cpt": { - ContentType: "application/mac-compactpro", - Compressible: false, - }, - "crd": { - ContentType: "application/x-mscardfile", - Compressible: false, - }, - "crl": { - ContentType: "application/pkix-crl", - Compressible: false, - }, - "crt": { - ContentType: "application/x-x509-ca-cert", - Compressible: false, - }, - "crx": { - ContentType: "application/x-chrome-extension", - Compressible: false, - }, - "cryptonote": { - ContentType: "application/vnd.rig.cryptonote", - Compressible: false, - }, - "csh": { - ContentType: "application/x-csh", - Compressible: false, - }, - "csl": { - ContentType: "application/vnd.citationstyles.style+xml", - Compressible: false, - }, - "csml": { - ContentType: "chemical/x-csml", - Compressible: false, - }, - "csp": { - ContentType: "application/vnd.commonspace", - Compressible: false, - }, - "css": { - ContentType: "text/css", - Compressible: false, - }, - "cst": { - ContentType: "application/x-director", - Compressible: false, - }, - "csv": { - ContentType: "text/csv", - Compressible: false, - }, - "cu": { - ContentType: "application/cu-seeme", - Compressible: false, - }, - "curl": { - ContentType: "text/vnd.curl", - Compressible: false, - }, - "cww": { - ContentType: "application/prs.cww", - Compressible: false, - }, - "cxt": { - ContentType: "application/x-director", - Compressible: false, - }, - "cxx": { - ContentType: "text/x-c", - Compressible: false, - }, - "dae": { - ContentType: "model/vnd.collada+xml", - Compressible: false, - }, - "daf": { - ContentType: "application/vnd.mobius.daf", - Compressible: false, - }, - "dart": { - ContentType: "application/vnd.dart", - Compressible: false, - }, - "dataless": { - ContentType: "application/vnd.fdsn.seed", - Compressible: false, - }, - "davmount": { - ContentType: "application/davmount+xml", - Compressible: false, - }, - "dbk": { - ContentType: "application/docbook+xml", - Compressible: false, - }, - "dcr": { - ContentType: "application/x-director", - Compressible: false, - }, - "dcurl": { - ContentType: "text/vnd.curl.dcurl", - Compressible: false, - }, - "dd2": { - ContentType: "application/vnd.oma.dd2+xml", - Compressible: false, - }, - "ddd": { - ContentType: "application/vnd.fujixerox.ddd", - Compressible: false, - }, - "deb": { - ContentType: "application/x-debian-package", - Compressible: false, - }, - "def": { - ContentType: "text/plain", - Compressible: false, - }, - "deploy": { - ContentType: "application/octet-stream", - Compressible: false, - }, - "der": { - ContentType: "application/x-x509-ca-cert", - Compressible: false, - }, - "dfac": { - ContentType: "application/vnd.dreamfactory", - Compressible: false, - }, - "dgc": { - ContentType: "application/x-dgc-compressed", - Compressible: false, - }, - "dic": { - ContentType: "text/x-c", - Compressible: false, - }, - "dir": { - ContentType: "application/x-director", - Compressible: false, - }, - "dis": { - ContentType: "application/vnd.mobius.dis", - Compressible: false, - }, - "disposition-notification": { - ContentType: "message/disposition-notification", - Compressible: false, - }, - "dist": { - ContentType: "application/octet-stream", - Compressible: false, - }, - "distz": { - ContentType: "application/octet-stream", - Compressible: false, - }, - "djv": { - ContentType: "image/vnd.djvu", - Compressible: false, - }, - "djvu": { - ContentType: "image/vnd.djvu", - Compressible: false, - }, - "dll": { - ContentType: "application/x-msdownload", - Compressible: false, - }, - "dmg": { - ContentType: "application/x-apple-diskimage", - Compressible: false, - }, - "dmp": { - ContentType: "application/vnd.tcpdump.pcap", - Compressible: false, - }, - "dms": { - ContentType: "application/octet-stream", - Compressible: false, - }, - "dna": { - ContentType: "application/vnd.dna", - Compressible: false, - }, - "doc": { - ContentType: "application/msword", - Compressible: false, - }, - "docm": { - ContentType: "application/vnd.ms-word.document.macroenabled.12", - Compressible: false, - }, - "docx": { - ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", - Compressible: false, - }, - "dot": { - ContentType: "application/msword", - Compressible: false, - }, - "dotm": { - ContentType: "application/vnd.ms-word.template.macroenabled.12", - Compressible: false, - }, - "dotx": { - ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.template", - Compressible: false, - }, - "dp": { - ContentType: "application/vnd.osgi.dp", - Compressible: false, - }, - "dpg": { - ContentType: "application/vnd.dpgraph", - Compressible: false, - }, - "dra": { - ContentType: "audio/vnd.dra", - Compressible: false, - }, - "drle": { - ContentType: "image/dicom-rle", - Compressible: false, - }, - "dsc": { - ContentType: "text/prs.lines.tag", - Compressible: false, - }, - "dssc": { - ContentType: "application/dssc+der", - Compressible: false, - }, - "dtb": { - ContentType: "application/x-dtbook+xml", - Compressible: false, - }, - "dtd": { - ContentType: "application/xml-dtd", - Compressible: false, - }, - "dts": { - ContentType: "audio/vnd.dts", - Compressible: false, - }, - "dtshd": { - ContentType: "audio/vnd.dts.hd", - Compressible: false, - }, - "dump": { - ContentType: "application/octet-stream", - Compressible: false, - }, - "dvb": { - ContentType: "video/vnd.dvb.file", - Compressible: false, - }, - "dvi": { - ContentType: "application/x-dvi", - Compressible: false, - }, - "dwf": { - ContentType: "model/vnd.dwf", - Compressible: false, - }, - "dwg": { - ContentType: "image/vnd.dwg", - Compressible: false, - }, - "dxf": { - ContentType: "image/vnd.dxf", - Compressible: false, - }, - "dxp": { - ContentType: "application/vnd.spotfire.dxp", - Compressible: false, - }, - "dxr": { - ContentType: "application/x-director", - Compressible: false, - }, - "ear": { - ContentType: "application/java-archive", - Compressible: false, - }, - "ecelp4800": { - ContentType: "audio/vnd.nuera.ecelp4800", - Compressible: false, - }, - "ecelp7470": { - ContentType: "audio/vnd.nuera.ecelp7470", - Compressible: false, - }, - "ecelp9600": { - ContentType: "audio/vnd.nuera.ecelp9600", - Compressible: false, - }, - "ecma": { - ContentType: "application/ecmascript", - Compressible: false, - }, - "edm": { - ContentType: "application/vnd.novadigm.edm", - Compressible: false, - }, - "edx": { - ContentType: "application/vnd.novadigm.edx", - Compressible: false, - }, - "efif": { - ContentType: "application/vnd.picsel", - Compressible: false, - }, - "ei6": { - ContentType: "application/vnd.pg.osasli", - Compressible: false, - }, - "elc": { - ContentType: "application/octet-stream", - Compressible: false, - }, - "emf": { - ContentType: "image/emf", - Compressible: false, - }, - "eml": { - ContentType: "message/rfc822", - Compressible: false, - }, - "emma": { - ContentType: "application/emma+xml", - Compressible: false, - }, - "emz": { - ContentType: "application/x-msmetafile", - Compressible: false, - }, - "eol": { - ContentType: "audio/vnd.digital-winds", - Compressible: false, - }, - "eot": { - ContentType: "application/vnd.ms-fontobject", - Compressible: false, - }, - "eps": { - ContentType: "application/postscript", - Compressible: false, - }, - "epub": { - ContentType: "application/epub+zip", - Compressible: false, - }, - "es": { - ContentType: "application/ecmascript", - Compressible: false, - }, - "es3": { - ContentType: "application/vnd.eszigno3+xml", - Compressible: false, - }, - "esa": { - ContentType: "application/vnd.osgi.subsystem", - Compressible: false, - }, - "esf": { - ContentType: "application/vnd.epson.esf", - Compressible: false, - }, - "et3": { - ContentType: "application/vnd.eszigno3+xml", - Compressible: false, - }, - "etx": { - ContentType: "text/x-setext", - Compressible: false, - }, - "eva": { - ContentType: "application/x-eva", - Compressible: false, - }, - "evy": { - ContentType: "application/x-envoy", - Compressible: false, - }, - "exe": { - ContentType: "application/x-msdownload", - Compressible: false, - }, - "exi": { - ContentType: "application/exi", - Compressible: false, - }, - "exr": { - ContentType: "image/aces", - Compressible: false, - }, - "ext": { - ContentType: "application/vnd.novadigm.ext", - Compressible: false, - }, - "ez": { - ContentType: "application/andrew-inset", - Compressible: false, - }, - "ez2": { - ContentType: "application/vnd.ezpix-album", - Compressible: false, - }, - "ez3": { - ContentType: "application/vnd.ezpix-package", - Compressible: false, - }, - "f": { - ContentType: "text/x-fortran", - Compressible: false, - }, - "f4v": { - ContentType: "video/x-f4v", - Compressible: false, - }, - "f77": { - ContentType: "text/x-fortran", - Compressible: false, - }, - "f90": { - ContentType: "text/x-fortran", - Compressible: false, - }, - "fbs": { - ContentType: "image/vnd.fastbidsheet", - Compressible: false, - }, - "fcdt": { - ContentType: "application/vnd.adobe.formscentral.fcdt", - Compressible: false, - }, - "fcs": { - ContentType: "application/vnd.isac.fcs", - Compressible: false, - }, - "fdf": { - ContentType: "application/vnd.fdf", - Compressible: false, - }, - "fe_launch": { - ContentType: "application/vnd.denovo.fcselayout-link", - Compressible: false, - }, - "fg5": { - ContentType: "application/vnd.fujitsu.oasysgp", - Compressible: false, - }, - "fgd": { - ContentType: "application/x-director", - Compressible: false, - }, - "fh": { - ContentType: "image/x-freehand", - Compressible: false, - }, - "fh4": { - ContentType: "image/x-freehand", - Compressible: false, - }, - "fh5": { - ContentType: "image/x-freehand", - Compressible: false, - }, - "fh7": { - ContentType: "image/x-freehand", - Compressible: false, - }, - "fhc": { - ContentType: "image/x-freehand", - Compressible: false, - }, - "fig": { - ContentType: "application/x-xfig", - Compressible: false, - }, - "fits": { - ContentType: "image/fits", - Compressible: false, - }, - "flac": { - ContentType: "audio/x-flac", - Compressible: false, - }, - "fli": { - ContentType: "video/x-fli", - Compressible: false, - }, - "flo": { - ContentType: "application/vnd.micrografx.flo", - Compressible: false, - }, - "flv": { - ContentType: "video/x-flv", - Compressible: false, - }, - "flw": { - ContentType: "application/vnd.kde.kivio", - Compressible: false, - }, - "flx": { - ContentType: "text/vnd.fmi.flexstor", - Compressible: false, - }, - "fly": { - ContentType: "text/vnd.fly", - Compressible: false, - }, - "fm": { - ContentType: "application/vnd.framemaker", - Compressible: false, - }, - "fnc": { - ContentType: "application/vnd.frogans.fnc", - Compressible: false, - }, - "for": { - ContentType: "text/x-fortran", - Compressible: false, - }, - "fpx": { - ContentType: "image/vnd.fpx", - Compressible: false, - }, - "frame": { - ContentType: "application/vnd.framemaker", - Compressible: false, - }, - "fsc": { - ContentType: "application/vnd.fsc.weblaunch", - Compressible: false, - }, - "fst": { - ContentType: "image/vnd.fst", - Compressible: false, - }, - "ftc": { - ContentType: "application/vnd.fluxtime.clip", - Compressible: false, - }, - "fti": { - ContentType: "application/vnd.anser-web-funds-transfer-initiation", - Compressible: false, - }, - "fvt": { - ContentType: "video/vnd.fvt", - Compressible: false, - }, - "fxp": { - ContentType: "application/vnd.adobe.fxp", - Compressible: false, - }, - "fxpl": { - ContentType: "application/vnd.adobe.fxp", - Compressible: false, - }, - "fzs": { - ContentType: "application/vnd.fuzzysheet", - Compressible: false, - }, - "g2w": { - ContentType: "application/vnd.geoplan", - Compressible: false, - }, - "g3": { - ContentType: "image/g3fax", - Compressible: false, - }, - "g3w": { - ContentType: "application/vnd.geospace", - Compressible: false, - }, - "gac": { - ContentType: "application/vnd.groove-account", - Compressible: false, - }, - "gam": { - ContentType: "application/x-tads", - Compressible: false, - }, - "gbr": { - ContentType: "application/rpki-ghostbusters", - Compressible: false, - }, - "gca": { - ContentType: "application/x-gca-compressed", - Compressible: false, - }, - "gdl": { - ContentType: "model/vnd.gdl", - Compressible: false, - }, - "gdoc": { - ContentType: "application/vnd.google-apps.document", - Compressible: false, - }, - "geo": { - ContentType: "application/vnd.dynageo", - Compressible: false, - }, - "geojson": { - ContentType: "application/geo+json", - Compressible: false, - }, - "gex": { - ContentType: "application/vnd.geometry-explorer", - Compressible: false, - }, - "ggb": { - ContentType: "application/vnd.geogebra.file", - Compressible: false, - }, - "ggt": { - ContentType: "application/vnd.geogebra.tool", - Compressible: false, - }, - "ghf": { - ContentType: "application/vnd.groove-help", - Compressible: false, - }, - "gif": { - ContentType: "image/gif", - Compressible: false, - }, - "gim": { - ContentType: "application/vnd.groove-identity-message", - Compressible: false, - }, - "glb": { - ContentType: "model/gltf-binary", - Compressible: false, - }, - "gltf": { - ContentType: "model/gltf+json", - Compressible: false, - }, - "gml": { - ContentType: "application/gml+xml", - Compressible: false, - }, - "gmx": { - ContentType: "application/vnd.gmx", - Compressible: false, - }, - "gnumeric": { - ContentType: "application/x-gnumeric", - Compressible: false, - }, - "gph": { - ContentType: "application/vnd.flographit", - Compressible: false, - }, - "gpx": { - ContentType: "application/gpx+xml", - Compressible: false, - }, - "gqf": { - ContentType: "application/vnd.grafeq", - Compressible: false, - }, - "gqs": { - ContentType: "application/vnd.grafeq", - Compressible: false, - }, - "gram": { - ContentType: "application/srgs", - Compressible: false, - }, - "gramps": { - ContentType: "application/x-gramps-xml", - Compressible: false, - }, - "gre": { - ContentType: "application/vnd.geometry-explorer", - Compressible: false, - }, - "grv": { - ContentType: "application/vnd.groove-injector", - Compressible: false, - }, - "grxml": { - ContentType: "application/srgs+xml", - Compressible: false, - }, - "gsf": { - ContentType: "application/x-font-ghostscript", - Compressible: false, - }, - "gsheet": { - ContentType: "application/vnd.google-apps.spreadsheet", - Compressible: false, - }, - "gslides": { - ContentType: "application/vnd.google-apps.presentation", - Compressible: false, - }, - "gtar": { - ContentType: "application/x-gtar", - Compressible: false, - }, - "gtm": { - ContentType: "application/vnd.groove-tool-message", - Compressible: false, - }, - "gtw": { - ContentType: "model/vnd.gtw", - Compressible: false, - }, - "gv": { - ContentType: "text/vnd.graphviz", - Compressible: false, - }, - "gxf": { - ContentType: "application/gxf", - Compressible: false, - }, - "gxt": { - ContentType: "application/vnd.geonext", - Compressible: false, - }, - "gz": { - ContentType: "application/gzip", - Compressible: false, - }, - "h": { - ContentType: "text/x-c", - Compressible: false, - }, - "h261": { - ContentType: "video/h261", - Compressible: false, - }, - "h263": { - ContentType: "video/h263", - Compressible: false, - }, - "h264": { - ContentType: "video/h264", - Compressible: false, - }, - "hal": { - ContentType: "application/vnd.hal+xml", - Compressible: false, - }, - "hbci": { - ContentType: "application/vnd.hbci", - Compressible: false, - }, - "hbs": { - ContentType: "text/x-handlebars-template", - Compressible: false, - }, - "hdd": { - ContentType: "application/x-virtualbox-hdd", - Compressible: false, - }, - "hdf": { - ContentType: "application/x-hdf", - Compressible: false, - }, - "heic": { - ContentType: "image/heic", - Compressible: false, - }, - "heics": { - ContentType: "image/heic-sequence", - Compressible: false, - }, - "heif": { - ContentType: "image/heif", - Compressible: false, - }, - "heifs": { - ContentType: "image/heif-sequence", - Compressible: false, - }, - "hh": { - ContentType: "text/x-c", - Compressible: false, - }, - "hjson": { - ContentType: "application/hjson", - Compressible: false, - }, - "hlp": { - ContentType: "application/winhlp", - Compressible: false, - }, - "hpgl": { - ContentType: "application/vnd.hp-hpgl", - Compressible: false, - }, - "hpid": { - ContentType: "application/vnd.hp-hpid", - Compressible: false, - }, - "hps": { - ContentType: "application/vnd.hp-hps", - Compressible: false, - }, - "hqx": { - ContentType: "application/mac-binhex40", - Compressible: false, - }, - "htc": { - ContentType: "text/x-component", - Compressible: false, - }, - "htke": { - ContentType: "application/vnd.kenameaapp", - Compressible: false, - }, - "htm": { - ContentType: "text/html", - Compressible: false, - }, - "html": { - ContentType: "text/html", - Compressible: false, - }, - "hvd": { - ContentType: "application/vnd.yamaha.hv-dic", - Compressible: false, - }, - "hvp": { - ContentType: "application/vnd.yamaha.hv-voice", - Compressible: false, - }, - "hvs": { - ContentType: "application/vnd.yamaha.hv-script", - Compressible: false, - }, - "i2g": { - ContentType: "application/vnd.intergeo", - Compressible: false, - }, - "icc": { - ContentType: "application/vnd.iccprofile", - Compressible: false, - }, - "ice": { - ContentType: "x-conference/x-cooltalk", - Compressible: false, - }, - "icm": { - ContentType: "application/vnd.iccprofile", - Compressible: false, - }, - "ico": { - ContentType: "image/x-icon", - Compressible: false, - }, - "ics": { - ContentType: "text/calendar", - Compressible: false, - }, - "ief": { - ContentType: "image/ief", - Compressible: false, - }, - "ifb": { - ContentType: "text/calendar", - Compressible: false, - }, - "ifm": { - ContentType: "application/vnd.shana.informed.formdata", - Compressible: false, - }, - "iges": { - ContentType: "model/iges", - Compressible: false, - }, - "igl": { - ContentType: "application/vnd.igloader", - Compressible: false, - }, - "igm": { - ContentType: "application/vnd.insors.igm", - Compressible: false, - }, - "igs": { - ContentType: "model/iges", - Compressible: false, - }, - "igx": { - ContentType: "application/vnd.micrografx.igx", - Compressible: false, - }, - "iif": { - ContentType: "application/vnd.shana.informed.interchange", - Compressible: false, - }, - "img": { - ContentType: "application/octet-stream", - Compressible: false, - }, - "imp": { - ContentType: "application/vnd.accpac.simply.imp", - Compressible: false, - }, - "ims": { - ContentType: "application/vnd.ms-ims", - Compressible: false, - }, - "in": { - ContentType: "text/plain", - Compressible: false, - }, - "ini": { - ContentType: "text/plain", - Compressible: false, - }, - "ink": { - ContentType: "application/inkml+xml", - Compressible: false, - }, - "inkml": { - ContentType: "application/inkml+xml", - Compressible: false, - }, - "install": { - ContentType: "application/x-install-instructions", - Compressible: false, - }, - "iota": { - ContentType: "application/vnd.astraea-software.iota", - Compressible: false, - }, - "ipfix": { - ContentType: "application/ipfix", - Compressible: false, - }, - "ipk": { - ContentType: "application/vnd.shana.informed.package", - Compressible: false, - }, - "irm": { - ContentType: "application/vnd.ibm.rights-management", - Compressible: false, - }, - "irp": { - ContentType: "application/vnd.irepository.package+xml", - Compressible: false, - }, - "iso": { - ContentType: "application/x-iso9660-image", - Compressible: false, - }, - "itp": { - ContentType: "application/vnd.shana.informed.formtemplate", - Compressible: false, - }, - "ivp": { - ContentType: "application/vnd.immervision-ivp", - Compressible: false, - }, - "ivu": { - ContentType: "application/vnd.immervision-ivu", - Compressible: false, - }, - "jad": { - ContentType: "text/vnd.sun.j2me.app-descriptor", - Compressible: false, - }, - "jade": { - ContentType: "text/jade", - Compressible: false, - }, - "jam": { - ContentType: "application/vnd.jam", - Compressible: false, - }, - "jar": { - ContentType: "application/java-archive", - Compressible: false, - }, - "jardiff": { - ContentType: "application/x-java-archive-diff", - Compressible: false, - }, - "java": { - ContentType: "text/x-java-source", - Compressible: false, - }, - "jisp": { - ContentType: "application/vnd.jisp", - Compressible: false, - }, - "jls": { - ContentType: "image/jls", - Compressible: false, - }, - "jlt": { - ContentType: "application/vnd.hp-jlyt", - Compressible: false, - }, - "jng": { - ContentType: "image/x-jng", - Compressible: false, - }, - "jnlp": { - ContentType: "application/x-java-jnlp-file", - Compressible: false, - }, - "joda": { - ContentType: "application/vnd.joost.joda-archive", - Compressible: false, - }, - "jp2": { - ContentType: "image/jp2", - Compressible: false, - }, - "jpe": { - ContentType: "image/jpeg", - Compressible: false, - }, - "jpeg": { - ContentType: "image/jpeg", - Compressible: false, - }, - "jpf": { - ContentType: "image/jpx", - Compressible: false, - }, - "jpg": { - ContentType: "image/jpeg", - Compressible: false, - }, - "jpg2": { - ContentType: "image/jp2", - Compressible: false, - }, - "jpgm": { - ContentType: "video/jpm", - Compressible: false, - }, - "jpgv": { - ContentType: "video/jpeg", - Compressible: false, - }, - "jpm": { - ContentType: "video/jpm", - Compressible: false, - }, - "jpx": { - ContentType: "image/jpx", - Compressible: false, - }, - "js": { - ContentType: "application/javascript", - Compressible: false, - }, - "json": { - ContentType: "application/json", - Compressible: false, - }, - "json5": { - ContentType: "application/json5", - Compressible: false, - }, - "jsonld": { - ContentType: "application/ld+json", - Compressible: false, - }, - "jsonml": { - ContentType: "application/jsonml+json", - Compressible: false, - }, - "jsx": { - ContentType: "text/jsx", - Compressible: false, - }, - "kar": { - ContentType: "audio/midi", - Compressible: false, - }, - "karbon": { - ContentType: "application/vnd.kde.karbon", - Compressible: false, - }, - "keynote": { - ContentType: "application/vnd.apple.keynote", - Compressible: false, - }, - "kfo": { - ContentType: "application/vnd.kde.kformula", - Compressible: false, - }, - "kia": { - ContentType: "application/vnd.kidspiration", - Compressible: false, - }, - "kml": { - ContentType: "application/vnd.google-earth.kml+xml", - Compressible: false, - }, - "kmz": { - ContentType: "application/vnd.google-earth.kmz", - Compressible: false, - }, - "kne": { - ContentType: "application/vnd.kinar", - Compressible: false, - }, - "knp": { - ContentType: "application/vnd.kinar", - Compressible: false, - }, - "kon": { - ContentType: "application/vnd.kde.kontour", - Compressible: false, - }, - "kpr": { - ContentType: "application/vnd.kde.kpresenter", - Compressible: false, - }, - "kpt": { - ContentType: "application/vnd.kde.kpresenter", - Compressible: false, - }, - "kpxx": { - ContentType: "application/vnd.ds-keypoint", - Compressible: false, - }, - "ksp": { - ContentType: "application/vnd.kde.kspread", - Compressible: false, - }, - "ktr": { - ContentType: "application/vnd.kahootz", - Compressible: false, - }, - "ktx": { - ContentType: "image/ktx", - Compressible: false, - }, - "ktz": { - ContentType: "application/vnd.kahootz", - Compressible: false, - }, - "kwd": { - ContentType: "application/vnd.kde.kword", - Compressible: false, - }, - "kwt": { - ContentType: "application/vnd.kde.kword", - Compressible: false, - }, - "lasxml": { - ContentType: "application/vnd.las.las+xml", - Compressible: false, - }, - "latex": { - ContentType: "application/x-latex", - Compressible: false, - }, - "lbd": { - ContentType: "application/vnd.llamagraphics.life-balance.desktop", - Compressible: false, - }, - "lbe": { - ContentType: "application/vnd.llamagraphics.life-balance.exchange+xml", - Compressible: false, - }, - "les": { - ContentType: "application/vnd.hhe.lesson-player", - Compressible: false, - }, - "less": { - ContentType: "text/less", - Compressible: false, - }, - "lha": { - ContentType: "application/x-lzh-compressed", - Compressible: false, - }, - "link66": { - ContentType: "application/vnd.route66.link66+xml", - Compressible: false, - }, - "list": { - ContentType: "text/plain", - Compressible: false, - }, - "list3820": { - ContentType: "application/vnd.ibm.modcap", - Compressible: false, - }, - "listafp": { - ContentType: "application/vnd.ibm.modcap", - Compressible: false, - }, - "litcoffee": { - ContentType: "text/coffeescript", - Compressible: false, - }, - "lnk": { - ContentType: "application/x-ms-shortcut", - Compressible: false, - }, - "log": { - ContentType: "text/plain", - Compressible: false, - }, - "lostxml": { - ContentType: "application/lost+xml", - Compressible: false, - }, - "lrf": { - ContentType: "application/octet-stream", - Compressible: false, - }, - "lrm": { - ContentType: "application/vnd.ms-lrm", - Compressible: false, - }, - "ltf": { - ContentType: "application/vnd.frogans.ltf", - Compressible: false, - }, - "lua": { - ContentType: "text/x-lua", - Compressible: false, - }, - "luac": { - ContentType: "application/x-lua-bytecode", - Compressible: false, - }, - "lvp": { - ContentType: "audio/vnd.lucent.voice", - Compressible: false, - }, - "lwp": { - ContentType: "application/vnd.lotus-wordpro", - Compressible: false, - }, - "lzh": { - ContentType: "application/x-lzh-compressed", - Compressible: false, - }, - "m13": { - ContentType: "application/x-msmediaview", - Compressible: false, - }, - "m14": { - ContentType: "application/x-msmediaview", - Compressible: false, - }, - "m1v": { - ContentType: "video/mpeg", - Compressible: false, - }, - "m21": { - ContentType: "application/mp21", - Compressible: false, - }, - "m2a": { - ContentType: "audio/mpeg", - Compressible: false, - }, - "m2v": { - ContentType: "video/mpeg", - Compressible: false, - }, - "m3a": { - ContentType: "audio/mpeg", - Compressible: false, - }, - "m3u": { - ContentType: "audio/x-mpegurl", - Compressible: false, - }, - "m3u8": { - ContentType: "application/vnd.apple.mpegurl", - Compressible: false, - }, - "m4a": { - ContentType: "audio/x-m4a", - Compressible: false, - }, - "m4p": { - ContentType: "application/mp4", - Compressible: false, - }, - "m4u": { - ContentType: "video/vnd.mpegurl", - Compressible: false, - }, - "m4v": { - ContentType: "video/x-m4v", - Compressible: false, - }, - "ma": { - ContentType: "application/mathematica", - Compressible: false, - }, - "mads": { - ContentType: "application/mads+xml", - Compressible: false, - }, - "mag": { - ContentType: "application/vnd.ecowin.chart", - Compressible: false, - }, - "maker": { - ContentType: "application/vnd.framemaker", - Compressible: false, - }, - "man": { - ContentType: "text/troff", - Compressible: false, - }, - "manifest": { - ContentType: "text/cache-manifest", - Compressible: false, - }, - "map": { - ContentType: "application/json", - Compressible: false, - }, - "mar": { - ContentType: "application/octet-stream", - Compressible: false, - }, - "markdown": { - ContentType: "text/markdown", - Compressible: false, - }, - "mathml": { - ContentType: "application/mathml+xml", - Compressible: false, - }, - "mb": { - ContentType: "application/mathematica", - Compressible: false, - }, - "mbk": { - ContentType: "application/vnd.mobius.mbk", - Compressible: false, - }, - "mbox": { - ContentType: "application/mbox", - Compressible: false, - }, - "mc1": { - ContentType: "application/vnd.medcalcdata", - Compressible: false, - }, - "mcd": { - ContentType: "application/vnd.mcd", - Compressible: false, - }, - "mcurl": { - ContentType: "text/vnd.curl.mcurl", - Compressible: false, - }, - "md": { - ContentType: "text/markdown", - Compressible: false, - }, - "mdb": { - ContentType: "application/x-msaccess", - Compressible: false, - }, - "mdi": { - ContentType: "image/vnd.ms-modi", - Compressible: false, - }, - "me": { - ContentType: "text/troff", - Compressible: false, - }, - "mesh": { - ContentType: "model/mesh", - Compressible: false, - }, - "meta4": { - ContentType: "application/metalink4+xml", - Compressible: false, - }, - "metalink": { - ContentType: "application/metalink+xml", - Compressible: false, - }, - "mets": { - ContentType: "application/mets+xml", - Compressible: false, - }, - "mfm": { - ContentType: "application/vnd.mfmp", - Compressible: false, - }, - "mft": { - ContentType: "application/rpki-manifest", - Compressible: false, - }, - "mgp": { - ContentType: "application/vnd.osgeo.mapguide.package", - Compressible: false, - }, - "mgz": { - ContentType: "application/vnd.proteus.magazine", - Compressible: false, - }, - "mid": { - ContentType: "audio/midi", - Compressible: false, - }, - "midi": { - ContentType: "audio/midi", - Compressible: false, - }, - "mie": { - ContentType: "application/x-mie", - Compressible: false, - }, - "mif": { - ContentType: "application/vnd.mif", - Compressible: false, - }, - "mime": { - ContentType: "message/rfc822", - Compressible: false, - }, - "mj2": { - ContentType: "video/mj2", - Compressible: false, - }, - "mjp2": { - ContentType: "video/mj2", - Compressible: false, - }, - "mjs": { - ContentType: "application/javascript", - Compressible: false, - }, - "mk3d": { - ContentType: "video/x-matroska", - Compressible: false, - }, - "mka": { - ContentType: "audio/x-matroska", - Compressible: false, - }, - "mkd": { - ContentType: "text/x-markdown", - Compressible: false, - }, - "mks": { - ContentType: "video/x-matroska", - Compressible: false, - }, - "mkv": { - ContentType: "video/x-matroska", - Compressible: false, - }, - "mlp": { - ContentType: "application/vnd.dolby.mlp", - Compressible: false, - }, - "mmd": { - ContentType: "application/vnd.chipnuts.karaoke-mmd", - Compressible: false, - }, - "mmf": { - ContentType: "application/vnd.smaf", - Compressible: false, - }, - "mml": { - ContentType: "text/mathml", - Compressible: false, - }, - "mmr": { - ContentType: "image/vnd.fujixerox.edmics-mmr", - Compressible: false, - }, - "mng": { - ContentType: "video/x-mng", - Compressible: false, - }, - "mny": { - ContentType: "application/x-msmoney", - Compressible: false, - }, - "mobi": { - ContentType: "application/x-mobipocket-ebook", - Compressible: false, - }, - "mods": { - ContentType: "application/mods+xml", - Compressible: false, - }, - "mov": { - ContentType: "video/quicktime", - Compressible: false, - }, - "movie": { - ContentType: "video/x-sgi-movie", - Compressible: false, - }, - "mp2": { - ContentType: "audio/mpeg", - Compressible: false, - }, - "mp21": { - ContentType: "application/mp21", - Compressible: false, - }, - "mp2a": { - ContentType: "audio/mpeg", - Compressible: false, - }, - "mp3": { - ContentType: "audio/mpeg", - Compressible: false, - }, - "mp4": { - ContentType: "video/mp4", - Compressible: false, - }, - "mp4a": { - ContentType: "audio/mp4", - Compressible: false, - }, - "mp4s": { - ContentType: "application/mp4", - Compressible: false, - }, - "mp4v": { - ContentType: "video/mp4", - Compressible: false, - }, - "mpc": { - ContentType: "application/vnd.mophun.certificate", - Compressible: false, - }, - "mpd": { - ContentType: "application/dash+xml", - Compressible: false, - }, - "mpe": { - ContentType: "video/mpeg", - Compressible: false, - }, - "mpeg": { - ContentType: "video/mpeg", - Compressible: false, - }, - "mpg": { - ContentType: "video/mpeg", - Compressible: false, - }, - "mpg4": { - ContentType: "video/mp4", - Compressible: false, - }, - "mpga": { - ContentType: "audio/mpeg", - Compressible: false, - }, - "mpkg": { - ContentType: "application/vnd.apple.installer+xml", - Compressible: false, - }, - "mpm": { - ContentType: "application/vnd.blueice.multipass", - Compressible: false, - }, - "mpn": { - ContentType: "application/vnd.mophun.application", - Compressible: false, - }, - "mpp": { - ContentType: "application/vnd.ms-project", - Compressible: false, - }, - "mpt": { - ContentType: "application/vnd.ms-project", - Compressible: false, - }, - "mpy": { - ContentType: "application/vnd.ibm.minipay", - Compressible: false, - }, - "mqy": { - ContentType: "application/vnd.mobius.mqy", - Compressible: false, - }, - "mrc": { - ContentType: "application/marc", - Compressible: false, - }, - "mrcx": { - ContentType: "application/marcxml+xml", - Compressible: false, - }, - "ms": { - ContentType: "text/troff", - Compressible: false, - }, - "mscml": { - ContentType: "application/mediaservercontrol+xml", - Compressible: false, - }, - "mseed": { - ContentType: "application/vnd.fdsn.mseed", - Compressible: false, - }, - "mseq": { - ContentType: "application/vnd.mseq", - Compressible: false, - }, - "msf": { - ContentType: "application/vnd.epson.msf", - Compressible: false, - }, - "msg": { - ContentType: "application/vnd.ms-outlook", - Compressible: false, - }, - "msh": { - ContentType: "model/mesh", - Compressible: false, - }, - "msi": { - ContentType: "application/x-msdownload", - Compressible: false, - }, - "msl": { - ContentType: "application/vnd.mobius.msl", - Compressible: false, - }, - "msm": { - ContentType: "application/octet-stream", - Compressible: false, - }, - "msp": { - ContentType: "application/octet-stream", - Compressible: false, - }, - "msty": { - ContentType: "application/vnd.muvee.style", - Compressible: false, - }, - "mts": { - ContentType: "model/vnd.mts", - Compressible: false, - }, - "mus": { - ContentType: "application/vnd.musician", - Compressible: false, - }, - "musicxml": { - ContentType: "application/vnd.recordare.musicxml+xml", - Compressible: false, - }, - "mvb": { - ContentType: "application/x-msmediaview", - Compressible: false, - }, - "mwf": { - ContentType: "application/vnd.mfer", - Compressible: false, - }, - "mxf": { - ContentType: "application/mxf", - Compressible: false, - }, - "mxl": { - ContentType: "application/vnd.recordare.musicxml", - Compressible: false, - }, - "mxml": { - ContentType: "application/xv+xml", - Compressible: false, - }, - "mxs": { - ContentType: "application/vnd.triscape.mxs", - Compressible: false, - }, - "mxu": { - ContentType: "video/vnd.mpegurl", - Compressible: false, - }, - "n-gage": { - ContentType: "application/vnd.nokia.n-gage.symbian.install", - Compressible: false, - }, - "n3": { - ContentType: "text/n3", - Compressible: false, - }, - "nb": { - ContentType: "application/mathematica", - Compressible: false, - }, - "nbp": { - ContentType: "application/vnd.wolfram.player", - Compressible: false, - }, - "nc": { - ContentType: "application/x-netcdf", - Compressible: false, - }, - "ncx": { - ContentType: "application/x-dtbncx+xml", - Compressible: false, - }, - "nfo": { - ContentType: "text/x-nfo", - Compressible: false, - }, - "ngdat": { - ContentType: "application/vnd.nokia.n-gage.data", - Compressible: false, - }, - "nitf": { - ContentType: "application/vnd.nitf", - Compressible: false, - }, - "nlu": { - ContentType: "application/vnd.neurolanguage.nlu", - Compressible: false, - }, - "nml": { - ContentType: "application/vnd.enliven", - Compressible: false, - }, - "nnd": { - ContentType: "application/vnd.noblenet-directory", - Compressible: false, - }, - "nns": { - ContentType: "application/vnd.noblenet-sealer", - Compressible: false, - }, - "nnw": { - ContentType: "application/vnd.noblenet-web", - Compressible: false, - }, - "npx": { - ContentType: "image/vnd.net-fpx", - Compressible: false, - }, - "nsc": { - ContentType: "application/x-conference", - Compressible: false, - }, - "nsf": { - ContentType: "application/vnd.lotus-notes", - Compressible: false, - }, - "ntf": { - ContentType: "application/vnd.nitf", - Compressible: false, - }, - "numbers": { - ContentType: "application/vnd.apple.numbers", - Compressible: false, - }, - "nzb": { - ContentType: "application/x-nzb", - Compressible: false, - }, - "oa2": { - ContentType: "application/vnd.fujitsu.oasys2", - Compressible: false, - }, - "oa3": { - ContentType: "application/vnd.fujitsu.oasys3", - Compressible: false, - }, - "oas": { - ContentType: "application/vnd.fujitsu.oasys", - Compressible: false, - }, - "obd": { - ContentType: "application/x-msbinder", - Compressible: false, - }, - "obj": { - ContentType: "application/x-tgif", - Compressible: false, - }, - "oda": { - ContentType: "application/oda", - Compressible: false, - }, - "odb": { - ContentType: "application/vnd.oasis.opendocument.database", - Compressible: false, - }, - "odc": { - ContentType: "application/vnd.oasis.opendocument.chart", - Compressible: false, - }, - "odf": { - ContentType: "application/vnd.oasis.opendocument.formula", - Compressible: false, - }, - "odft": { - ContentType: "application/vnd.oasis.opendocument.formula-template", - Compressible: false, - }, - "odg": { - ContentType: "application/vnd.oasis.opendocument.graphics", - Compressible: false, - }, - "odi": { - ContentType: "application/vnd.oasis.opendocument.image", - Compressible: false, - }, - "odm": { - ContentType: "application/vnd.oasis.opendocument.text-master", - Compressible: false, - }, - "odp": { - ContentType: "application/vnd.oasis.opendocument.presentation", - Compressible: false, - }, - "ods": { - ContentType: "application/vnd.oasis.opendocument.spreadsheet", - Compressible: false, - }, - "odt": { - ContentType: "application/vnd.oasis.opendocument.text", - Compressible: false, - }, - "oga": { - ContentType: "audio/ogg", - Compressible: false, - }, - "ogg": { - ContentType: "audio/ogg", - Compressible: false, - }, - "ogv": { - ContentType: "video/ogg", - Compressible: false, - }, - "ogx": { - ContentType: "application/ogg", - Compressible: false, - }, - "omdoc": { - ContentType: "application/omdoc+xml", - Compressible: false, - }, - "onepkg": { - ContentType: "application/onenote", - Compressible: false, - }, - "onetmp": { - ContentType: "application/onenote", - Compressible: false, - }, - "onetoc": { - ContentType: "application/onenote", - Compressible: false, - }, - "onetoc2": { - ContentType: "application/onenote", - Compressible: false, - }, - "opf": { - ContentType: "application/oebps-package+xml", - Compressible: false, - }, - "opml": { - ContentType: "text/x-opml", - Compressible: false, - }, - "oprc": { - ContentType: "application/vnd.palm", - Compressible: false, - }, - "org": { - ContentType: "text/x-org", - Compressible: false, - }, - "osf": { - ContentType: "application/vnd.yamaha.openscoreformat", - Compressible: false, - }, - "osfpvg": { - ContentType: "application/vnd.yamaha.openscoreformat.osfpvg+xml", - Compressible: false, - }, - "otc": { - ContentType: "application/vnd.oasis.opendocument.chart-template", - Compressible: false, - }, - "otf": { - ContentType: "font/otf", - Compressible: false, - }, - "otg": { - ContentType: "application/vnd.oasis.opendocument.graphics-template", - Compressible: false, - }, - "oth": { - ContentType: "application/vnd.oasis.opendocument.text-web", - Compressible: false, - }, - "oti": { - ContentType: "application/vnd.oasis.opendocument.image-template", - Compressible: false, - }, - "otp": { - ContentType: "application/vnd.oasis.opendocument.presentation-template", - Compressible: false, - }, - "ots": { - ContentType: "application/vnd.oasis.opendocument.spreadsheet-template", - Compressible: false, - }, - "ott": { - ContentType: "application/vnd.oasis.opendocument.text-template", - Compressible: false, - }, - "ova": { - ContentType: "application/x-virtualbox-ova", - Compressible: false, - }, - "ovf": { - ContentType: "application/x-virtualbox-ovf", - Compressible: false, - }, - "owl": { - ContentType: "application/rdf+xml", - Compressible: false, - }, - "oxps": { - ContentType: "application/oxps", - Compressible: false, - }, - "oxt": { - ContentType: "application/vnd.openofficeorg.extension", - Compressible: false, - }, - "p": { - ContentType: "text/x-pascal", - Compressible: false, - }, - "p10": { - ContentType: "application/pkcs10", - Compressible: false, - }, - "p12": { - ContentType: "application/x-pkcs12", - Compressible: false, - }, - "p7b": { - ContentType: "application/x-pkcs7-certificates", - Compressible: false, - }, - "p7c": { - ContentType: "application/pkcs7-mime", - Compressible: false, - }, - "p7m": { - ContentType: "application/pkcs7-mime", - Compressible: false, - }, - "p7r": { - ContentType: "application/x-pkcs7-certreqresp", - Compressible: false, - }, - "p7s": { - ContentType: "application/pkcs7-signature", - Compressible: false, - }, - "p8": { - ContentType: "application/pkcs8", - Compressible: false, - }, - "pac": { - ContentType: "application/x-ns-proxy-autoconfig", - Compressible: false, - }, - "pages": { - ContentType: "application/vnd.apple.pages", - Compressible: false, - }, - "pas": { - ContentType: "text/x-pascal", - Compressible: false, - }, - "paw": { - ContentType: "application/vnd.pawaafile", - Compressible: false, - }, - "pbd": { - ContentType: "application/vnd.powerbuilder6", - Compressible: false, - }, - "pbm": { - ContentType: "image/x-portable-bitmap", - Compressible: false, - }, - "pcap": { - ContentType: "application/vnd.tcpdump.pcap", - Compressible: false, - }, - "pcf": { - ContentType: "application/x-font-pcf", - Compressible: false, - }, - "pcl": { - ContentType: "application/vnd.hp-pcl", - Compressible: false, - }, - "pclxl": { - ContentType: "application/vnd.hp-pclxl", - Compressible: false, - }, - "pct": { - ContentType: "image/x-pict", - Compressible: false, - }, - "pcurl": { - ContentType: "application/vnd.curl.pcurl", - Compressible: false, - }, - "pcx": { - ContentType: "image/x-pcx", - Compressible: false, - }, - "pdb": { - ContentType: "application/x-pilot", - Compressible: false, - }, - "pde": { - ContentType: "text/x-processing", - Compressible: false, - }, - "pdf": { - ContentType: "application/pdf", - Compressible: false, - }, - "pem": { - ContentType: "application/x-x509-ca-cert", - Compressible: false, - }, - "pfa": { - ContentType: "application/x-font-type1", - Compressible: false, - }, - "pfb": { - ContentType: "application/x-font-type1", - Compressible: false, - }, - "pfm": { - ContentType: "application/x-font-type1", - Compressible: false, - }, - "pfr": { - ContentType: "application/font-tdpfr", - Compressible: false, - }, - "pfx": { - ContentType: "application/x-pkcs12", - Compressible: false, - }, - "pgm": { - ContentType: "image/x-portable-graymap", - Compressible: false, - }, - "pgn": { - ContentType: "application/x-chess-pgn", - Compressible: false, - }, - "pgp": { - ContentType: "application/pgp-encrypted", - Compressible: false, - }, - "php": { - ContentType: "application/x-httpd-php", - Compressible: false, - }, - "pic": { - ContentType: "image/x-pict", - Compressible: false, - }, - "pkg": { - ContentType: "application/octet-stream", - Compressible: false, - }, - "pki": { - ContentType: "application/pkixcmp", - Compressible: false, - }, - "pkipath": { - ContentType: "application/pkix-pkipath", - Compressible: false, - }, - "pkpass": { - ContentType: "application/vnd.apple.pkpass", - Compressible: false, - }, - "pl": { - ContentType: "application/x-perl", - Compressible: false, - }, - "plb": { - ContentType: "application/vnd.3gpp.pic-bw-large", - Compressible: false, - }, - "plc": { - ContentType: "application/vnd.mobius.plc", - Compressible: false, - }, - "plf": { - ContentType: "application/vnd.pocketlearn", - Compressible: false, - }, - "pls": { - ContentType: "application/pls+xml", - Compressible: false, - }, - "pm": { - ContentType: "application/x-perl", - Compressible: false, - }, - "pml": { - ContentType: "application/vnd.ctc-posml", - Compressible: false, - }, - "png": { - ContentType: "image/png", - Compressible: false, - }, - "pnm": { - ContentType: "image/x-portable-anymap", - Compressible: false, - }, - "portpkg": { - ContentType: "application/vnd.macports.portpkg", - Compressible: false, - }, - "pot": { - ContentType: "application/vnd.ms-powerpoint", - Compressible: false, - }, - "potm": { - ContentType: "application/vnd.ms-powerpoint.template.macroenabled.12", - Compressible: false, - }, - "potx": { - ContentType: "application/vnd.openxmlformats-officedocument.presentationml.template", - Compressible: false, - }, - "ppam": { - ContentType: "application/vnd.ms-powerpoint.addin.macroenabled.12", - Compressible: false, - }, - "ppd": { - ContentType: "application/vnd.cups-ppd", - Compressible: false, - }, - "ppm": { - ContentType: "image/x-portable-pixmap", - Compressible: false, - }, - "pps": { - ContentType: "application/vnd.ms-powerpoint", - Compressible: false, - }, - "ppsm": { - ContentType: "application/vnd.ms-powerpoint.slideshow.macroenabled.12", - Compressible: false, - }, - "ppsx": { - ContentType: "application/vnd.openxmlformats-officedocument.presentationml.slideshow", - Compressible: false, - }, - "ppt": { - ContentType: "application/vnd.ms-powerpoint", - Compressible: false, - }, - "pptm": { - ContentType: "application/vnd.ms-powerpoint.presentation.macroenabled.12", - Compressible: false, - }, - "pptx": { - ContentType: "application/vnd.openxmlformats-officedocument.presentationml.presentation", - Compressible: false, - }, - "pqa": { - ContentType: "application/vnd.palm", - Compressible: false, - }, - "prc": { - ContentType: "application/x-pilot", - Compressible: false, - }, - "pre": { - ContentType: "application/vnd.lotus-freelance", - Compressible: false, - }, - "prf": { - ContentType: "application/pics-rules", - Compressible: false, - }, - "ps": { - ContentType: "application/postscript", - Compressible: false, - }, - "psb": { - ContentType: "application/vnd.3gpp.pic-bw-small", - Compressible: false, - }, - "psd": { - ContentType: "image/vnd.adobe.photoshop", - Compressible: false, - }, - "psf": { - ContentType: "application/x-font-linux-psf", - Compressible: false, - }, - "pskcxml": { - ContentType: "application/pskc+xml", - Compressible: false, - }, - "pti": { - ContentType: "image/prs.pti", - Compressible: false, - }, - "ptid": { - ContentType: "application/vnd.pvi.ptid1", - Compressible: false, - }, - "pub": { - ContentType: "application/x-mspublisher", - Compressible: false, - }, - "pvb": { - ContentType: "application/vnd.3gpp.pic-bw-var", - Compressible: false, - }, - "pwn": { - ContentType: "application/vnd.3m.post-it-notes", - Compressible: false, - }, - "pya": { - ContentType: "audio/vnd.ms-playready.media.pya", - Compressible: false, - }, - "pyv": { - ContentType: "video/vnd.ms-playready.media.pyv", - Compressible: false, - }, - "qam": { - ContentType: "application/vnd.epson.quickanime", - Compressible: false, - }, - "qbo": { - ContentType: "application/vnd.intu.qbo", - Compressible: false, - }, - "qfx": { - ContentType: "application/vnd.intu.qfx", - Compressible: false, - }, - "qps": { - ContentType: "application/vnd.publishare-delta-tree", - Compressible: false, - }, - "qt": { - ContentType: "video/quicktime", - Compressible: false, - }, - "qwd": { - ContentType: "application/vnd.quark.quarkxpress", - Compressible: false, - }, - "qwt": { - ContentType: "application/vnd.quark.quarkxpress", - Compressible: false, - }, - "qxb": { - ContentType: "application/vnd.quark.quarkxpress", - Compressible: false, - }, - "qxd": { - ContentType: "application/vnd.quark.quarkxpress", - Compressible: false, - }, - "qxl": { - ContentType: "application/vnd.quark.quarkxpress", - Compressible: false, - }, - "qxt": { - ContentType: "application/vnd.quark.quarkxpress", - Compressible: false, - }, - "ra": { - ContentType: "audio/x-realaudio", - Compressible: false, - }, - "ram": { - ContentType: "audio/x-pn-realaudio", - Compressible: false, - }, - "raml": { - ContentType: "application/raml+yaml", - Compressible: false, - }, - "rar": { - ContentType: "application/x-rar-compressed", - Compressible: false, - }, - "ras": { - ContentType: "image/x-cmu-raster", - Compressible: false, - }, - "rcprofile": { - ContentType: "application/vnd.ipunplugged.rcprofile", - Compressible: false, - }, - "rdf": { - ContentType: "application/rdf+xml", - Compressible: false, - }, - "rdz": { - ContentType: "application/vnd.data-vision.rdz", - Compressible: false, - }, - "rep": { - ContentType: "application/vnd.businessobjects", - Compressible: false, - }, - "res": { - ContentType: "application/x-dtbresource+xml", - Compressible: false, - }, - "rgb": { - ContentType: "image/x-rgb", - Compressible: false, - }, - "rif": { - ContentType: "application/reginfo+xml", - Compressible: false, - }, - "rip": { - ContentType: "audio/vnd.rip", - Compressible: false, - }, - "ris": { - ContentType: "application/x-research-info-systems", - Compressible: false, - }, - "rl": { - ContentType: "application/resource-lists+xml", - Compressible: false, - }, - "rlc": { - ContentType: "image/vnd.fujixerox.edmics-rlc", - Compressible: false, - }, - "rld": { - ContentType: "application/resource-lists-diff+xml", - Compressible: false, - }, - "rm": { - ContentType: "application/vnd.rn-realmedia", - Compressible: false, - }, - "rmi": { - ContentType: "audio/midi", - Compressible: false, - }, - "rmp": { - ContentType: "audio/x-pn-realaudio-plugin", - Compressible: false, - }, - "rms": { - ContentType: "application/vnd.jcp.javame.midlet-rms", - Compressible: false, - }, - "rmvb": { - ContentType: "application/vnd.rn-realmedia-vbr", - Compressible: false, - }, - "rnc": { - ContentType: "application/relax-ng-compact-syntax", - Compressible: false, - }, - "rng": { - ContentType: "application/xml", - Compressible: false, - }, - "roa": { - ContentType: "application/rpki-roa", - Compressible: false, - }, - "roff": { - ContentType: "text/troff", - Compressible: false, - }, - "rp9": { - ContentType: "application/vnd.cloanto.rp9", - Compressible: false, - }, - "rpm": { - ContentType: "application/x-redhat-package-manager", - Compressible: false, - }, - "rpss": { - ContentType: "application/vnd.nokia.radio-presets", - Compressible: false, - }, - "rpst": { - ContentType: "application/vnd.nokia.radio-preset", - Compressible: false, - }, - "rq": { - ContentType: "application/sparql-query", - Compressible: false, - }, - "rs": { - ContentType: "application/rls-services+xml", - Compressible: false, - }, - "rsd": { - ContentType: "application/rsd+xml", - Compressible: false, - }, - "rss": { - ContentType: "application/rss+xml", - Compressible: false, - }, - "rtf": { - ContentType: "text/rtf", - Compressible: false, - }, - "rtx": { - ContentType: "text/richtext", - Compressible: false, - }, - "run": { - ContentType: "application/x-makeself", - Compressible: false, - }, - "s": { - ContentType: "text/x-asm", - Compressible: false, - }, - "s3m": { - ContentType: "audio/s3m", - Compressible: false, - }, - "saf": { - ContentType: "application/vnd.yamaha.smaf-audio", - Compressible: false, - }, - "sass": { - ContentType: "text/x-sass", - Compressible: false, - }, - "sbml": { - ContentType: "application/sbml+xml", - Compressible: false, - }, - "sc": { - ContentType: "application/vnd.ibm.secure-container", - Compressible: false, - }, - "scd": { - ContentType: "application/x-msschedule", - Compressible: false, - }, - "scm": { - ContentType: "application/vnd.lotus-screencam", - Compressible: false, - }, - "scq": { - ContentType: "application/scvp-cv-request", - Compressible: false, - }, - "scs": { - ContentType: "application/scvp-cv-response", - Compressible: false, - }, - "scss": { - ContentType: "text/x-scss", - Compressible: false, - }, - "scurl": { - ContentType: "text/vnd.curl.scurl", - Compressible: false, - }, - "sda": { - ContentType: "application/vnd.stardivision.draw", - Compressible: false, - }, - "sdc": { - ContentType: "application/vnd.stardivision.calc", - Compressible: false, - }, - "sdd": { - ContentType: "application/vnd.stardivision.impress", - Compressible: false, - }, - "sdkd": { - ContentType: "application/vnd.solent.sdkm+xml", - Compressible: false, - }, - "sdkm": { - ContentType: "application/vnd.solent.sdkm+xml", - Compressible: false, - }, - "sdp": { - ContentType: "application/sdp", - Compressible: false, - }, - "sdw": { - ContentType: "application/vnd.stardivision.writer", - Compressible: false, - }, - "sea": { - ContentType: "application/x-sea", - Compressible: false, - }, - "see": { - ContentType: "application/vnd.seemail", - Compressible: false, - }, - "seed": { - ContentType: "application/vnd.fdsn.seed", - Compressible: false, - }, - "sema": { - ContentType: "application/vnd.sema", - Compressible: false, - }, - "semd": { - ContentType: "application/vnd.semd", - Compressible: false, - }, - "semf": { - ContentType: "application/vnd.semf", - Compressible: false, - }, - "ser": { - ContentType: "application/java-serialized-object", - Compressible: false, - }, - "setpay": { - ContentType: "application/set-payment-initiation", - Compressible: false, - }, - "setreg": { - ContentType: "application/set-registration-initiation", - Compressible: false, - }, - "sfd-hdstx": { - ContentType: "application/vnd.hydrostatix.sof-data", - Compressible: false, - }, - "sfs": { - ContentType: "application/vnd.spotfire.sfs", - Compressible: false, - }, - "sfv": { - ContentType: "text/x-sfv", - Compressible: false, - }, - "sgi": { - ContentType: "image/sgi", - Compressible: false, - }, - "sgl": { - ContentType: "application/vnd.stardivision.writer-global", - Compressible: false, - }, - "sgm": { - ContentType: "text/sgml", - Compressible: false, - }, - "sgml": { - ContentType: "text/sgml", - Compressible: false, - }, - "sh": { - ContentType: "application/x-sh", - Compressible: false, - }, - "shar": { - ContentType: "application/x-shar", - Compressible: false, - }, - "shex": { - ContentType: "text/shex", - Compressible: false, - }, - "shf": { - ContentType: "application/shf+xml", - Compressible: false, - }, - "shtml": { - ContentType: "text/html", - Compressible: false, - }, - "sid": { - ContentType: "image/x-mrsid-image", - Compressible: false, - }, - "sig": { - ContentType: "application/pgp-signature", - Compressible: false, - }, - "sil": { - ContentType: "audio/silk", - Compressible: false, - }, - "silo": { - ContentType: "model/mesh", - Compressible: false, - }, - "sis": { - ContentType: "application/vnd.symbian.install", - Compressible: false, - }, - "sisx": { - ContentType: "application/vnd.symbian.install", - Compressible: false, - }, - "sit": { - ContentType: "application/x-stuffit", - Compressible: false, - }, - "sitx": { - ContentType: "application/x-stuffitx", - Compressible: false, - }, - "skd": { - ContentType: "application/vnd.koan", - Compressible: false, - }, - "skm": { - ContentType: "application/vnd.koan", - Compressible: false, - }, - "skp": { - ContentType: "application/vnd.koan", - Compressible: false, - }, - "skt": { - ContentType: "application/vnd.koan", - Compressible: false, - }, - "sldm": { - ContentType: "application/vnd.ms-powerpoint.slide.macroenabled.12", - Compressible: false, - }, - "sldx": { - ContentType: "application/vnd.openxmlformats-officedocument.presentationml.slide", - Compressible: false, - }, - "slim": { - ContentType: "text/slim", - Compressible: false, - }, - "slm": { - ContentType: "text/slim", - Compressible: false, - }, - "slt": { - ContentType: "application/vnd.epson.salt", - Compressible: false, - }, - "sm": { - ContentType: "application/vnd.stepmania.stepchart", - Compressible: false, - }, - "smf": { - ContentType: "application/vnd.stardivision.math", - Compressible: false, - }, - "smi": { - ContentType: "application/smil+xml", - Compressible: false, - }, - "smil": { - ContentType: "application/smil+xml", - Compressible: false, - }, - "smv": { - ContentType: "video/x-smv", - Compressible: false, - }, - "smzip": { - ContentType: "application/vnd.stepmania.package", - Compressible: false, - }, - "snd": { - ContentType: "audio/basic", - Compressible: false, - }, - "snf": { - ContentType: "application/x-font-snf", - Compressible: false, - }, - "so": { - ContentType: "application/octet-stream", - Compressible: false, - }, - "spc": { - ContentType: "application/x-pkcs7-certificates", - Compressible: false, - }, - "spf": { - ContentType: "application/vnd.yamaha.smaf-phrase", - Compressible: false, - }, - "spl": { - ContentType: "application/x-futuresplash", - Compressible: false, - }, - "spot": { - ContentType: "text/vnd.in3d.spot", - Compressible: false, - }, - "spp": { - ContentType: "application/scvp-vp-response", - Compressible: false, - }, - "spq": { - ContentType: "application/scvp-vp-request", - Compressible: false, - }, - "spx": { - ContentType: "audio/ogg", - Compressible: false, - }, - "sql": { - ContentType: "application/x-sql", - Compressible: false, - }, - "src": { - ContentType: "application/x-wais-source", - Compressible: false, - }, - "srt": { - ContentType: "application/x-subrip", - Compressible: false, - }, - "sru": { - ContentType: "application/sru+xml", - Compressible: false, - }, - "srx": { - ContentType: "application/sparql-results+xml", - Compressible: false, - }, - "ssdl": { - ContentType: "application/ssdl+xml", - Compressible: false, - }, - "sse": { - ContentType: "application/vnd.kodak-descriptor", - Compressible: false, - }, - "ssf": { - ContentType: "application/vnd.epson.ssf", - Compressible: false, - }, - "ssml": { - ContentType: "application/ssml+xml", - Compressible: false, - }, - "st": { - ContentType: "application/vnd.sailingtracker.track", - Compressible: false, - }, - "stc": { - ContentType: "application/vnd.sun.xml.calc.template", - Compressible: false, - }, - "std": { - ContentType: "application/vnd.sun.xml.draw.template", - Compressible: false, - }, - "stf": { - ContentType: "application/vnd.wt.stf", - Compressible: false, - }, - "sti": { - ContentType: "application/vnd.sun.xml.impress.template", - Compressible: false, - }, - "stk": { - ContentType: "application/hyperstudio", - Compressible: false, - }, - "stl": { - ContentType: "application/vnd.ms-pki.stl", - Compressible: false, - }, - "str": { - ContentType: "application/vnd.pg.format", - Compressible: false, - }, - "stw": { - ContentType: "application/vnd.sun.xml.writer.template", - Compressible: false, - }, - "styl": { - ContentType: "text/stylus", - Compressible: false, - }, - "stylus": { - ContentType: "text/stylus", - Compressible: false, - }, - "sub": { - ContentType: "text/vnd.dvb.subtitle", - Compressible: false, - }, - "sus": { - ContentType: "application/vnd.sus-calendar", - Compressible: false, - }, - "susp": { - ContentType: "application/vnd.sus-calendar", - Compressible: false, - }, - "sv4cpio": { - ContentType: "application/x-sv4cpio", - Compressible: false, - }, - "sv4crc": { - ContentType: "application/x-sv4crc", - Compressible: false, - }, - "svc": { - ContentType: "application/vnd.dvb.service", - Compressible: false, - }, - "svd": { - ContentType: "application/vnd.svd", - Compressible: false, - }, - "svg": { - ContentType: "image/svg+xml", - Compressible: false, - }, - "svgz": { - ContentType: "image/svg+xml", - Compressible: false, - }, - "swa": { - ContentType: "application/x-director", - Compressible: false, - }, - "swf": { - ContentType: "application/x-shockwave-flash", - Compressible: false, - }, - "swi": { - ContentType: "application/vnd.aristanetworks.swi", - Compressible: false, - }, - "sxc": { - ContentType: "application/vnd.sun.xml.calc", - Compressible: false, - }, - "sxd": { - ContentType: "application/vnd.sun.xml.draw", - Compressible: false, - }, - "sxg": { - ContentType: "application/vnd.sun.xml.writer.global", - Compressible: false, - }, - "sxi": { - ContentType: "application/vnd.sun.xml.impress", - Compressible: false, - }, - "sxm": { - ContentType: "application/vnd.sun.xml.math", - Compressible: false, - }, - "sxw": { - ContentType: "application/vnd.sun.xml.writer", - Compressible: false, - }, - "t": { - ContentType: "text/troff", - Compressible: false, - }, - "t3": { - ContentType: "application/x-t3vm-image", - Compressible: false, - }, - "t38": { - ContentType: "image/t38", - Compressible: false, - }, - "taglet": { - ContentType: "application/vnd.mynfc", - Compressible: false, - }, - "tao": { - ContentType: "application/vnd.tao.intent-module-archive", - Compressible: false, - }, - "tap": { - ContentType: "image/vnd.tencent.tap", - Compressible: false, - }, - "tar": { - ContentType: "application/x-tar", - Compressible: false, - }, - "tcap": { - ContentType: "application/vnd.3gpp2.tcap", - Compressible: false, - }, - "tcl": { - ContentType: "application/x-tcl", - Compressible: false, - }, - "teacher": { - ContentType: "application/vnd.smart.teacher", - Compressible: false, - }, - "tei": { - ContentType: "application/tei+xml", - Compressible: false, - }, - "teicorpus": { - ContentType: "application/tei+xml", - Compressible: false, - }, - "tex": { - ContentType: "application/x-tex", - Compressible: false, - }, - "texi": { - ContentType: "application/x-texinfo", - Compressible: false, - }, - "texinfo": { - ContentType: "application/x-texinfo", - Compressible: false, - }, - "text": { - ContentType: "text/plain", - Compressible: false, - }, - "tfi": { - ContentType: "application/thraud+xml", - Compressible: false, - }, - "tfm": { - ContentType: "application/x-tex-tfm", - Compressible: false, - }, - "tfx": { - ContentType: "image/tiff-fx", - Compressible: false, - }, - "tga": { - ContentType: "image/x-tga", - Compressible: false, - }, - "thmx": { - ContentType: "application/vnd.ms-officetheme", - Compressible: false, - }, - "tif": { - ContentType: "image/tiff", - Compressible: false, - }, - "tiff": { - ContentType: "image/tiff", - Compressible: false, - }, - "tk": { - ContentType: "application/x-tcl", - Compressible: false, - }, - "tmo": { - ContentType: "application/vnd.tmobile-livetv", - Compressible: false, - }, - "torrent": { - ContentType: "application/x-bittorrent", - Compressible: false, - }, - "tpl": { - ContentType: "application/vnd.groove-tool-template", - Compressible: false, - }, - "tpt": { - ContentType: "application/vnd.trid.tpt", - Compressible: false, - }, - "tr": { - ContentType: "text/troff", - Compressible: false, - }, - "tra": { - ContentType: "application/vnd.trueapp", - Compressible: false, - }, - "trm": { - ContentType: "application/x-msterminal", - Compressible: false, - }, - "ts": { - ContentType: "video/mp2t", - Compressible: false, - }, - "tsd": { - ContentType: "application/timestamped-data", - Compressible: false, - }, - "tsv": { - ContentType: "text/tab-separated-values", - Compressible: false, - }, - "ttc": { - ContentType: "font/collection", - Compressible: false, - }, - "ttf": { - ContentType: "font/ttf", - Compressible: false, - }, - "ttl": { - ContentType: "text/turtle", - Compressible: false, - }, - "twd": { - ContentType: "application/vnd.simtech-mindmapper", - Compressible: false, - }, - "twds": { - ContentType: "application/vnd.simtech-mindmapper", - Compressible: false, - }, - "txd": { - ContentType: "application/vnd.genomatix.tuxedo", - Compressible: false, - }, - "txf": { - ContentType: "application/vnd.mobius.txf", - Compressible: false, - }, - "txt": { - ContentType: "text/plain", - Compressible: false, - }, - "u32": { - ContentType: "application/x-authorware-bin", - Compressible: false, - }, - "u8dsn": { - ContentType: "message/global-delivery-status", - Compressible: false, - }, - "u8hdr": { - ContentType: "message/global-headers", - Compressible: false, - }, - "u8mdn": { - ContentType: "message/global-disposition-notification", - Compressible: false, - }, - "u8msg": { - ContentType: "message/global", - Compressible: false, - }, - "udeb": { - ContentType: "application/x-debian-package", - Compressible: false, - }, - "ufd": { - ContentType: "application/vnd.ufdl", - Compressible: false, - }, - "ufdl": { - ContentType: "application/vnd.ufdl", - Compressible: false, - }, - "ulx": { - ContentType: "application/x-glulx", - Compressible: false, - }, - "umj": { - ContentType: "application/vnd.umajin", - Compressible: false, - }, - "unityweb": { - ContentType: "application/vnd.unity", - Compressible: false, - }, - "uoml": { - ContentType: "application/vnd.uoml+xml", - Compressible: false, - }, - "uri": { - ContentType: "text/uri-list", - Compressible: false, - }, - "uris": { - ContentType: "text/uri-list", - Compressible: false, - }, - "urls": { - ContentType: "text/uri-list", - Compressible: false, - }, - "ustar": { - ContentType: "application/x-ustar", - Compressible: false, - }, - "utz": { - ContentType: "application/vnd.uiq.theme", - Compressible: false, - }, - "uu": { - ContentType: "text/x-uuencode", - Compressible: false, - }, - "uva": { - ContentType: "audio/vnd.dece.audio", - Compressible: false, - }, - "uvd": { - ContentType: "application/vnd.dece.data", - Compressible: false, - }, - "uvf": { - ContentType: "application/vnd.dece.data", - Compressible: false, - }, - "uvg": { - ContentType: "image/vnd.dece.graphic", - Compressible: false, - }, - "uvh": { - ContentType: "video/vnd.dece.hd", - Compressible: false, - }, - "uvi": { - ContentType: "image/vnd.dece.graphic", - Compressible: false, - }, - "uvm": { - ContentType: "video/vnd.dece.mobile", - Compressible: false, - }, - "uvp": { - ContentType: "video/vnd.dece.pd", - Compressible: false, - }, - "uvs": { - ContentType: "video/vnd.dece.sd", - Compressible: false, - }, - "uvt": { - ContentType: "application/vnd.dece.ttml+xml", - Compressible: false, - }, - "uvu": { - ContentType: "video/vnd.uvvu.mp4", - Compressible: false, - }, - "uvv": { - ContentType: "video/vnd.dece.video", - Compressible: false, - }, - "uvva": { - ContentType: "audio/vnd.dece.audio", - Compressible: false, - }, - "uvvd": { - ContentType: "application/vnd.dece.data", - Compressible: false, - }, - "uvvf": { - ContentType: "application/vnd.dece.data", - Compressible: false, - }, - "uvvg": { - ContentType: "image/vnd.dece.graphic", - Compressible: false, - }, - "uvvh": { - ContentType: "video/vnd.dece.hd", - Compressible: false, - }, - "uvvi": { - ContentType: "image/vnd.dece.graphic", - Compressible: false, - }, - "uvvm": { - ContentType: "video/vnd.dece.mobile", - Compressible: false, - }, - "uvvp": { - ContentType: "video/vnd.dece.pd", - Compressible: false, - }, - "uvvs": { - ContentType: "video/vnd.dece.sd", - Compressible: false, - }, - "uvvt": { - ContentType: "application/vnd.dece.ttml+xml", - Compressible: false, - }, - "uvvu": { - ContentType: "video/vnd.uvvu.mp4", - Compressible: false, - }, - "uvvv": { - ContentType: "video/vnd.dece.video", - Compressible: false, - }, - "uvvx": { - ContentType: "application/vnd.dece.unspecified", - Compressible: false, - }, - "uvvz": { - ContentType: "application/vnd.dece.zip", - Compressible: false, - }, - "uvx": { - ContentType: "application/vnd.dece.unspecified", - Compressible: false, - }, - "uvz": { - ContentType: "application/vnd.dece.zip", - Compressible: false, - }, - "vbox": { - ContentType: "application/x-virtualbox-vbox", - Compressible: false, - }, - "vbox-extpack": { - ContentType: "application/x-virtualbox-vbox-extpack", - Compressible: false, - }, - "vcard": { - ContentType: "text/vcard", - Compressible: false, - }, - "vcd": { - ContentType: "application/x-cdlink", - Compressible: false, - }, - "vcf": { - ContentType: "text/x-vcard", - Compressible: false, - }, - "vcg": { - ContentType: "application/vnd.groove-vcard", - Compressible: false, - }, - "vcs": { - ContentType: "text/x-vcalendar", - Compressible: false, - }, - "vcx": { - ContentType: "application/vnd.vcx", - Compressible: false, - }, - "vdi": { - ContentType: "application/x-virtualbox-vdi", - Compressible: false, - }, - "vhd": { - ContentType: "application/x-virtualbox-vhd", - Compressible: false, - }, - "vis": { - ContentType: "application/vnd.visionary", - Compressible: false, - }, - "viv": { - ContentType: "video/vnd.vivo", - Compressible: false, - }, - "vmdk": { - ContentType: "application/x-virtualbox-vmdk", - Compressible: false, - }, - "vob": { - ContentType: "video/x-ms-vob", - Compressible: false, - }, - "vor": { - ContentType: "application/vnd.stardivision.writer", - Compressible: false, - }, - "vox": { - ContentType: "application/x-authorware-bin", - Compressible: false, - }, - "vrml": { - ContentType: "model/vrml", - Compressible: false, - }, - "vsd": { - ContentType: "application/vnd.visio", - Compressible: false, - }, - "vsf": { - ContentType: "application/vnd.vsf", - Compressible: false, - }, - "vss": { - ContentType: "application/vnd.visio", - Compressible: false, - }, - "vst": { - ContentType: "application/vnd.visio", - Compressible: false, - }, - "vsw": { - ContentType: "application/vnd.visio", - Compressible: false, - }, - "vtf": { - ContentType: "image/vnd.valve.source.texture", - Compressible: false, - }, - "vtt": { - ContentType: "text/vtt", - Compressible: false, - }, - "vtu": { - ContentType: "model/vnd.vtu", - Compressible: false, - }, - "vxml": { - ContentType: "application/voicexml+xml", - Compressible: false, - }, - "w3d": { - ContentType: "application/x-director", - Compressible: false, - }, - "wad": { - ContentType: "application/x-doom", - Compressible: false, - }, - "wadl": { - ContentType: "application/vnd.sun.wadl+xml", - Compressible: false, - }, - "war": { - ContentType: "application/java-archive", - Compressible: false, - }, - "wasm": { - ContentType: "application/wasm", - Compressible: false, - }, - "wav": { - ContentType: "audio/x-wav", - Compressible: false, - }, - "wax": { - ContentType: "audio/x-ms-wax", - Compressible: false, - }, - "wbmp": { - ContentType: "image/vnd.wap.wbmp", - Compressible: false, - }, - "wbs": { - ContentType: "application/vnd.criticaltools.wbs+xml", - Compressible: false, - }, - "wbxml": { - ContentType: "application/vnd.wap.wbxml", - Compressible: false, - }, - "wcm": { - ContentType: "application/vnd.ms-works", - Compressible: false, - }, - "wdb": { - ContentType: "application/vnd.ms-works", - Compressible: false, - }, - "wdp": { - ContentType: "image/vnd.ms-photo", - Compressible: false, - }, - "weba": { - ContentType: "audio/webm", - Compressible: false, - }, - "webapp": { - ContentType: "application/x-web-app-manifest+json", - Compressible: false, - }, - "webm": { - ContentType: "video/webm", - Compressible: false, - }, - "webmanifest": { - ContentType: "application/manifest+json", - Compressible: false, - }, - "webp": { - ContentType: "image/webp", - Compressible: false, - }, - "wg": { - ContentType: "application/vnd.pmi.widget", - Compressible: false, - }, - "wgt": { - ContentType: "application/widget", - Compressible: false, - }, - "wks": { - ContentType: "application/vnd.ms-works", - Compressible: false, - }, - "wm": { - ContentType: "video/x-ms-wm", - Compressible: false, - }, - "wma": { - ContentType: "audio/x-ms-wma", - Compressible: false, - }, - "wmd": { - ContentType: "application/x-ms-wmd", - Compressible: false, - }, - "wmf": { - ContentType: "image/wmf", - Compressible: false, - }, - "wml": { - ContentType: "text/vnd.wap.wml", - Compressible: false, - }, - "wmlc": { - ContentType: "application/vnd.wap.wmlc", - Compressible: false, - }, - "wmls": { - ContentType: "text/vnd.wap.wmlscript", - Compressible: false, - }, - "wmlsc": { - ContentType: "application/vnd.wap.wmlscriptc", - Compressible: false, - }, - "wmv": { - ContentType: "video/x-ms-wmv", - Compressible: false, - }, - "wmx": { - ContentType: "video/x-ms-wmx", - Compressible: false, - }, - "wmz": { - ContentType: "application/x-msmetafile", - Compressible: false, - }, - "woff": { - ContentType: "font/woff", - Compressible: false, - }, - "woff2": { - ContentType: "font/woff2", - Compressible: false, - }, - "wpd": { - ContentType: "application/vnd.wordperfect", - Compressible: false, - }, - "wpl": { - ContentType: "application/vnd.ms-wpl", - Compressible: false, - }, - "wps": { - ContentType: "application/vnd.ms-works", - Compressible: false, - }, - "wqd": { - ContentType: "application/vnd.wqd", - Compressible: false, - }, - "wri": { - ContentType: "application/x-mswrite", - Compressible: false, - }, - "wrl": { - ContentType: "model/vrml", - Compressible: false, - }, - "wsc": { - ContentType: "message/vnd.wfa.wsc", - Compressible: false, - }, - "wsdl": { - ContentType: "application/wsdl+xml", - Compressible: false, - }, - "wspolicy": { - ContentType: "application/wspolicy+xml", - Compressible: false, - }, - "wtb": { - ContentType: "application/vnd.webturbo", - Compressible: false, - }, - "wvx": { - ContentType: "video/x-ms-wvx", - Compressible: false, - }, - "x32": { - ContentType: "application/x-authorware-bin", - Compressible: false, - }, - "x3d": { - ContentType: "model/x3d+xml", - Compressible: false, - }, - "x3db": { - ContentType: "model/x3d+binary", - Compressible: false, - }, - "x3dbz": { - ContentType: "model/x3d+binary", - Compressible: false, - }, - "x3dv": { - ContentType: "model/x3d+vrml", - Compressible: false, - }, - "x3dvz": { - ContentType: "model/x3d+vrml", - Compressible: false, - }, - "x3dz": { - ContentType: "model/x3d+xml", - Compressible: false, - }, - "xaml": { - ContentType: "application/xaml+xml", - Compressible: false, - }, - "xap": { - ContentType: "application/x-silverlight-app", - Compressible: false, - }, - "xar": { - ContentType: "application/vnd.xara", - Compressible: false, - }, - "xbap": { - ContentType: "application/x-ms-xbap", - Compressible: false, - }, - "xbd": { - ContentType: "application/vnd.fujixerox.docuworks.binder", - Compressible: false, - }, - "xbm": { - ContentType: "image/x-xbitmap", - Compressible: false, - }, - "xdf": { - ContentType: "application/xcap-diff+xml", - Compressible: false, - }, - "xdm": { - ContentType: "application/vnd.syncml.dm+xml", - Compressible: false, - }, - "xdp": { - ContentType: "application/vnd.adobe.xdp+xml", - Compressible: false, - }, - "xdssc": { - ContentType: "application/dssc+xml", - Compressible: false, - }, - "xdw": { - ContentType: "application/vnd.fujixerox.docuworks", - Compressible: false, - }, - "xenc": { - ContentType: "application/xenc+xml", - Compressible: false, - }, - "xer": { - ContentType: "application/patch-ops-error+xml", - Compressible: false, - }, - "xfdf": { - ContentType: "application/vnd.adobe.xfdf", - Compressible: false, - }, - "xfdl": { - ContentType: "application/vnd.xfdl", - Compressible: false, - }, - "xht": { - ContentType: "application/xhtml+xml", - Compressible: false, - }, - "xhtml": { - ContentType: "application/xhtml+xml", - Compressible: false, - }, - "xhvml": { - ContentType: "application/xv+xml", - Compressible: false, - }, - "xif": { - ContentType: "image/vnd.xiff", - Compressible: false, - }, - "xla": { - ContentType: "application/vnd.ms-excel", - Compressible: false, - }, - "xlam": { - ContentType: "application/vnd.ms-excel.addin.macroenabled.12", - Compressible: false, - }, - "xlc": { - ContentType: "application/vnd.ms-excel", - Compressible: false, - }, - "xlf": { - ContentType: "application/x-xliff+xml", - Compressible: false, - }, - "xlm": { - ContentType: "application/vnd.ms-excel", - Compressible: false, - }, - "xls": { - ContentType: "application/vnd.ms-excel", - Compressible: false, - }, - "xlsb": { - ContentType: "application/vnd.ms-excel.sheet.binary.macroenabled.12", - Compressible: false, - }, - "xlsm": { - ContentType: "application/vnd.ms-excel.sheet.macroenabled.12", - Compressible: false, - }, - "xlsx": { - ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", - Compressible: false, - }, - "xlt": { - ContentType: "application/vnd.ms-excel", - Compressible: false, - }, - "xltm": { - ContentType: "application/vnd.ms-excel.template.macroenabled.12", - Compressible: false, - }, - "xltx": { - ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.template", - Compressible: false, - }, - "xlw": { - ContentType: "application/vnd.ms-excel", - Compressible: false, - }, - "xm": { - ContentType: "audio/xm", - Compressible: false, - }, - "xml": { - ContentType: "text/xml", - Compressible: false, - }, - "xo": { - ContentType: "application/vnd.olpc-sugar", - Compressible: false, - }, - "xop": { - ContentType: "application/xop+xml", - Compressible: false, - }, - "xpi": { - ContentType: "application/x-xpinstall", - Compressible: false, - }, - "xpl": { - ContentType: "application/xproc+xml", - Compressible: false, - }, - "xpm": { - ContentType: "image/x-xpixmap", - Compressible: false, - }, - "xpr": { - ContentType: "application/vnd.is-xpr", - Compressible: false, - }, - "xps": { - ContentType: "application/vnd.ms-xpsdocument", - Compressible: false, - }, - "xpw": { - ContentType: "application/vnd.intercon.formnet", - Compressible: false, - }, - "xpx": { - ContentType: "application/vnd.intercon.formnet", - Compressible: false, - }, - "xsd": { - ContentType: "application/xml", - Compressible: false, - }, - "xsl": { - ContentType: "application/xml", - Compressible: false, - }, - "xslt": { - ContentType: "application/xslt+xml", - Compressible: false, - }, - "xsm": { - ContentType: "application/vnd.syncml+xml", - Compressible: false, - }, - "xspf": { - ContentType: "application/xspf+xml", - Compressible: false, - }, - "xul": { - ContentType: "application/vnd.mozilla.xul+xml", - Compressible: false, - }, - "xvm": { - ContentType: "application/xv+xml", - Compressible: false, - }, - "xvml": { - ContentType: "application/xv+xml", - Compressible: false, - }, - "xwd": { - ContentType: "image/x-xwindowdump", - Compressible: false, - }, - "xyz": { - ContentType: "chemical/x-xyz", - Compressible: false, - }, - "xz": { - ContentType: "application/x-xz", - Compressible: false, - }, - "yaml": { - ContentType: "text/yaml", - Compressible: false, - }, - "yang": { - ContentType: "application/yang", - Compressible: false, - }, - "yin": { - ContentType: "application/yin+xml", - Compressible: false, - }, - "yml": { - ContentType: "text/yaml", - Compressible: false, - }, - "ymp": { - ContentType: "text/x-suse-ymp", - Compressible: false, - }, - "z1": { - ContentType: "application/x-zmachine", - Compressible: false, - }, - "z2": { - ContentType: "application/x-zmachine", - Compressible: false, - }, - "z3": { - ContentType: "application/x-zmachine", - Compressible: false, - }, - "z4": { - ContentType: "application/x-zmachine", - Compressible: false, - }, - "z5": { - ContentType: "application/x-zmachine", - Compressible: false, - }, - "z6": { - ContentType: "application/x-zmachine", - Compressible: false, - }, - "z7": { - ContentType: "application/x-zmachine", - Compressible: false, - }, - "z8": { - ContentType: "application/x-zmachine", - Compressible: false, - }, - "zaz": { - ContentType: "application/vnd.zzazz.deck+xml", - Compressible: false, - }, - "zip": { - ContentType: "application/zip", - Compressible: false, - }, - "zir": { - ContentType: "application/vnd.zul", - Compressible: false, - }, - "zirz": { - ContentType: "application/vnd.zul", - Compressible: false, - }, - "zmm": { - ContentType: "application/vnd.handheld-entertainment+xml", - Compressible: false, - }, -} diff --git a/pkg/mimedb/db_test.go b/pkg/mimedb/db_test.go deleted file mode 100644 index 95d12c135..000000000 --- a/pkg/mimedb/db_test.go +++ /dev/null @@ -1,45 +0,0 @@ -// 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 . - -package mimedb - -import "testing" - -func TestMimeLookup(t *testing.T) { - // Test mimeLookup. - contentType := DB["txt"].ContentType - if contentType != "text/plain" { - t.Fatalf("Invalid content type are found expected \"application/x-msdownload\", got %s", contentType) - } - compressible := DB["txt"].Compressible - if compressible { - t.Fatalf("Invalid content type are found expected \"false\", got %t", compressible) - } -} - -func TestTypeByExtension(t *testing.T) { - // Test TypeByExtension. - contentType := TypeByExtension(".txt") - if contentType != "text/plain" { - t.Fatalf("Invalid content type are found expected \"text/plain\", got %s", contentType) - } - // Test non-existent type resolution - contentType = TypeByExtension(".abc") - if contentType != "application/octet-stream" { - t.Fatalf("Invalid content type are found expected \"application/octet-stream\", got %s", contentType) - } -} diff --git a/pkg/mimedb/resolve-db.go b/pkg/mimedb/resolve-db.go deleted file mode 100644 index 40b6a736e..000000000 --- a/pkg/mimedb/resolve-db.go +++ /dev/null @@ -1,34 +0,0 @@ -// 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 . - -package mimedb - -import ( - "strings" -) - -// TypeByExtension resolves the extension to its respective content-type. -func TypeByExtension(ext string) string { - // Set default to "application/octet-stream". - var contentType = "application/octet-stream" - if ext != "" { - if content, ok := DB[strings.ToLower(strings.TrimPrefix(ext, "."))]; ok { - contentType = content.ContentType - } - } - return contentType -} diff --git a/pkg/mimedb/util/gen-db.go b/pkg/mimedb/util/gen-db.go deleted file mode 100644 index 63990cde6..000000000 --- a/pkg/mimedb/util/gen-db.go +++ /dev/null @@ -1,146 +0,0 @@ -// 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 . - -// Package mimedb is a database of file extension to mime content-type. -// Definitions are imported from NodeJS mime-db project under MIT license. - -package main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "os" - "strings" - "text/template" -) - -const progTempl = `// DO NOT EDIT THIS FILE. IT IS AUTO-GENERATED BY "gen-db.go". -// 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 . - -// Package mimedb is a database of file extension to mime content-type. -// Definitions are imported from NodeJS mime-db project under MIT license. -package mimedb - -// DB - Mime is a collection of mime types with extension as key and content-type as value. -var DB = map[string]struct { - ContentType string - Compressible bool -}{ -{{range $extension, $entry := . }} "{{$extension}}": { - ContentType: "{{$entry.ContentType}}", - Compressible: {{$entry.Compressible}}, - }, -{{end}}} -` - -type mimeEntry struct { - ContentType string `json:"contentType"` - Compressible bool `json:"compresible"` -} - -type mimeDB map[string]mimeEntry - -// JSON data from gobindata and parse them into extDB. -func convertDB(jsonFile string) (mimeDB, error) { - // Structure of JSON data from mime-db project. - type dbEntry struct { - Source string `json:"source"` - Compressible bool `json:"compresible"` - Extensions []string `json:"extensions"` - } - - // Access embedded "db.json" inside go-bindata. - jsonDB, err := ioutil.ReadFile(jsonFile) - if err != nil { - return nil, err - } - - // Convert db.json into go's typed structure. - db := make(map[string]dbEntry) - if err := json.Unmarshal(jsonDB, &db); err != nil { - return nil, err - } - - mDB := make(mimeDB) - - // Generate a new database from mime-db. - for key, val := range db { - if len(val.Extensions) > 0 { - /* Denormalize - each extension has its own - unique content-type now. Looks will be fast. */ - for _, ext := range val.Extensions { - /* Single extension type may map to - multiple content-types. In that case, - simply prefer the longest content-type - to maintain some level of - consistency. Only guarantee is, - whatever content type is assigned, it - is appropriate and valid type. */ - if strings.Compare(mDB[ext].ContentType, key) < 0 { - mDB[ext] = mimeEntry{ - ContentType: key, - Compressible: val.Compressible, - } - } - } - } - } - return mDB, nil -} - -func main() { - // Take input json file from command-line". - if len(os.Args) != 2 { - fmt.Print("Syntax:\n\tgen-db /path/to/db.json\n") - os.Exit(1) - } - - // Load and convert db.json into new database with extension - // as key. - mDB, err := convertDB(os.Args[1]) - if err != nil { - panic(err) - } - - // Generate db embedded go program. - tmpl := template.New("mimedb") - mimeTmpl, err := tmpl.Parse(progTempl) - if err != nil { - panic(err) - } - - err = mimeTmpl.Execute(os.Stdout, mDB) - if err != nil { - panic(err) - } -} diff --git a/pkg/quick/encoding.go b/pkg/quick/encoding.go deleted file mode 100644 index 99024dc7d..000000000 --- a/pkg/quick/encoding.go +++ /dev/null @@ -1,191 +0,0 @@ -// 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 . - -package quick - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "runtime" - "strings" - "time" - - etcd "go.etcd.io/etcd/client/v3" - yaml "gopkg.in/yaml.v2" -) - -// ConfigEncoding is a generic interface which -// marshal/unmarshal configuration. -type ConfigEncoding interface { - Unmarshal([]byte, interface{}) error - Marshal(interface{}) ([]byte, error) -} - -// YAML encoding implements ConfigEncoding -type yamlEncoding struct{} - -func (y yamlEncoding) Unmarshal(b []byte, v interface{}) error { - return yaml.Unmarshal(b, v) -} - -func (y yamlEncoding) Marshal(v interface{}) ([]byte, error) { - return yaml.Marshal(v) -} - -// JSON encoding implements ConfigEncoding -type jsonEncoding struct{} - -func (j jsonEncoding) Unmarshal(b []byte, v interface{}) error { - err := json.Unmarshal(b, v) - if err != nil { - // Try to return a sophisticated json error message if possible - switch jerr := err.(type) { - case *json.SyntaxError: - return fmt.Errorf("Unable to parse JSON schema due to a syntax error at '%s'", - FormatJSONSyntaxError(bytes.NewReader(b), jerr.Offset)) - case *json.UnmarshalTypeError: - return fmt.Errorf("Unable to parse JSON, type '%v' cannot be converted into the Go '%v' type", - jerr.Value, jerr.Type) - } - return err - } - return nil -} - -func (j jsonEncoding) Marshal(v interface{}) ([]byte, error) { - return json.MarshalIndent(v, "", "\t") -} - -// Convert a file extension to the appropriate struct capable -// to marshal/unmarshal data -func ext2EncFormat(fileExtension string) ConfigEncoding { - // Lower the file extension - ext := strings.ToLower(fileExtension) - ext = strings.TrimPrefix(ext, ".") - // Return the appropriate encoder/decoder according - // to the extension - switch ext { - case "yml", "yaml": - // YAML - return yamlEncoding{} - default: - // JSON - return jsonEncoding{} - } -} - -// toMarshaller returns the right marshal function according -// to the given file extension -func toMarshaller(ext string) func(interface{}) ([]byte, error) { - return ext2EncFormat(ext).Marshal -} - -// toUnmarshaller returns the right marshal function according -// to the given file extension -func toUnmarshaller(ext string) func([]byte, interface{}) error { - return ext2EncFormat(ext).Unmarshal -} - -// saveFileConfig marshals with the right encoding format -// according to the filename extension, if no extension is -// provided, json will be selected. -func saveFileConfig(filename string, v interface{}) error { - // Fetch filename's extension - ext := filepath.Ext(filename) - // Marshal data - dataBytes, err := toMarshaller(ext)(v) - if err != nil { - return err - } - if runtime.GOOS == "windows" { - dataBytes = []byte(strings.Replace(string(dataBytes), "\n", "\r\n", -1)) - } - // Save data. - return writeFile(filename, dataBytes) - -} - -func saveFileConfigEtcd(filename string, clnt *etcd.Client, v interface{}) error { - // Fetch filename's extension - ext := filepath.Ext(filename) - // Marshal data - dataBytes, err := toMarshaller(ext)(v) - if err != nil { - return err - } - if runtime.GOOS == "windows" { - dataBytes = []byte(strings.Replace(string(dataBytes), "\n", "\r\n", -1)) - } - - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - _, err = clnt.Put(ctx, filename, string(dataBytes)) - if err == context.DeadlineExceeded { - return fmt.Errorf("etcd setup is unreachable, please check your endpoints %s", clnt.Endpoints()) - } else if err != nil { - return fmt.Errorf("unexpected error %w returned by etcd setup, please check your endpoints %s", err, clnt.Endpoints()) - } - return nil -} - -func loadFileConfigEtcd(filename string, clnt *etcd.Client, v interface{}) error { - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - resp, err := clnt.Get(ctx, filename) - if err != nil { - if err == context.DeadlineExceeded { - return fmt.Errorf("etcd setup is unreachable, please check your endpoints %s", clnt.Endpoints()) - } - return fmt.Errorf("unexpected error %w returned by etcd setup, please check your endpoints %s", err, clnt.Endpoints()) - } - if resp.Count == 0 { - return os.ErrNotExist - } - - for _, ev := range resp.Kvs { - if string(ev.Key) == filename { - fileData := ev.Value - if runtime.GOOS == "windows" { - fileData = bytes.Replace(fileData, []byte("\r\n"), []byte("\n"), -1) - } - // Unmarshal file's content - return toUnmarshaller(filepath.Ext(filename))(fileData, v) - } - } - return os.ErrNotExist -} - -// loadFileConfig unmarshals the file's content with the right -// decoder format according to the filename extension. If no -// extension is provided, json will be selected by default. -func loadFileConfig(filename string, v interface{}) error { - fileData, err := ioutil.ReadFile(filename) - if err != nil { - return err - } - if runtime.GOOS == "windows" { - fileData = []byte(strings.Replace(string(fileData), "\r\n", "\n", -1)) - } - - // Unmarshal file's content - return toUnmarshaller(filepath.Ext(filename))(fileData, v) -} diff --git a/pkg/quick/errorutil.go b/pkg/quick/errorutil.go deleted file mode 100644 index e56c1dfd5..000000000 --- a/pkg/quick/errorutil.go +++ /dev/null @@ -1,81 +0,0 @@ -// 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 . - -package quick - -import ( - "bufio" - "bytes" - "fmt" - "io" - - "github.com/cheggaaa/pb" -) - -const errorFmt = "%5d: %s <<<<" - -// FormatJSONSyntaxError generates a pretty printed json syntax error since -// golang doesn't provide an easy way to report the location of the error -func FormatJSONSyntaxError(data io.Reader, offset int64) (highlight string) { - var readLine bytes.Buffer - var errLine = 1 - var readBytes int64 - - bio := bufio.NewReader(data) - - // termWidth is set to a default one to use when we are - // not able to calculate terminal width via OS syscalls - termWidth := 25 - - // errorShift is the length of the minimum needed place for - // error msg accessories, like <--, etc.. We calculate it - // dynamically to avoid an eventual bug after modifying errorFmt - errorShift := len(fmt.Sprintf(errorFmt, 1, "")) - - if width, err := pb.GetTerminalWidth(); err == nil { - termWidth = width - } - - for { - b, err := bio.ReadByte() - if err != nil { - break - } - readBytes++ - if readBytes > offset { - break - } - if b == '\n' { - readLine.Reset() - errLine++ - continue - } else if b == '\t' { - readLine.WriteByte(' ') - } else if b == '\r' { - break - } - readLine.WriteByte(b) - } - - lineLen := readLine.Len() - idx := lineLen - termWidth + errorShift - if idx < 0 || idx > lineLen-1 { - idx = 0 - } - - return fmt.Sprintf(errorFmt, errLine, readLine.String()[idx:]) -} diff --git a/pkg/quick/quick.go b/pkg/quick/quick.go deleted file mode 100644 index 1a8d634ac..000000000 --- a/pkg/quick/quick.go +++ /dev/null @@ -1,236 +0,0 @@ -// 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 . - -package quick - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "os" - "reflect" - "sync" - - "github.com/fatih/structs" - "github.com/minio/minio/pkg/safe" - etcd "go.etcd.io/etcd/client/v3" -) - -// Config - generic config interface functions -type Config interface { - String() string - Version() string - Save(string) error - Load(string) error - Data() interface{} - Diff(Config) ([]structs.Field, error) - DeepDiff(Config) ([]structs.Field, error) -} - -// config - implements quick.Config interface -type config struct { - data interface{} - clnt *etcd.Client - lock *sync.RWMutex -} - -// Version returns the current config file format version -func (d config) Version() string { - st := structs.New(d.data) - f := st.Field("Version") - return f.Value().(string) -} - -// String converts JSON config to printable string -func (d config) String() string { - configBytes, _ := json.MarshalIndent(d.data, "", "\t") - return string(configBytes) -} - -// Save writes config data to a file. Data format -// is selected based on file extension or JSON if -// not provided. -func (d config) Save(filename string) error { - d.lock.Lock() - defer d.lock.Unlock() - - if d.clnt != nil { - return saveFileConfigEtcd(filename, d.clnt, d.data) - } - - // Backup if given file exists - oldData, err := ioutil.ReadFile(filename) - if err != nil { - // Ignore if file does not exist. - if !os.IsNotExist(err) { - return err - } - } else { - // Save read data to the backup file. - backupFilename := filename + ".old" - if err = writeFile(backupFilename, oldData); err != nil { - return err - } - } - - // Save data. - return saveFileConfig(filename, d.data) -} - -// Load - loads config from file and merge with currently set values -// File content format is guessed from the file name extension, if not -// available, consider that we have JSON. -func (d config) Load(filename string) error { - d.lock.Lock() - defer d.lock.Unlock() - if d.clnt != nil { - return loadFileConfigEtcd(filename, d.clnt, d.data) - } - return loadFileConfig(filename, d.data) -} - -// Data - grab internal data map for reading -func (d config) Data() interface{} { - return d.data -} - -// Diff - list fields that are in A but not in B -func (d config) Diff(c Config) ([]structs.Field, error) { - var fields []structs.Field - - currFields := structs.Fields(d.Data()) - newFields := structs.Fields(c.Data()) - - var found bool - for _, currField := range currFields { - found = false - for _, newField := range newFields { - if reflect.DeepEqual(currField.Name(), newField.Name()) { - found = true - } - } - if !found { - fields = append(fields, *currField) - } - } - return fields, nil -} - -// DeepDiff - list fields in A that are missing or not equal to fields in B -func (d config) DeepDiff(c Config) ([]structs.Field, error) { - var fields []structs.Field - - currFields := structs.Fields(d.Data()) - newFields := structs.Fields(c.Data()) - - var found bool - for _, currField := range currFields { - found = false - for _, newField := range newFields { - if reflect.DeepEqual(currField.Value(), newField.Value()) { - found = true - } - } - if !found { - fields = append(fields, *currField) - } - } - return fields, nil -} - -// CheckData - checks the validity of config data. Data should be of -// type struct and contain a string type field called "Version". -func CheckData(data interface{}) error { - if !structs.IsStruct(data) { - return fmt.Errorf("interface must be struct type") - } - - st := structs.New(data) - f, ok := st.FieldOk("Version") - if !ok { - return fmt.Errorf("struct ‘%s’ must have field ‘Version’", st.Name()) - } - - if f.Kind() != reflect.String { - return fmt.Errorf("‘Version’ field in struct ‘%s’ must be a string type", st.Name()) - } - - return nil -} - -// writeFile writes data to a file named by filename. -// If the file does not exist, writeFile creates it; -// otherwise writeFile truncates it before writing. -func writeFile(filename string, data []byte) error { - safeFile, err := safe.CreateFile(filename) - if err != nil { - return err - } - _, err = safeFile.Write(data) - if err != nil { - return err - } - return safeFile.Close() -} - -// GetVersion - extracts the version information. -func GetVersion(filename string, clnt *etcd.Client) (version string, err error) { - var qc Config - qc, err = LoadConfig(filename, clnt, &struct { - Version string - }{}) - if err != nil { - return "", err - } - return qc.Version(), nil -} - -// LoadConfig - loads json config from filename for the a given struct data -func LoadConfig(filename string, clnt *etcd.Client, data interface{}) (qc Config, err error) { - qc, err = NewConfig(data, clnt) - if err != nil { - return nil, err - } - return qc, qc.Load(filename) -} - -// SaveConfig - saves given configuration data into given file as JSON. -func SaveConfig(data interface{}, filename string, clnt *etcd.Client) (err error) { - if err = CheckData(data); err != nil { - return err - } - var qc Config - qc, err = NewConfig(data, clnt) - if err != nil { - return err - } - return qc.Save(filename) -} - -// NewConfig loads config from etcd client if provided, otherwise loads from a local filename. -// fails when all else fails. -func NewConfig(data interface{}, clnt *etcd.Client) (cfg Config, err error) { - if err := CheckData(data); err != nil { - return nil, err - } - - d := new(config) - d.data = data - d.clnt = clnt - d.lock = new(sync.RWMutex) - return d, nil -} diff --git a/pkg/quick/quick_test.go b/pkg/quick/quick_test.go deleted file mode 100644 index 857862670..000000000 --- a/pkg/quick/quick_test.go +++ /dev/null @@ -1,505 +0,0 @@ -// 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 . - -package quick - -import ( - "bytes" - "encoding/json" - "io/ioutil" - "os" - "reflect" - "runtime" - "strings" - "testing" -) - -func TestReadVersion(t *testing.T) { - type myStruct struct { - Version string - } - saveMe := myStruct{"1"} - config, err := NewConfig(&saveMe, nil) - if err != nil { - t.Fatal(err) - } - err = config.Save("test.json") - if err != nil { - t.Fatal(err) - } - - version, err := GetVersion("test.json", nil) - if err != nil { - t.Fatal(err) - } - if version != "1" { - t.Fatalf("Expected version '1', got '%v'", version) - } -} - -func TestReadVersionErr(t *testing.T) { - type myStruct struct { - Version int - } - saveMe := myStruct{1} - _, err := NewConfig(&saveMe, nil) - if err == nil { - t.Fatal("Unexpected should fail in initialization for bad input") - } - - err = ioutil.WriteFile("test.json", []byte("{ \"version\":2,"), 0644) - if err != nil { - t.Fatal(err) - } - - _, err = GetVersion("test.json", nil) - if err == nil { - t.Fatal("Unexpected should fail to fetch version") - } - - err = ioutil.WriteFile("test.json", []byte("{ \"version\":2 }"), 0644) - if err != nil { - t.Fatal(err) - } - - _, err = GetVersion("test.json", nil) - if err == nil { - t.Fatal("Unexpected should fail to fetch version") - } -} - -func TestSaveFailOnDir(t *testing.T) { - defer os.RemoveAll("test-1.json") - err := os.MkdirAll("test-1.json", 0644) - if err != nil { - t.Fatal(err) - } - type myStruct struct { - Version string - } - saveMe := myStruct{"1"} - config, err := NewConfig(&saveMe, nil) - if err != nil { - t.Fatal(err) - } - err = config.Save("test-1.json") - if err == nil { - t.Fatal("Unexpected should fail to save if test-1.json is a directory") - } -} - -func TestCheckData(t *testing.T) { - err := CheckData(nil) - if err == nil { - t.Fatal("Unexpected should fail") - } - - type myStructBadNoVersion struct { - User string - Password string - Directories []string - } - saveMeBadNoVersion := myStructBadNoVersion{"guest", "nopassword", []string{"Work", "Documents", "Music"}} - err = CheckData(&saveMeBadNoVersion) - if err == nil { - t.Fatal("Unexpected should fail if Version is not set") - } - - type myStructBadVersionInt struct { - Version int - User string - Password string - } - saveMeBadVersionInt := myStructBadVersionInt{1, "guest", "nopassword"} - err = CheckData(&saveMeBadVersionInt) - if err == nil { - t.Fatal("Unexpected should fail if Version is integer") - } - - type myStructGood struct { - Version string - User string - Password string - Directories []string - } - - saveMeGood := myStructGood{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - err = CheckData(&saveMeGood) - if err != nil { - t.Fatal(err) - } -} - -func TestLoadFile(t *testing.T) { - type myStruct struct { - Version string - User string - Password string - Directories []string - } - saveMe := myStruct{} - _, err := LoadConfig("test.json", nil, &saveMe) - if err == nil { - t.Fatal(err) - } - - file, err := os.Create("test.json") - if err != nil { - t.Fatal(err) - } - if err = file.Close(); err != nil { - t.Fatal(err) - } - _, err = LoadConfig("test.json", nil, &saveMe) - if err == nil { - t.Fatal("Unexpected should fail to load empty JSON") - } - config, err := NewConfig(&saveMe, nil) - if err != nil { - t.Fatal(err) - } - err = config.Load("test-non-exist.json") - if err == nil { - t.Fatal("Unexpected should fail to Load non-existent config") - } - - err = config.Load("test.json") - if err == nil { - t.Fatal("Unexpected should fail to load empty JSON") - } - - saveMe = myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - config, err = NewConfig(&saveMe, nil) - if err != nil { - t.Fatal(err) - } - err = config.Save("test.json") - if err != nil { - t.Fatal(err) - } - saveMe1 := myStruct{} - _, err = LoadConfig("test.json", nil, &saveMe1) - if err != nil { - t.Fatal(err) - } - if !reflect.DeepEqual(saveMe1, saveMe) { - t.Fatalf("Expected %v, got %v", saveMe1, saveMe) - } - - saveMe2 := myStruct{} - err = json.Unmarshal([]byte(config.String()), &saveMe2) - if err != nil { - t.Fatal(err) - } - if !reflect.DeepEqual(saveMe2, saveMe1) { - t.Fatalf("Expected %v, got %v", saveMe2, saveMe1) - } -} - -func TestYAMLFormat(t *testing.T) { - testYAML := "test.yaml" - defer os.RemoveAll(testYAML) - - type myStruct struct { - Version string - User string - Password string - Directories []string - } - - plainYAML := `version: "1" -user: guest -password: nopassword -directories: -- Work -- Documents -- Music -` - - if runtime.GOOS == "windows" { - plainYAML = strings.Replace(plainYAML, "\n", "\r\n", -1) - } - - saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - - // Save format using - config, err := NewConfig(&saveMe, nil) - if err != nil { - t.Fatal(err) - } - - err = config.Save(testYAML) - if err != nil { - t.Fatal(err) - } - - // Check if the saved structure in actually an YAML format - b, err := ioutil.ReadFile(testYAML) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal([]byte(plainYAML), b) { - t.Fatalf("Expected %v, got %v", plainYAML, string(b)) - } - - // Check if the loaded data is the same as the saved one - loadMe := myStruct{} - config, err = NewConfig(&loadMe, nil) - if err != nil { - t.Fatal(err) - } - - err = config.Load(testYAML) - if err != nil { - t.Fatal(err) - } - - if !reflect.DeepEqual(saveMe, loadMe) { - t.Fatalf("Expected %v, got %v", saveMe, loadMe) - } -} - -func TestJSONFormat(t *testing.T) { - testJSON := "test.json" - defer os.RemoveAll(testJSON) - - type myStruct struct { - Version string - User string - Password string - Directories []string - } - - plainJSON := `{ - "Version": "1", - "User": "guest", - "Password": "nopassword", - "Directories": [ - "Work", - "Documents", - "Music" - ] -}` - - if runtime.GOOS == "windows" { - plainJSON = strings.Replace(plainJSON, "\n", "\r\n", -1) - } - - saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - - // Save format using - config, err := NewConfig(&saveMe, nil) - if err != nil { - t.Fatal(err) - } - - err = config.Save(testJSON) - if err != nil { - t.Fatal(err) - } - - // Check if the saved structure in actually an JSON format - b, err := ioutil.ReadFile(testJSON) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal([]byte(plainJSON), b) { - t.Fatalf("Expected %v, got %v", plainJSON, string(b)) - } - - // Check if the loaded data is the same as the saved one - loadMe := myStruct{} - config, err = NewConfig(&loadMe, nil) - if err != nil { - t.Fatal(err) - } - err = config.Load(testJSON) - if err != nil { - t.Fatal(err) - } - - if !reflect.DeepEqual(saveMe, loadMe) { - t.Fatalf("Expected %v, got %v", saveMe, loadMe) - } -} - -func TestSaveLoad(t *testing.T) { - defer os.RemoveAll("test.json") - type myStruct struct { - Version string - User string - Password string - Directories []string - } - saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - config, err := NewConfig(&saveMe, nil) - if err != nil { - t.Fatal(err) - } - err = config.Save("test.json") - if err != nil { - t.Fatal(err) - } - - loadMe := myStruct{Version: "1"} - newConfig, err := NewConfig(&loadMe, nil) - if err != nil { - t.Fatal(err) - } - err = newConfig.Load("test.json") - if err != nil { - t.Fatal(err) - } - - if !reflect.DeepEqual(config.Data(), newConfig.Data()) { - t.Fatalf("Expected %v, got %v", config.Data(), newConfig.Data()) - } - if !reflect.DeepEqual(config.Data(), &loadMe) { - t.Fatalf("Expected %v, got %v", config.Data(), &loadMe) - } - - mismatch := myStruct{"1.1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - if reflect.DeepEqual(config.Data(), &mismatch) { - t.Fatal("Expected to mismatch but succeeded instead") - } -} - -func TestSaveBackup(t *testing.T) { - defer os.RemoveAll("test.json") - defer os.RemoveAll("test.json.old") - type myStruct struct { - Version string - User string - Password string - Directories []string - } - saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - config, err := NewConfig(&saveMe, nil) - if err != nil { - t.Fatal(err) - } - err = config.Save("test.json") - if err != nil { - t.Fatal(err) - } - - loadMe := myStruct{Version: "1"} - newConfig, err := NewConfig(&loadMe, nil) - if err != nil { - t.Fatal(err) - } - err = newConfig.Load("test.json") - if err != nil { - t.Fatal(err) - } - - if !reflect.DeepEqual(config.Data(), newConfig.Data()) { - t.Fatalf("Expected %v, got %v", config.Data(), newConfig.Data()) - } - if !reflect.DeepEqual(config.Data(), &loadMe) { - t.Fatalf("Expected %v, got %v", config.Data(), &loadMe) - } - - mismatch := myStruct{"1.1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - if reflect.DeepEqual(newConfig.Data(), &mismatch) { - t.Fatal("Expected to mismatch but succeeded instead") - } - - config, err = NewConfig(&mismatch, nil) - if err != nil { - t.Fatal(err) - } - err = config.Save("test.json") - if err != nil { - t.Fatal(err) - } -} - -func TestDiff(t *testing.T) { - type myStruct struct { - Version string - User string - Password string - Directories []string - } - saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - config, err := NewConfig(&saveMe, nil) - if err != nil { - t.Fatal(err) - } - - type myNewConfigStruct struct { - Version string - // User string - Password string - Directories []string - } - - mismatch := myNewConfigStruct{"1", "nopassword", []string{"Work", "documents", "Music"}} - newConfig, err := NewConfig(&mismatch, nil) - if err != nil { - t.Fatal(err) - } - - fields, err := config.Diff(newConfig) - if err != nil { - t.Fatal(err) - } - if len(fields) != 1 { - t.Fatalf("Expected len 1, got %v", len(fields)) - } - - // Uncomment for debugging - // for i, field := range fields { - // fmt.Printf("Diff[%d]: %s=%v\n", i, field.Name(), field.Value()) - // } -} - -func TestDeepDiff(t *testing.T) { - type myStruct struct { - Version string - User string - Password string - Directories []string - } - saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - config, err := NewConfig(&saveMe, nil) - if err != nil { - t.Fatal(err) - } - - mismatch := myStruct{"1", "Guest", "nopassword", []string{"Work", "documents", "Music"}} - newConfig, err := NewConfig(&mismatch, nil) - if err != nil { - t.Fatal(err) - } - - fields, err := config.DeepDiff(newConfig) - if err != nil { - t.Fatal(err) - } - if len(fields) != 2 { - t.Fatalf("Expected len 2, got %v", len(fields)) - } - - // Uncomment for debugging - // for i, field := range fields { - // fmt.Printf("DeepDiff[%d]: %s=%v\n", i, field.Name(), field.Value()) - // } -} diff --git a/pkg/safe/safe.go b/pkg/safe/safe.go deleted file mode 100644 index 79c605081..000000000 --- a/pkg/safe/safe.go +++ /dev/null @@ -1,133 +0,0 @@ -// 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 . - -package safe - -import ( - "errors" - "io/ioutil" - "os" - "path/filepath" -) - -// File represents safe file descriptor. -type File struct { - name string - tmpfile *os.File - closed bool - aborted bool -} - -// Write writes len(b) bytes to the temporary File. In case of error, the temporary file is removed. -func (file *File) Write(b []byte) (n int, err error) { - if file.closed { - err = errors.New("write on closed file") - return - } - if file.aborted { - err = errors.New("write on aborted file") - return - } - - defer func() { - if err != nil { - os.Remove(file.tmpfile.Name()) - file.aborted = true - } - }() - - n, err = file.tmpfile.Write(b) - return -} - -// Close closes the temporary File and renames to the named file. In case of error, the temporary file is removed. -func (file *File) Close() (err error) { - defer func() { - if err != nil { - os.Remove(file.tmpfile.Name()) - file.aborted = true - } - }() - - if file.closed { - err = errors.New("close on closed file") - return - } - if file.aborted { - err = errors.New("close on aborted file") - return - } - - if err = file.tmpfile.Close(); err != nil { - return - } - - err = os.Rename(file.tmpfile.Name(), file.name) - - file.closed = true - return -} - -// Abort aborts the temporary File by closing and removing the temporary file. -func (file *File) Abort() (err error) { - if file.closed { - err = errors.New("abort on closed file") - return - } - if file.aborted { - err = errors.New("abort on aborted file") - return - } - - file.tmpfile.Close() - err = os.Remove(file.tmpfile.Name()) - file.aborted = true - return -} - -// CreateFile creates the named file safely from unique temporary file. -// The temporary file is renamed to the named file upon successful close -// to safeguard intermediate state in the named file. The temporary file -// is created in the name of the named file with suffixed unique number -// and prefixed "$tmpfile" string. While creating the temporary file, -// missing parent directories are also created. The temporary file is -// removed if case of any intermediate failure. Not removed temporary -// files can be cleaned up by identifying them using "$tmpfile" prefix -// string. -func CreateFile(name string) (*File, error) { - // ioutil.TempFile() fails if parent directory is missing. - // Create parent directory to avoid such error. - dname := filepath.Dir(name) - if err := os.MkdirAll(dname, 0700); err != nil { - return nil, err - } - - fname := filepath.Base(name) - tmpfile, err := ioutil.TempFile(dname, "$tmpfile."+fname+".") - if err != nil { - return nil, err - } - - if err = os.Chmod(tmpfile.Name(), 0600); err != nil { - if rerr := os.Remove(tmpfile.Name()); rerr != nil { - err = rerr - } - return nil, err - } - - return &File{name: name, tmpfile: tmpfile}, nil -} diff --git a/pkg/safe/safe_test.go b/pkg/safe/safe_test.go deleted file mode 100644 index 83345caf2..000000000 --- a/pkg/safe/safe_test.go +++ /dev/null @@ -1,193 +0,0 @@ -// 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 . - -package safe - -import ( - "io/ioutil" - "os" - "path" - "testing" -) - -type MySuite struct { - root string -} - -func (s *MySuite) SetUpSuite(t *testing.T) { - root, err := ioutil.TempDir(os.TempDir(), "safe_test.go.") - if err != nil { - t.Fatal(err) - } - s.root = root -} - -func (s *MySuite) TearDownSuite(t *testing.T) { - err := os.RemoveAll(s.root) - if err != nil { - t.Fatal(err) - } -} - -func TestSafeAbort(t *testing.T) { - s := &MySuite{} - s.SetUpSuite(t) - defer s.TearDownSuite(t) - - f, err := CreateFile(path.Join(s.root, "testfile-abort")) - if err != nil { - t.Fatal(err) - } - - _, err = os.Stat(path.Join(s.root, "testfile-abort")) - if !os.IsNotExist(err) { - t.Fatal(err) - } - err = f.Abort() - if err != nil { - t.Fatal(err) - } - err = f.Close() - if err != nil { - if err.Error() != "close on aborted file" { - t.Fatal(err) - } - } -} - -func TestSafeClose(t *testing.T) { - s := &MySuite{} - s.SetUpSuite(t) - defer s.TearDownSuite(t) - - f, err := CreateFile(path.Join(s.root, "testfile-close")) - if err != nil { - t.Fatal(err) - } - - _, err = os.Stat(path.Join(s.root, "testfile-close")) - if !os.IsNotExist(err) { - t.Fatal(err) - } - - err = f.Close() - if err != nil { - t.Fatal(err) - } - - _, err = os.Stat(path.Join(s.root, "testfile-close")) - if err != nil { - t.Fatal(err) - } - - err = os.Remove(path.Join(s.root, "testfile-close")) - if err != nil { - t.Fatal(err) - } - - err = f.Abort() - if err != nil { - if err.Error() != "abort on closed file" { - t.Fatal(err) - } - } -} - -func TestSafe(t *testing.T) { - s := &MySuite{} - s.SetUpSuite(t) - defer s.TearDownSuite(t) - - f, err := CreateFile(path.Join(s.root, "testfile-safe")) - if err != nil { - t.Fatal(err) - } - - _, err = os.Stat(path.Join(s.root, "testfile-safe")) - if !os.IsNotExist(err) { - t.Fatal(err) - } - - err = f.Close() - if err != nil { - t.Fatal(err) - } - - _, err = f.Write([]byte("Test")) - if err != nil { - if err.Error() != "write on closed file" { - t.Fatal(err) - } - } - - err = f.Close() - if err != nil { - if err.Error() != "close on closed file" { - t.Fatal(err) - } - } - - _, err = os.Stat(path.Join(s.root, "testfile-safe")) - if err != nil { - t.Fatal(err) - } - - err = os.Remove(path.Join(s.root, "testfile-safe")) - if err != nil { - t.Fatal(err) - } -} - -func TestSafeAbortWrite(t *testing.T) { - s := &MySuite{} - s.SetUpSuite(t) - defer s.TearDownSuite(t) - - f, err := CreateFile(path.Join(s.root, "purgefile-abort")) - if err != nil { - t.Fatal(err) - } - - _, err = os.Stat(path.Join(s.root, "purgefile-abort")) - if !os.IsNotExist(err) { - t.Fatal(err) - } - - err = f.Abort() - if err != nil { - t.Fatal(err) - } - - _, err = os.Stat(path.Join(s.root, "purgefile-abort")) - if !os.IsNotExist(err) { - t.Fatal(err) - } - - err = f.Abort() - if err != nil { - if err.Error() != "abort on aborted file" { - t.Fatal(err) - } - } - - _, err = f.Write([]byte("Test")) - if err != nil { - if err.Error() != "write on aborted file" { - t.Fatal(err) - } - } -} diff --git a/pkg/sys/rlimit-file_bsd.go b/pkg/sys/rlimit-file_bsd.go deleted file mode 100644 index 5ece8436d..000000000 --- a/pkg/sys/rlimit-file_bsd.go +++ /dev/null @@ -1,41 +0,0 @@ -// +build freebsd dragonfly - -// 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 . - -package sys - -import ( - "syscall" -) - -// GetMaxOpenFileLimit - returns maximum file descriptor number that can be opened by this process. -func GetMaxOpenFileLimit() (curLimit, maxLimit uint64, err error) { - var rlimit syscall.Rlimit - if err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlimit); err == nil { - curLimit = uint64(rlimit.Cur) - maxLimit = uint64(rlimit.Max) - } - - return curLimit, maxLimit, err -} - -// SetMaxOpenFileLimit - sets maximum file descriptor number that can be opened by this process. -func SetMaxOpenFileLimit(curLimit, maxLimit uint64) error { - rlimit := syscall.Rlimit{Cur: int64(curLimit), Max: int64(curLimit)} - return syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rlimit) -} diff --git a/pkg/sys/rlimit-file_nix.go b/pkg/sys/rlimit-file_nix.go deleted file mode 100644 index 1ac5c3623..000000000 --- a/pkg/sys/rlimit-file_nix.go +++ /dev/null @@ -1,49 +0,0 @@ -// +build linux darwin openbsd netbsd solaris - -// 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 . - -package sys - -import ( - "runtime" - "syscall" -) - -// GetMaxOpenFileLimit - returns maximum file descriptor number that can be opened by this process. -func GetMaxOpenFileLimit() (curLimit, maxLimit uint64, err error) { - var rlimit syscall.Rlimit - if err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlimit); err == nil { - curLimit = rlimit.Cur - maxLimit = rlimit.Max - } - - return curLimit, maxLimit, err -} - -// SetMaxOpenFileLimit - sets maximum file descriptor number that can be opened by this process. -func SetMaxOpenFileLimit(curLimit, maxLimit uint64) error { - if runtime.GOOS == "darwin" && curLimit > 10240 { - // The max file limit is 10240, even though - // the max returned by Getrlimit is 1<<63-1. - // This is OPEN_MAX in sys/syslimits.h. - // refer https://github.com/golang/go/issues/30401 - curLimit = 10240 - } - rlimit := syscall.Rlimit{Cur: curLimit, Max: maxLimit} - return syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rlimit) -} diff --git a/pkg/sys/rlimit-file_test.go b/pkg/sys/rlimit-file_test.go deleted file mode 100644 index 1d8145c1b..000000000 --- a/pkg/sys/rlimit-file_test.go +++ /dev/null @@ -1,41 +0,0 @@ -// 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 . - -package sys - -import "testing" - -// Test get max open file limit. -func TestGetMaxOpenFileLimit(t *testing.T) { - _, _, err := GetMaxOpenFileLimit() - if err != nil { - t.Errorf("expected: nil, got: %v", err) - } -} - -// Test set open file limit -func TestSetMaxOpenFileLimit(t *testing.T) { - curLimit, maxLimit, err := GetMaxOpenFileLimit() - if err != nil { - t.Fatalf("Unable to get max open file limit. %v", err) - } - - err = SetMaxOpenFileLimit(curLimit, maxLimit) - if err != nil { - t.Errorf("expected: nil, got: %v", err) - } -} diff --git a/pkg/sys/rlimit-file_windows.go b/pkg/sys/rlimit-file_windows.go deleted file mode 100644 index f9f621724..000000000 --- a/pkg/sys/rlimit-file_windows.go +++ /dev/null @@ -1,32 +0,0 @@ -// +build windows - -// 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 . - -package sys - -// GetMaxOpenFileLimit - returns maximum file descriptor number that can be opened by this process. -func GetMaxOpenFileLimit() (curLimit, maxLimit uint64, err error) { - // Nothing to do for windows. - return curLimit, maxLimit, err -} - -// SetMaxOpenFileLimit - sets maximum file descriptor number that can be opened by this process. -func SetMaxOpenFileLimit(curLimit, maxLimit uint64) error { - // Nothing to do for windows. - return nil -} diff --git a/pkg/sys/rlimit-memory_bsd.go b/pkg/sys/rlimit-memory_bsd.go deleted file mode 100644 index a0b68675f..000000000 --- a/pkg/sys/rlimit-memory_bsd.go +++ /dev/null @@ -1,39 +0,0 @@ -// +build freebsd dragonfly - -// 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 . - -package sys - -import "syscall" - -// GetMaxMemoryLimit - returns the maximum size of the process's virtual memory (address space) in bytes. -func GetMaxMemoryLimit() (curLimit, maxLimit uint64, err error) { - var rlimit syscall.Rlimit - if err = syscall.Getrlimit(syscall.RLIMIT_DATA, &rlimit); err == nil { - curLimit = uint64(rlimit.Cur) - maxLimit = uint64(rlimit.Max) - } - - return curLimit, maxLimit, err -} - -// SetMaxMemoryLimit - sets the maximum size of the process's virtual memory (address space) in bytes. -func SetMaxMemoryLimit(curLimit, maxLimit uint64) error { - rlimit := syscall.Rlimit{Cur: int64(curLimit), Max: int64(maxLimit)} - return syscall.Setrlimit(syscall.RLIMIT_DATA, &rlimit) -} diff --git a/pkg/sys/rlimit-memory_nix.go b/pkg/sys/rlimit-memory_nix.go deleted file mode 100644 index 1a9398c86..000000000 --- a/pkg/sys/rlimit-memory_nix.go +++ /dev/null @@ -1,39 +0,0 @@ -// +build linux darwin netbsd solaris - -// 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 . - -package sys - -import "syscall" - -// GetMaxMemoryLimit - returns the maximum size of the process's virtual memory (address space) in bytes. -func GetMaxMemoryLimit() (curLimit, maxLimit uint64, err error) { - var rlimit syscall.Rlimit - if err = syscall.Getrlimit(syscall.RLIMIT_AS, &rlimit); err == nil { - curLimit = rlimit.Cur - maxLimit = rlimit.Max - } - - return curLimit, maxLimit, err -} - -// SetMaxMemoryLimit - sets the maximum size of the process's virtual memory (address space) in bytes. -func SetMaxMemoryLimit(curLimit, maxLimit uint64) error { - rlimit := syscall.Rlimit{Cur: curLimit, Max: maxLimit} - return syscall.Setrlimit(syscall.RLIMIT_AS, &rlimit) -} diff --git a/pkg/sys/rlimit-memory_openbsd.go b/pkg/sys/rlimit-memory_openbsd.go deleted file mode 100644 index 89caf15f5..000000000 --- a/pkg/sys/rlimit-memory_openbsd.go +++ /dev/null @@ -1,39 +0,0 @@ -// +build openbsd - -// 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 . - -package sys - -import "syscall" - -// GetMaxMemoryLimit - returns the maximum size of the process's virtual memory (address space) in bytes. -func GetMaxMemoryLimit() (curLimit, maxLimit uint64, err error) { - var rlimit syscall.Rlimit - if err = syscall.Getrlimit(syscall.RLIMIT_DATA, &rlimit); err == nil { - curLimit = rlimit.Cur - maxLimit = rlimit.Max - } - - return curLimit, maxLimit, err -} - -// SetMaxMemoryLimit - sets the maximum size of the process's virtual memory (address space) in bytes. -func SetMaxMemoryLimit(curLimit, maxLimit uint64) error { - rlimit := syscall.Rlimit{Cur: curLimit, Max: maxLimit} - return syscall.Setrlimit(syscall.RLIMIT_DATA, &rlimit) -} diff --git a/pkg/sys/rlimit-memory_test.go b/pkg/sys/rlimit-memory_test.go deleted file mode 100644 index 9e2c1efe8..000000000 --- a/pkg/sys/rlimit-memory_test.go +++ /dev/null @@ -1,41 +0,0 @@ -// 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 . - -package sys - -import "testing" - -// Test get max memory limit. -func TestGetMaxMemoryLimit(t *testing.T) { - _, _, err := GetMaxMemoryLimit() - if err != nil { - t.Errorf("expected: nil, got: %v", err) - } -} - -// Test set memory limit -func TestSetMaxMemoryLimit(t *testing.T) { - curLimit, maxLimit, err := GetMaxMemoryLimit() - if err != nil { - t.Fatalf("Unable to get max memory limit. %v", err) - } - - err = SetMaxMemoryLimit(curLimit, maxLimit) - if err != nil { - t.Errorf("expected: nil, got: %v", err) - } -} diff --git a/pkg/sys/rlimit-memory_windows.go b/pkg/sys/rlimit-memory_windows.go deleted file mode 100644 index d93375b5b..000000000 --- a/pkg/sys/rlimit-memory_windows.go +++ /dev/null @@ -1,32 +0,0 @@ -// +build windows - -// 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 . - -package sys - -// GetMaxMemoryLimit - returns the maximum size of the process's virtual memory (address space) in bytes. -func GetMaxMemoryLimit() (curLimit, maxLimit uint64, err error) { - // Nothing to do for windows. - return curLimit, maxLimit, err -} - -// SetMaxMemoryLimit - sets the maximum size of the process's virtual memory (address space) in bytes. -func SetMaxMemoryLimit(curLimit, maxLimit uint64) error { - // Nothing to do for windows. - return nil -} diff --git a/pkg/sys/stats.go b/pkg/sys/stats.go deleted file mode 100644 index 32748dc34..000000000 --- a/pkg/sys/stats.go +++ /dev/null @@ -1,23 +0,0 @@ -// 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 . - -package sys - -// Stats - system statistics. -type Stats struct { - TotalRAM uint64 // Physical RAM size in bytes, -} diff --git a/pkg/sys/stats_bsd.go b/pkg/sys/stats_bsd.go deleted file mode 100644 index ca527feb7..000000000 --- a/pkg/sys/stats_bsd.go +++ /dev/null @@ -1,46 +0,0 @@ -// +build openbsd freebsd dragonfly - -// 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 . - -package sys - -import ( - "encoding/binary" - "syscall" -) - -func getHwPhysmem() (uint64, error) { - totalString, err := syscall.Sysctl("hw.physmem") - if err != nil { - return 0, err - } - - // syscall.sysctl() helpfully assumes the result is a null-terminated string and - // removes the last byte of the result if it's 0 :/ - totalString += "\x00" - - total := uint64(binary.LittleEndian.Uint64([]byte(totalString))) - - return total, nil -} - -// GetStats - return system statistics for bsd. -func GetStats() (stats Stats, err error) { - stats.TotalRAM, err = getHwPhysmem() - return stats, err -} diff --git a/pkg/sys/stats_darwin.go b/pkg/sys/stats_darwin.go deleted file mode 100644 index 0ac4df0b7..000000000 --- a/pkg/sys/stats_darwin.go +++ /dev/null @@ -1,44 +0,0 @@ -// +build darwin - -// 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 . - -package sys - -import ( - "encoding/binary" - "syscall" -) - -func getHwMemsize() (uint64, error) { - totalString, err := syscall.Sysctl("hw.memsize") - if err != nil { - return 0, err - } - - // syscall.sysctl() helpfully assumes the result is a null-terminated string and - // removes the last byte of the result if it's 0 :/ - totalString += "\x00" - - return binary.LittleEndian.Uint64([]byte(totalString)), nil -} - -// GetStats - return system statistics for macOS. -func GetStats() (stats Stats, err error) { - stats.TotalRAM, err = getHwMemsize() - return stats, err -} diff --git a/pkg/sys/stats_linux.go b/pkg/sys/stats_linux.go deleted file mode 100644 index b5fc99abb..000000000 --- a/pkg/sys/stats_linux.go +++ /dev/null @@ -1,88 +0,0 @@ -// +build linux,!arm,!386 - -// 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 . - -package sys - -import ( - "os" - "syscall" - - "github.com/minio/minio/pkg/cgroup" -) - -// Get the final system memory limit chosen by the user. -// by default without any configuration on a vanilla Linux -// system you would see physical RAM limit. If cgroup -// is configured at some point in time this function -// would return the memory limit chosen for the given pid. -func getMemoryLimit() (sysLimit uint64, err error) { - if sysLimit, err = getSysinfoMemoryLimit(); err != nil { - // Physical memory info is not accessible, just exit here. - return 0, err - } - - // Following code is deliberately ignoring the error. - cGroupLimit, gerr := cgroup.GetMemoryLimit(os.Getpid()) - if gerr != nil { - // Upon error just return system limit. - return sysLimit, nil - } - - // cgroup limit is lesser than system limit means - // user wants to limit the memory usage further - // treat cgroup limit as the system limit. - if cGroupLimit <= sysLimit { - sysLimit = cGroupLimit - } - - // Final system limit. - return sysLimit, nil - -} - -// Get physical RAM size of the node. -func getSysinfoMemoryLimit() (limit uint64, err error) { - var si syscall.Sysinfo_t - if err = syscall.Sysinfo(&si); err != nil { - return 0, err - } - - // Some fields in syscall.Sysinfo_t have different integer sizes - // in different platform architectures. Cast all fields to uint64. - unit := si.Unit - totalRAM := si.Totalram - - // Total RAM is always the multiplicative value - // of unit size and total ram. - //nolint:unconvert - return uint64(unit) * uint64(totalRAM), nil -} - -// GetStats - return system statistics, currently only -// supported value is TotalRAM. -func GetStats() (stats Stats, err error) { - var limit uint64 - limit, err = getMemoryLimit() - if err != nil { - return Stats{}, err - } - - stats.TotalRAM = limit - return stats, nil -} diff --git a/pkg/sys/stats_linux_32bit.go b/pkg/sys/stats_linux_32bit.go deleted file mode 100644 index 627439b85..000000000 --- a/pkg/sys/stats_linux_32bit.go +++ /dev/null @@ -1,87 +0,0 @@ -// +build linux,arm linux,386 - -// 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 . - -package sys - -import ( - "os" - "syscall" - - "github.com/minio/minio/pkg/cgroup" -) - -// Get the final system memory limit chosen by the user. -// by default without any configuration on a vanilla Linux -// system you would see physical RAM limit. If cgroup -// is configured at some point in time this function -// would return the memory limit chosen for the given pid. -func getMemoryLimit() (sysLimit uint64, err error) { - if sysLimit, err = getSysinfoMemoryLimit(); err != nil { - // Physical memory info is not accessible, just exit here. - return 0, err - } - - // Following code is deliberately ignoring the error. - cGroupLimit, gerr := cgroup.GetMemoryLimit(os.Getpid()) - if gerr != nil { - // Upon error just return system limit. - return sysLimit, nil - } - - // cgroup limit is lesser than system limit means - // user wants to limit the memory usage further - // treat cgroup limit as the system limit. - if cGroupLimit <= sysLimit { - sysLimit = cGroupLimit - } - - // Final system limit. - return sysLimit, nil - -} - -// Get physical RAM size of the node. -func getSysinfoMemoryLimit() (limit uint64, err error) { - var si syscall.Sysinfo_t - if err = syscall.Sysinfo(&si); err != nil { - return 0, err - } - - // Some fields in syscall.Sysinfo_t have different integer sizes - // in different platform architectures. Cast all fields to uint64. - unit := si.Unit - totalRAM := si.Totalram - - // Total RAM is always the multiplicative value - // of unit size and total ram. - return uint64(unit) * uint64(totalRAM), nil -} - -// GetStats - return system statistics, currently only -// supported value is TotalRAM. -func GetStats() (stats Stats, err error) { - var limit uint64 - limit, err = getMemoryLimit() - if err != nil { - return Stats{}, err - } - - stats.TotalRAM = limit - return stats, nil -} diff --git a/pkg/sys/stats_netbsd.go b/pkg/sys/stats_netbsd.go deleted file mode 100644 index e44ca4cb5..000000000 --- a/pkg/sys/stats_netbsd.go +++ /dev/null @@ -1,46 +0,0 @@ -// +build netbsd - -// 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 . - -package sys - -import ( - "encoding/binary" - "syscall" -) - -func getHwPhysmem() (uint64, error) { - totalString, err := syscall.Sysctl("hw.physmem64") - if err != nil { - return 0, err - } - - // syscall.sysctl() helpfully assumes the result is a null-terminated string and - // removes the last byte of the result if it's 0 :/ - totalString += "\x00" - - total := uint64(binary.LittleEndian.Uint64([]byte(totalString))) - - return total, nil -} - -// GetStats - return system statistics for bsd. -func GetStats() (stats Stats, err error) { - stats.TotalRAM, err = getHwPhysmem() - return stats, err -} diff --git a/pkg/sys/stats_solaris.go b/pkg/sys/stats_solaris.go deleted file mode 100644 index b8d4f622d..000000000 --- a/pkg/sys/stats_solaris.go +++ /dev/null @@ -1,26 +0,0 @@ -// 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 . - -package sys - -import "errors" - -// GetStats - stub implementation for Solaris, this will not give us -// complete functionality but will enable fs setups on Solaris. -func GetStats() (stats Stats, err error) { - return Stats{}, errors.New("Not implemented") -} diff --git a/pkg/sys/stats_test.go b/pkg/sys/stats_test.go deleted file mode 100644 index f39db2b02..000000000 --- a/pkg/sys/stats_test.go +++ /dev/null @@ -1,31 +0,0 @@ -// 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 . - -package sys - -import "testing" - -// Test get stats result. -func TestGetStats(t *testing.T) { - stats, err := GetStats() - if err != nil { - t.Errorf("Tests: Expected `nil`, Got %s", err) - } - if stats.TotalRAM == 0 { - t.Errorf("Tests: Expected `n > 0`, Got %d", stats.TotalRAM) - } -} diff --git a/pkg/sys/stats_windows.go b/pkg/sys/stats_windows.go deleted file mode 100644 index 04646a1f6..000000000 --- a/pkg/sys/stats_windows.go +++ /dev/null @@ -1,57 +0,0 @@ -// +build windows - -// 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 . - -package sys - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -var ( - modkernel32 = windows.NewLazySystemDLL("kernel32.dll") - procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx") -) - -type memoryStatusEx struct { - cbSize uint32 - dwMemoryLoad uint32 - ullTotalPhys uint64 // in bytes - ullAvailPhys uint64 - ullTotalPageFile uint64 - ullAvailPageFile uint64 - ullTotalVirtual uint64 - ullAvailVirtual uint64 - ullAvailExtendedVirtual uint64 -} - -// GetStats - return system statistics for windows. -func GetStats() (stats Stats, err error) { - var memInfo memoryStatusEx - memInfo.cbSize = uint32(unsafe.Sizeof(memInfo)) - if mem, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo))); mem == 0 { - err = syscall.GetLastError() - } else { - stats.TotalRAM = memInfo.ullTotalPhys - } - - return stats, err -} diff --git a/pkg/sys/threads.go b/pkg/sys/threads.go deleted file mode 100644 index 3e83c01a1..000000000 --- a/pkg/sys/threads.go +++ /dev/null @@ -1,39 +0,0 @@ -// +build linux - -// 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 . - -package sys - -import ( - "io/ioutil" - "strconv" - "strings" -) - -// GetMaxThreads returns the maximum number of threads that the system can create. -func GetMaxThreads() (int, error) { - sysMaxThreadsStr, err := ioutil.ReadFile("/proc/sys/kernel/threads-max") - if err != nil { - return 0, err - } - sysMaxThreads, err := strconv.Atoi(strings.TrimSpace(string(sysMaxThreadsStr))) - if err != nil { - return 0, err - } - return sysMaxThreads, nil -} diff --git a/pkg/sys/threads_other.go b/pkg/sys/threads_other.go deleted file mode 100644 index b1991e55b..000000000 --- a/pkg/sys/threads_other.go +++ /dev/null @@ -1,27 +0,0 @@ -// +build !linux - -// 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 . - -package sys - -import "errors" - -// GetMaxThreads returns the maximum number of threads that the system can create. -func GetMaxThreads() (int, error) { - return 0, errors.New("getting max threads is not supported") -} diff --git a/pkg/trie/trie.go b/pkg/trie/trie.go deleted file mode 100644 index f661e68fc..000000000 --- a/pkg/trie/trie.go +++ /dev/null @@ -1,119 +0,0 @@ -// 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 . - -// Package trie implements a simple trie tree for minio server/tools borrows -// idea from - https://godoc.org/golang.org/x/text/internal/triegen. -package trie - -// Node trie tree node container carries value and children. -type Node struct { - exists bool - value string - child map[rune]*Node // runes as child. -} - -// newNode create a new trie node. -func newNode() *Node { - return &Node{ - exists: false, - value: "", - child: make(map[rune]*Node), - } -} - -// Trie is a trie container. -type Trie struct { - root *Node - size int -} - -// Root returns root node. -func (t *Trie) Root() *Node { - return t.root -} - -// Insert insert a key. -func (t *Trie) Insert(key string) { - curNode := t.root - for _, v := range key { - if curNode.child[v] == nil { - curNode.child[v] = newNode() - } - curNode = curNode.child[v] - } - - if !curNode.exists { - // increment when new rune child is added. - t.size++ - curNode.exists = true - } - // value is stored for retrieval in future. - curNode.value = key -} - -// PrefixMatch - prefix match. -func (t *Trie) PrefixMatch(key string) []string { - node, _ := t.findNode(key) - if node == nil { - return nil - } - return t.Walk(node) -} - -// Walk the tree. -func (t *Trie) Walk(node *Node) (ret []string) { - if node.exists { - ret = append(ret, node.value) - } - for _, v := range node.child { - ret = append(ret, t.Walk(v)...) - } - return -} - -// find nodes corresponding to key. -func (t *Trie) findNode(key string) (node *Node, index int) { - curNode := t.root - f := false - for k, v := range key { - if f { - index = k - f = false - } - if curNode.child[v] == nil { - return nil, index - } - curNode = curNode.child[v] - if curNode.exists { - f = true - } - } - - if curNode.exists { - index = len(key) - } - - return curNode, index -} - -// NewTrie create a new trie. -func NewTrie() *Trie { - return &Trie{ - root: newNode(), - size: 0, - } -} diff --git a/pkg/trie/trie_test.go b/pkg/trie/trie_test.go deleted file mode 100644 index 566f4e36a..000000000 --- a/pkg/trie/trie_test.go +++ /dev/null @@ -1,69 +0,0 @@ -// 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 . - -package trie - -import ( - "testing" -) - -// Simply make sure creating a new tree works. -func TestNewTrie(t *testing.T) { - trie := NewTrie() - - if trie.size != 0 { - t.Errorf("expected size 0, got: %d", trie.size) - } -} - -// Ensure that we can insert new keys into the tree, then check the size. -func TestInsert(t *testing.T) { - trie := NewTrie() - - // We need to have an empty tree to begin with. - if trie.size != 0 { - t.Errorf("expected size 0, got: %d", trie.size) - } - - trie.Insert("key") - trie.Insert("keyy") - - // After inserting, we should have a size of two. - if trie.size != 2 { - t.Errorf("expected size 2, got: %d", trie.size) - } -} - -// Ensure that PrefixMatch gives us the correct two keys in the tree. -func TestPrefixMatch(t *testing.T) { - trie := NewTrie() - - // Feed it some fodder: only 'minio' and 'miny-os' should trip the matcher. - trie.Insert("minio") - trie.Insert("amazon") - trie.Insert("cheerio") - trie.Insert("miny-o's") - - matches := trie.PrefixMatch("min") - if len(matches) != 2 { - t.Errorf("expected two matches, got: %d", len(matches)) - } - - if matches[0] != "minio" && matches[1] != "minio" { - t.Errorf("expected one match to be 'minio', got: '%s' and '%s'", matches[0], matches[1]) - } -} diff --git a/pkg/wildcard/match.go b/pkg/wildcard/match.go deleted file mode 100644 index 78f20f5de..000000000 --- a/pkg/wildcard/match.go +++ /dev/null @@ -1,68 +0,0 @@ -// 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 . - -package wildcard - -// MatchSimple - finds whether the text matches/satisfies the pattern string. -// supports only '*' wildcard in the pattern. -// considers a file system path as a flat name space. -func MatchSimple(pattern, name string) bool { - if pattern == "" { - return name == pattern - } - if pattern == "*" { - return true - } - // Does only wildcard '*' match. - return deepMatchRune([]rune(name), []rune(pattern), true) -} - -// Match - finds whether the text matches/satisfies the pattern string. -// supports '*' and '?' wildcards in the pattern string. -// unlike path.Match(), considers a path as a flat name space while matching the pattern. -// The difference is illustrated in the example here https://play.golang.org/p/Ega9qgD4Qz . -func Match(pattern, name string) (matched bool) { - if pattern == "" { - return name == pattern - } - if pattern == "*" { - return true - } - // Does extended wildcard '*' and '?' match. - return deepMatchRune([]rune(name), []rune(pattern), false) -} - -func deepMatchRune(str, pattern []rune, simple bool) bool { - for len(pattern) > 0 { - switch pattern[0] { - default: - if len(str) == 0 || str[0] != pattern[0] { - return false - } - case '?': - if len(str) == 0 && !simple { - return false - } - case '*': - return deepMatchRune(str, pattern[1:], simple) || - (len(str) > 0 && deepMatchRune(str[1:], pattern, simple)) - } - str = str[1:] - pattern = pattern[1:] - } - return len(str) == 0 && len(pattern) == 0 -} diff --git a/pkg/wildcard/match_test.go b/pkg/wildcard/match_test.go deleted file mode 100644 index 11348c34f..000000000 --- a/pkg/wildcard/match_test.go +++ /dev/null @@ -1,543 +0,0 @@ -// 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 . - -package wildcard_test - -import ( - "testing" - - "github.com/minio/minio/pkg/wildcard" -) - -// TestMatch - Tests validate the logic of wild card matching. -// `Match` supports '*' and '?' wildcards. -// Sample usage: In resource matching for bucket policy validation. -func TestMatch(t *testing.T) { - testCases := []struct { - pattern string - text string - matched bool - }{ - // Test case - 1. - // Test case with pattern "*". Expected to match any text. - { - pattern: "*", - text: "s3:GetObject", - matched: true, - }, - // Test case - 2. - // Test case with empty pattern. This only matches empty string. - { - pattern: "", - text: "s3:GetObject", - matched: false, - }, - // Test case - 3. - // Test case with empty pattern. This only matches empty string. - { - pattern: "", - text: "", - matched: true, - }, - // Test case - 4. - // Test case with single "*" at the end. - { - pattern: "s3:*", - text: "s3:ListMultipartUploadParts", - matched: true, - }, - // Test case - 5. - // Test case with a no "*". In this case the pattern and text should be the same. - { - pattern: "s3:ListBucketMultipartUploads", - text: "s3:ListBucket", - matched: false, - }, - // Test case - 6. - // Test case with a no "*". In this case the pattern and text should be the same. - { - pattern: "s3:ListBucket", - text: "s3:ListBucket", - matched: true, - }, - // Test case - 7. - // Test case with a no "*". In this case the pattern and text should be the same. - { - pattern: "s3:ListBucketMultipartUploads", - text: "s3:ListBucketMultipartUploads", - matched: true, - }, - // Test case - 8. - // Test case with pattern containing key name with a prefix. Should accept the same text without a "*". - { - pattern: "my-bucket/oo*", - text: "my-bucket/oo", - matched: true, - }, - // Test case - 9. - // Test case with "*" at the end of the pattern. - { - pattern: "my-bucket/In*", - text: "my-bucket/India/Karnataka/", - matched: true, - }, - // Test case - 10. - // Test case with prefixes shuffled. - // This should fail. - { - pattern: "my-bucket/In*", - text: "my-bucket/Karnataka/India/", - matched: false, - }, - // Test case - 11. - // Test case with text expanded to the wildcards in the pattern. - { - pattern: "my-bucket/In*/Ka*/Ban", - text: "my-bucket/India/Karnataka/Ban", - matched: true, - }, - // Test case - 12. - // Test case with the keyname part is repeated as prefix several times. - // This is valid. - { - pattern: "my-bucket/In*/Ka*/Ban", - text: "my-bucket/India/Karnataka/Ban/Ban/Ban/Ban/Ban", - matched: true, - }, - // Test case - 13. - // Test case to validate that `*` can be expanded into multiple prefixes. - { - pattern: "my-bucket/In*/Ka*/Ban", - text: "my-bucket/India/Karnataka/Area1/Area2/Area3/Ban", - matched: true, - }, - // Test case - 14. - // Test case to validate that `*` can be expanded into multiple prefixes. - { - pattern: "my-bucket/In*/Ka*/Ban", - text: "my-bucket/India/State1/State2/Karnataka/Area1/Area2/Area3/Ban", - matched: true, - }, - // Test case - 15. - // Test case where the keyname part of the pattern is expanded in the text. - { - pattern: "my-bucket/In*/Ka*/Ban", - text: "my-bucket/India/Karnataka/Bangalore", - matched: false, - }, - // Test case - 16. - // Test case with prefixes and wildcard expanded for all "*". - { - pattern: "my-bucket/In*/Ka*/Ban*", - text: "my-bucket/India/Karnataka/Bangalore", - matched: true, - }, - // Test case - 17. - // Test case with keyname part being a wildcard in the pattern. - { - pattern: "my-bucket/*", - text: "my-bucket/India", - matched: true, - }, - // Test case - 18. - { - pattern: "my-bucket/oo*", - text: "my-bucket/odo", - matched: false, - }, - - // Test case with pattern containing wildcard '?'. - // Test case - 19. - // "my-bucket?/" matches "my-bucket1/", "my-bucket2/", "my-bucket3" etc... - // doesn't match "mybucket/". - { - pattern: "my-bucket?/abc*", - text: "mybucket/abc", - matched: false, - }, - // Test case - 20. - { - pattern: "my-bucket?/abc*", - text: "my-bucket1/abc", - matched: true, - }, - // Test case - 21. - { - pattern: "my-?-bucket/abc*", - text: "my--bucket/abc", - matched: false, - }, - // Test case - 22. - { - pattern: "my-?-bucket/abc*", - text: "my-1-bucket/abc", - matched: true, - }, - // Test case - 23. - { - pattern: "my-?-bucket/abc*", - text: "my-k-bucket/abc", - matched: true, - }, - // Test case - 24. - { - pattern: "my??bucket/abc*", - text: "mybucket/abc", - matched: false, - }, - // Test case - 25. - { - pattern: "my??bucket/abc*", - text: "my4abucket/abc", - matched: true, - }, - // Test case - 26. - { - pattern: "my-bucket?abc*", - text: "my-bucket/abc", - matched: true, - }, - // Test case 27-28. - // '?' matches '/' too. (works with s3). - // This is because the namespace is considered flat. - // "abc?efg" matches both "abcdefg" and "abc/efg". - { - pattern: "my-bucket/abc?efg", - text: "my-bucket/abcdefg", - matched: true, - }, - { - pattern: "my-bucket/abc?efg", - text: "my-bucket/abc/efg", - matched: true, - }, - // Test case - 29. - { - pattern: "my-bucket/abc????", - text: "my-bucket/abc", - matched: false, - }, - // Test case - 30. - { - pattern: "my-bucket/abc????", - text: "my-bucket/abcde", - matched: false, - }, - // Test case - 31. - { - pattern: "my-bucket/abc????", - text: "my-bucket/abcdefg", - matched: true, - }, - // Test case 32-34. - // test case with no '*'. - { - pattern: "my-bucket/abc?", - text: "my-bucket/abc", - matched: false, - }, - { - pattern: "my-bucket/abc?", - text: "my-bucket/abcd", - matched: true, - }, - { - pattern: "my-bucket/abc?", - text: "my-bucket/abcde", - matched: false, - }, - // Test case 35. - { - pattern: "my-bucket/mnop*?", - text: "my-bucket/mnop", - matched: false, - }, - // Test case 36. - { - pattern: "my-bucket/mnop*?", - text: "my-bucket/mnopqrst/mnopqr", - matched: true, - }, - // Test case 37. - { - pattern: "my-bucket/mnop*?", - text: "my-bucket/mnopqrst/mnopqrs", - matched: true, - }, - // Test case 38. - { - pattern: "my-bucket/mnop*?", - text: "my-bucket/mnop", - matched: false, - }, - // Test case 39. - { - pattern: "my-bucket/mnop*?", - text: "my-bucket/mnopq", - matched: true, - }, - // Test case 40. - { - pattern: "my-bucket/mnop*?", - text: "my-bucket/mnopqr", - matched: true, - }, - // Test case 41. - { - pattern: "my-bucket/mnop*?and", - text: "my-bucket/mnopqand", - matched: true, - }, - // Test case 42. - { - pattern: "my-bucket/mnop*?and", - text: "my-bucket/mnopand", - matched: false, - }, - // Test case 43. - { - pattern: "my-bucket/mnop*?and", - text: "my-bucket/mnopqand", - matched: true, - }, - // Test case 44. - { - pattern: "my-bucket/mnop*?", - text: "my-bucket/mn", - matched: false, - }, - // Test case 45. - { - pattern: "my-bucket/mnop*?", - text: "my-bucket/mnopqrst/mnopqrs", - matched: true, - }, - // Test case 46. - { - pattern: "my-bucket/mnop*??", - text: "my-bucket/mnopqrst", - matched: true, - }, - // Test case 47. - { - pattern: "my-bucket/mnop*qrst", - text: "my-bucket/mnopabcdegqrst", - matched: true, - }, - // Test case 48. - { - pattern: "my-bucket/mnop*?and", - text: "my-bucket/mnopqand", - matched: true, - }, - // Test case 49. - { - pattern: "my-bucket/mnop*?and", - text: "my-bucket/mnopand", - matched: false, - }, - // Test case 50. - { - pattern: "my-bucket/mnop*?and?", - text: "my-bucket/mnopqanda", - matched: true, - }, - // Test case 51. - { - pattern: "my-bucket/mnop*?and", - text: "my-bucket/mnopqanda", - matched: false, - }, - // Test case 52. - - { - pattern: "my-?-bucket/abc*", - text: "my-bucket/mnopqanda", - matched: false, - }, - } - // Iterating over the test cases, call the function under test and asert the output. - for i, testCase := range testCases { - actualResult := wildcard.Match(testCase.pattern, testCase.text) - if testCase.matched != actualResult { - t.Errorf("Test %d: Expected the result to be `%v`, but instead found it to be `%v`", i+1, testCase.matched, actualResult) - } - } -} - -// TestMatchSimple - Tests validate the logic of wild card matching. -// `MatchSimple` supports matching for only '*' in the pattern string. -func TestMatchSimple(t *testing.T) { - testCases := []struct { - pattern string - text string - matched bool - }{ - // Test case - 1. - // Test case with pattern "*". Expected to match any text. - { - pattern: "*", - text: "s3:GetObject", - matched: true, - }, - // Test case - 2. - // Test case with empty pattern. This only matches empty string. - { - pattern: "", - text: "s3:GetObject", - matched: false, - }, - // Test case - 3. - // Test case with empty pattern. This only matches empty string. - { - pattern: "", - text: "", - matched: true, - }, - // Test case - 4. - // Test case with single "*" at the end. - { - pattern: "s3:*", - text: "s3:ListMultipartUploadParts", - matched: true, - }, - // Test case - 5. - // Test case with a no "*". In this case the pattern and text should be the same. - { - pattern: "s3:ListBucketMultipartUploads", - text: "s3:ListBucket", - matched: false, - }, - // Test case - 6. - // Test case with a no "*". In this case the pattern and text should be the same. - { - pattern: "s3:ListBucket", - text: "s3:ListBucket", - matched: true, - }, - // Test case - 7. - // Test case with a no "*". In this case the pattern and text should be the same. - { - pattern: "s3:ListBucketMultipartUploads", - text: "s3:ListBucketMultipartUploads", - matched: true, - }, - // Test case - 8. - // Test case with pattern containing key name with a prefix. Should accept the same text without a "*". - { - pattern: "my-bucket/oo*", - text: "my-bucket/oo", - matched: true, - }, - // Test case - 9. - // Test case with "*" at the end of the pattern. - { - pattern: "my-bucket/In*", - text: "my-bucket/India/Karnataka/", - matched: true, - }, - // Test case - 10. - // Test case with prefixes shuffled. - // This should fail. - { - pattern: "my-bucket/In*", - text: "my-bucket/Karnataka/India/", - matched: false, - }, - // Test case - 11. - // Test case with text expanded to the wildcards in the pattern. - { - pattern: "my-bucket/In*/Ka*/Ban", - text: "my-bucket/India/Karnataka/Ban", - matched: true, - }, - // Test case - 12. - // Test case with the keyname part is repeated as prefix several times. - // This is valid. - { - pattern: "my-bucket/In*/Ka*/Ban", - text: "my-bucket/India/Karnataka/Ban/Ban/Ban/Ban/Ban", - matched: true, - }, - // Test case - 13. - // Test case to validate that `*` can be expanded into multiple prefixes. - { - pattern: "my-bucket/In*/Ka*/Ban", - text: "my-bucket/India/Karnataka/Area1/Area2/Area3/Ban", - matched: true, - }, - // Test case - 14. - // Test case to validate that `*` can be expanded into multiple prefixes. - { - pattern: "my-bucket/In*/Ka*/Ban", - text: "my-bucket/India/State1/State2/Karnataka/Area1/Area2/Area3/Ban", - matched: true, - }, - // Test case - 15. - // Test case where the keyname part of the pattern is expanded in the text. - { - pattern: "my-bucket/In*/Ka*/Ban", - text: "my-bucket/India/Karnataka/Bangalore", - matched: false, - }, - // Test case - 16. - // Test case with prefixes and wildcard expanded for all "*". - { - pattern: "my-bucket/In*/Ka*/Ban*", - text: "my-bucket/India/Karnataka/Bangalore", - matched: true, - }, - // Test case - 17. - // Test case with keyname part being a wildcard in the pattern. - { - pattern: "my-bucket/*", - text: "my-bucket/India", - matched: true, - }, - // Test case - 18. - { - pattern: "my-bucket/oo*", - text: "my-bucket/odo", - matched: false, - }, - // Test case - 11. - { - pattern: "my-bucket/oo?*", - text: "my-bucket/oo???", - matched: true, - }, - // Test case - 12: - { - pattern: "my-bucket/oo??*", - text: "my-bucket/odo", - matched: false, - }, - // Test case - 13: - { - pattern: "?h?*", - text: "?h?hello", - matched: true, - }, - } - // Iterating over the test cases, call the function under test and asert the output. - for i, testCase := range testCases { - actualResult := wildcard.MatchSimple(testCase.pattern, testCase.text) - if testCase.matched != actualResult { - t.Errorf("Test %d: Expected the result to be `%v`, but instead found it to be `%v`", i+1, testCase.matched, actualResult) - } - } -} diff --git a/pkg/words/damerau-levenshtein.go b/pkg/words/damerau-levenshtein.go deleted file mode 100644 index 3fb814e13..000000000 --- a/pkg/words/damerau-levenshtein.go +++ /dev/null @@ -1,65 +0,0 @@ -// 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 . - -package words - -import "math" - -// Returns the minimum value of a slice of integers -func minimum(integers []int) (minVal int) { - minVal = math.MaxInt32 - for _, v := range integers { - if v < minVal { - minVal = v - } - } - return -} - -// DamerauLevenshteinDistance calculates distance between two strings using an algorithm -// described in https://en.wikipedia.org/wiki/Damerau-Levenshtein_distance -func DamerauLevenshteinDistance(a string, b string) int { - var cost int - d := make([][]int, len(a)+1) - for i := 1; i <= len(a)+1; i++ { - d[i-1] = make([]int, len(b)+1) - } - for i := 0; i <= len(a); i++ { - d[i][0] = i - } - for j := 0; j <= len(b); j++ { - d[0][j] = j - } - for i := 1; i <= len(a); i++ { - for j := 1; j <= len(b); j++ { - if a[i-1] == b[j-1] { - cost = 0 - } else { - cost = 1 - } - d[i][j] = minimum([]int{ - d[i-1][j] + 1, - d[i][j-1] + 1, - d[i-1][j-1] + cost, - }) - if i > 1 && j > 1 && a[i-1] == b[j-2] && a[i-2] == b[j-1] { - d[i][j] = minimum([]int{d[i][j], d[i-2][j-2] + cost}) // transposition - } - } - } - return d[len(a)][len(b)] -} diff --git a/pkg/words/damerau-levenshtein_test.go b/pkg/words/damerau-levenshtein_test.go deleted file mode 100644 index 7a35e4a45..000000000 --- a/pkg/words/damerau-levenshtein_test.go +++ /dev/null @@ -1,66 +0,0 @@ -// 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 . - -package words - -import ( - "math" - "testing" -) - -// Test minimum function which calculates the minimal value in a list of integers -func TestMinimum(t *testing.T) { - type testCase struct { - listval []int - expected int - } - testCases := []testCase{ - {listval: []int{3, 4, 15}, expected: 3}, - {listval: []int{}, expected: math.MaxInt32}, - } - // Validate all the test cases. - for i, tt := range testCases { - val := minimum(tt.listval) - if val != tt.expected { - t.Errorf("Test %d:, Expected %d, got %d", i+1, tt.expected, val) - } - } -} - -// Test DamerauLevenshtein which calculates the difference distance between two words -func TestDamerauLevenshtein(t *testing.T) { - type testCase struct { - word1 string - word2 string - distance int - } - testCases := []testCase{ - {word1: "", word2: "", distance: 0}, - {word1: "a", word2: "a", distance: 0}, - {word1: "a", word2: "b", distance: 1}, - {word1: "rm", word2: "tm", distance: 1}, - {word1: "version", word2: "evrsion", distance: 1}, - {word1: "version", word2: "bersio", distance: 2}, - } - // Validate all the test cases. - for i, tt := range testCases { - d := DamerauLevenshteinDistance(tt.word1, tt.word2) - if d != tt.distance { - t.Errorf("Test %d:, Expected %d, got %d", i+1, tt.distance, d) - } - } -}