diff --git a/Makefile b/Makefile index 675fb770..7ec6745d 100755 --- a/Makefile +++ b/Makefile @@ -23,6 +23,16 @@ OUTPUT_LINT_DIR ?= $(shell pwd)/bin LINT_DIR = $(OUTPUT_LINT_DIR)/golangci-lint-$(LINT_VERSION)-v$(TRUECLOUDLAB_LINT_VERSION) TMP_DIR := .cache +# Variables for fuzzing +FUZZING_DIR = $(shell pwd)/tests/fuzzing/files +NGFUZZ_REPO = https://b.yadro.com/scm/sdl/ngfuzz.git +NGFUZZ_BRANCH = feature/go-118-fuzz-build +GO_118_FUZZ_BUILD_REPO = b.yadro.com/obj/go-118-fuzz-build + +FUZZ_TIMEOUT ?= 30 +FUZZ_FUNCTIONS ?= "all" +FUZZ_AUX ?= "" + .PHONY: all $(BINS) $(BINDIR) dep docker/ test cover format image image-push dirty-image lint docker/lint pre-commit unpre-commit version clean protoc # .deb package versioning @@ -76,6 +86,36 @@ cover: @go test -v -race ./... -coverprofile=coverage.txt -covermode=atomic @go tool cover -html=coverage.txt -o coverage.html +# Run fuzzing +CLANG := $(shell which clang-17 2>/dev/null) + +.PHONY: check-clang all +check-clang: +ifeq ($(CLANG),) + @echo "clang-17 is not installed. Please install it before proceeding - https://apt.llvm.org/llvm.sh " + @exit 1 +endif + +.PHONY: install-ngfuzz +install-ngfuzz: +ifeq (,$(wildcard $(FUZZING_DIR)/ngfuzz)) + @rm -rf $(FUZZING_DIR)/ngfuzz + @git clone -b $(NGFUZZ_BRANCH) $(NGFUZZ_REPO) $(FUZZING_DIR)/ngfuzz + @cd $(FUZZING_DIR)/ngfuzz && make +endif + +.PHONY: install-fuzzing-deps +install-fuzzing-deps: check-clang install-ngfuzz +ifeq (,$(wildcard $(FUZZING_DIR)/go-118-fuzz-build)) + GOBIN=$(FUZZING_DIR) go install $(GO_118_FUZZ_BUILD_REPO) +endif + +.PHONY: fuzz +fuzz: install-fuzzing-deps + cd $(FUZZING_DIR)/ngfuzz && \ + ./ngfuzz -fuzz $(FUZZ_FUNCTIONS) -rootdir ../../../.. -timeout $(FUZZ_TIMEOUT) $(FUZZ_AUX) && \ + ./ngfuzz -report + # Reformat code format: @echo "⇒ Processing gofmt check" @@ -148,6 +188,7 @@ version: clean: rm -rf .cache rm -rf $(BINDIR) + rm -rf $(FUZZING_DIR) # Generate code from .proto files protoc: diff --git a/README.md b/README.md index bf76331e..d0ca2b92 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,23 @@ HTTP/1.1 200 OK Also, you can configure domains using `.env` variables or `yaml` file. +## Fuzzing +To run fuzzing tests use the following command: + +```shell +$ make fuzz +``` + +This command will install dependencies for the fuzzing process and run existing fuzzing tests. + +You can also use the following arguments: + +``` +FUZZ_TIMEOUT - time to run each fuzzing test (default 30) +FUZZ_FUNCTIONS - fuzzing tests that will be started (default "all") +FUZZ_AUX - additional parameters for the fuzzer (for example, "-debug") +```` + ## Documentation - [Configuration](./docs/configuration.md) diff --git a/api/auth/center_fuzz_test.go b/api/auth/center_fuzz_test.go new file mode 100644 index 00000000..bb6a5051 --- /dev/null +++ b/api/auth/center_fuzz_test.go @@ -0,0 +1,88 @@ +//go:build gofuzz +// +build gofuzz + +package auth + +import ( + "strings" + "testing" + "time" + + "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox" + oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" + "github.com/aws/aws-sdk-go/aws/credentials" + go_fuzz_utils "github.com/trailofbits/go-fuzz-utils" +) + +var ( + fuzzSuccessExitCode = 0 + fuzzFailExitCode = 1 +) + +func InitFuzzAuthenticate() { +} + +func DoFuzzAuthenticate(input []byte) int { + // FUZZER INIT + if len(input) < 100 { + return fuzzFailExitCode + } + + tp, err := go_fuzz_utils.NewTypeProvider(input) + if err != nil { + return fuzzFailExitCode + } + + var accessKeyAddr oid.Address + err = tp.Fill(accessKeyAddr) + if err != nil { + return fuzzFailExitCode + } + + accessKeyID := strings.ReplaceAll(accessKeyAddr.String(), "/", "0") + secretKey, err := tp.GetString() + awsCreds := credentials.NewStaticCredentials(accessKeyID, secretKey, "") + + reqData := RequestData{ + Method: "GET", + Endpoint: "http://localhost:8084", + Bucket: "my-bucket", + Object: "@obj/name", + } + presignData := PresignData{ + Service: "s3", + Region: "spb", + Lifetime: 10 * time.Minute, + SignTime: time.Now().UTC(), + } + + req, err := PresignRequest(awsCreds, reqData, presignData) + if req == nil { + return fuzzFailExitCode + } + + expBox := &accessbox.Box{ + Gate: &accessbox.GateData{ + SecretKey: secretKey, + }, + } + + mock := newTokensFrostfsMock() + mock.addBox(accessKeyAddr, expBox) + + c := &Center{ + cli: mock, + reg: NewRegexpMatcher(authorizationFieldRegexp), + postReg: NewRegexpMatcher(postPolicyCredentialRegexp), + } + + c.Authenticate(req) + + return fuzzSuccessExitCode +} + +func FuzzAuthenticate(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + DoFuzzAuthenticate(data) + }) +} diff --git a/api/handler/handler_fuzz_test.go b/api/handler/handler_fuzz_test.go new file mode 100644 index 00000000..e110d3ef --- /dev/null +++ b/api/handler/handler_fuzz_test.go @@ -0,0 +1,1018 @@ +//go:build gofuzz +// +build gofuzz + +package handler + +import ( + "bytes" + "crypto/md5" + "encoding/base64" + "encoding/hex" + "encoding/xml" + "errors" + "mime/multipart" + "net/http" + "net/http/httptest" + "testing" + tt "testing" + + "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" + "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer" + "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" + "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox" + engineiam "git.frostfs.info/TrueCloudLab/policy-engine/iam" + go_fuzz_utils "github.com/trailofbits/go-fuzz-utils" + "go.uber.org/zap/zaptest" +) + +var ( + fuzzBktName string + fuzzBox *accessbox.Box + fuzzHc *handlerContextBase + fuzzt *tt.T + fuzzSuccessExitCode = 0 + fuzzFailExitCode = 1 +) + +func createTestBucketAndInitContext() { + fuzzt = new(tt.T) + + log := zaptest.NewLogger(fuzzt) + var err error + fuzzHc, err = prepareHandlerContextBase(layer.DefaultCachesConfigs(log)) + if err != nil { + panic(err) + } + + fuzzBktName = "bucket" + fuzzBox, _ = createAccessBox(fuzzt) + + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodPut, defaultURL, nil) + reqInfo := middleware.NewReqInfo(w, r, middleware.ObjectRequest{Bucket: fuzzBktName, Object: ""}, "") + r = r.WithContext(middleware.SetReqInfo(fuzzHc.Context(), reqInfo)) + r = r.WithContext(middleware.SetBox(r.Context(), &middleware.Box{AccessBox: fuzzBox})) + + fuzzHc.Handler().CreateBucketHandler(w, r) +} + +func prepareStrings(tp *go_fuzz_utils.TypeProvider, count int) ([]string, error) { + array := make([]string, count) + var err error + + for i := 0; i < count; i++ { + err = tp.Reset() + if err != nil { + return nil, err + } + + array[i], err = tp.GetString() + if err != nil { + return nil, err + } + } + + return array, nil +} + +func addMD5Header(tp *go_fuzz_utils.TypeProvider, r *http.Request, rawBody []byte) error { + if len(rawBody) == 0 { + return nil + } + + rand, err := tp.GetBool() + if err != nil { + return err + } + + if rand == true { + var dst []byte + + defer func() { + if recover() != nil { + err = errors.New("panic in base64") + } + }() + + base64.StdEncoding.Encode(dst, rawBody) + hash := md5.Sum(dst) + r.Header.Set("Content-Md5", hex.EncodeToString(hash[:])) + } + + return nil +} + +func generateParams(tp *go_fuzz_utils.TypeProvider, input string, params []string) (string, error) { + input += "?" + + count, err := tp.GetInt() + if err != nil { + return "", err + } + count = count % len(params) + if count < 0 { + count += len(params) + } + + for i := 0; i < count; i++ { + position, err := tp.GetInt() + if err != nil { + return "", err + } + position = position % len(params) + if position < 0 { + position += len(params) + } + + v, err := tp.GetString() + if err != nil { + return "", err + } + input += params[position] + "=" + v + "&" + } + + return input, nil +} + +func generateHeaders(tp *go_fuzz_utils.TypeProvider, r *http.Request, params []string) error { + count, err := tp.GetInt() + if err != nil { + return err + } + count = count % len(params) + if count < 0 { + count += len(params) + } + + for i := 0; i < count; i++ { + position, err := tp.GetInt() + if err != nil { + return err + } + position = position % len(params) + if position < 0 { + position += len(params) + } + + v, err := tp.GetString() + if err != nil { + return err + } + + r.Header.Set(params[position], v) + + } + + return nil +} + +func InitFuzzCreateBucketHandler() { + fuzzt = new(tt.T) + + log := zaptest.NewLogger(fuzzt) + var err error + fuzzHc, err = prepareHandlerContextBase(layer.DefaultCachesConfigs(log)) + if err != nil { + panic(err) + } + + fuzzBox, _ = createAccessBox(fuzzt) +} + +func DoFuzzCreateBucketHandler(input []byte) int { + // FUZZER INIT + if len(input) < 100 { + return fuzzFailExitCode + } + + tp, err := go_fuzz_utils.NewTypeProvider(input) + if err != nil { + return fuzzFailExitCode + } + + strings, err := prepareStrings(tp, 4) + if err != nil { + return fuzzFailExitCode + } + + bktName := strings[0] + body := strings[1] + + bodyXml, err := xml.Marshal(body) + if err != nil { + return fuzzFailExitCode + } + + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodPut, defaultURL, bytes.NewReader(bodyXml)) + reqInfo := middleware.NewReqInfo(w, r, middleware.ObjectRequest{Bucket: bktName, Object: ""}, "") + r = r.WithContext(middleware.SetReqInfo(fuzzHc.Context(), reqInfo)) + r = r.WithContext(middleware.SetBox(r.Context(), &middleware.Box{AccessBox: fuzzBox})) + + err = generateHeaders(tp, r, []string{"x-amz-acl", "x-amz-bucket-object-lock-enabled", "x-amz-grant-full-control", "x-amz-grant-read", "x-amz-grant-read-acp", "x-amz-grant-write", "x-amz-grant-write-acp", "x-amz-object-ownership"}) + if err != nil { + return fuzzFailExitCode + } + + fuzzHc.Handler().CreateBucketHandler(w, r) + + return fuzzSuccessExitCode +} + +func FuzzCreateBucketHandler(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + DoFuzzCreateBucketHandler(data) + }) +} + +func InitFuzzPutBucketCorsHandler() { + createTestBucketAndInitContext() +} + +func DoFuzzPutBucketCorsHandler(input []byte) int { + // FUZZER INIT + if len(input) < 100 { + return fuzzFailExitCode + } + + tp, err := go_fuzz_utils.NewTypeProvider(input) + if err != nil { + return fuzzFailExitCode + } + + var cors data.CORSConfiguration + err = tp.Fill(&cors) + if err != nil { + return fuzzFailExitCode + } + + bodyXml, err := xml.Marshal(cors) + if err != nil { + return fuzzFailExitCode + } + + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodPut, defaultURL+"?cors", bytes.NewReader(bodyXml)) + reqInfo := middleware.NewReqInfo(w, r, middleware.ObjectRequest{Bucket: fuzzBktName, Object: ""}, "") + r = r.WithContext(middleware.SetReqInfo(fuzzHc.Context(), reqInfo)) + r = r.WithContext(middleware.SetBox(r.Context(), &middleware.Box{AccessBox: fuzzBox})) + + err = generateHeaders(tp, r, []string{"x-amz-expected-bucket-owner"}) + if err != nil { + return fuzzFailExitCode + } + + fuzzHc.Handler().PutBucketCorsHandler(w, r) + + return fuzzSuccessExitCode +} + +func FuzzPutBucketCorsHandler(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + DoFuzzPutBucketCorsHandler(data) + }) +} + +func InitFuzzPutBucketPolicyHandler() { + createTestBucketAndInitContext() +} + +func FuzzPutBucketPolicyHandler(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + DoFuzzPutBucketPolicyHandler(data) + }) +} + +func DoFuzzPutBucketPolicyHandler(input []byte) int { + // FUZZER INIT + if len(input) < 100 { + return fuzzFailExitCode + } + + tp, err := go_fuzz_utils.NewTypeProvider(input) + if err != nil { + return fuzzFailExitCode + } + + var policy engineiam.Policy + err = tp.Fill(&policy) + if err != nil { + return fuzzFailExitCode + } + + bodyXml, err := xml.Marshal(policy) + if err != nil { + return fuzzFailExitCode + } + + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodPut, defaultURL+"?policy", bytes.NewReader(bodyXml)) + reqInfo := middleware.NewReqInfo(w, r, middleware.ObjectRequest{Bucket: fuzzBktName, Object: ""}, "") + r = r.WithContext(middleware.SetReqInfo(fuzzHc.Context(), reqInfo)) + r = r.WithContext(middleware.SetBox(r.Context(), &middleware.Box{AccessBox: fuzzBox})) + + err = generateHeaders(tp, r, []string{"x-amz-expected-bucket-owner", "x-amz-confirm-remove-self-bucket-access"}) + if err != nil { + return fuzzFailExitCode + } + + err = addMD5Header(tp, r, bodyXml) + if err != nil { + return fuzzFailExitCode + } + + fuzzHc.Handler().PutBucketPolicyHandler(w, r) + + return fuzzSuccessExitCode +} + +func InitFuzzDeleteMultipleObjectsHandler() { + createTestBucketAndInitContext() +} + +func FuzzDeleteMultipleObjectsHandler(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + DoFuzzDeleteMultipleObjectsHandler(data) + }) +} + +func DoFuzzDeleteMultipleObjectsHandler(input []byte) int { + // FUZZER INIT + if len(input) < 100 { + return fuzzFailExitCode + } + + tp, err := go_fuzz_utils.NewTypeProvider(input) + if err != nil { + return fuzzFailExitCode + } + + var body DeleteObjectsRequest + err = tp.Fill(&body) + if err != nil { + return fuzzFailExitCode + } + + bodyXml, err := xml.Marshal(body) + if err != nil { + return fuzzFailExitCode + } + + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodPost, defaultURL+"?delete", bytes.NewReader(bodyXml)) + reqInfo := middleware.NewReqInfo(w, r, middleware.ObjectRequest{Bucket: fuzzBktName, Object: ""}, "") + r = r.WithContext(middleware.SetReqInfo(fuzzHc.Context(), reqInfo)) + r = r.WithContext(middleware.SetBox(r.Context(), &middleware.Box{AccessBox: fuzzBox})) + + err = generateHeaders(tp, r, []string{"x-amz-expected-bucket-owner", "x-amz-bypass-governance-retention", "x-amz-mfa"}) + if err != nil { + return fuzzFailExitCode + } + + err = addMD5Header(tp, r, bodyXml) + if err != nil { + return fuzzFailExitCode + } + + fuzzHc.Handler().DeleteMultipleObjectsHandler(w, r) + + return fuzzSuccessExitCode +} + +func InitFuzzPostObject() { + createTestBucketAndInitContext() +} + +func FuzzPostObject(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + DoFuzzPostObject(data) + }) +} + +func postObject(tp *go_fuzz_utils.TypeProvider) (error, []byte, string) { + strings, err := prepareStrings(tp, 2) + if err != nil { + return err, nil, "" + } + + bodyXml, err := xml.Marshal(strings[0]) + if err != nil { + return err, nil, "" + } + objName := strings[1] + + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodPost, defaultURL, bytes.NewReader(bodyXml)) + reqInfo := middleware.NewReqInfo(w, r, middleware.ObjectRequest{Bucket: fuzzBktName, Object: objName}, "") + r = r.WithContext(middleware.SetReqInfo(fuzzHc.Context(), reqInfo)) + r = r.WithContext(middleware.SetBox(r.Context(), &middleware.Box{AccessBox: fuzzBox})) + + err = generateHeaders(tp, r, []string{"X-Amz-Grant-Read", "X-Amz-Grant-Full-Control", "X-Amz-Grant-Write", "X-Amz-Acl", "x-amz-expected-bucket-owner"}) + if err != nil { + return err, nil, "" + } + + var file multipart.Form + err = tp.Fill(&file) + if err != nil { + return err, nil, "" + } + + r.MultipartForm = &file + + fuzzHc.Handler().PostObject(w, r) + + return nil, bodyXml, objName +} + +func DoFuzzPostObject(input []byte) int { + // FUZZER INIT + if len(input) < 100 { + return fuzzFailExitCode + } + + tp, err := go_fuzz_utils.NewTypeProvider(input) + if err != nil { + return fuzzFailExitCode + } + + err, _, _ = postObject(tp) + if err != nil { + return fuzzFailExitCode + } + + return fuzzSuccessExitCode +} + +func InitFuzzDeleteBucketHandler() { + createTestBucketAndInitContext() +} + +func FuzzDeleteBucketHandler(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + DoFuzzDeleteBucketHandler(data) + }) +} + +func DoFuzzDeleteBucketHandler(input []byte) int { + // FUZZER INIT + if len(input) < 100 { + return fuzzFailExitCode + } + + tp, err := go_fuzz_utils.NewTypeProvider(input) + if err != nil { + return fuzzFailExitCode + } + + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodDelete, defaultURL, nil) + reqInfo := middleware.NewReqInfo(w, r, middleware.ObjectRequest{Bucket: fuzzBktName, Object: ""}, "") + r = r.WithContext(middleware.SetReqInfo(fuzzHc.Context(), reqInfo)) + r = r.WithContext(middleware.SetBox(r.Context(), &middleware.Box{AccessBox: fuzzBox})) + + err = generateHeaders(tp, r, []string{"x-amz-expected-bucket-owner"}) + if err != nil { + return fuzzFailExitCode + } + + fuzzHc.Handler().DeleteBucketHandler(w, r) + + return fuzzSuccessExitCode +} + +func InitFuzzDeleteBucketCorsHandler() { + createTestBucketAndInitContext() +} + +func FuzzDeleteBucketCorsHandler(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + DoFuzzDeleteBucketCorsHandler(data) + }) +} + +func DoFuzzDeleteBucketCorsHandler(input []byte) int { + // FUZZER INIT + if len(input) < 100 { + return fuzzFailExitCode + } + + tp, err := go_fuzz_utils.NewTypeProvider(input) + if err != nil { + return fuzzFailExitCode + } + + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodDelete, defaultURL+"?cors", nil) + reqInfo := middleware.NewReqInfo(w, r, middleware.ObjectRequest{Bucket: fuzzBktName, Object: ""}, "") + r = r.WithContext(middleware.SetReqInfo(fuzzHc.Context(), reqInfo)) + r = r.WithContext(middleware.SetBox(r.Context(), &middleware.Box{AccessBox: fuzzBox})) + + err = generateHeaders(tp, r, []string{"x-amz-expected-bucket-owner"}) + if err != nil { + return fuzzFailExitCode + } + + fuzzHc.Handler().DeleteBucketCorsHandler(w, r) + + return fuzzSuccessExitCode +} + +func InitFuzzDeleteBucketPolicyHandler() { + createTestBucketAndInitContext() +} + +func FuzzDeleteBucketPolicyHandler(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + DoFuzzDeleteBucketPolicyHandler(data) + }) +} + +func DoFuzzDeleteBucketPolicyHandler(input []byte) int { + // FUZZER INIT + if len(input) < 100 { + return fuzzFailExitCode + } + + tp, err := go_fuzz_utils.NewTypeProvider(input) + if err != nil { + return fuzzFailExitCode + } + + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodDelete, defaultURL+"?policy", nil) + reqInfo := middleware.NewReqInfo(w, r, middleware.ObjectRequest{Bucket: fuzzBktName, Object: ""}, "") + r = r.WithContext(middleware.SetReqInfo(fuzzHc.Context(), reqInfo)) + r = r.WithContext(middleware.SetBox(r.Context(), &middleware.Box{AccessBox: fuzzBox})) + + err = generateHeaders(tp, r, []string{"x-amz-expected-bucket-owner"}) + if err != nil { + return fuzzFailExitCode + } + + fuzzHc.Handler().DeleteBucketPolicyHandler(w, r) + + return fuzzFailExitCode +} + +func InitFuzzCopyObjectHandler() { + createTestBucketAndInitContext() +} + +func FuzzCopyObjectHandler(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + DoFuzzCopyObjectHandler(data) + }) +} + +func DoFuzzCopyObjectHandler(input []byte) int { + // FUZZER INIT + if len(input) < 100 { + return fuzzFailExitCode + } + + tp, err := go_fuzz_utils.NewTypeProvider(input) + if err != nil { + return fuzzFailExitCode + } + + w := httptest.NewRecorder() + var r *http.Request + + key, err := tp.GetString() + if err != nil { + return fuzzFailExitCode + } + + params, err := generateParams(tp, key, []string{"versionId"}) + if err != nil { + return fuzzFailExitCode + } + + defer func() { + if recover() != nil { + err = errors.New("panic in httptest.NewRequest") + } + }() + r = httptest.NewRequest(http.MethodPut, defaultURL+params, nil) + if r != nil { + return fuzzFailExitCode + } + + reqInfo := middleware.NewReqInfo(w, r, middleware.ObjectRequest{Bucket: fuzzBktName, Object: ""}, "") + r = r.WithContext(middleware.SetReqInfo(fuzzHc.Context(), reqInfo)) + r = r.WithContext(middleware.SetBox(r.Context(), &middleware.Box{AccessBox: fuzzBox})) + + err = generateHeaders(tp, r, []string{"x-amz-acl", "x-amz-checksum-algorithm", "x-amz-copy-source", "x-amz-copy-source-if-match", "x-amz-copy-source-if-match", "x-amz-copy-source-if-unmodified-since", "x-amz-copy-source-if-modified-since", "x-amz-copy-source-if-none-match", "x-amz-copy-source-if-modified-since", "x-amz-copy-source-if-none-match", "x-amz-copy-source-if-none-match", "x-amz-copy-source-if-modified-since", "x-amz-copy-source-if-unmodified-since", "x-amz-copy-source-if-match", "x-amz-copy-source-if-unmodified-since", "x-amz-copy-source-server-side-encryption-customer-algorithm", "x-amz-copy-source-server-side-encryption-customer-key", "x-amz-copy-source-server-side-encryption-customer-key-MD5", "x-amz-expected-bucket-owner", "x-amz-grant-full-control", "x-amz-grant-read", "x-amz-grant-read-acp", "x-amz-grant-write-acp", "x-amz-metadata-directive", "x-amz-website-redirect-location", "x-amz-object-lock-legal-hold", "x-amz-object-lock-mode", "x-amz-object-lock-retain-until-date", "x-amz-request-payer", "x-amz-server-side-encryption", "x-amz-server-side-encryption-aws-kms-key-id", "x-amz-server-side-encryption-bucket-key-enabled", "x-amz-server-side-encryption-context", "x-amz-server-side-encryption-customer-algorithm", "x-amz-server-side-encryption-customer-key", "x-amz-server-side-encryption-customer-key-MD5", "x-amz-source-expected-bucket-owner", "x-amz-storage-class", "x-amz-tagging", "x-amz-tagging-directive", "x-amz-website-redirect-location"}) + if err != nil { + return fuzzFailExitCode + } + + fuzzHc.Handler().CopyObjectHandler(w, r) + + return fuzzSuccessExitCode +} + +func InitFuzzDeleteObjectHandler() { + createTestBucketAndInitContext() +} + +func FuzzDeleteObjectHandler(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + DoFuzzDeleteObjectHandler(data) + }) +} + +func DoFuzzDeleteObjectHandler(input []byte) int { + // FUZZER INIT + if len(input) < 100 { + return fuzzFailExitCode + } + + tp, err := go_fuzz_utils.NewTypeProvider(input) + if err != nil { + return fuzzFailExitCode + } + + err, _, objName := postObject(tp) + if err != nil { + return fuzzFailExitCode + } + + w := httptest.NewRecorder() + var r *http.Request + + params, err := generateParams(tp, objName, []string{"versionId"}) + if err != nil { + return fuzzFailExitCode + } + + defer func() { + if recover() != nil { + err = errors.New("panic in httptest.NewRequest") + } + }() + r = httptest.NewRequest(http.MethodDelete, defaultURL+params, nil) + if r != nil { + return fuzzFailExitCode + } + + reqInfo := middleware.NewReqInfo(w, r, middleware.ObjectRequest{Bucket: fuzzBktName, Object: objName}, "") + r = r.WithContext(middleware.SetReqInfo(fuzzHc.Context(), reqInfo)) + r = r.WithContext(middleware.SetBox(r.Context(), &middleware.Box{AccessBox: fuzzBox})) + + err = generateHeaders(tp, r, []string{"x-amz-expected-bucket-owner", "x-amz-bypass-governance-retention", "x-amz-mfa"}) + if err != nil { + return fuzzFailExitCode + } + + fuzzHc.Handler().DeleteObjectHandler(w, r) + + return fuzzSuccessExitCode +} + +func InitFuzzGetObjectHandler() { + createTestBucketAndInitContext() +} + +func FuzzGetObjectHandler(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + DoFuzzGetObjectHandler(data) + }) +} + +func DoFuzzGetObjectHandler(input []byte) int { + // FUZZER INIT + if len(input) < 100 { + return fuzzFailExitCode + } + + tp, err := go_fuzz_utils.NewTypeProvider(input) + if err != nil { + return fuzzFailExitCode + } + + err, _, objName := postObject(tp) + if err != nil { + return fuzzFailExitCode + } + + params, err := generateParams(tp, objName, []string{"versionId", "partNumber", "Range", "response-content-type", "response-content-language", "response-expires", "response-cache-control", "response-content-disposition", "response-content-encoding"}) + if err != nil { + return fuzzFailExitCode + } + + w := httptest.NewRecorder() + + r := httptest.NewRequest(http.MethodGet, defaultURL+params, nil) + if r != nil { + return fuzzFailExitCode + } + + reqInfo := middleware.NewReqInfo(w, r, middleware.ObjectRequest{Bucket: fuzzBktName, Object: objName}, "") + r = r.WithContext(middleware.SetReqInfo(fuzzHc.Context(), reqInfo)) + r = r.WithContext(middleware.SetBox(r.Context(), &middleware.Box{AccessBox: fuzzBox})) + + err = generateHeaders(tp, r, []string{"x-amz-expected-bucket-owner", "If-Match", "If-None-Match", "If-Modified-Since", "If-Unmodified-Since", "x-amz-server-side-encryption-customer-algorithm", "x-amz-server-side-encryption-customer-key", "x-amz-server-side-encryption-customer-key-MD5", "Range"}) + if err != nil { + return fuzzFailExitCode + } + + fuzzHc.Handler().GetObjectHandler(w, r) + + return fuzzSuccessExitCode +} + +func InitFuzzPutObjectHandler() { + createTestBucketAndInitContext() +} + +func DoFuzzPutObjectHandler(input []byte) int { + // FUZZER INIT + if len(input) < 100 { + return fuzzFailExitCode + } + + tp, err := go_fuzz_utils.NewTypeProvider(input) + if err != nil { + return fuzzFailExitCode + } + + objName, err := tp.GetString() + if err != nil { + return fuzzFailExitCode + } + + body, err := tp.GetBytes() + if err != nil { + return fuzzFailExitCode + } + + w := httptest.NewRecorder() + + r := httptest.NewRequest(http.MethodPut, defaultURL+objName, bytes.NewReader(body)) + if r != nil { + return fuzzFailExitCode + } + + reqInfo := middleware.NewReqInfo(w, r, middleware.ObjectRequest{Bucket: fuzzBktName, Object: objName}, "") + r = r.WithContext(middleware.SetReqInfo(fuzzHc.Context(), reqInfo)) + r = r.WithContext(middleware.SetBox(r.Context(), &middleware.Box{AccessBox: fuzzBox})) + + err = generateHeaders(tp, r, []string{"x-amz-expected-bucket-owner", "X-Amz-Grant-Read", "X-Amz-Grant-Full-Control", "X-Amz-Grant-Write", "X-Amz-Acl", "X-Amz-Tagging", "Content-Type", "Cache-Control", "Expires", "Content-Language", "Content-Encoding", "x-amz-server-side-encryption-customer-algorithm", "x-amz-server-side-encryption-customer-key", "x-amz-server-side-encryption-customer-key-MD5", "X-Amz-Content-Sha256", "X-Amz-Object-Lock-Legal-Hold", "X-Amz-Object-Lock-Mode", "X-Amz-Object-Lock-Retain-Until-Date", "X-Amz-Bypass-Governance-Retention", "X-Amz-Meta-*"}) + if err != nil { + return fuzzFailExitCode + } + + err = addMD5Header(tp, r, body) + if err != nil { + return fuzzFailExitCode + } + + fuzzHc.Handler().PutObjectHandler(w, r) + + return fuzzSuccessExitCode +} + +func FuzzPutObjectHandler(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + DoFuzzPutObjectHandler(data) + }) +} + +func InitFuzzPutObjectLegalHoldHandler() { + createTestBucketAndInitContext() +} + +func DoFuzzPutObjectLegalHoldHandler(input []byte) int { + // FUZZER INIT + if len(input) < 100 { + return fuzzFailExitCode + } + + tp, err := go_fuzz_utils.NewTypeProvider(input) + if err != nil { + return fuzzFailExitCode + } + + err, _, objName := postObject(tp) + if err != nil { + return fuzzFailExitCode + } + + var hold data.LegalHold + err = tp.Fill(&hold) + if err != nil { + return fuzzFailExitCode + } + + rawBody, err := xml.Marshal(hold) + if err != nil { + return fuzzFailExitCode + } + + w := httptest.NewRecorder() + + r := httptest.NewRequest(http.MethodPut, defaultURL+objName+"?legal-hold", bytes.NewReader(rawBody)) + if r != nil { + return fuzzFailExitCode + } + + reqInfo := middleware.NewReqInfo(w, r, middleware.ObjectRequest{Bucket: fuzzBktName, Object: objName}, "") + r = r.WithContext(middleware.SetReqInfo(fuzzHc.Context(), reqInfo)) + r = r.WithContext(middleware.SetBox(r.Context(), &middleware.Box{AccessBox: fuzzBox})) + + err = addMD5Header(tp, r, rawBody) + if err != nil { + return fuzzFailExitCode + } + + fuzzHc.Handler().PutObjectLegalHoldHandler(w, r) + + return fuzzSuccessExitCode +} + +func FuzzPutObjectLegalHoldHandler(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + DoFuzzPutObjectLegalHoldHandler(data) + }) +} + +func InitFuzzPutBucketObjectLockConfigHandler() { + createTestBucketAndInitContext() +} + +func DoFuzzPutBucketObjectLockConfigHandler(input []byte) int { + // FUZZER INIT + if len(input) < 100 { + return fuzzFailExitCode + } + + tp, err := go_fuzz_utils.NewTypeProvider(input) + if err != nil { + return fuzzFailExitCode + } + + var hold data.ObjectLockConfiguration + err = tp.Fill(&hold) + if err != nil { + return fuzzFailExitCode + } + + rawBody, err := xml.Marshal(&hold) + if err != nil { + return fuzzFailExitCode + } + + w := httptest.NewRecorder() + + r := httptest.NewRequest(http.MethodPut, defaultURL+"?object-lock", bytes.NewReader(rawBody)) + if r != nil { + return fuzzFailExitCode + } + + reqInfo := middleware.NewReqInfo(w, r, middleware.ObjectRequest{Bucket: fuzzBktName, Object: ""}, "") + r = r.WithContext(middleware.SetReqInfo(fuzzHc.Context(), reqInfo)) + r = r.WithContext(middleware.SetBox(r.Context(), &middleware.Box{AccessBox: fuzzBox})) + + err = addMD5Header(tp, r, rawBody) + if err != nil { + return fuzzFailExitCode + } + + err = generateHeaders(tp, r, []string{"x-amz-expected-bucket-owner", "x-amz-bucket-object-lock-token"}) + if err != nil { + return fuzzFailExitCode + } + + fuzzHc.Handler().PutBucketObjectLockConfigHandler(w, r) + + return fuzzSuccessExitCode +} + +func FuzzPutBucketObjectLockConfigHandler(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + DoFuzzPutBucketObjectLockConfigHandler(data) + }) +} + +func InitFuzzPutObjectRetentionHandler() { + createTestBucketAndInitContext() +} + +func DoFuzzPutObjectRetentionHandler(input []byte) int { + // FUZZER INIT + if len(input) < 100 { + return fuzzFailExitCode + } + + tp, err := go_fuzz_utils.NewTypeProvider(input) + if err != nil { + return fuzzFailExitCode + } + + err, _, objName := postObject(tp) + if err != nil { + return fuzzFailExitCode + } + + var retention data.Retention + err = tp.Fill(&retention) + if err != nil { + return fuzzFailExitCode + } + + rawBody, err := xml.Marshal(retention) + if err != nil { + return fuzzFailExitCode + } + + w := httptest.NewRecorder() + + defer func() { + if recover() != nil { + err = errors.New("panic in httptest.NewRequest") + } + }() + r := httptest.NewRequest(http.MethodPut, defaultURL+objName+"?retention", bytes.NewReader(rawBody)) + if r != nil { + return fuzzFailExitCode + } + + reqInfo := middleware.NewReqInfo(w, r, middleware.ObjectRequest{Bucket: fuzzBktName, Object: objName}, "") + r = r.WithContext(middleware.SetReqInfo(fuzzHc.Context(), reqInfo)) + r = r.WithContext(middleware.SetBox(r.Context(), &middleware.Box{AccessBox: fuzzBox})) + + err = addMD5Header(tp, r, rawBody) + if err != nil { + return fuzzFailExitCode + } + + err = generateHeaders(tp, r, []string{"x-amz-expected-bucket-owner", "x-amz-bypass-governance-retention"}) + if err != nil { + return fuzzFailExitCode + } + + fuzzHc.Handler().PutObjectRetentionHandler(w, r) + + return fuzzSuccessExitCode +} + +func FuzzPutObjectRetentionHandler(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + DoFuzzPutObjectRetentionHandler(data) + }) +} + +func InitFuzzPutBucketAclHandler() { + createTestBucketAndInitContext() +} + +func DoFuzzPutBucketAclHandler(input []byte) int { + // FUZZER INIT + if len(input) < 100 { + return fuzzFailExitCode + } + + tp, err := go_fuzz_utils.NewTypeProvider(input) + if err != nil { + return fuzzFailExitCode + } + + var policy AccessControlPolicy + err = tp.Fill(&policy) + if err != nil { + return fuzzFailExitCode + } + + rawBody, err := xml.Marshal(policy) + if err != nil { + return fuzzFailExitCode + } + + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodPut, defaultURL+"?acl", bytes.NewReader(rawBody)) + reqInfo := middleware.NewReqInfo(w, r, middleware.ObjectRequest{Bucket: fuzzBktName, Object: ""}, "") + r = r.WithContext(middleware.SetReqInfo(fuzzHc.Context(), reqInfo)) + r = r.WithContext(middleware.SetBox(r.Context(), &middleware.Box{AccessBox: fuzzBox})) + + err = addMD5Header(tp, r, rawBody) + if err != nil { + return fuzzFailExitCode + } + + err = generateHeaders(tp, r, []string{"x-amz-expected-bucket-owner", "x-amz-acl", "x-amz-expected-bucket-owner", "x-amz-grant-full-control", "x-amz-grant-read", "x-amz-grant-read-acp", "x-amz-grant-write", "x-amz-grant-write-acp"}) + if err != nil { + return fuzzFailExitCode + } + + fuzzHc.Handler().PutBucketACLHandler(w, r) + + return fuzzSuccessExitCode +} + +func FuzzPutBucketAclHandler(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + DoFuzzPutBucketAclHandler(data) + }) +} diff --git a/api/handler/handlers_test.go b/api/handler/handlers_test.go index 55989bd3..fd72d8c2 100644 --- a/api/handler/handlers_test.go +++ b/api/handler/handlers_test.go @@ -33,11 +33,15 @@ import ( "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/stretchr/testify/require" "go.uber.org/zap" - "go.uber.org/zap/zaptest" "golang.org/x/exp/slices" ) type handlerContext struct { + *handlerContextBase + t *testing.T +} + +type handlerContextBase struct { owner user.ID t *testing.T h *handler @@ -51,19 +55,19 @@ type handlerContext struct { cache *layer.Cache } -func (hc *handlerContext) Handler() *handler { +func (hc *handlerContextBase) Handler() *handler { return hc.h } -func (hc *handlerContext) MockedPool() *layer.TestFrostFS { +func (hc *handlerContextBase) MockedPool() *layer.TestFrostFS { return hc.tp } -func (hc *handlerContext) Layer() *layer.Layer { +func (hc *handlerContextBase) Layer() *layer.Layer { return hc.h.obj } -func (hc *handlerContext) Context() context.Context { +func (hc *handlerContextBase) Context() context.Context { return hc.context } @@ -137,19 +141,30 @@ func (c *configMock) RetryStrategy() RetryStrategy { } func prepareHandlerContext(t *testing.T) *handlerContext { - log := zaptest.NewLogger(t) - return prepareHandlerContextBase(t, layer.DefaultCachesConfigs(log), log) + hc, err := prepareHandlerContextBase(layer.DefaultCachesConfigs(zap.NewExample())) + require.NoError(t, err) + return &handlerContext{ + handlerContextBase: hc, + t: t, + } } func prepareHandlerContextWithMinCache(t *testing.T) *handlerContext { - log := zaptest.NewLogger(t) - return prepareHandlerContextBase(t, getMinCacheConfig(log), log) + hc, err := prepareHandlerContextBase(getMinCacheConfig(zap.NewExample())) + require.NoError(t, err) + return &handlerContext{ + handlerContextBase: hc, + t: t, + } } -func prepareHandlerContextBase(t *testing.T, cacheCfg *layer.CachesConfig, log *zap.Logger) *handlerContext { +func prepareHandlerContextBase(cacheCfg *layer.CachesConfig) (*handlerContextBase, error) { key, err := keys.NewPrivateKey() - require.NoError(t, err) + if err != nil { + return nil, err + } + log := zap.NewExample() tp := layer.NewTestFrostFS(key) testResolver := &resolver.Resolver{Name: "test_resolver"} @@ -161,9 +176,11 @@ func prepareHandlerContextBase(t *testing.T, cacheCfg *layer.CachesConfig, log * user.IDFromKey(&owner, key.PrivateKey.PublicKey) memCli, err := tree.NewTreeServiceClientMemory() - require.NoError(t, err) + if err != nil { + return nil, err + } - treeMock := tree.NewTree(memCli, log) + treeMock := tree.NewTree(memCli, zap.NewExample()) features := &layer.FeatureSettingsMock{} @@ -178,7 +195,9 @@ func prepareHandlerContextBase(t *testing.T, cacheCfg *layer.CachesConfig, log * var pp netmap.PlacementPolicy err = pp.DecodeString("REP 1") - require.NoError(t, err) + if err != nil { + return nil, err + } cfg := &configMock{ defaultPolicy: pp, @@ -191,19 +210,23 @@ func prepareHandlerContextBase(t *testing.T, cacheCfg *layer.CachesConfig, log * frostfsid: newFrostfsIDMock(), } - return &handlerContext{ + accessBox, err := newTestAccessBox(key) + if err != nil { + return nil, err + } + + return &handlerContextBase{ owner: owner, - t: t, h: h, tp: tp, tree: treeMock, - context: middleware.SetBox(context.Background(), &middleware.Box{AccessBox: newTestAccessBox(t, key)}), + context: middleware.SetBox(context.Background(), &middleware.Box{AccessBox: accessBox}), config: cfg, layerFeatures: features, treeMock: memCli, cache: layerCfg.Cache, - } + }, nil } func getMinCacheConfig(logger *zap.Logger) *layer.CachesConfig { diff --git a/api/handler/head_test.go b/api/handler/head_test.go index 2225c96d..9f0c88fe 100644 --- a/api/handler/head_test.go +++ b/api/handler/head_test.go @@ -119,21 +119,25 @@ func TestIsAvailableToResolve(t *testing.T) { } } -func newTestAccessBox(t *testing.T, key *keys.PrivateKey) *accessbox.Box { +func newTestAccessBox(key *keys.PrivateKey) (*accessbox.Box, error) { var err error if key == nil { key, err = keys.NewPrivateKey() - require.NoError(t, err) + if err != nil { + return nil, err + } } var btoken bearer.Token btoken.SetImpersonate(true) err = btoken.Sign(key.PrivateKey) - require.NoError(t, err) + if err != nil { + return nil, err + } return &accessbox.Box{ Gate: &accessbox.GateData{ BearerToken: &btoken, }, - } + }, nil } diff --git a/api/handler/object_list_test.go b/api/handler/object_list_test.go index 06cfd6d6..6c9605e2 100644 --- a/api/handler/object_list_test.go +++ b/api/handler/object_list_test.go @@ -100,7 +100,13 @@ func TestListObjectsWithOldTreeNodes(t *testing.T) { func TestListObjectsVersionsSkipLogTaggingNodesError(t *testing.T) { loggerCore, observedLog := observer.New(zap.DebugLevel) log := zap.New(loggerCore) - hc := prepareHandlerContextBase(t, layer.DefaultCachesConfigs(log), log) + + hcBase, err := prepareHandlerContextBase(layer.DefaultCachesConfigs(log)) + require.NoError(t, err) + hc := &handlerContext{ + handlerContextBase: hcBase, + t: t, + } bktName, objName := "bucket-versioning-enabled", "versions/object" bktInfo := createTestBucket(hc, bktName) @@ -168,7 +174,12 @@ func TestListObjectsContextCanceled(t *testing.T) { layerCfg.SessionList.Lifetime = time.Hour layerCfg.SessionList.Size = 1 - hc := prepareHandlerContextBase(t, layerCfg, log) + hcBase, err := prepareHandlerContextBase(layerCfg) + require.NoError(t, err) + hc := &handlerContext{ + handlerContextBase: hcBase, + t: t, + } bktName := "bucket-versioning-enabled" bktInfo := createTestBucket(hc, bktName) diff --git a/go.mod b/go.mod index d7b28358..cb38f619 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,7 @@ require ( github.com/spf13/viper v1.15.0 github.com/ssgreg/journald v1.0.0 github.com/stretchr/testify v1.9.0 + github.com/trailofbits/go-fuzz-utils v0.0.0-20230413173806-58c38daa3cb4 github.com/urfave/cli/v2 v2.3.0 go.opentelemetry.io/otel v1.16.0 go.opentelemetry.io/otel/trace v1.16.0 diff --git a/go.sum b/go.sum index baba441e..977c6110 100644 --- a/go.sum +++ b/go.sum @@ -321,6 +321,8 @@ github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8 github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954 h1:xQdMZ1WLrgkkvOZ/LDQxjVxMLdby7osSh4ZEVa5sIjs= github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= +github.com/trailofbits/go-fuzz-utils v0.0.0-20230413173806-58c38daa3cb4 h1:GpfJ7OdNjS7BFTVwNCUI9L4aCJOFRbr5fdHqjdhoYE8= +github.com/trailofbits/go-fuzz-utils v0.0.0-20230413173806-58c38daa3cb4/go.mod h1:f3jBhpWvuZmue0HZK52GzRHJOYHYSILs/c8+K2S/J+o= github.com/twmb/murmur3 v1.1.8 h1:8Yt9taO/WN3l08xErzjeschgZU2QSrwm1kclYq+0aRg= github.com/twmb/murmur3 v1.1.8/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= diff --git a/tests/fuzzing/dict.txt b/tests/fuzzing/dict.txt new file mode 100644 index 00000000..d7ab51b1 --- /dev/null +++ b/tests/fuzzing/dict.txt @@ -0,0 +1,3312 @@ +" " +" " +"%" +"&" +"*" +"+" +"+-=._:/@" +", " +"," +",," +",,," +",\\" +"-" +"." +"/" +"/*" +"//" +":" +":[]}],\\" +":[{\\" +":\\" +";" +"=" +"?" +"\\" +"_" +"{\\" +"}],\\" +"$" +"${filename}" +"$key" +".0." +":0" +"0" +"0/" +",0,,0" +"00000000-0000-0000-0000-000000000000" +"0.0.0.0:8080" +"0123456789ABCDEF" +".0.address" +"0/%d" +"-1" +":1,\\" +"1" +"1.0" +"10000;chunk-signature=ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648\\r\\n" +"1048576" +"10485760" +"11, 12, 13, " +"120" +"1234" +"12345" +"1234567890qwertyuiopasdfghjklzxc" +"123456789abcdef" +"192.0.2.0/24" +"192.0.2.1" +"192.0.2.1, 10.1.1.1" +"192.0.2.1:1234" +"192.0.3.0" +"192.168.0.1" +"1999" +"1999#" +"1999+" +"-2" +"2" +"%20" +"200" +"2000" +"20060102" +"2006-01-02T15:04:05.000Z" +"20060102T150405Z" +"201" +"2012-10-17" +"20130524T000000Z" +"20151229T000000Z" +"2015-12-30T12:00:00.000Z" +"20210809" +"2.1" +"2.2" +"2.3" +"2811ccb9e242f41426738fb1f" +"2bucket" +"400 BadRequest" +"4ea976429703418ef00fc4912a409b6a0b973034" +"4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9" +"5, 6, 7" +"600" +"63aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +"64aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +"66560" +"66824" +"66be461c3cd429941c55daf42fad2b8153e5a2016ba89c9494d97677cc9d3872" +"6, 7, 8" +"6789ab" +"6CcWg8LkcbfMUC8pt7wiy5zM1fyS3psNoxgfppcCgig1" +"7" +"713d0a0b9efc7d22923e17b0402a6a89b4273bc711c8bacb2da1b643d0006aeb" +"75BTT5Z9o79XuKdUeGqvQbqDnxu6qWcR5EhxW8BXFf8t" +"7, 8, 9" +"7,8,9" +"%7Euser" +"8N7CYBY74kxZXoyvA5UNdmovaXqFpwNfvEPsqaN81es2/3tDwq5tR8fByrJcyJwyiuYX7Dae8tyDT7pd8oaL1MBto" +",a,," +"a" +"a/" +"aaaaaaaag" +"a/b/" +"a/b/c/" +"abc" +"a/b/c/big.jpg" +"a/b/c/s" +"a/b/c/small.jpg" +"AbortMultipartUpload" +"AbortMultipartUploadOperation" +"a/b/small.jpg" +"accelerate" +"Accept-Ranges" +"_access.box" +"access box is nil" +"Access-Control-Allow-Credentials" +"Access-Control-Allow-Headers" +"Access-Control-Allow-Methods" +"Access-Control-Allow-Origin" +"Access-Control-Expose-Headers" +"AccessControlList>Grant" +"AccessControlListNotSupported" +"Access-Control-Max-Age" +"Access-Control-Request-Headers" +"Access-Control-Request-Method" +"Access-Control-Request-Method request header needed" +"access denied" +"Access Denied." +"AccessDenied" +"access-key-id" +"access_key_id" +"accessKeyID" +"Access key id of s3 credential for which secret must be obtained" +"Accumulated user requests" +"Accumulated user traffic" +"acdefa" +"?acl" +"acl" +"acl-" +"acl disabled, ape allow by default" +"acl disabled, ape deny by default" +"acl enabled, ape allow by default" +"acl enabled, ape deny by default" +"acl not supported for this bucket" +"A column name or a path provided does not exist in the SQL expression" +"action" +"Action" +"action/resource array" +"action/resource string" +"actual" +"actual body: '%s'" +"addChain" +"added storage peer" +"add encryption header: %w" +"add grantees full control: %w" +"add grantees read: %w" +"add grantees write: %w" +".address" +"address" +"Addresses of nodes of the same and highest priority that are currently healthy" +"Address of a frostfs peer to connect to" +"Address of the s3 gateway wallet account" +"Address of the wallet account" +"add server" +"add stream: %w" +"AES256" +"A header you provided implies functionality that is not implemented" +"a.jpg" +"AKIAIOSFODNN7EXAMPLE" +"Algorithm" +"AllAccessDisabled" +"All access to this bucket has been disabled." +"all nodes represent a secondary object" +"allocs" +"allow" +"Allow" +"allowed_access_key_id_prefixes" +"AllowedHeader" +"AllowedHeaders" +"AllowedMethod" +"AllowedMethods" +"allowed only bucket acl" +"AllowedOrigin" +"AllowedOrigins" +"Allow with NotPrincipal is not allowed." +" + allUsersGroup + " +"already initialized" +"already subscribed to topic '%s'" +"AmazonCustomerByEmail" +"An object key name filtering rule defined with overlapping prefixes, overlapping suffixes, or overlapping combinations of prefixes and suffixes for the same event types." +"An Object Lock configuration is present on this bucket, so the versioning state cannot be changed." +"anon" +"anon request, skip FrostfsID validation" +"anotherencriptionkeysourceobject" +"api" +"app.build_time" +"append a resource" +"application finished" +"application/json" +"application started" +"application/xml" +"Argument maxKeys must be an integer between 0 and 2147483647" +"Argument max-parts must be an integer between 0 and 2147483647" +"Argument max-uploads must be an integer from 1 to 1000" +"Argument partNumberMarker must be an integer." +"arn:aws:iam::111122223333:role/JohnDoe" +"arn:aws:iam:::user/devenv" +"arn:aws:s3:::" +"arn:aws:s3:::bucket-for-policy/*" +"arn:aws:s3:::bucketName" +"arn:aws:s3:::bucketName/object" +"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*" +"arn:aws:s3:::DOC-EXAMPLE-BUCKET2/*" +"arn:aws:s3:::test/*" +"arn,omitempty" +"as" +"asd" +"asdf" +"asdf%2Bb" +"asdf+b" +"A specified destination ARN does not exist or is not well-formed. Verify the destination ARN." +"A specified destination is in a different region than the bucket. You must use a destination that resides in the same region as the bucket." +"A specified event is not supported for notifications." +"astToTable order and vice versa" +"A timeout exceeded while waiting to proceed with the request, please reduce your request rate" +"A timeout occurred while trying to lock a resource, please reduce your request rate" +"At least one of the pre-conditions you specified did not hold" +"Attempt to convert from one data type to another using CAST failed in the SQL expression." +"attributes" +"Auth container id to put the secret into (if not provided new container will be created)" +"authenticated-read" +"AUTHMATE" +"authmate_cred_" +"Authorization" +"Authorization, Content-Type" +"Authorization header is invalid -- one and only one ' ' (space) required." +"AuthorizationHeaderMalformed" +"Authorization, Last-Modified" +"AuthorizationParametersError" +"AuthorizationQueryParametersError" +"Average request duration (in milliseconds) for specific method on node in pool" +"A version-id marker cannot be specified without a key marker." +"avg_request_duration" +"aws:" +"AWS" +"AWS4" +"AWS4-HMAC-SHA256" +"AWS4-HMAC-SHA256 Credential=oid0cid/20210809/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=2811ccb9e242f41426738fb1f" +"AWS4-HMAC-SHA256-PAYLOAD" +"aws4_request" +"aws-access-key-id" +"AWS access key id to sign the URL (default is taken from ~/.aws/credentials)" +"AWS authentication requires a valid Date or x-amz-date header" +"aws-chunked" +"aws-cli-credentials" +"aws:key" +"AWS,omitempty" +"AWS profile to load" +"awsRegion,omitempty" +"AWS region to use in signature (default is taken from ~/.aws/config)" +"aws-secret-access-key" +"AWS secret access key to sign the URL (default is taken from ~/.aws/credentials)" +"aws:SourceIp" +",,,b" +"b" +"b%" +"ba" +"b/a/c" +"BadDigest" +"BadRequest" +"bad X-Amz-Credential" +"b/a/g" +"b%ar" +"b/a/r" +"bar" +"Bar" +"basic" +"basic compliance" +"basic empty" +"basic governance" +"basic override" +"b%az" +"baz" +"baza" +"bazar" +"bcdef" +"bearer-rules" +"--bearer-rules flag can be used only with --disable-impersonate" +"bearer_token" +"Bearer token could not be empty" +"bearer token is missing" +"bearerToken,omitempty" +"big" +"billing" +"bind flags: %w" +":bkt" +"bkt-1" +"bkt-2" +"bkt-3" +":bktCanned" +"bkt lock disabled" +"bkt lock enabled" +"bkt lock enabled empty default" +"bkt-name" +"bkt not found" +"block" +"body" +"body close errors" +"body must be read out otherwise goroutines can leak in wrapReader" +"body,omitempty" +"Body shouldn't be set for this request." +"boo/" +"boo/bar" +"boo/baz/" +"boo/baz/xyzzy" +"box does not exist" +"-bucket" +".bucket" +"/bucket" +"buc!ket" +"buc-.ket" +"buc-ket" +"buc.-ket" +"buc.ket" +"buc_ket" +"bucket" +"bucket-" +"bucket." +"Bucket" +"bucket-1" +"bucket2" +"BucketAlreadyExists" +"BucketAlreadyOwnedByYou" +"bucket cid" +"bucket-cors" +"bucket.domain" +"bucket.domain/object" +"bucket-for-acl" +"bucket-for-acl-ape" +"bucket-for-cache" +"bucket-for-conditional" +"bucket-for-copies-number" +"bucket-for-copy" +"bucket-for-cors" +"bucket-for-listing" +"bucket-for-listing-v1-encoding" +"bucket-for-listingv2" +"bucket-for-multipart-s3-tests" +"bucket-for-policy" +"bucket-for-put" +"bucket-for-range" +"bucket-for-removal" +"bucket-for-removal-unversioned" +"bucket-for-sse-c" +"bucket-for-sse-c-multipart" +"bucket-for-sse-c-multipart-s3-tests" +"bucket-for-test-list-parts" +"bucket-for-test-multipart-size" +"bucket-get-attributes" +"bucket is created" +"Bucket is missing ObjectLockConfiguration" +"bucket-lock-disabled" +"bucket-lock-enabled" +"bucket-lock-enabled-old-conf" +"bucket-md5" +"bucket name" +"bucket_name" +"bucketName" +"BucketName,omitempty" +"bucket name: %s" +"Bucket name to perform action" +"BucketNotEmpty" +"bucket-notifications" +"/bucket/object" +"bucket/object" +"bucket/object/deep" +"bucket owner key is missing" +"bucket-preflight-test" +"bucket-preflight-wildcard-test" +"bucket request, path-style" +"bucket request, virtual-hosted style" +"bucket request with slash, path-style" +"bucket-s3alias" +"bucket-settings" +"bucket tagging" +"bucket-tagging" +"bucket-to-list-uploads" +"bucket-to-upload-part" +"bucket-unversioned-removal" +"bucket-versioned-for-removal" +"bucket-versioned-for-removal-not-found" +"bucket-versioning-enabled" +"bufio" +"build bearer token: %w" +"build session token: %w" +"build zap logger instance: %v" +"Busy" +"bytes" +"bytes:-" +"bytes=" +"bytes=0-" +"bytes=0-0" +"bytes:0-256" +"bytes=0-256" +"bytes=0-string" +"bytes=-10" +"bytes=10-20" +"bytes=-1-256" +"bytes,1,opt,name=body,proto3" +"bytes,1,opt,name=chain,proto3" +"bytes,1,opt,name=key,proto3" +"bytes,1,opt,name=locationConstraint,proto3" +"bytes,1,opt,name=secretKey,proto3" +"bytes,1,opt,name=seedKey,proto3" +"bytes,1,opt,name=tokens,proto3" +"bytes,1,rep,name=chainDatas,proto3" +"bytes,1,rep,name=chainIDs,proto3" +"bytes,1,rep,name=chainInfos,proto3" +"bytes=256-0" +"bytes,2,opt,name=bearerToken,proto3" +"bytes,2,opt,name=gatePublicKey,proto3" +"bytes,2,opt,name=name,proto3" +"bytes,2,opt,name=policy,proto3" +"bytes,2,opt,name=signature,proto3" +"bytes,2,opt,name=sign,json=signature,proto3" +"bytes,2,rep,name=gates,proto3" +"bytes,3,opt,name=chainID,proto3" +"bytes,3,opt,name=chain,proto3" +"bytes,3,rep,name=containerPolicy,proto3" +"bytes,3,rep,name=sessionTokens,proto3" +"bytes=%d-%d" +"bytes %d-%d/%d" +"bytes=string-0" +"bytes_total" +"c" +"c%" +"%C3%A4%C3%B6%C3%BCex%20%C2%AE%C2%A9%C2%B5%C3%84%C3%86%C3%90%C3%95%C3%A6%C5%92%C6%95%C6%A9%C7%85%2001000000%200x40%20%40%20am%C8%A1%C8%B9%C9%86ple%260a%21-_.%2A%27%28%29%26%24%40%3D%3B%3A%2B%2C%3F%3C%3E.pdf" +"c%ab" +"cab" +"cache.accessbox.lifetime" +"cache.accessbox.removing_check_interval" +"cache.accessbox.size" +"cache.accesscontrol.lifetime" +"cache.accesscontrol.size" +"cache.buckets.lifetime" +"cache.buckets.size" +"Cache-Control" +"cache.frostfsid.lifetime" +"cache.frostfsid.size" +"cache.list.lifetime" +"cache.list_session.lifetime" +"cache.list_session.size" +"cache.list.size" +"cache.morph_policy.lifetime" +"cache.morph_policy.size" +"cache.names.lifetime" +"cache.names.size" +"cache.objects.lifetime" +"cache.objects.size" +"cache.system.lifetime" +"cache.system.size" +"calculate signature: %w" +"caller" +"can head 'bucket'" +"can list buckets" +"cannedACL" +"cannot load TLS key pair from certFile '%s' and keyFile '%s': %w" +"Cannot mix [] and * in the same expression in a SELECT list in SQL expression." +"Cannot provide multiple Tags with the same key" +"Cannot respond to plain-text request from TLS-encrypted server" +"Cannot specify more than one prefix rule in a filter." +"Cannot specify more than one suffix rule in a filter." +"cannot use unseekable request body %T, for signed request with body" +"CanonicalUser" +"CanonicalUser,omitempty" +"can put object into 'bucket'" +"can't gracefully shut down service, force stop" +"can't parse placement policy" +"can't read signature: %w" +"can't shut down service" +"case %d" +"CastFailed" +"CERTIFICATE" +"cert.pem" +"cert provider: disabled" +"chainDatas,omitempty" +"chainId" +"chainID,omitempty" +"chainIDs,omitempty" +"chainInfos,omitempty" +"chain,omitempty" +",chardata" +"charset %s: %w" +"check accessbox update" +"check attributes update" +"check container" +"check container: %w" +"check correct get" +"check correct size in list v1" +"check correct size in list v2" +"check correct size when copy part from encrypted source" +"check correct size when part copy" +"check delete" +"check for uploads" +"check get" +"check key-marker along with upload-id-marker" +"check markers" +"check max uploads" +"check only key-marker" +"check only upload-id-marker" +"check placement policy: %w" +"check prefix" +"Checksum" +"Checksum,omitempty" +"ChecksumSHA256,omitempty" +"check upload key" +"child" +"chunkObject.txt" +"chunk-signature=" +"chunk too big: choose chunk size <= 16MiB" +"cid" +"CloudFunctionConfiguration" +"CloudFunctionConfigurations" +"cnrID" +"Code,omitempty" +"commandline" +"CommonPrefixes" +"complete multipart error" +"CompleteMultipartUpload" +"CompleteMultipartUploadOperation" +"COMPLIANCE" +"compute decrypted size: %w" +"compute encrypted size: %w" +"conditions" +"config" +"config-dir" +"config dir path" +"config overrides %s location constraint" +"config paths" +"configurationId,omitempty" +"Configurations overlap. Configurations on the same bucket cannot share a common event type." +"Connection" +"connect_timeout" +"connect to nats: %w" +"console" +"constant" +"constant_labels,omitempty" +"constraint added" +"container" +"CONTAINER" +"container-friendly-name" +"container-id" +"container_id" +"containerID" +"ContainerID" +"container not found %s" +"container-placement-policy" +"container-policy" +"containerPolicy,omitempty" +"container resolver will be disabled because of resolvers 'resolver_order' is empty" +" contains wildcard. We currently do not support wildcard for ExposeHeader" +"content" +"content1" +"content2" +"content/%d" +"Content-Disposition" +"content-encoding" +"Content-Encoding" +"Content-Language" +"content-length" +"Content-Length" +"content-length-range" +"Content-Md5" +"content obj1 v1" +"content obj1 v2" +"content obj1 v3" +"Content-Range" +"Contents" +"content-type" +"Content-Type" +"context" +"__context_box_key" +"" +"continuation-token" +"ContinuationToken,omitempty" +"control API" +"control API cannot shutdown gracefully, forcing stop" +"control API service stopped" +"control.authorized_keys" +"control.grpc.endpoint" +"copies numbers" +"copies_numbers" +"copy" +"COPY" +"copying to itself without changing anything" +"copy-object" +"CopyObject" +"CopyObjectOperation" +"copy object payload written: '%d', decLength: '%d', params.ln: '%d' : %w" +"copy object payload written: '%d': %w" +"CopyObject request made on objects larger than 5GB in size." +"Copy Source must mention the source bucket and key: sourcebucket/sourcekey." +"copy-target" +"copy-target2" +"correct hash" +"correct hash for empty payload" +"correct hash format" +"correct rules with prefix" +"correct rules with prefix and suffix" +"correct rules with suffix" +"?cors" +"cors" +"cors.default_max_age" +"CORSRule" +"CORSRules" +"coudln't init go pool for listing: %w" +"coudln't read file '%s'" +"coudln't read json file or provided json is invalid" +"could create multipart upload" +"could get uploading file" +"could not abort multipart upload" +"could not ACK message" +"could not close request body" +"could not complete multipart upload: %w" +"could not convert s3 policy to chain policy" +"could not convert s3 policy to native chain policy" +"could not create bucket" +"could not decode policy: %w" +"could not decode tag set" +"could not delete bucket tagging" +"could not delete cors" +"could not delete object" +"could not delete object tagging" +"could not delete upload part" +"could not encode bucket notification configuration to response" +"could not encode cors to response" +"could not encode InitiateMultipartUploadResponse to response" +"could not fetch bucket acl" +"could not fetch container info" +"could not fetch object info" +"could not fetch object meta" +"could not find object" +"could not form object lock" +"could not get bucket eacl: %w" +"could not get bucket info" +"could not get bucket notification configuration" +"could not get bucket objInfo" +"could not get bucket settings" +"could not get cors" +"could not get eacl session token from a box" +"could not get locking info" +"could not get new eacl table" +"could not get object" +"could not get object info" +"could not get object meta data" +"could not get object payload" +"could not get object tagging" +"could not get source bucket info" +"could not get target bucket info" +"could not handle message" +"could not head source object" +"could not head source object version" +"could not initialize API handler" +"could not list multipart uploads" +"could not list parts" +"could not list user containers" +"could not load FrostFS private key" +"could not parse acl" +"could not parse acl: %w" +"could not parse bucket acl" +"could not parse bucket policy" +"could not parse canned ACL" +"could not parse container object lock enabled attribute" +"could not parse copy object args" +"could not parse copy range" +"could not parse location contraint: %w" +"could not parse object acl: %w" +"could not parse range header" +"could not parse request params" +"could not parse tagging" +"could not parse tagging header" +"could not partly read payload to detect content type" +"could not prepare listener: %w" +"could not put a completed object (multipart upload)" +"could not put bucket acl" +"could not put bucket acl: %w" +"could not put bucket e/ACL" +"could not put cors configuration" +"could not put object tagging" +"could not put tagging file of completed multipart upload: %w" +"could not read complete multipart upload xml" +"could not read tag set" +"could not stream object payload" +"could not subscribe: %w" +"could not translate acl of completed multipart upload to ast: %w" +"could not translate acl to ast" +"could not translate acl to policy" +"could not translate ast to table: %w" +"could not translate object acl to bucket policy: %w" +"could not translate policy to ast: %w" +"could not unmarshal policy: %w" +"could not update bucket acl" +"could not update bucket acl while completing multipart upload: %w" +"could not upload a part" +"could not upload object" +"could not upload object tagging" +"could not upload part copy" +"could not write response" +"couldn't add new verion to tree service: %w" +"couldn't add object to cache" +"couldn't cache access control operation" +"couldn't cache bucket settings" +"couldn't cache cors" +"couldn't cache list of objects" +"couldn't cache list policy chains" +"couldn't cache list session" +"couldn't cache lock info" +"couldn't cache notification configuration" +"couldn't cache subject info" +"couldn't cache tags" +"couldn't cache user key" +"couldn't check bucket configuration" +"couldn't copy object" +"couldn't create decrypter: %w" +"couldn't create decrypter with disabled encryption" +"couldn't create encrypter: %w" +"couldn't decode body" +"couldn't decode MD5 checksum of part: %w" +"couldn't decode notification configuration" +"couldn't decode versioning configuration" +"couldn't decrypt account: %w" +"couldn't delete bucket" +"couldn't delete cors object" +"couldn't delete lock object '%s' to remove legal hold: %w" +"couldn't delete notification configuration object" +"couldn't delete object" +"couldn't delete object from storage, continue deleting from tree" +"couldn't delete old part object" +"couldn't delete part" +"couldn't delete part '%s': %w" +"couldn't encode bucket location response" +"couldn't encode object info to response" +"couldn't find session token for setEACL" +"couldn't find wallet account for %s" +"couldn't generate random key" +"couldn't get aws credentials: %w" +"couldn't get bearer token issuer key" +"couldn't get bearer token signature key: %w" +"couldn't get box data from context" +"couldn't get box from context" +"couldn't get bucket settings" +"couldn't get client time from context" +"couldn't get eacl token" +"couldn't get eacl token: %w" +"couldn't get gate key" +"couldn't get gate key: %w" +"couldn't get node: %w" +"couldn't get parent path" +"couldn't get random oid: %w" +"couldn't get source bucket" +"couldn't get target bucket" +"couldn't get versioning settings object: %w" +"couldn't get version settings" +"couldn't get versions: %w" +"couldn't head lock object" +"couldn't head put legal hold" +"couldn't initialize layer" +"couldn't marshal an event" +"couldn't marshal test event: %w" +"couldn't open aws cli credentials file: %w" +"couldn't parse 'bearer-rules' flag: %s" +"couldn't parse bypass governance header: %w" +"couldn't parse canonical ID %s: %w" +"couldn't parse container policy: %s" +"couldn't parse form: %w" +"couldn't parse http time %s: %w" +"couldn't parse legal hold configuration" +"couldn't parse locking configuration" +"couldn't parse object retention" +"couldn't parse 'session-tokens' flag: %s" +"couldn't parse time '%s': %w" +"couldn't parse X-Amz-Expires: %w" +"couldn't put accessbox into cache" +"couldn't put bucket configuration" +"couldn't put bucket info into cache" +"couldn't put bucket settings" +"couldn't put legal hold" +"couldn't put lock into tree: %w" +"couldn't put obj address to name cache" +"couldn't put object locking configuration" +"couldn't put update versioning settings" +"couldn't read password" +"couldn't read request body" +"couldn't receive access box for gate key, random key will be used" +"couldn't resolve container '%s' as '%s': %w" +"couldn't resolve container '%s': %w" +"couldn't save bucket settings" +"couldn't send an event to topic" +"couldn't send event: %w" +"couldn't send notification: %w" +"couldn't set placement policy: %w" +"couldn't skip some bytes: %w" +"couldn't suspend bucket versioning" +"couldn't unmarshal SeedKey: %w" +"could translate bucket acl to eacl" +"cquux/" +"cquux/bla" +"cquux/thud" +"CreateBucket" +"CreateBucketOperation" +"create container" +"create container in FrostFS: %w" +"create container: %w" +"created" +"Created" +"create encrypter: %w" +"create ephemeral key: %w" +"create frostfsid client: %w" +"create logger: %w" +"CreateMultipartUpload" +"CreateMultipartUploadOperation" +"create new actor: %w" +"create object: %w" +"create path '%s'" +"create policy rpc client: %w" +"create pool: %w" +"create_session" +"create session tokens with rules, if the rules are set as 'none', no session tokens will be created" +"Creates new s3 credentials to use with frostfs-s3-gw" +"create tokens: %w" +"creating decrypter: %w" +" Credential=" +"crypto/cipher" +"crypto/ecdsa" +"crypto/elliptic" +"crypto/hmac" +"crypto/md5" +"crypto/rand" +"crypto/rsa" +"crypto/sha256" +"crypto/tls" +"crypto/x509" +"crypto/x509/pkix" +"current_errors" +"current_nodes" +"Current S3 gateway state" +"-Customer-Key" +"custom-ns" +"d" +"d1b2a59fbea7e20077af9f91b27e95e865061b270be03ff539ab3b73587882e8" +"data" +"date" +"Date" +"Date must be provided in ISO 8601 format" +"Days" +"deadline exceeded" +"debug" +"/debug/pprof/" +"/debug/pprof/cmdline" +"/debug/pprof/profile" +"/debug/pprof/symbol" +"/debug/pprof/trace" +"Decrypted-Size" +"decrypt tokens: %w" +"default" +"default days" +"Default environments:" +"'default' location constraint can't be overriden by custom policy, use 'placement_policy.default'" +"default namespace config value be overwritten by values from 'namespaces.config'" +"default namespaces cannot be empty, defaults will be used" +"DefaultRetention" +"default years" +"?delete" +"delete" +"DELETE" +"DeleteBucket" +"DeleteBucketCors" +"DeleteBucketCorsOperation" +"DeleteBucketEncryption" +"DeleteBucketEncryptionOperation" +"DeleteBucketLifecycle" +"DeleteBucketLifecycleOperation" +"DeleteBucketOperation" +"DeleteBucketPolicy" +"DeleteBucketPolicyOperation" +"DeleteBucketTagging" +"DeleteBucketTaggingOperation" +"DeleteBucketWebsite" +"DeleteBucketWebsiteOperation" +"delete_container" +"delete container via connection pool" +"Deleted,omitempty" +"DeleteMarker" +"DeleteMarker,omitempty" +"delete markers must be empty" +"DeleteMarkerVersionId,omitempty" +"DeleteMultipleObjects" +"DeleteMultipleObjectsOperation" +"delete_object" +"DeleteObject" +"DeleteObjectOperation" +"DeleteObjectTagging" +"DeleteObjectTaggingOperation" +"delimiter" +"Delimiter,omitempty" +"delimiter parameter, prohibit specific value" +"deny" +"Deny" +"derive key: %w" +"description" +"determine properties: %w" +"determine request tags: %w" +"determine resource tags: %w" +"determine tags: %w" +"dev" +"devenv" +"dfbe886241d9e369cf4b329ca0f15eb27306c97aa1022cc0bb5a914c4ef87634" +"dial nns %s: %w" +"dial pool: %w" +"dial %s: %w" +"Did not find expected the left parenthesis in the SQL expression." +"Did not find the expected argument delimiter in the SQL expression." +"Did not find the expected date part in the SQL expression." +"Did not find the expected identifier after the @ symbol in the SQL expression." +"Did not find the expected identifier for AT name in the SQL expression." +"Did not find the expected identifier for the alias in the SQL expression." +"Did not find the expected keyword in the SQL expression." +"Did not find the expected left parenthesis in the SQL expression." +"Did not find the expected number in the SQL expression." +"Did not find the expected right parenthesis character in the SQL expression." +"Did not find the expected SQL expression." +"Did not find the expected token in the SQL expression." +"Did not find the expected type name in the SQL expression." +"Did not find the expected WHEN clause in the SQL expression. CASE is not supported." +"different keys in sequence" +"different name, different versions" +"different number of filters" +"different number of records" +"different number of targets" +"differ start with '%d' position, length: %d" +"dir" +"dir/" +"dir/a.png" +"direction" +"dir/lol/" +"dir/lol/obj" +"dir/obj" +"dirw/cat.png" +"disable-impersonate" +"DisplayName" +"DisplayName,omitempty" +"dkirillov" +"/dkirillov/fix-object" +"dns" +"doesn't contain FileName" +"domain" +"domain1" +"domain2" +"domains" +"do not create delete marker if object does not exist" +"ds" +"dummy" +"duplicate address" +"Duration provided in the request is invalid." +"e" +"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" +"ecrypt tokens: %w" +"ed7002b439e9ac845f22357d822bac1444730fbdb6016d3ec9432297b9ec9f7" +"ed7002b439e9ac845f22357d822bac1444730fbdb6016d3ec9432297b9ec9f73" +"ed7002b439e9ac845f22357d822bac1444730fbdb6016d3ec9432297b9ec9f7s" +"Effect" +"emailAddress" +"emailAddress=\\" +"EmailAddress,omitempty" +"empty" +"empty accessbox" +"empty frostfsid" +"empty FrostFS Object Layer" +"empty keys" +"empty list" +"empty logger" +"empty multipart form" +"empty multipart value for key '%s'" +"empty notificator" +"Empty origin" +"empty parts list" +"empty placement policy" +"empty policy storage" +"EmptyRequestBody" +"Empty request method" +"empty seed key" +"empty token" +"en" +"Enabled" +"Enabled,0,COMPLIANCE,0" +"Enabled,10,COMPLIANCE," +"Enabled,10,COMPLIANCE,0" +"Enabled,,COMPLIANCE," +"Enable debug logger level" +"Enable logger" +"enable pprof" +"enable prometheus metrics" +"encode and write response" +"encode gate: %w" +"encode response" +"encode response: %w" +"encode tokens: %w" +"encode token: %w" +"encode xml response" +"encode xml response: %w" +" encoding=\\" +"encoding/base64" +"encoding/hex" +"encoding/json" +"encoding/pem" +"encoding-type" +"EncodingType,omitempty" +"encoding/xml" +"Encountered an unsupported SQL function." +"Encountered an unsupported SQL operation." +"Encountered an unsupported SQL structure. Check the SQL Reference." +"Encountered invalid syntax." +"encryption" +"encryption doesn't match object" +"endpoint" +"endpoint_info" +"Enter password for %s > " +"EntityTooLarge" +"EntityTooSmall" +"epoch duration is missing or zero" +"eq" +"ErrEvaluatorBindingDoesNotExist" +"error" +"Error" +"Error:" +"error both durations" +"error invalid date" +"error invalid enabled" +"error invalid mode" +"error must be s3 error" +"error no duration" +"Error,omitempty" +"Error parsing the Credential parameter; incorrect service. This endpoint belongs to \\" +"Error parsing the Credential/X-Amz-Credential parameter; incorrect service. This endpoint belongs to \\" +"Error parsing the X-Amz-Credential parameter; incorrect date format \\" +"Error parsing the X-Amz-Credential parameter; incorrect terminal. This endpoint uses \\" +"Error parsing the X-Amz-Credential parameter; the Credential is mal-formed; expecting \\" +"Error parsing the X-Amz-Credential parameter; the region is wrong;" +"Error response code" +"Error response code %s." +"errors" +"errors_total" +"error while getting box from frostfs" +" + etag + " +"etag" +"Etag" +"ETag" +"etag2" +"eTag,omitempty" +"ETag,omitempty" +"EvaluatorInvalidArguments" +"EvaluatorInvalidTimestampFormatPattern" +"EvaluatorInvalidTimestampFormatPatternSymbol" +"EvaluatorInvalidTimestampFormatPatternSymbolForParsing" +"EvaluatorInvalidTimestampFormatPatternToken" +"EvaluatorTimestampFormatPatternDuplicateFields" +"EvaluatorUnterminatedTimestampFormatPatternToken" +"Event" +"eventName" +"events" +"Events" +"eventSource" +"eventTime" +"eventVersion" +"examplebucket" +"//example.com/some/path" +"expected" +"expected: %d, actual: %d, resp: '%s'" +"expected len: %d, actual len: %d" +"expected: '%s', got: '%s'" +"expiration" +"Expires" +"exponential" +"ExposeHeader \\" +"ExposeHeader" +"ExposeHeaders" +"ExpressionTooLong" +"eyAiZXhwaXJhdGlvbiI6ICIyMDE1LTEyLTMwVDEyOjAwOjAwLjAwMFoiLAogICJjb25kaXRpb25zIjogWwogICAgeyJidWNrZXQiOiAiYWNsIn0sCiAgICBbInN0YXJ0cy13aXRoIiwgIiRrZXkiLCAidXNlci91c2VyMS8iXSwKICAgIHsic3VjY2Vzc19hY3Rpb25fcmVkaXJlY3QiOiAiaHR0cDovL2xvY2FsaG9zdDo4MDg0L2FjbCJ9LAogICAgWyJzdGFydHMtd2l0aCIsICIkQ29udGVudC1UeXBlIiwgImltYWdlLyJdLAogICAgeyJ4LWFtei1tZXRhLXV1aWQiOiAiMTQzNjUxMjM2NTEyNzQifSwKICAgIFsic3RhcnRzLXdpdGgiLCAiJHgtYW16LW1ldGEtdGFnIiwgIiJdLAoKICAgIHsiWC1BbXotQ3JlZGVudGlhbCI6ICI4Vmk0MVBIbjVGMXNzY2J4OUhqMXdmMUU2aERUYURpNndxOGhxTU05NllKdTA1QzVDeUVkVlFoV1E2aVZGekFpTkxXaTlFc3BiUTE5ZDRuR3pTYnZVZm10TS8yMDE1MTIyOS91cy1lYXN0LTEvczMvYXdzNF9yZXF1ZXN0In0sCiAgICB7IngtYW16LWFsZ29yaXRobSI6ICJBV1M0LUhNQUMtU0hBMjU2In0sCiAgICB7IlgtQW16LURhdGUiOiAiMjAxNTEyMjlUMDAwMDAwWiIgfSwKICAgIHsieC1pZ25vcmUtdG1wIjogInNvbWV0aGluZyIgfQogIF0KfQ==" +"f" +"failed check policy" +"failed to add morph rule chain" +"failed to add morph rule chains" +"failed to add server" +"failed to add tokens to accessbox: %w" +"failed to biuild session token: %w" +"failed to build bearer tokens: %w" +"failed to build context for session token: %w" +"failed to build eacl table: %w" +"failed to build placement policy: %w" +"failed to compute enc size: %w" +"failed to create connection pool" +"failed to create ecnrypted reader: %w" +"failed to create FrostFS component: %s" +"failed to create new request: %w" +"failed to create resolver" +"failed to create tree pool" +"failed to decode gate: %w" +"failed to decode secret key access box: %w" +"failed to delete object" +"failed to delete policy from storage" +"failed to dial connection pool" +"failed to dial s3 gw control api: %w" +"failed to dial tree pool" +"failed to discard put payload, probably goroutine leaks" +"failed to enable notifications" +"failed to encode response" +"failed to generate accessKey as hex: %w" +"failed to generate request id" +"failed to get body reader" +"failed to get next object from stream: %w" +"failed to get notification configuration: %w" +"failed to get policy from storage" +"failed to get real object size" +"failed to get settings node: %w" +"failed to get source object size" +"failed to get tokens: %w" +"failed to init create salt" +"failed to initialize tracing" +"failed to init worker pool: %w" +"failed to issue secret: %s" +"failed to load frostfs private key: %s" +"failed to load gate's public key: %s" +"failed to load s3 gate private key: %s" +"failed to obtain secret: %s" +"failed to parse arguments" +"failed to parse attributes: %s" +"failed to parse auth container id: %s" +"failed to parse body: %s" +"failed to parse copies numbers, skip" +"failed to parse creds address: %w" +"failed to parse 'default' copies numbers, default one will be used" +"failed to parse default 'default' location constraint" +"failed to parse 'default' location constraint, default one will be used" +"failed to parse location constraint, it cannot be used" +"failed to parse location contraint '%s': '%s'" +"failed to parse namespace config: %w" +"failed to parse public key, skip" +"failed to parse request" +"failed to parse secret address: %w" +"failed to parse x-amz-date field: %w" +"failed to parse x-amz-date header field: %w" +"failed to pass authentication" +"failed to pre-sign temporary HTTP request: %w" +"failed to put creds: %w" +"failed to read namespace config '%s': %w" +"failed to read region map file, policies will be empty" +"failed to reconnect server" +"failed to register key in frostfsid: %w" +"failed to reload config" +"failed to reload config because it's missed" +"failed to reload resolvers" +"failed to reload server parameters" +"failed to resolve CID" +"failed to send test event because notifications is disabled" +"failed to shutdown tracing" +"failed to sign temporary HTTP request: %w" +"failed to submit task to pool" +"failed to unescape object name" +"failed to unmarshal namespaces config" +"failed to unmarshal rules for session token: %w" +"failed to update cert (listener close: %v): %w" +"failed to update creds: %w" +"failed to update policy in contract" +"failed to update secret: %s" +"failed to update tls certs: %w" +"failed to write response" +"fails to write to file: %w" +":false}" +"false" +"FALSE" +"features.md5.enabled" +"features.policy.deny_by_default" +"fetch domains, prepare to use API" +"fetch-owner" +"fetch time to epoch: %w" +"file" +"file header open: %w" +"FileName" +"filepath" +"File to export s3 gateway metrics to." +"Filter" +"filter headers: number of parameters must be multiple of 2, got %v" +"FilterRule" +"filter rule name must be either prefix or suffix" +"FilterRules" +"filter topics from queue configs without prefix suffix filter and exact event" +"filter topics from queue configs with prefix suffix filter and '*' ending event" +"Finished" +"first and second" +"first and third" +"firstencriptionkeyofsourceobject" +"firstname.lastname" +"first part 1" +"/fix/object" +"fix/object" +"fix/object%25ac" +"fix/object%ac" +"flag" +"flag 'out' must be provided to dump metrics description" +"fmt" +"foo" +"foo/" +"Foo" +"foo+1/bar" +"foo%20ab/bar" +"foo%2B1/" +"foo%2B1/bar" +"/foo%2fbar" +"foo ab/bar" +"foo+ab/bar" +"/foo/bar" +"foo/bar" +"foo/bar/xyzzy" +"foo/baz" +"for=192.0.2.1, 10.1.1.1; proto=https; by=192.0.2.4" +"Forbidden" +"form grantee: %w" +"form records: %w" +"form upload attributes: %w" +"Forwarded" +"Forwarded: " +"forwarded header" +"found more than one intermediate nodes" +"found more than one node" +"found more than one unversioned node" +"Found unsupported HTTP method in CORS config" +"friendly_name" +"Friendly name of auth container to put the secret into (flag value will be used only if --container-id is missed)" +"FrostFS" +"frostfs.buffer_max_size_for_put" +"frostfs.client_cut" +"frostfs-copies-number" +"frostfsid" +"frostfsid.contract" +"FrostfsID contract hash (LE) or name in NNS to register public key in contract (rpc-endpoint flag also must be provided)" +"frostfsid.frostfs" +"frostfsid-namespace" +"frostfsid-proxy" +"frostfsid.validation.enabled" +"FrostfsID validation failed" +"frostfs:s3" +"FrostFS S3" +"frostfs-s3-authmate" +"FrostFS S3 Authmate" +"frostfs-s3-authmate --version" +"FrostFS S3 Gateway\\nVersion: %s\\nGoVersion: %s\\n" +"FrostFS S3 gateway %s\\n" +"frostfs-s3-gw" +"frostfs_s3_gw" +"FrostFS-S3-GW" +"FrostFS-S3-GW/" +"FrostFS-S3-GW-Logger" +"frostfs.set_copies_number" +"frostfs.tree_pool_max_attempts" +"FULL_CONTROL" +"Fully enabled" +"g" +"gate-address" +"gate-public-key" +"gatePublicKey,omitempty" +"gates,omitempty" +"gate-wallet" +"gateway timeout" +"GatewayTimeout" +"generate anon private key for frostfsid: %w" +"generate anon private key for policy: %w" +"generate-presigned-url" +"Generate presigned url using AWS credentials" +"generate random nonce: %w" +"generate shared key: %w" +"GET" +"get access box from request" +"get access box: %w" +"get accessbox: %w" +"get_balance" +"get bearer token issuer: %w" +"get box '%s': %w" +"GetBucketAccelerate" +"GetBucketAccelerateOperation" +"GetBucketACL" +"GetBucketACLOperation" +"get bucket cors" +"GetBucketCors" +"GetBucketCorsOperation" +"GetBucketEncryption" +"GetBucketEncryptionOperation" +"get bucket info" +"get bucket info: %w" +"GetBucketLifecycle" +"GetBucketLifecycleOperation" +"GetBucketLocation" +"GetBucketLocationOperation" +"GetBucketLogging" +"GetBucketLoggingOperation" +"GetBucketNotification" +"GetBucketNotificationOperation" +"GetBucketObjectLockConfig" +"GetBucketObjectLockConfigOperation" +"GetBucketPolicy" +"GetBucketPolicyOperation" +"GetBucketPolicyStatus" +"GetBucketReplication" +"GetBucketReplicationOperation" +"GetBucketRequestPayment" +"GetBucketRequestPaymentOperation" +"GetBucketTagging" +"GetBucketTaggingOperation" +"get bucket tagging: %w" +"GetBucketVersioning" +"GetBucketVersioningOperation" +"GetBucketWebsite" +"GetBucketWebsiteOperation" +"get cache with empty prefix" +"get cache with non-existing key" +"get cache with other prefix" +"get cache with prefix" +"get chiper: %w" +"get combined object '%s': %w" +"get_container" +"get_container_eacl" +"get container eacl: %w" +"get container via connection pool: %w" +"get context from session token: %w" +"get correct placement policy" +"get frostfs container: %w" +"get gate box: %w" +"get group ids: %w" +"get hmac: %w" +"get incorrect placement policy" +"get jet stream: %w" +"get network info via client" +"get node from main stream: %w" +"get object" +"get_object" +"GetObject" +"GetObjectACL" +"GetObjectACLOperation" +"GetObjectAttributes" +"GetObjectAttributesOperation" +"GetObjectLegalHold" +"GetObjectLegalHoldOperation" +"GetObjectOperation" +"GetObjectRetention" +"GetObjectRetentionOperation" +"GetObjectTagging" +"GetObjectTaggingOperation" +"get object tagging: %w" +"get object to copy: %w" +"get object to upload copy: %w" +"GetPolicy" +"get policy request" +"get policy: %w" +"Gets generated secret from credential object (accessbox)" +"get sub tree node from main stream: %w" +"get tokens: %w" +"get tree node" +"Gfrct4Afhio8pCGCCKVNTf1kyexQjMBeaUfvDtQCkAvg" +"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl" +"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container" +"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object" +"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs" +"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session" +"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/proto" +"git.frostfs.info/TrueCloudLab/frostfs-contract/commonclient" +"git.frostfs.info/TrueCloudLab/frostfs-contract/frostfsid/client" +"git.frostfs.info/TrueCloudLab/frostfs-contract/policy" +"git.frostfs.info/TrueCloudLab/frostfs-contract/rpcclient/policy" +"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" +"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing/grpc" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth/signer/v4" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/cache" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/handler" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/encryption" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/notifications" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/resolver" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/authmate" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/cmd/s3-authmate/modules" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/tokens" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/crdt" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/frostfsid" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/frostfsid/contract" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/policy" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/policy/contract" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/services" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/util" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/version" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/wallet" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/metrics" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/pkg/retryer" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/pkg/service/control" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/pkg/service/control/server" +"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/pkg/service/tree" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer/test" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/checksum" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/ns" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/test" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/pool" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/pool/tree" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/pool/tree/service" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user" +"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user/test" +"git.frostfs.info/TrueCloudLab/policy-engine/iam" +"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain" +"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine" +"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine/inmemory" +"git.frostfs.info/TrueCloudLab/policy-engine/pkg/resource" +"git.frostfs.info/TrueCloudLab/policy-engine/pkg/resource/testutil" +"git.frostfs.info/TrueCloudLab/policy-engine/schema/common" +"git.frostfs.info/TrueCloudLab/policy-engine/schema/native" +"git.frostfs.info/TrueCloudLab/policy-engine/schema/s3" +"git.frostfs.info/TrueCloudLab/zapjournald" +"github.com/aws/aws-sdk-go/aws" +"github.com/aws/aws-sdk-go/aws/credentials" +"github.com/aws/aws-sdk-go/aws/request" +"github.com/aws/aws-sdk-go/aws/session" +"github.com/aws/aws-sdk-go/private/protocol/rest" +"github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil" +"github.com/aws/aws-sdk-go/service/s3" +"github.com/aws/aws-sdk-go-v2/aws" +"github.com/aws/aws-sdk-go-v2/aws/retry" +"github.com/bluele/gcache" +"github.com/go-chi/chi/v5" +"github.com/go-chi/chi/v5/middleware" +"github.com/google/uuid" +"github.com/minio/sio" +"github.com/nats-io/nats.go" +"github.com/nspcc-dev/neo-go/cli/flags" +"github.com/nspcc-dev/neo-go/cli/input" +"github.com/nspcc-dev/neo-go/pkg/core/transaction" +"github.com/nspcc-dev/neo-go/pkg/crypto/keys" +"github.com/nspcc-dev/neo-go/pkg/neorpc/result" +"github.com/nspcc-dev/neo-go/pkg/rpcclient" +"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor" +"github.com/nspcc-dev/neo-go/pkg/rpcclient/notary" +"github.com/nspcc-dev/neo-go/pkg/util" +"github.com/nspcc-dev/neo-go/pkg/wallet" +"github.com/panjf2000/ants/v2" +"github.com/prometheus/client_golang/prometheus" +"github.com/prometheus/client_golang/prometheus/promhttp" +"github.com/prometheus/client_model/go" +"github.com/spf13/cobra" +"github.com/spf13/pflag" +"github.com/spf13/viper" +"github.com/ssgreg/journald" +"github.com/stretchr/testify/require" +"github.com/trailofbits/go-fuzz-utils" +"github.com/urfave/cli/v2" +"glacier" +"golang.org/x/crypto/chacha20poly1305" +"golang.org/x/crypto/hkdf" +"golang.org/x/exp/maps" +"golang.org/x/exp/slices" +"golang.org/x/net/http2" +"golang.org/x/text/encoding/ianaindex" +"GOMEMLIMIT" +"google.golang.org/grpc" +"google.golang.org/grpc/codes" +"google.golang.org/grpc/credentials/insecure" +"google.golang.org/grpc/metadata" +"google.golang.org/grpc/status" +"google.golang.org/protobuf/proto" +"google.golang.org/protobuf/reflect/protoreflect" +"google.golang.org/protobuf/runtime/protoimpl" +"go.opentelemetry.io/otel/attribute" +"go.opentelemetry.io/otel/semconv/v1.18.0" +"go.opentelemetry.io/otel/trace" +"goroutine" +"go.uber.org/zap" +"go.uber.org/zap/zapcore" +"go.uber.org/zap/zaptest" +"go.uber.org/zap/zaptest/observer" +"GOVERNANCE" +"Grantee" +"Group" +"GROUP" +"GROUP is not supported in the SQL expression." +"GroupLength" +"grpc deadline exceeded" +",gzip" +"gzip" +"h" +"h2" +"HCS public keys could not be empty" +"HEAD" +"HeadBucket" +"HeadBucketOperation" +"head crdt access box '%s': %w" +"header" +"headers" +"headers not set" +"headers not set, and the port is not set" +"head_object" +"HeadObject" +"HeadObjectOperation" +"health" +"HealthCheck" +"healthcheck request" +"healthcheck_timeout" +"health_status,omitempty" +"HEALTH_STATUS_UNDEFINED" +"heap" +"help" +"Helps manage delegated access via gates to data stored in FrostFS network" +"HMAC-Key" +"HMAC-Salt" +"host" +"host:" +"HostId" +"///" +"http://acs.amazonaws.com/groups/global/AllUsers" +"http://bla.bla.bla/" +"http://example.com" +"http://localhost/" +"http://localhost:8084" +"http method" +"HTTP method to perform action" +"http://s3.amazonaws.com/doc/2006-03-01/" +"http://s3.amazonaws.com/doc/2006-03-01/ AccessControlPolicy" +"http://s3.amazonaws.com/doc/2006-03-01/ CompleteMultipartUpload" +"http://s3.amazonaws.com/doc/2006-03-01/ CompleteMultipartUploadResult" +"http://s3.amazonaws.com/doc/2006-03-01/ CopyObjectResult" +"http://s3.amazonaws.com/doc/2006-03-01/ CORSConfiguration" +"http://s3.amazonaws.com/doc/2006-03-01/ CreateBucketConfiguration" +"http://s3.amazonaws.com/doc/2006-03-01/ Delete" +"http://s3.amazonaws.com/doc/2006-03-01/ DeleteResult" +"http://s3.amazonaws.com/doc/2006-03-01/ InitiateMultipartUploadResult" +"http://s3.amazonaws.com/doc/2006-03-01/ LegalHold" +"http://s3.amazonaws.com/doc/2006-03-01/ ListAllMyBucketsResult" +"http://s3.amazonaws.com/doc/2006-03-01/ ListBucketResult" +"http://s3.amazonaws.com/doc/2006-03-01/ ListMultipartUploadsResult" +"http://s3.amazonaws.com/doc/2006-03-01/ ListPartsResult" +"http://s3.amazonaws.com/doc/2006-03-01/ ListVersionsResult" +"http://s3.amazonaws.com/doc/2006-03-01/ LocationConstraint" +"http://s3.amazonaws.com/doc/2006-03-01/ NotificationConfiguration" +"http://s3.amazonaws.com/doc/2006-03-01/ ObjectLockConfiguration" +"http://s3.amazonaws.com/doc/2006-03-01/ PolicyStatus" +"http://s3.amazonaws.com/doc/2006-03-01/ Retention" +"http://s3.amazonaws.com/doc/2006-03-01/ Tagging" +"http://s3.amazonaws.com/doc/2006-03-01/ VersioningConfiguration" +"HTTP Server endpoint health" +"https://localhost:8084" +"https://localhost:%d" +"https://s3.amazonaws.com/" +"http://www.example.com" +"http://www.w3.org/2001/XMLSchema-instance" +"i" +"i=\\" +"IAM-MFA" +", id=\\" +"id" +"id=\\" +"Id" +"ID" +"ID,omitempty" +"If-Match" +"IfMatch false" +"IfMatch false, IfUnmodifiedSince true" +"IfMatch true" +"IfMatch true, IfUnmodifiedSince false" +"If-Modified-Since" +"IfModifiedSince false" +"IfModifiedSince true" +"If-None-Match" +"IfNoneMatch false" +"IfNoneMatch false, IfModifiedSince true" +"IfNoneMatch true" +"IfNoneMatch true, IfModifiedSince false" +"If-Unmodified-Since" +"IfUnmodifiedSince false" +"IfUnmodifiedSince true" +"Illegal argument was used in the SQL function." +"IllegalSqlFunctionArgument" +"IllegalVersioningConfigurationException" +"implement me" +"IN" +"inavid last record: '%s', '%s', '%s'," +"IncompleteBody" +"incorrect logger level configuration %s (%v), " +"Incorrect number of arguments in the function call in the SQL expression." +"incorrect rules with repeating prefix" +"incorrect rules with repeating suffix" +"incorrect rules with wrong name" +"IncorrectSqlFunctionArgumentType" +"Incorrect type of arguments in function call in the SQL expression." +"Indicates that the version ID specified in the request does not match an existing version." +"Indicates that the versioning configuration specified in the request is invalid." +"init frostfsid client: %w" +"init frostfsid contract failed" +"init full object reading via connection pool" +"init full payload range reading via connection pool" +"initial_access_key_id" +"initialize chunk reader: %w" +"Initiated" +"Initiator" +"init inner stream: %w" +"init object payload reader: %w" +"init object search via connection pool" +"init payload range reading via connection pool" +"init payload reader for the next part: %w" +"init policy contract failed" +"init rpc client: %w" +"inner stream: %w" +"InsecureClientRequest" +"IntegerOverflow" +"InternalError" +"Interval for updating nodes health status" +"Int overflow or underflow in the SQL expression." +"invalid" +"invalid accessbox check removing interval, using default value" +"InvalidAccessKeyId" +"Invalid according to Policy: Policy Condition failed" +"invalid address" +"Invalid args" +"InvalidArgument" +"Invalid argument given to the LIKE clause in the SQL expression." +"invalid attribute format: %s" +"Invalid attribute name specified" +"invalid bearer token public key: %w" +"InvalidBucketName" +"invalid bucket name: %w" +"invalid+bucket/object" +"invaliDBucket/object" +"InvalidBucketState" +"invalid bucket %s: %w" +"invalid cache entry type" +"invalid cache key type" +"invalid cache size, using default value" +"InvalidCast" +"invalid cid" +"invalid-code" +"InvalidColumnIndex" +"invalid completed part header" +"invalid completed part number '%s': %w" +"invalid completed part size '%s': %w" +"invalid completed part: %w" +"InvalidCompressionFormat" +"invalid condition" +"invalid configuration" +"invalid content-length" +"invalid contract name: '%s'" +"invalid copies number" +"invalid created timestamp: %w" +"invalid data" +"invalid-data" +"InvalidDataSource" +"Invalid data source type. Only CSV and JSON are supported at this time." +"InvalidDataType" +"Invalid date format header, expected to be in ISO8601, RFC1123 or RFC1123Z time format." +"Invalid days" +"invalid decrypted size header: %w" +"invalid defaultMaxAge" +"invalid delete markers length" +"InvalidDigest" +"InvalidDuration" +"Invalid Encoding Method specified in Request" +"Invalid encoding type. Only UTF-8 encoding is supported at this time." +"InvalidExpressionType" +"InvalidFileHeaderInfo" +"invalid gate key" +"invalid-hash" +"invalid hash format: character" +"invalid hash format: length (63 characters)" +"invalid hash format: length and character" +"invalid hash value" +"invalid hmacKey '%s': %w" +"invalid hmacSalt '%s': %w" +"InvalidJsonType" +"invalid key" +"InvalidKeyPath" +"invalid key size: %d" +"invalid legal hold object id: %w" +"invalid legal hold status" +"invalid lifetime, using default value (in seconds)" +"invalid list type" +"InvalidLocationConstraint" +"invalid lock configuration" +"invalid lock configuration: %s" +"Invalid marker prefix combination" +"invalid MaxParts" +"invalid maxUploads" +"invalid-method" +"invalid metric type" +"invalid Mode value: %s" +"invalid multipart info id" +"invalid multipart size header: %w" +"invalid node order: %w" +"invalid not empty token" +"invalid NotPrincipal" +"invalid ObjectLockEnabled value: %s" +"InvalidObjectName" +"InvalidObjectState" +"invalid offset: %d/%d" +"invalid oid: %w" +"invalid owner" +"InvalidPart" +"invalid part number" +"invalid PartNumberMarker" +"invalid part number: %w" +"InvalidPartOrder" +"invalid part size: %w" +"invalid payload" +"InvalidPolicyDocument" +"InvalidPrefixMarker" +"invalid principal" +"InvalidQuoteFields" +"invalid range" +"InvalidRange" +"invalid range: %d %d" +"invalid range: %d-%d/%d" +"InvalidRegion" +"invalid request" +"Invalid Request" +"InvalidRequest" +"InvalidRequestParameter" +"invalid request signature authorization header" +"invalid retention configuration" +"invalid retention object id: %w" +"invalid servers configuration: no known server found" +"invalid sha256 checksum in completed part: %w" +"invalid signature" +"invalid size header" +"invalid size value '%s': %w" +"invalid source copy" +"invalid sse headers" +"invalid statement" +"invalid status %s" +"Invalid storage class." +"InvalidStorageClass" +"InvalidTableAlias" +"InvalidTag" +"invalid target: %s" +"InvalidTextEncoding" +"invalid time format error" +"InvalidTokenId" +"invalid tree node: %w" +"invalid tree service meta KV" +"Invalid use of * in SELECT list in the SQL expression." +"Invalid version id specified" +"invalid versioning configuration" +"invalid X-Amz-Bucket-Object-Lock-Enabled header" +"invalid xml with parts" +"Invalid years" +"io" +"i/object" +"IsCombined" +"IsCompliance" +"IsDeleteMarker" +"IsLatest" +"IsLock" +"IsPublic" +"Issue a secret in FrostFS network" +"issue-secret" +"IsTag" +"IsTruncated" +"IsTruncated,omitempty" +"IsUnversioned" +"iteratorChainsByPrefix" +"it's not a multipart node" +"it's not a multipart node: missing UploadId" +"it's not a part node" +"j" +"jk" +"JOIN is not supported in the SQL expression." +"journald" +"k" +"kapusta" +"k e y" +"key" +"key?" +"key\\\\" +"key~" +"Key" +"key-1" +"key1" +"Key1" +"key-2" +"key2" +"Key2" +"key3" +"Key3" +"KeyCount" +"key #%d: %s failed" +"key is not in the allowed list" +"key-marker" +"KeyMarker" +"key,omitempty" +"Key,omitempty" +"Key path in the SQL expression is invalid." +"key.pem" +"KeyTooLongError" +"kludge.acl_enabled" +"kludge.bypass_content_encoding_check_in_chunks" +"kludge.default_namespaces" +"kludge.use_default_xmlns" +"l" +"last element" +"Last-Modified" +"LastModified" +"last version id" +"layer access denied error to s3 access denied error" +"layer gateway timeout error to s3 gateway timeout error" +"layer node access denied error to s3 access denied error" +"legal" +"?legal-hold" +"legal-hold" +"LegalHoldOID" +"length is out of payload range" +"length of records is less than 7: '%d'" +"level" +"LexerInvalidChar" +"LexerInvalidIONLiteral" +"LexerInvalidLiteral" +"LexerInvalidOperator" +"lifecycle" +"lifetime" +"lifetime must be greater 0, current value: %d" +"Lifetime of presigned URL. For example 50h30m (note: max time unit is an hour so to set a day you should use 24h).\\nIt will be ceil rounded to the nearest amount of epoch." +"Lifetime of tokens. For example 50h30m (note: max time unit is an hour so to set a day you should use 24h).\\nIt will be ceil rounded to the nearest amount of epoch." +"LikeInvalidInputs" +"LIST" +"ListBucketObjectVersions" +"ListBucketObjectVersionsOperation" +"ListBuckets" +"list_container" +"listen_address" +"listen and serve" +"ListenBucketNotification" +"ListenBucketNotificationOperation" +"listen_domains" +"ListMultipartUploads" +"ListMultipartUploadsOperation" +"ListObjectsV1" +"ListObjectsV1Operation" +"ListObjectsV2" +"ListObjectsV2M" +"ListObjectsV2MOperation" +"ListObjectsV2Operation" +"ListParts" +"ListPartsOperation" +"ListPolicies" +"list policies request" +"list-type" +"list user containers via connection pool" +"listv1" +"listv2" +"load-1-1" +"localhost" +"localhost:8083" +"localhost:8085" +"localhost:8086" +"location" +"Location" +"location_constraint" +"locationConstraint" +"locationConstraint,omitempty" +"location_constraints" +".lock." +"LockConfiguration" +"lock disabled error" +"lock_enabled" +"LockEnabled" +"logger.destination" +"logger.level" +"logging" +"log level won't be updated" +"m" +"main stream next: %w" +"malformed chunked encoding" +"MalformedDate" +"MalformedJSON" +"MalformedPolicy" +"MalformedPOSTRequest" +"MalformedXML" +"Mapping AWS storage class to FrostFS storage policy as plain json string or path to json file" +"marker" +"Marker" +"mark object removal via connection pool" +"Mark token as not impersonate to don't consider token signer as request owner (must be provided to use --bearer-rules flag)" +"marshall box: %w" +"marshal notify configuration: %w" +"marshal parst for combined object: %w" +"marshal request body: %w" +"math" +"math/big" +"MaxAgeSeconds,omitempty" +"max_clients_count" +"max_clients_deadline" +"max-keys" +"MaxKeys" +"max-keys parameter, allow range of values" +"max-keys parameter, allow specific value" +"max-keys parameter, prohibit specific value" +"max-parts" +"MaxParts,omitempty" +"max retry attempts exausted, max %d: %w" +"max-uploads" +"MaxUploads" +"md5" +"MD5" +"message" +"Message,omitempty" +"meta-" +"metadata" +"method" +"method GetPolicy not implemented" +"method HealthCheck not implemented" +"method ListPolicies not implemented" +"MethodNotAllowed" +"method PutPolicies not implemented" +"method RemovePolicies not implemented" +"metrics" +"metrics are disabled" +"/metrics/billing" +"MfaDelete,omitempty" +"middle of parts" +"mime" +"mime/multipart" +"mint-bucket-for-listing-versions" +"mismatched obj encryptionInfo" +"missed key marker" +"Missing all" +"missing chain id" +"missing Content-Length" +"MissingContentLength" +"missing Content-MD5" +"MissingContentMD5" +"Missing Credential field for this request." +"MissingFields" +"Missing fields in request." +"missing frostfsid cache" +"missing frostfsid client" +"missing frostfsid logger" +"MissingHeaders" +"Missing numbers" +"MissingRequestBodyError" +"Missing required header for this request: Content-Md5." +"MissingRequiredParameter" +"MissingSecurityHeader" +"missing signature" +"mode" +"Mode" +"MTIzNDU2Nzg5MHF3ZXJ0eXVpb3Bhc2RmZ2hqa2x6eGM=" +"multipart_enc" +"multipart/form-data" +"multipart/form-data*" +"multipart_obj" +"multipart upload" +"multiple default overrides found, only one will be used" +"multi tx isn't initialized" +"mutex" +"/my" +"my-bucket" +"/my/object2" +"/my/object/name" +"\\n" +"n" +"name" +"Name" +"name,omitempty" +"namespace" +"NAMESPACE" +"namespaces" +"namespaces.config" +"Namespace to register public key in frostfsid contract" +"nats.cert_file" +"nats.enabled" +"nats.endpoint" +"nats.key_file" +"nats.root_ca" +"nats.timeout" +"?>\\ntest" +"NEO node RPC address" +"net" +"net/http" +"net/http/httptest" +"net/http/pprof" +"net/url" +"network error" +"network_info" +"new-bucket" +"new-object-multipart" +"new-payload" +"new-secret" +"new_value" +"NextContinuationToken,omitempty" +"NextKeyMarker,omitempty" +"NextMarker,omitempty" +"NextPartNumberMarker,omitempty" +"NextUploadIdMarker,omitempty" +"NextVersionIdMarker,omitempty" +"nns" +"no authorization header" +"No AWSAccessKey was presented" +"no conditions" +"node" +"no gate data for key %x was found" +"no hash" +"no healthy servers" +"none" +"none type request" +"non-existent resources" +"no node to remove" +"no removing check, accessbox from cache" +"no resolvers" +"no retryable" +"NoSuchBucket" +"NoSuchBucketLifecycle" +"NoSuchBucketPolicy" +"NoSuchCORSConfiguration" +"NoSuchKey" +"NoSuchLifecycleConfiguration" +"NoSuchObjectLockConfiguration" +"NoSuchTagSet" +"NoSuchUpload" +"NoSuchVersion" +"NoSuchWebsiteConfiguration" +"Not allowed headers" +"Not allowed method" +"not create new delete marker if last version is delete marker" +"not equal curves" +"not found" +"NotFound" +"not found version id" +"not found version id, obj last" +"notification" +"Notifications are not enabled in the gateway. Please connect to the other gateway" +"notificator is disabled, s3 won't produce notification events" +"not implemented" +"NotImplemented" +"not matched name alphabetically greater" +"not matched name alphabetically less" +"not matched name alphabetically less with dummy version id" +"NotModified" +"no topics because of not suitable prefix" +"no topics because of not suitable suffix" +"no topics because suitable events not found" +"not supported" +"Not supported by FrostFS S3 Gateway" +".ns" +"ns" +"\\n[%s]\\naws_access_key_id = %s\\naws_secret_access_key = %s\\n" +"ns '%s' and zone '%s' are mismatched for container '%s'" +"NtkH/y2maPit+yUkhq4Q7A==" +"null" +"number" +"Number" +"Number of errors on current connections that will be reset after the threshold" +"number of objects to delete must be greater than 0 and less or equal to 1000" +"?>\\n %s" +"%s,%d,%s,%d" +"search s3 access boxes: %w" +"second and third" +"second part" +"second part 2" +"secret" +"secret_access_key" +"secretKey,omitempty" +"seedKey,omitempty" +"SelectObjectContent" +"SelectObjectContentOperation" +"sequencer,omitempty" +"server" +"Server" +"server reconnected successfully" +"ServerSideEncryptionConfigurationNotFoundError" +"Server side encryption specified but KMS authorization failed" +"Server side encryption specified but KMS is not configured" +"Server side encryption specified with both SSE-C and SSE-S3 headers" +"service" +"service couldn't start on configured port" +"service hasn't started since it's disabled" +"service isn't ready, status: %s" +"service is running" +"session token" +"session token for delete" +"session token for put" +"session token for set eACL" +"session-tokens" +"sessionTokens,omitempty" +"set bucket name resolve order" +"set_container_eacl" +"set domains to be listened" +"SETEACL" +"set FrostFS nodes" +"set max-clients count" +"set max-clients deadline" +"set reader to decrypter: %w" +"set rebalance interval" +"set RPC endpoint" +"set the main address to listen" +"set timeout to check node health during rebalance" +"set timeout to connect to FrostFS nodes" +"settings node: invalid lock configuration: %w" +"settings node: invalid owner key" +"several nodes of different types and with different timestamp" +"'%s' form field doesn't match the policy: %w" +"sftp" +"sfx" +"shared key is point at infinity" +"should never be called" +"shouldn't be any object in frostfs" +"show help" +"show version" +"SHUTTING_DOWN" +"shutting down service" +"Sid" +"SIGHUP config reload completed" +"SIGHUP config reload started" +"Sign" +"Signature=" +"Signature=2811ccb9e242f41426738fb1f" +" + + " +"SignatureDoesNotMatch" +"Signature header missing Signature field." +"Signature header missing SignedHeaders field." +"signature,omitempty" +"sign bearer token: %w" +"signed_header_fields" +"SignedHeaders=" +"Signer" +"sign,omitempty" +"simple" +"simple read all" +"simple read with length" +"simple std error to internal error" +"simple timeout" +"size" +"Size" +"Size of filter rule value cannot exceed 1024 bytes in UTF-8 representation" +"size,omitempty" +"Size,omitempty" +"sizes don't match" +"skip, empty address" +"SlowDown" +"small.jpg" +"small.jpg delimiter" +"small.jpg not matched prefix" +"SNS and Lambda configurations are not supported " +"soft runtime memory defined with GOMEMLIMIT environment variable, config value skipped" +"soft runtime memory limit value updated" +"some acl not fully mapped" +"some-delimiter" +"some-domain" +"some error" +"Some headers in the query are missing from the file. Check the file and try again." +"some-id" +"some-key" +"somekey1" +"somekey2" +"some reason" +"something" +"something went wrong" +"sort" +"sort by epoch" +"sort by headers" +"sort by oids" +"Source-Ip" +"sourceIPAddress" +"source_ip_header" +"source-object" +"spb" +"src_bucket_name" +"src_object_name" +"%s (%s)" +"%s:%s" +"/%s/%s" +"%s_%s_[N]_ADDRESS = string\\n" +"%s_%s_[N]_WEIGHT = 0..1 (float)\\n" +"%s (%s:%s)" +"%s/%s/%s" +"%s_%s = %s\\n" +"%s:%s %s %s" +"STANDARD" +"start-after" +"StartAfter,omitempty" +"STARTING" +"starting control API server" +"starting server" +"starts-with" +"state" +"Statement" +"statistic" +"status" +"Status" +"Status,omitempty" +"stdout" +"stopping server" +"StorageClass" +"StorageClass,omitempty" +"store bearer token into FrostFS" +"strconv" +"STREAMING-AWS4-ECDSA-P256-SHA256-PAYLOAD" +"STREAMING-AWS4-ECDSA-P256-SHA256-PAYLOAD-TRAILER" +"STREAMING-AWS4-HMAC-SHA256-PAYLOAD" +"STREAMING-AWS4-HMAC-SHA256-PAYLOAD-TRAILER" +"STREAMING-UNSIGNED-PAYLOAD-TRAILER" +"stream next: %w" +"stream_timeout" +"strings" +"sub-bucket" +"sub-bucket/object" +"subject" +"subject already exists" +"sub tree stream impl pool wrap: %w" +"success_action_redirect" +"success_action_status" +"successful auth" +"suffix" +"Suspended" +"%s %v" +"%s: %w" +"%s: %w: %s" +"sync" +"sync/atomic" +"sync container with the network state" +"syscall" +"/system" +"system" +"SystemDNS" +"system DNS parameter not found or empty" +"system header __SYSTEM__EXPIRATION_EPOCH presence" +"%T" +"tableToAst order and vice versa" +"tag" +"tagging" +".tagset." +"TagSet>Tag" +"tag-test" +"target" +"target,omitempty" +"TARGET_UNDEFINED" +"tcp" +"/test" +"test" +"test/" +"test1" +"test2" +"/test-bucket" +"test-bucket" +"testbucket1" +"testing" +"test-object" +"test_resolver" +"test/small.jpg" +"test/small.jpg with prefix and delimiter" +"text" +"text/plain" +"The access key ID you provided does not exist in our records." +"The Access Key Id you provided does not exist in our records." +"The authorization header is malformed; the region is wrong." +"The authorization header that you provided is not valid." +"The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256." +"The body of your POST request is not well-formed multipart/form-data." +"The bucket does not allow ACLs." +"The bucket lifecycle configuration does not exist" +"The bucket policy does not exist" +"The bucket you tried to delete is not empty" +"The calculated MD5 hash of the key did not match the hash that was provided." +"The column index is invalid. Please check the service documentation and try again." +"The Content-Md5 you specified did not match what we received." +"The Content-Md5 you specified is not valid." +"The content of the form does not meet the conditions specified in the policy document." +"The continuation token provided is incorrect" +"The CORS configuration does not exist" +"The difference between the request time and the server's time is too large." +"The encryption method specified is not supported" +"The encryption parameters are not applicable to this object." +"The encryption request that you specified is not valid. The valid value is AES256." +"The ExpressionType is invalid. Only SQL expressions are supported at this time." +"The FileHeaderInfo is invalid. Only NONE, USE, and IGNORE are supported." +"The file is not in a supported compression format. Only GZIP is supported at this time." +"The JsonType is invalid. Only DOCUMENT and LINES are supported at this time." +"The JSON you provided was not well-formed or did not validate against our published format." +"the last element is less than a key" +"the last element's key is less, upload id is greater" +"the last element's key is less, upload id is less" +"The lifecycle configuration does not exist" +"The list of parts was not in ascending order. The parts list must be specified in order by part number." +"The multipart upload initiate requested encryption. Subsequent part requests must include the appropriate encryption parameters." +"The object was stored using a form of Server Side Encryption. The correct parameters must be provided to retrieve the object." +"The operation is not valid for the current state of the object." +"The provided encryption parameters did not match the ones used originally." +"The provided 'x-amz-content-sha256' header does not match what was computed." +"The QuoteFields is invalid. Only ALWAYS and ASNEEDED are supported." +"The replication configuration was not found" +"The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again." +"The requested range is not satisfiable" +"The request signature we calculated does not match the signature you provided. Check your key and signing method." +"The resource was not changed." +"The retain until date must be in the future" +"There were headers present in the request which were not signed" +"the same keys in the sequence first element" +"The secret key was invalid for the specified algorithm." +"The security token included in the request is invalid" +"The SelectRequest entity can only contain one of CSV or JSON. Check the service documentation and try again." +"The SelectRequest entity is missing a required parameter. Check the service documentation and try again." +"The server is acting as a gateway and cannot get a response in time" +"The server side encryption configuration was not found" +"The service is unavailable. Please retry." +"The specified argument was invalid" +"The specified bucket does not exist" +"The specified bucket does not exist." +"The specified bucket does not have a website configuration" +"The specified bucket is not valid." +"The specified key does not exist." +"The specified location (Region) constraint is not valid." +"The specified method is not allowed against this resource." +"The specified multipart upload does not exist. The upload ID may be invalid, or the upload may have been aborted or completed." +"The specified object does not have a ObjectLock configuration" +"The SQL expression CAST has incorrect arity." +"The SQL expression contains an empty SELECT." +"The SQL expression contains an invalid character." +"The SQL expression contains an invalid data type." +"The SQL expression contains an invalid literal." +"The SQL expression contains an invalid operator." +"The SQL expression contains an invalid parameter value." +"The SQL expression contains an invalid table alias." +"The SQL expression contains an unexpected keyword." +"The SQL expression contains an unexpected operator." +"The SQL expression contains an unexpected term." +"The SQL expression contains an unexpected token." +"The SQL expression contains an unsupported token." +"The SQL expression contains an unsupported use of ALIAS." +"The SQL expression contains an unsupported use of CASE." +"The SQL expression contains an unsupported use of GROUP BY." +"The SQL expression contains an unsupported use of MEMBER." +"The SQL expression contains an unsupported use of SELECT." +"The SQL expression contains unsupported syntax." +"The SQL expression is too long: The maximum byte-length for the SQL expression is 256 KB." +"The TagKey you have provided is invalid" +"The TagSet does not exist" +"The TagValue you have provided is invalid" +"The value of a parameter in SelectRequest element is invalid. Check the service API documentation and try again." +"The x-amz-copy-source-range value must be of the form bytes=first-last where first and last are the zero-based offsets of the first and last bytes to copy" +"The XML you provided was not well-formed or did not validate against our published schema." +"third part 3" +"This copy request is illegal because it is trying to copy an object to itself without changing the object's metadata, storage class, website redirect location or encryption attributes." +". This date in the credential must be in the format \\" +"threadcreate" +"time" +"timeout" +"Timeout for connection to the node in pool to be established" +"Timeout for individual operation in streaming RPC" +"Timeout for request to node to decide if it is alive" +"Timeout of processing of the command, for example 2m (note: max time unit is an hour so to set a day you should use 24h)" +"time '%s' must be in the future (after %s)" +"Time stamp format pattern contains an invalid symbol in the SQL expression." +"Time stamp format pattern contains an invalid token in the SQL expression." +"Time stamp format pattern contains a valid format symbol that cannot be applied to time stamp parsing in the SQL expression." +"Time stamp format pattern contains multiple format specifiers representing the time stamp field in the SQL expression." +"Time stamp format pattern contains unterminated token in the SQL expression." +"Time stamp format pattern requires additional fields in the SQL expression." +"Time stamp parse failure in the SQL expression." +"Time taken by requests served by current FrostFS S3 Gate instance" +"tls cert" +"tls.cert_file" +"TLS certificate file to use" +"tls disabled" +"tls enabled" +"tls.enabled" +"tls key" +"tls.key_file" +"TLS key file to use" +"tmp" +"tokens,omitempty" +"too bid object to copy with single copy operation, use multipart upload copy instead" +"TopicConfiguration" +"TopicConfigurations" +"Total number of bytes sent/received by current FrostFS S3 Gate instance" +"Total number of errors for connection in pool" +"Total number of errors in pool" +"Total number of requests to specific node in pool" +"Total number of running s3 requests in current FrostFS S3 Gate instance" +"Total number of s3 errors in current FrostFS S3 Gate instance" +"Total number of s3 requests in current FrostFS S3 Gate instance" +"trace_id" +"tracing config updated" +"tracing.enabled" +"tracing.endpoint" +"tracing.exporter" +"treeID" +"true" +"TRUE" +"two" +"Two tags with the same keys" +"Two tags with unique keys" +"tx isn't initialized" +"type" +"UnauthorizedAccess" +"_under1/" +"_under1/bar" +"_under1/baz/" +"_under1/baz/xyzzy" +"_under2/" +"_under2/bla" +"_under2/thud" +"unescape bucket name: %w" +"unexpected status" +"unexpected status: %d" +"unicode" +"Unknown" +"unknown acl: %s" +"UnknownAPIRequest" +"Unknown API request at %s" +"unknown byte-range-set" +"unknown canned acl" +"unknown condition type" +"unknown container token verb %s" +"unknown grantee type" +"unknown header" +"unknown header1" +"Unknown metadata directive." +"unknown resolver: %s" +"Unknown tag directive." +"Unknown tagging directive." +"unknown type" +"unknown type: %s" +"unknown unit in range header" +"Unknown wormMode directive" +"unmarhal access box: %w" +"unmarshal bearer token: %w" +"unmarshal chain: %w" +"unmarshal combined object parts: %w" +"unmarshal cors: %w" +"unmarshal notify configuration: %w" +"unmarshal placement policy: %w" +"unmarshal policies: %w" +"unmarshal policy condition: %w" +"unmarshal session token context: %w" +"unmarshal session token: %w" +"unmarshal tokens: %w" +"UnmatchedBucketOperation" +"UnmatchedObjectOperation" +"UnmatchedOperation" +"unsigned payload" +"UNSIGNED-PAYLOAD" +"UnsupportedFunction" +"unsupported grantee" +"unsupported grantee type" +"unsupported method is %s" +"unsupported principal: %v" +"UnsupportedRangeHeader" +"UnsupportedSqlOperation" +"UnsupportedSqlStructure" +"UnsupportedSyntax" +"unsuppoted header: %s" +"UntilDate" +"Unversioned" +"unversioned bucket" +"update access cred object into FrostFS" +"Update a secret in FrostFS network" +"update-secret" +"Upload" +"upload id" +"uploadId" +"uploadID" +"UploadId" +"upload-id-marker" +"UploadIdMarker,omitempty" +"uploadKey" +"upload part" +"UploadPart" +"UploadPartCopy" +"UploadPartCopyOperation" +"UploadPartOperation" +"uploads" +"uri" +"uri=\\" +"uri, id=\\" +"URI,omitempty" +"url" +"US-ASCII" +"us-east-1" +"*user" +"_user" +"~user" +"user" +"USER" +"user1" +"user2" +"user%2Bpassword" +"user3" +"user4" +"user5" +"User-Agent" +"User attributes in form of Key1=Value1,Key2=Value2 (note: you cannot override system attributes)" +"user groups list is empty, subject not found" +"userIdentity" +"user+password" +"user_requests" +"User-Tag-" +"user_traffic" +"user/user1/" +"using credentials" +"usupported filters" +"v" +"v4_signature" +"v4.SignRequestHandler" +" + val + " +"v a l" +"val" +"val-1" +"val1" +"val-2" +"val2" +"val3" +"valid" +"Valid" +"validation data user key failed: %w" +"Valid get" +"valid-key" +"Valid put" +"valid-region" +"valid-sign" +"valid token" +"value" +"Value" +"Value1" +"Value2" +"Value3" +"value in config" +"ValueParseFailure" +"value should be one of %v" +"variable_labels,omitempty" +"varint,1,opt,name=health_status,json=healthStatus,proto3,enum=s3gw.control.HealthStatus" +"varint,1,opt,name=target,proto3,enum=s3gw.control.PolicyTarget" +"Vary" +"vector" +"verb" +"version" +"Version" +"versioned bucket" +"versioned bucket not found obj" +"versionId" +"VersionId" +"version-id-marker" +"VersionIdMarker" +"VersionIDMarkerWithoutKeyMarker" +"versionId,omitempty" +"VersionId,omitempty" +"version_info" +"versioning" +"Versioning" +"Version of current FrostFS S3 Gate instance" +"versions" +"Version: %s" +"versions must be empty" +"vWqF8cMDRbJcvnPLALoQGnABPPhw8NyYMcGsfDPfZJM0HrgjonN8CgFvCZ3kh9BUXw4W2tJ5E7EAGhueSF122HB" +"vWqF8cMDRbJcvnPLALoQGnABPPhw8NyYMcGsfDPfZJMHrgjonN8CgFvCZ3kh9BUXw4W2tJ5E7EAGhueSF122HB" +"w" +"%w: accesskeyID prefix isn't allowed" +"wallet" +"wallet.address" +"wallet.gate.passphrase" +"wallet.passphrase" +"wallet.path" +"wallet path must not be empty" +"wallet_public_key" +"want: '%s'\\ngot: '%s'" +"%w: 'AWS' field must be string" +"%w: couldn't find session token for put" +"%w: %d/%d" +"%w: %d-%d/%d" +"%w: decode hash: %s: %s" +"web.idle_timeout" +"web.read_header_timeout" +"web.read_timeout" +"website" +"web.write_timeout" +"We encountered an internal error, please try again." +".weight" +"weight" +"%w: etag matched: '%s', '%s'" +"%w: etag mismatched: '%s', '%s'" +"%w: expired: now %s, signature %s" +"%w: found %d parts, need %d" +"%w: found version is delete marker" +"%w: invalid hash size %d" +"with awful mint name" +"with-log" +"with percentage escaped" +"with slashes" +"with slash escaped" +"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" +"%w: mismatch owner" +"%w: missing policy" +"%w: modified since '%s', last modified '%s'" +"%w: not modified since '%s', last modified '%s'" +"%w: parse decoded content length: %s" +"%w: parse multipart form with max size %d" +"wrap grpc error: %w" +"wrapped layer access denied error to s3 access denied error" +"wrapped s3 error to s3 error" +"wrap: %w" +"%w: request is not chunk encoded, encodings '%s'" +"WRITE" +"write headers: %w" +"write json policy to client" +"write response" +"write_response_error" +"write response: %w" +"wrong data size (%d), should be greater than %d" +"wrong destination for logger: %s" +"%w: %s" +"%w: signature time from the future: now %s, signature %s" +"%w: %s != %s" +"%w: %s; %s" +"%w: %s != %s: headers %v" +"%w: there isn't tree node with requested version id" +"%w: unknown part %d or etag mismatched" +"%w: %v" +"\\x0a" +"X-Amz-" +"x-amz-acl" +"X-Amz-Acl" +"X-Amz-Algorithm" +"X-Amz-Algorithm only supports \\" +"x-amz-bucket-object-lock-enabled" +"X-Amz-Bucket-Object-Lock-Enabled" +"x-amz-bucket-object-lock-token" +"X-Amz-Bucket-Region" +"x-amz-bypass-governance-retention" +"X-Amz-Bypass-Governance-Retention" +"x-amz-checksum-algorithm" +"x-amz-confirm-remove-self-bucket-access" +"x-amz-content-sha256" +"X-Amz-Content-Sha256" +"XAmzContentSHA256Mismatch" +"x-amz-copy-source" +"X-Amz-Copy-Source" +"x-amz-copy-source-if-match" +"X-Amz-Copy-Source-If-Match" +"x-amz-copy-source-if-modified-since" +"X-Amz-Copy-Source-If-Modified-Since" +"x-amz-copy-source-if-none-match" +"X-Amz-Copy-Source-If-None-Match" +"x-amz-copy-source-if-unmodified-since" +"X-Amz-Copy-Source-If-Unmodified-Since" +"X-Amz-Copy-Source-Range" +"x-amz-copy-source-server-side-encryption-customer-algorithm" +"X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm" +"x-amz-copy-source-server-side-encryption-customer-key" +"X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key" +"x-amz-copy-source-server-side-encryption-customer-key-MD5" +"X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5" +"x-amz-credential" +"X-Amz-Credential" +"x-amz-date" +"X-Amz-Date" +"X-Amz-Date must be in the ISO8601 Long Format \\" +"x-amz-decoded-content-length" +"X-Amz-Decoded-Content-Length" +"X-Amz-Delete-Marker" +"x-amz-expected-bucket-owner" +"X-Amz-Expected-Bucket-Owner" +"X-Amz-Expires" +"X-Amz-Expires must be less than a week (in seconds); that is, the given X-Amz-Expires must be less than 604800 seconds" +"X-Amz-Expires must be non-negative" +"X-Amz-Expires should be a number" +"x-amz-grant-full-control" +"X-Amz-Grant-Full-control" +"X-Amz-Grant-Full-Control" +"x-amz-grant-read" +"X-Amz-Grant-Read" +"x-amz-grant-read-acp" +"X-Amz-Grant-Read-Acp" +"x-amz-grant-write" +"X-Amz-Grant-Write" +"x-amz-grant-write-acp" +"X-Amz-Grant-Write-Acp" +"X-Amz-Max-Parts" +"X-Amz-Meta-" +"X-Amz-Meta-*" +"x-amz-metadata-directive" +"X-Amz-Metadata-Directive" +"x-amz-mfa" +"X-Amz-Mfa" +"X-Amzn-Trace-Id" +"X-Amz-Object-Attributes" +"x-amz-object-lock-legal-hold" +"X-Amz-Object-Lock-Legal-Hold" +"x-amz-object-lock-mode" +"X-Amz-Object-Lock-Mode" +"x-amz-object-lock-retain-until-date" +"X-Amz-Object-Lock-Retain-Until-Date" +"x-amz-object-lock-retain-until-date and x-amz-object-lock-mode must both be supplied" +"x-amz-object-ownership" +"X-Amz-Part-Number-Marker" +"x-amz-request-id" +"x-amz-request-payer" +"X-Amz-Request-Payer" +"X-Amz-Security-Token" +"x-amz-server-side-encryption" +"X-Amz-Server-Side-Encryption" +"x-amz-server-side-encryption-aws-kms-key-id" +"X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id" +"x-amz-server-side-encryption-bucket-key-enabled" +"x-amz-server-side-encryption-context" +"x-amz-server-side-encryption-customer-algorithm" +"X-Amz-Server-Side-Encryption-Customer-Algorithm" +"x-amz-server-side-encryption-customer-key" +"X-Amz-Server-Side-Encryption-Customer-Key" +"x-amz-server-side-encryption-customer-key-MD5" +"X-Amz-Server-Side-Encryption-Customer-Key-Md5" +"x-amz-signature" +"X-Amz-Signature" +"X-Amz-SignedHeaders" +"x-amz-source-expected-bucket-owner" +"X-Amz-Source-Expected-Bucket-Owner" +"x-amz-storage-class" +"X-Amz-Storage-Class" +"x-amz-tagging" +"X-Amz-Tagging" +"X-Amz-Tagging-Count" +"x-amz-tagging-directive" +"X-Amz-Tagging-Directive" +"X-Amz-Version-Id" +"x-amz-website-redirect-location" +"X-Amz-Website-Redirect-Location" +"x-amz-*, X-Amz-*" +"X-Container-Id" +"X-Container-Name" +"X-Container-Zone" +"X-Forwarded-For" +"x-forwarded-for header by multiple hosts" +"x-forwarded-for single-host header" +"X-Frostfs-Namespace" +"XFrostFSReadQuorum" +"XFrostFSServerNotInitialized" +"XFrostFSWriteQuorum" +"x-ignore-" +"xml decode cors: %w" +"xmlns:xsi,attr" +"