This reverts commit f14c79f170.
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
be7ee97dd3
Коммит
29fae242e1
5
vendor/github.com/minio/minio-go/v6/README.md
сгенерированный
поставляемый
5
vendor/github.com/minio/minio-go/v6/README.md
сгенерированный
поставляемый
@@ -190,11 +190,6 @@ The full API Reference is available here.
|
||||
* [setbucketlifecycle.go](https://github.com/minio/minio-go/blob/master/examples/s3/setbucketlifecycle.go)
|
||||
* [getbucketlifecycle.go](https://github.com/minio/minio-go/blob/master/examples/s3/getbucketlifecycle.go)
|
||||
|
||||
### Full Examples : Bucket encryption Operations
|
||||
* [setbucketencryption.go](https://github.com/minio/minio-go/blob/master/examples/s3/setbucketencryption.go)
|
||||
* [getbucketencryption.go](https://github.com/minio/minio-go/blob/master/examples/s3/getbucketencryption.go)
|
||||
* [deletebucketencryption.go](https://github.com/minio/minio-go/blob/master/examples/s3/deletebucketencryption.go)
|
||||
|
||||
### Full Examples : Bucket notification Operations
|
||||
* [setbucketnotification.go](https://github.com/minio/minio-go/blob/master/examples/s3/setbucketnotification.go)
|
||||
* [getbucketnotification.go](https://github.com/minio/minio-go/blob/master/examples/s3/getbucketnotification.go)
|
||||
|
||||
9
vendor/github.com/minio/minio-go/v6/api-compose-object.go
сгенерированный
поставляемый
9
vendor/github.com/minio/minio-go/v6/api-compose-object.go
сгенерированный
поставляемый
@@ -60,13 +60,6 @@ type DestInfoOptions struct {
|
||||
// Otherwise this field is ignored
|
||||
UserTags map[string]string
|
||||
ReplaceTags bool
|
||||
|
||||
// Specifies whether you want to apply a Legal Hold to the copied object.
|
||||
LegalHold LegalHoldStatus
|
||||
|
||||
// Object Retention related fields
|
||||
Mode RetentionMode
|
||||
RetainUntilDate time.Time
|
||||
}
|
||||
|
||||
// Process custom-metadata to remove a `x-amz-meta-` prefix if
|
||||
@@ -114,8 +107,6 @@ func NewDestinationInfo(bucket, object string, sse encrypt.ServerSide, userMeta
|
||||
UserMeta: m,
|
||||
UserTags: nil,
|
||||
ReplaceTags: false,
|
||||
LegalHold: LegalHoldStatus(""),
|
||||
Mode: RetentionMode(""),
|
||||
}
|
||||
return DestinationInfo{
|
||||
bucket: bucket,
|
||||
|
||||
3
vendor/github.com/minio/minio-go/v6/api-datatypes.go
сгенерированный
поставляемый
3
vendor/github.com/minio/minio-go/v6/api-datatypes.go
сгенерированный
поставляемый
@@ -82,9 +82,6 @@ type ObjectInfo struct {
|
||||
// x-amz-meta-* headers stripped "x-amz-meta-" prefix containing the first value.
|
||||
UserMetadata StringMap `json:"userMetadata"`
|
||||
|
||||
// x-amz-tagging values in their k/v values.
|
||||
UserTags map[string]string `json:"userTags"`
|
||||
|
||||
// Owner name.
|
||||
Owner struct {
|
||||
DisplayName string `json:"name"`
|
||||
|
||||
71
vendor/github.com/minio/minio-go/v6/api-get-bucket-encryption.go
сгенерированный
поставляемый
71
vendor/github.com/minio/minio-go/v6/api-get-bucket-encryption.go
сгенерированный
поставляемый
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* MinIO Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* Copyright 2020 MinIO, Inc.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package minio
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/minio/minio-go/v6/pkg/s3utils"
|
||||
)
|
||||
|
||||
// GetBucketEncryption - get default encryption configuration for a bucket.
|
||||
func (c Client) GetBucketEncryption(bucketName string) (ServerSideEncryptionConfiguration, error) {
|
||||
return c.GetBucketEncryptionWithContext(context.Background(), bucketName)
|
||||
}
|
||||
|
||||
// GetBucketEncryptionWithContext gets the default encryption configuration on an existing bucket with a context to control cancellations and timeouts.
|
||||
func (c Client) GetBucketEncryptionWithContext(ctx context.Context, bucketName string) (ServerSideEncryptionConfiguration, error) {
|
||||
// Input validation.
|
||||
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
|
||||
return ServerSideEncryptionConfiguration{}, err
|
||||
}
|
||||
|
||||
// Get resources properly escaped and lined up before
|
||||
// using them in http request.
|
||||
urlValues := make(url.Values)
|
||||
urlValues.Set("encryption", "")
|
||||
|
||||
// Execute GET on bucket to get the default encryption configuration.
|
||||
resp, err := c.executeMethod(ctx, http.MethodGet, requestMetadata{
|
||||
bucketName: bucketName,
|
||||
queryValues: urlValues,
|
||||
})
|
||||
|
||||
defer closeResponse(resp)
|
||||
if err != nil {
|
||||
return ServerSideEncryptionConfiguration{}, err
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return ServerSideEncryptionConfiguration{}, httpRespToErrorResponse(resp, bucketName, "")
|
||||
}
|
||||
|
||||
bucketEncryptionBuf, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return ServerSideEncryptionConfiguration{}, err
|
||||
}
|
||||
|
||||
encryptionConfig := ServerSideEncryptionConfiguration{}
|
||||
if err := xml.Unmarshal(bucketEncryptionBuf, &encryptionConfig); err != nil {
|
||||
return ServerSideEncryptionConfiguration{}, err
|
||||
}
|
||||
return encryptionConfig, nil
|
||||
}
|
||||
12
vendor/github.com/minio/minio-go/v6/api-get-object-file.go
сгенерированный
поставляемый
12
vendor/github.com/minio/minio-go/v6/api-get-object-file.go
сгенерированный
поставляемый
@@ -87,17 +87,6 @@ func (c Client) fGetObjectWithContext(ctx context.Context, bucketName, objectNam
|
||||
return err
|
||||
}
|
||||
|
||||
// If we return early with an error, be sure to close and delete
|
||||
// filePart. If we have an error along the way there is a chance
|
||||
// that filePart is somehow damaged, and we should discard it.
|
||||
closeAndRemove := true
|
||||
defer func() {
|
||||
if closeAndRemove {
|
||||
_ = filePart.Close()
|
||||
_ = os.Remove(filePartPath)
|
||||
}
|
||||
}()
|
||||
|
||||
// Issue Stat to get the current offset.
|
||||
st, err = filePart.Stat()
|
||||
if err != nil {
|
||||
@@ -122,7 +111,6 @@ func (c Client) fGetObjectWithContext(ctx context.Context, bucketName, objectNam
|
||||
}
|
||||
|
||||
// Close the file before rename, this is specifically needed for Windows users.
|
||||
closeAndRemove = false
|
||||
if err = filePart.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
38
vendor/github.com/minio/minio-go/v6/api-get-object.go
сгенерированный
поставляемый
38
vendor/github.com/minio/minio-go/v6/api-get-object.go
сгенерированный
поставляемый
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* MinIO Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* Copyright 2015-2020 MinIO, Inc.
|
||||
* Copyright 2015-2017 MinIO, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,7 +23,9 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio-go/v6/pkg/s3utils"
|
||||
)
|
||||
@@ -633,10 +635,38 @@ func (c Client) getObject(ctx context.Context, bucketName, objectName string, op
|
||||
}
|
||||
}
|
||||
|
||||
objectStat, err := ToObjectInfo(bucketName, objectName, resp.Header)
|
||||
// Trim off the odd double quotes from ETag in the beginning and end.
|
||||
md5sum := trimEtag(resp.Header.Get("ETag"))
|
||||
|
||||
// Parse the date.
|
||||
date, err := time.Parse(http.TimeFormat, resp.Header.Get("Last-Modified"))
|
||||
if err != nil {
|
||||
closeResponse(resp)
|
||||
return nil, objectStat, resp.Header, nil
|
||||
msg := "Last-Modified time format not recognized. " + reportIssue
|
||||
return nil, ObjectInfo{}, nil, ErrorResponse{
|
||||
Code: "InternalError",
|
||||
Message: msg,
|
||||
RequestID: resp.Header.Get("x-amz-request-id"),
|
||||
HostID: resp.Header.Get("x-amz-id-2"),
|
||||
Region: resp.Header.Get("x-amz-bucket-region"),
|
||||
}
|
||||
}
|
||||
|
||||
// Get content-type.
|
||||
contentType := strings.TrimSpace(resp.Header.Get("Content-Type"))
|
||||
if contentType == "" {
|
||||
contentType = "application/octet-stream"
|
||||
}
|
||||
|
||||
objectStat := ObjectInfo{
|
||||
ETag: md5sum,
|
||||
Key: objectName,
|
||||
Size: resp.ContentLength,
|
||||
LastModified: date,
|
||||
ContentType: contentType,
|
||||
// Extract only the relevant header keys describing the object.
|
||||
// following function filters out a list of standard set of keys
|
||||
// which are not part of object metadata.
|
||||
Metadata: extractObjMetadata(resp.Header),
|
||||
}
|
||||
|
||||
// do not close body here, caller will close
|
||||
|
||||
28
vendor/github.com/minio/minio-go/v6/api-list.go
сгенерированный
поставляемый
28
vendor/github.com/minio/minio-go/v6/api-list.go
сгенерированный
поставляемый
@@ -317,14 +317,14 @@ func (c Client) listObjectsV2Query(bucketName, objectPrefix, continuationToken s
|
||||
}
|
||||
|
||||
for i, obj := range listBucketResult.Contents {
|
||||
listBucketResult.Contents[i].Key, err = decodeS3Name(obj.Key, listBucketResult.EncodingType)
|
||||
listBucketResult.Contents[i].Key, err = url.QueryUnescape(obj.Key)
|
||||
if err != nil {
|
||||
return listBucketResult, err
|
||||
}
|
||||
}
|
||||
|
||||
for i, obj := range listBucketResult.CommonPrefixes {
|
||||
listBucketResult.CommonPrefixes[i].Prefix, err = decodeS3Name(obj.Prefix, listBucketResult.EncodingType)
|
||||
listBucketResult.CommonPrefixes[i].Prefix, err = url.QueryUnescape(obj.Prefix)
|
||||
if err != nil {
|
||||
return listBucketResult, err
|
||||
}
|
||||
@@ -500,21 +500,21 @@ func (c Client) listObjectsQuery(bucketName, objectPrefix, objectMarker, delimit
|
||||
}
|
||||
|
||||
for i, obj := range listBucketResult.Contents {
|
||||
listBucketResult.Contents[i].Key, err = decodeS3Name(obj.Key, listBucketResult.EncodingType)
|
||||
listBucketResult.Contents[i].Key, err = url.QueryUnescape(obj.Key)
|
||||
if err != nil {
|
||||
return listBucketResult, err
|
||||
}
|
||||
}
|
||||
|
||||
for i, obj := range listBucketResult.CommonPrefixes {
|
||||
listBucketResult.CommonPrefixes[i].Prefix, err = decodeS3Name(obj.Prefix, listBucketResult.EncodingType)
|
||||
listBucketResult.CommonPrefixes[i].Prefix, err = url.QueryUnescape(obj.Prefix)
|
||||
if err != nil {
|
||||
return listBucketResult, err
|
||||
}
|
||||
}
|
||||
|
||||
if listBucketResult.NextMarker != "" {
|
||||
listBucketResult.NextMarker, err = decodeS3Name(listBucketResult.NextMarker, listBucketResult.EncodingType)
|
||||
listBucketResult.NextMarker, err = url.QueryUnescape(listBucketResult.NextMarker)
|
||||
if err != nil {
|
||||
return listBucketResult, err
|
||||
}
|
||||
@@ -697,25 +697,25 @@ func (c Client) listMultipartUploadsQuery(bucketName, keyMarker, uploadIDMarker,
|
||||
return listMultipartUploadsResult, err
|
||||
}
|
||||
|
||||
listMultipartUploadsResult.NextKeyMarker, err = decodeS3Name(listMultipartUploadsResult.NextKeyMarker, listMultipartUploadsResult.EncodingType)
|
||||
listMultipartUploadsResult.NextKeyMarker, err = url.QueryUnescape(listMultipartUploadsResult.NextKeyMarker)
|
||||
if err != nil {
|
||||
return listMultipartUploadsResult, err
|
||||
}
|
||||
|
||||
listMultipartUploadsResult.NextUploadIDMarker, err = decodeS3Name(listMultipartUploadsResult.NextUploadIDMarker, listMultipartUploadsResult.EncodingType)
|
||||
listMultipartUploadsResult.NextUploadIDMarker, err = url.QueryUnescape(listMultipartUploadsResult.NextUploadIDMarker)
|
||||
if err != nil {
|
||||
return listMultipartUploadsResult, err
|
||||
}
|
||||
|
||||
for i, obj := range listMultipartUploadsResult.Uploads {
|
||||
listMultipartUploadsResult.Uploads[i].Key, err = decodeS3Name(obj.Key, listMultipartUploadsResult.EncodingType)
|
||||
listMultipartUploadsResult.Uploads[i].Key, err = url.QueryUnescape(obj.Key)
|
||||
if err != nil {
|
||||
return listMultipartUploadsResult, err
|
||||
}
|
||||
}
|
||||
|
||||
for i, obj := range listMultipartUploadsResult.CommonPrefixes {
|
||||
listMultipartUploadsResult.CommonPrefixes[i].Prefix, err = decodeS3Name(obj.Prefix, listMultipartUploadsResult.EncodingType)
|
||||
listMultipartUploadsResult.CommonPrefixes[i].Prefix, err = url.QueryUnescape(obj.Prefix)
|
||||
if err != nil {
|
||||
return listMultipartUploadsResult, err
|
||||
}
|
||||
@@ -837,13 +837,3 @@ func (c Client) listObjectPartsQuery(bucketName, objectName, uploadID string, pa
|
||||
}
|
||||
return listObjectPartsResult, nil
|
||||
}
|
||||
|
||||
// Decode an S3 object name according to the encoding type
|
||||
func decodeS3Name(name, encodingType string) (string, error) {
|
||||
switch encodingType {
|
||||
case "url":
|
||||
return url.QueryUnescape(name)
|
||||
default:
|
||||
return name, nil
|
||||
}
|
||||
}
|
||||
|
||||
14
vendor/github.com/minio/minio-go/v6/api-notification.go
сгенерированный
поставляемый
14
vendor/github.com/minio/minio-go/v6/api-notification.go
сгенерированный
поставляемый
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* MinIO Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* Copyright 2017-2020 MinIO, Inc.
|
||||
* Copyright 2017 MinIO, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -89,13 +89,11 @@ type bucketMeta struct {
|
||||
|
||||
// Notification event object metadata.
|
||||
type objectMeta struct {
|
||||
Key string `json:"key"`
|
||||
Size int64 `json:"size,omitempty"`
|
||||
ETag string `json:"eTag,omitempty"`
|
||||
ContentType string `json:"contentType,omitempty"`
|
||||
UserMetadata map[string]string `json:"userMetadata,omitempty"`
|
||||
VersionID string `json:"versionId,omitempty"`
|
||||
Sequencer string `json:"sequencer"`
|
||||
Key string `json:"key"`
|
||||
Size int64 `json:"size,omitempty"`
|
||||
ETag string `json:"eTag,omitempty"`
|
||||
VersionID string `json:"versionId,omitempty"`
|
||||
Sequencer string `json:"sequencer"`
|
||||
}
|
||||
|
||||
// Notification event server specific metadata.
|
||||
|
||||
176
vendor/github.com/minio/minio-go/v6/api-object-legal-hold.go
сгенерированный
поставляемый
176
vendor/github.com/minio/minio-go/v6/api-object-legal-hold.go
сгенерированный
поставляемый
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
* MinIO Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* Copyright 2020 MinIO, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package minio
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/minio/minio-go/v6/pkg/s3utils"
|
||||
)
|
||||
|
||||
// objectLegalHold - object legal hold specified in
|
||||
// https://docs.aws.amazon.com/AmazonS3/latest/API/archive-RESTObjectPUTLegalHold.html
|
||||
type objectLegalHold struct {
|
||||
XMLNS string `xml:"xmlns,attr,omitempty"`
|
||||
XMLName xml.Name `xml:"LegalHold"`
|
||||
Status LegalHoldStatus `xml:"Status,omitempty"`
|
||||
}
|
||||
|
||||
// PutObjectLegalHoldOptions represents options specified by user for PutObjectLegalHold call
|
||||
type PutObjectLegalHoldOptions struct {
|
||||
VersionID string
|
||||
Status *LegalHoldStatus
|
||||
}
|
||||
|
||||
// GetObjectLegalHoldOptions represents options specified by user for GetObjectLegalHold call
|
||||
type GetObjectLegalHoldOptions struct {
|
||||
VersionID string
|
||||
}
|
||||
|
||||
// LegalHoldStatus - object legal hold status.
|
||||
type LegalHoldStatus string
|
||||
|
||||
const (
|
||||
// LegalHoldEnabled indicates legal hold is enabled
|
||||
LegalHoldEnabled LegalHoldStatus = "ON"
|
||||
|
||||
// LegalHoldDisabled indicates legal hold is disabled
|
||||
LegalHoldDisabled LegalHoldStatus = "OFF"
|
||||
)
|
||||
|
||||
func (r LegalHoldStatus) String() string {
|
||||
return string(r)
|
||||
}
|
||||
|
||||
// IsValid - check whether this legal hold status is valid or not.
|
||||
func (r LegalHoldStatus) IsValid() bool {
|
||||
return r == LegalHoldEnabled || r == LegalHoldDisabled
|
||||
}
|
||||
|
||||
func newObjectLegalHold(status *LegalHoldStatus) (*objectLegalHold, error) {
|
||||
if status == nil {
|
||||
return nil, fmt.Errorf("Status not set")
|
||||
}
|
||||
if !status.IsValid() {
|
||||
return nil, fmt.Errorf("invalid legal hold status `%v`", status)
|
||||
}
|
||||
legalHold := &objectLegalHold{
|
||||
Status: *status,
|
||||
}
|
||||
return legalHold, nil
|
||||
}
|
||||
|
||||
// PutObjectLegalHold : sets object legal hold for a given object and versionID.
|
||||
func (c Client) PutObjectLegalHold(bucketName, objectName string, opts PutObjectLegalHoldOptions) error {
|
||||
// Input validation.
|
||||
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s3utils.CheckValidObjectName(objectName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get resources properly escaped and lined up before
|
||||
// using them in http request.
|
||||
urlValues := make(url.Values)
|
||||
urlValues.Set("legal-hold", "")
|
||||
|
||||
if opts.VersionID != "" {
|
||||
urlValues.Set("versionId", opts.VersionID)
|
||||
}
|
||||
|
||||
lh, err := newObjectLegalHold(opts.Status)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lhData, err := xml.Marshal(lh)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
reqMetadata := requestMetadata{
|
||||
bucketName: bucketName,
|
||||
objectName: objectName,
|
||||
queryValues: urlValues,
|
||||
contentBody: bytes.NewReader(lhData),
|
||||
contentLength: int64(len(lhData)),
|
||||
contentMD5Base64: sumMD5Base64(lhData),
|
||||
contentSHA256Hex: sum256Hex(lhData),
|
||||
}
|
||||
|
||||
// Execute PUT Object Legal Hold.
|
||||
resp, err := c.executeMethod(context.Background(), "PUT", reqMetadata)
|
||||
defer closeResponse(resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resp != nil {
|
||||
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNoContent {
|
||||
return httpRespToErrorResponse(resp, bucketName, objectName)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetObjectLegalHold gets legal-hold status of given object.
|
||||
func (c Client) GetObjectLegalHold(bucketName, objectName string, opts GetObjectLegalHoldOptions) (status *LegalHoldStatus, err error) {
|
||||
// Input validation.
|
||||
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s3utils.CheckValidObjectName(objectName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
urlValues := make(url.Values)
|
||||
urlValues.Set("legal-hold", "")
|
||||
|
||||
if opts.VersionID != "" {
|
||||
urlValues.Set("versionId", opts.VersionID)
|
||||
}
|
||||
|
||||
// Execute GET on bucket to list objects.
|
||||
resp, err := c.executeMethod(context.Background(), "GET", requestMetadata{
|
||||
bucketName: bucketName,
|
||||
objectName: objectName,
|
||||
queryValues: urlValues,
|
||||
contentSHA256Hex: emptySHA256Hex,
|
||||
})
|
||||
defer closeResponse(resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp != nil {
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, httpRespToErrorResponse(resp, bucketName, objectName)
|
||||
}
|
||||
}
|
||||
lh := &objectLegalHold{}
|
||||
if err = xml.NewDecoder(resp.Body).Decode(lh); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &lh.Status, nil
|
||||
}
|
||||
27
vendor/github.com/minio/minio-go/v6/api-object-lock.go
сгенерированный
поставляемый
27
vendor/github.com/minio/minio-go/v6/api-object-lock.go
сгенерированный
поставляемый
@@ -183,11 +183,11 @@ func (c Client) SetBucketObjectLockConfig(bucketName string, mode *RetentionMode
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetObjectLockConfig gets object lock configuration of given bucket.
|
||||
func (c Client) GetObjectLockConfig(bucketName string) (objectLock string, mode *RetentionMode, validity *uint, unit *ValidityUnit, err error) {
|
||||
// GetBucketObjectLockConfig gets object lock configuration of given bucket.
|
||||
func (c Client) GetBucketObjectLockConfig(bucketName string) (mode *RetentionMode, validity *uint, unit *ValidityUnit, err error) {
|
||||
// Input validation.
|
||||
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
|
||||
return "", nil, nil, nil, err
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
urlValues := make(url.Values)
|
||||
@@ -201,16 +201,16 @@ func (c Client) GetObjectLockConfig(bucketName string) (objectLock string, mode
|
||||
})
|
||||
defer closeResponse(resp)
|
||||
if err != nil {
|
||||
return "", nil, nil, nil, err
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
if resp != nil {
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", nil, nil, nil, httpRespToErrorResponse(resp, bucketName, "")
|
||||
return nil, nil, nil, httpRespToErrorResponse(resp, bucketName, "")
|
||||
}
|
||||
}
|
||||
config := &objectLockConfig{}
|
||||
if err = xml.NewDecoder(resp.Body).Decode(config); err != nil {
|
||||
return "", nil, nil, nil, err
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
if config.Rule != nil {
|
||||
@@ -224,18 +224,9 @@ func (c Client) GetObjectLockConfig(bucketName string) (objectLock string, mode
|
||||
years := Years
|
||||
unit = &years
|
||||
}
|
||||
return config.ObjectLockEnabled, mode, validity, unit, nil
|
||||
|
||||
return mode, validity, unit, nil
|
||||
}
|
||||
return config.ObjectLockEnabled, nil, nil, nil, nil
|
||||
}
|
||||
|
||||
// GetBucketObjectLockConfig gets object lock configuration of given bucket.
|
||||
func (c Client) GetBucketObjectLockConfig(bucketName string) (mode *RetentionMode, validity *uint, unit *ValidityUnit, err error) {
|
||||
_, mode, validity, unit, err = c.GetObjectLockConfig(bucketName)
|
||||
return mode, validity, unit, err
|
||||
}
|
||||
|
||||
// SetObjectLockConfig sets object lock configuration in given bucket. mode, validity and unit are either all set or all nil.
|
||||
func (c Client) SetObjectLockConfig(bucketName string, mode *RetentionMode, validity *uint, unit *ValidityUnit) error {
|
||||
return c.SetBucketObjectLockConfig(bucketName, mode, validity, unit)
|
||||
return nil, nil, nil, nil
|
||||
}
|
||||
|
||||
2
vendor/github.com/minio/minio-go/v6/api-object-retention.go
сгенерированный
поставляемый
2
vendor/github.com/minio/minio-go/v6/api-object-retention.go
сгенерированный
поставляемый
@@ -100,7 +100,7 @@ func (c Client) PutObjectRetention(bucketName, objectName string, opts PutObject
|
||||
|
||||
if opts.GovernanceBypass {
|
||||
// Set the bypass goverenance retention header
|
||||
headers.Set(amzBypassGovernance, "true")
|
||||
headers.Set("x-amz-bypass-governance-retention", "True")
|
||||
}
|
||||
|
||||
reqMetadata := requestMetadata{
|
||||
|
||||
3
vendor/github.com/minio/minio-go/v6/api-object-tagging.go
сгенерированный
поставляемый
3
vendor/github.com/minio/minio-go/v6/api-object-tagging.go
сгенерированный
поставляемый
@@ -155,8 +155,7 @@ func (c Client) RemoveObjectTaggingWithContext(ctx context.Context, bucketName,
|
||||
}
|
||||
|
||||
if resp != nil {
|
||||
// S3 returns "204 No content" after Object tag deletion.
|
||||
if resp.StatusCode != http.StatusNoContent {
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return httpRespToErrorResponse(resp, bucketName, objectName)
|
||||
}
|
||||
}
|
||||
|
||||
97
vendor/github.com/minio/minio-go/v6/api-put-bucket.go
сгенерированный
поставляемый
97
vendor/github.com/minio/minio-go/v6/api-put-bucket.go
сгенерированный
поставляемый
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* MinIO Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* Copyright 2015-2020 MinIO, Inc.
|
||||
* Copyright 2015-2017 MinIO, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,25 +29,6 @@ import (
|
||||
"github.com/minio/minio-go/v6/pkg/s3utils"
|
||||
)
|
||||
|
||||
// ApplyServerSideEncryptionByDefault defines default encryption configuration, KMS or SSE. To activate
|
||||
// KMS, SSEAlgoritm needs to be set to "aws:kms"
|
||||
// Minio currently does not support Kms.
|
||||
type ApplyServerSideEncryptionByDefault struct {
|
||||
KmsMasterKeyID string `xml:"KMSMasterKeyID,omitempty"`
|
||||
SSEAlgorithm string `xml:"SSEAlgorithm"`
|
||||
}
|
||||
|
||||
// Rule layer encapsulates default encryption configuration
|
||||
type Rule struct {
|
||||
Apply ApplyServerSideEncryptionByDefault `xml:"ApplyServerSideEncryptionByDefault"`
|
||||
}
|
||||
|
||||
// ServerSideEncryptionConfiguration is the default encryption configuration structure
|
||||
type ServerSideEncryptionConfiguration struct {
|
||||
XMLName xml.Name `xml:"ServerSideEncryptionConfiguration"`
|
||||
Rules []Rule `xml:"Rule"`
|
||||
}
|
||||
|
||||
/// Bucket operations
|
||||
|
||||
func (c Client) makeBucket(ctx context.Context, bucketName string, location string, objectLockEnabled bool) (err error) {
|
||||
@@ -332,82 +313,6 @@ func (c Client) removeBucketLifecycle(ctx context.Context, bucketName string) er
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetBucketEncryption sets the default encryption configuration on an existing bucket.
|
||||
func (c Client) SetBucketEncryption(bucketName string, configuration ServerSideEncryptionConfiguration) error {
|
||||
return c.SetBucketEncryptionWithContext(context.Background(), bucketName, configuration)
|
||||
}
|
||||
|
||||
// SetBucketEncryptionWithContext sets the default encryption configuration on an existing bucket with a context to control cancellations and timeouts.
|
||||
func (c Client) SetBucketEncryptionWithContext(ctx context.Context, bucketName string, configuration ServerSideEncryptionConfiguration) error {
|
||||
// Input validation.
|
||||
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buf, err := xml.Marshal(&configuration)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get resources properly escaped and lined up before
|
||||
// using them in http request.
|
||||
urlValues := make(url.Values)
|
||||
urlValues.Set("encryption", "")
|
||||
|
||||
// Content-length is mandatory to set a default encryption configuration
|
||||
reqMetadata := requestMetadata{
|
||||
bucketName: bucketName,
|
||||
queryValues: urlValues,
|
||||
contentBody: bytes.NewReader(buf),
|
||||
contentLength: int64(len(buf)),
|
||||
contentMD5Base64: sumMD5Base64(buf),
|
||||
}
|
||||
|
||||
// Execute PUT to upload a new bucket default encryption configuration.
|
||||
resp, err := c.executeMethod(ctx, http.MethodPut, reqMetadata)
|
||||
defer closeResponse(resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return httpRespToErrorResponse(resp, bucketName, "")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteBucketEncryption removes the default encryption configuration on a bucket.
|
||||
func (c Client) DeleteBucketEncryption(bucketName string) error {
|
||||
return c.DeleteBucketEncryptionWithContext(context.Background(), bucketName)
|
||||
}
|
||||
|
||||
// DeleteBucketEncryptionWithContext removes the default encryption configuration on a bucket with a context to control cancellations and timeouts.
|
||||
func (c Client) DeleteBucketEncryptionWithContext(ctx context.Context, bucketName string) error {
|
||||
// Input validation.
|
||||
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get resources properly escaped and lined up before
|
||||
// using them in http request.
|
||||
urlValues := make(url.Values)
|
||||
urlValues.Set("encryption", "")
|
||||
|
||||
// DELETE default encryption configuration on a bucket.
|
||||
resp, err := c.executeMethod(ctx, http.MethodDelete, requestMetadata{
|
||||
bucketName: bucketName,
|
||||
queryValues: urlValues,
|
||||
contentSHA256Hex: emptySHA256Hex,
|
||||
})
|
||||
defer closeResponse(resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNoContent {
|
||||
return httpRespToErrorResponse(resp, bucketName, "")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetBucketNotification saves a new bucket notification.
|
||||
func (c Client) SetBucketNotification(bucketName string, bucketNotification BucketNotification) error {
|
||||
return c.SetBucketNotificationWithContext(context.Background(), bucketName, bucketNotification)
|
||||
|
||||
10
vendor/github.com/minio/minio-go/v6/api-put-object-copy.go
сгенерированный
поставляемый
10
vendor/github.com/minio/minio-go/v6/api-put-object-copy.go
сгенерированный
поставляемый
@@ -22,7 +22,6 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio-go/v6/pkg/encrypt"
|
||||
"github.com/minio/minio-go/v6/pkg/s3utils"
|
||||
@@ -46,15 +45,6 @@ func (c Client) CopyObjectWithProgress(dst DestinationInfo, src SourceInfo, prog
|
||||
header.Set(amzTaggingHeader, s3utils.TagEncode(dst.opts.UserTags))
|
||||
}
|
||||
|
||||
if dst.opts.LegalHold != LegalHoldStatus("") {
|
||||
header.Set(amzLegalHoldHeader, dst.opts.LegalHold.String())
|
||||
}
|
||||
|
||||
if dst.opts.Mode != RetentionMode("") && !dst.opts.RetainUntilDate.IsZero() {
|
||||
header.Set(amzLockMode, dst.opts.Mode.String())
|
||||
header.Set(amzLockRetainUntil, dst.opts.RetainUntilDate.Format(time.RFC3339))
|
||||
}
|
||||
|
||||
var err error
|
||||
var size int64
|
||||
// If progress bar is specified, size should be requested as well initiate a StatObject request.
|
||||
|
||||
4
vendor/github.com/minio/minio-go/v6/api-put-object-multipart.go
сгенерированный
поставляемый
4
vendor/github.com/minio/minio-go/v6/api-put-object-multipart.go
сгенерированный
поставляемый
@@ -50,7 +50,7 @@ func (c Client) putObjectMultipart(ctx context.Context, bucketName, objectName s
|
||||
return 0, ErrEntityTooLarge(size, maxSinglePutObjectSize, bucketName, objectName)
|
||||
}
|
||||
// Fall back to uploading as single PutObject operation.
|
||||
return c.putObject(ctx, bucketName, objectName, reader, size, opts)
|
||||
return c.putObjectNoChecksum(ctx, bucketName, objectName, reader, size, opts)
|
||||
}
|
||||
}
|
||||
return n, err
|
||||
@@ -104,7 +104,7 @@ func (c Client) putObjectMultipartNoStream(ctx context.Context, bucketName, obje
|
||||
// Choose hash algorithms to be calculated by hashCopyN,
|
||||
// avoid sha256 with non-v4 signature request or
|
||||
// HTTPS connection.
|
||||
hashAlgos, hashSums := c.hashMaterials(opts.SendContentMd5)
|
||||
hashAlgos, hashSums := c.hashMaterials()
|
||||
|
||||
length, rErr := io.ReadFull(reader, buf)
|
||||
if rErr == io.EOF {
|
||||
|
||||
70
vendor/github.com/minio/minio-go/v6/api-put-object-streaming.go
сгенерированный
поставляемый
70
vendor/github.com/minio/minio-go/v6/api-put-object-streaming.go
сгенерированный
поставляемый
@@ -18,14 +18,10 @@
|
||||
package minio
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"runtime/debug"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
@@ -44,11 +40,11 @@ import (
|
||||
func (c Client) putObjectMultipartStream(ctx context.Context, bucketName, objectName string,
|
||||
reader io.Reader, size int64, opts PutObjectOptions) (n int64, err error) {
|
||||
|
||||
if !isObject(reader) && isReadAt(reader) && !opts.SendContentMd5 {
|
||||
if !isObject(reader) && isReadAt(reader) {
|
||||
// Verify if the reader implements ReadAt and it is not a *minio.Object then we will use parallel uploader.
|
||||
n, err = c.putObjectMultipartStreamFromReadAt(ctx, bucketName, objectName, reader.(io.ReaderAt), size, opts)
|
||||
} else {
|
||||
n, err = c.putObjectMultipartStreamOptionalChecksum(ctx, bucketName, objectName, reader, size, opts)
|
||||
n, err = c.putObjectMultipartStreamNoChecksum(ctx, bucketName, objectName, reader, size, opts)
|
||||
}
|
||||
if err != nil {
|
||||
errResp := ToErrorResponse(err)
|
||||
@@ -60,7 +56,7 @@ func (c Client) putObjectMultipartStream(ctx context.Context, bucketName, object
|
||||
return 0, ErrEntityTooLarge(size, maxSinglePutObjectSize, bucketName, objectName)
|
||||
}
|
||||
// Fall back to uploading as single PutObject operation.
|
||||
return c.putObject(ctx, bucketName, objectName, reader, size, opts)
|
||||
return c.putObjectNoChecksum(ctx, bucketName, objectName, reader, size, opts)
|
||||
}
|
||||
}
|
||||
return n, err
|
||||
@@ -224,7 +220,7 @@ func (c Client) putObjectMultipartStreamFromReadAt(ctx context.Context, bucketNa
|
||||
return totalUploadedSize, nil
|
||||
}
|
||||
|
||||
func (c Client) putObjectMultipartStreamOptionalChecksum(ctx context.Context, bucketName, objectName string,
|
||||
func (c Client) putObjectMultipartStreamNoChecksum(ctx context.Context, bucketName, objectName string,
|
||||
reader io.Reader, size int64, opts PutObjectOptions) (n int64, err error) {
|
||||
// Input validation.
|
||||
if err = s3utils.CheckValidBucketName(bucketName); err != nil {
|
||||
@@ -261,47 +257,20 @@ func (c Client) putObjectMultipartStreamOptionalChecksum(ctx context.Context, bu
|
||||
// Initialize parts uploaded map.
|
||||
partsInfo := make(map[int]ObjectPart)
|
||||
|
||||
// Create a buffer.
|
||||
buf := make([]byte, partSize)
|
||||
defer debug.FreeOSMemory()
|
||||
|
||||
// Avoid declaring variables in the for loop
|
||||
var md5Base64 string
|
||||
var hookReader io.Reader
|
||||
|
||||
// Part number always starts with '1'.
|
||||
var partNumber int
|
||||
for partNumber = 1; partNumber <= totalPartsCount; partNumber++ {
|
||||
// Update progress reader appropriately to the latest offset
|
||||
// as we read from the source.
|
||||
hookReader := newHook(reader, opts.Progress)
|
||||
|
||||
// Proceed to upload the part.
|
||||
if partNumber == totalPartsCount {
|
||||
partSize = lastPartSize
|
||||
}
|
||||
|
||||
if opts.SendContentMd5 {
|
||||
length, rerr := io.ReadFull(reader, buf)
|
||||
if rerr == io.EOF && partNumber > 1 {
|
||||
break
|
||||
}
|
||||
if rerr != nil && rerr != io.ErrUnexpectedEOF && rerr != io.EOF {
|
||||
return 0, rerr
|
||||
}
|
||||
// Calculate md5sum.
|
||||
hash := md5.New()
|
||||
hash.Write(buf[:length])
|
||||
md5Base64 = base64.StdEncoding.EncodeToString(hash.Sum(nil))
|
||||
// Update progress reader appropriately to the latest offset
|
||||
// as we read from the source.
|
||||
hookReader = newHook(bytes.NewReader(buf[:length]), opts.Progress)
|
||||
} else {
|
||||
// Update progress reader appropriately to the latest offset
|
||||
// as we read from the source.
|
||||
hookReader = newHook(reader, opts.Progress)
|
||||
}
|
||||
|
||||
objPart, uerr := c.uploadPart(ctx, bucketName, objectName, uploadID,
|
||||
io.LimitReader(hookReader, partSize),
|
||||
partNumber, md5Base64, "", partSize, opts.ServerSideEncryption)
|
||||
partNumber, "", "", partSize, opts.ServerSideEncryption)
|
||||
if uerr != nil {
|
||||
return totalUploadedSize, uerr
|
||||
}
|
||||
@@ -347,9 +316,9 @@ func (c Client) putObjectMultipartStreamOptionalChecksum(ctx context.Context, bu
|
||||
return totalUploadedSize, nil
|
||||
}
|
||||
|
||||
// putObject special function used Google Cloud Storage. This special function
|
||||
// putObjectNoChecksum special function used Google Cloud Storage. This special function
|
||||
// is used for Google Cloud Storage since Google's multipart API is not S3 compatible.
|
||||
func (c Client) putObject(ctx context.Context, bucketName, objectName string, reader io.Reader, size int64, opts PutObjectOptions) (n int64, err error) {
|
||||
func (c Client) putObjectNoChecksum(ctx context.Context, bucketName, objectName string, reader io.Reader, size int64, opts PutObjectOptions) (n int64, err error) {
|
||||
// Input validation.
|
||||
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
|
||||
return 0, err
|
||||
@@ -374,30 +343,13 @@ func (c Client) putObject(ctx context.Context, bucketName, objectName string, re
|
||||
}
|
||||
}
|
||||
|
||||
var md5Base64 string
|
||||
if opts.SendContentMd5 {
|
||||
// Create a buffer.
|
||||
buf := make([]byte, size)
|
||||
defer debug.FreeOSMemory()
|
||||
|
||||
length, rErr := io.ReadFull(reader, buf)
|
||||
if rErr != nil && rErr != io.ErrUnexpectedEOF {
|
||||
return 0, rErr
|
||||
}
|
||||
|
||||
// Calculate md5sum.
|
||||
hash := md5.New()
|
||||
hash.Write(buf[:length])
|
||||
md5Base64 = base64.StdEncoding.EncodeToString(hash.Sum(nil))
|
||||
}
|
||||
|
||||
// Update progress reader appropriately to the latest offset as we
|
||||
// read from the source.
|
||||
readSeeker := newHook(reader, opts.Progress)
|
||||
|
||||
// This function does not calculate sha256 and md5sum for payload.
|
||||
// Execute put object.
|
||||
st, err := c.putObjectDo(ctx, bucketName, objectName, readSeeker, md5Base64, "", size, opts)
|
||||
st, err := c.putObjectDo(ctx, bucketName, objectName, readSeeker, "", "", size, opts)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
75
vendor/github.com/minio/minio-go/v6/api-put-object.go
сгенерированный
поставляемый
75
vendor/github.com/minio/minio-go/v6/api-put-object.go
сгенерированный
поставляемый
@@ -20,9 +20,6 @@ package minio
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -52,9 +49,6 @@ type PutObjectOptions struct {
|
||||
StorageClass string
|
||||
WebsiteRedirectLocation string
|
||||
PartSize uint64
|
||||
LegalHold LegalHoldStatus
|
||||
SendContentMd5 bool
|
||||
DisableMultipart bool
|
||||
}
|
||||
|
||||
// getNumThreads - gets the number of threads to be used in the multipart
|
||||
@@ -73,58 +67,48 @@ func (opts PutObjectOptions) getNumThreads() (numThreads int) {
|
||||
func (opts PutObjectOptions) Header() (header http.Header) {
|
||||
header = make(http.Header)
|
||||
|
||||
contentType := opts.ContentType
|
||||
if contentType == "" {
|
||||
contentType = "application/octet-stream"
|
||||
if opts.ContentType != "" {
|
||||
header["Content-Type"] = []string{opts.ContentType}
|
||||
} else {
|
||||
header["Content-Type"] = []string{"application/octet-stream"}
|
||||
}
|
||||
header.Set("Content-Type", contentType)
|
||||
|
||||
if opts.ContentEncoding != "" {
|
||||
header.Set("Content-Encoding", opts.ContentEncoding)
|
||||
header["Content-Encoding"] = []string{opts.ContentEncoding}
|
||||
}
|
||||
if opts.ContentDisposition != "" {
|
||||
header.Set("Content-Disposition", opts.ContentDisposition)
|
||||
header["Content-Disposition"] = []string{opts.ContentDisposition}
|
||||
}
|
||||
if opts.ContentLanguage != "" {
|
||||
header.Set("Content-Language", opts.ContentLanguage)
|
||||
header["Content-Language"] = []string{opts.ContentLanguage}
|
||||
}
|
||||
if opts.CacheControl != "" {
|
||||
header.Set("Cache-Control", opts.CacheControl)
|
||||
header["Cache-Control"] = []string{opts.CacheControl}
|
||||
}
|
||||
|
||||
if opts.Mode != nil {
|
||||
header.Set(amzLockMode, opts.Mode.String())
|
||||
header["x-amz-object-lock-mode"] = []string{opts.Mode.String()}
|
||||
}
|
||||
|
||||
if opts.RetainUntilDate != nil {
|
||||
header.Set("X-Amz-Object-Lock-Retain-Until-Date", opts.RetainUntilDate.Format(time.RFC3339))
|
||||
}
|
||||
|
||||
if opts.LegalHold != "" {
|
||||
header.Set(amzLegalHoldHeader, opts.LegalHold.String())
|
||||
header["x-amz-object-lock-retain-until-date"] = []string{opts.RetainUntilDate.Format(time.RFC3339)}
|
||||
}
|
||||
|
||||
if opts.ServerSideEncryption != nil {
|
||||
opts.ServerSideEncryption.Marshal(header)
|
||||
}
|
||||
|
||||
if opts.StorageClass != "" {
|
||||
header.Set(amzStorageClass, opts.StorageClass)
|
||||
header[amzStorageClass] = []string{opts.StorageClass}
|
||||
}
|
||||
|
||||
if opts.WebsiteRedirectLocation != "" {
|
||||
header.Set(amzWebsiteRedirectLocation, opts.WebsiteRedirectLocation)
|
||||
header[amzWebsiteRedirectLocation] = []string{opts.WebsiteRedirectLocation}
|
||||
}
|
||||
|
||||
if len(opts.UserTags) != 0 {
|
||||
header.Set(amzTaggingHeader, s3utils.TagEncode(opts.UserTags))
|
||||
header[amzTaggingHeader] = []string{s3utils.TagEncode(opts.UserTags)}
|
||||
}
|
||||
|
||||
for k, v := range opts.UserMetadata {
|
||||
if !isAmzHeader(k) && !isStandardHeader(k) && !isStorageClassHeader(k) {
|
||||
header.Set("X-Amz-Meta-"+k, v)
|
||||
header["X-Amz-Meta-"+k] = []string{v}
|
||||
} else {
|
||||
header.Set(k, v)
|
||||
header[k] = []string{v}
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -145,9 +129,6 @@ func (opts PutObjectOptions) validate() (err error) {
|
||||
return ErrInvalidArgument(opts.Mode.String() + " unsupported retention mode")
|
||||
}
|
||||
}
|
||||
if opts.LegalHold != "" && !opts.LegalHold.IsValid() {
|
||||
return ErrInvalidArgument(opts.LegalHold.String() + " unsupported legal-hold status")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -172,10 +153,6 @@ func (a completedParts) Less(i, j int) bool { return a[i].PartNumber < a[j].Part
|
||||
// be uploaded through this operation will be 5TiB.
|
||||
func (c Client) PutObject(bucketName, objectName string, reader io.Reader, objectSize int64,
|
||||
opts PutObjectOptions) (n int64, err error) {
|
||||
if objectSize < 0 && opts.DisableMultipart {
|
||||
return 0, errors.New("object size must be provided with disable multipart upload")
|
||||
}
|
||||
|
||||
return c.PutObjectWithContext(context.Background(), bucketName, objectName, reader, objectSize, opts)
|
||||
}
|
||||
|
||||
@@ -187,7 +164,8 @@ func (c Client) putObjectCommon(ctx context.Context, bucketName, objectName stri
|
||||
|
||||
// NOTE: Streaming signature is not supported by GCS.
|
||||
if s3utils.IsGoogleEndpoint(*c.endpointURL) {
|
||||
return c.putObject(ctx, bucketName, objectName, reader, size, opts)
|
||||
// Do not compute MD5 for Google Cloud Storage.
|
||||
return c.putObjectNoChecksum(ctx, bucketName, objectName, reader, size, opts)
|
||||
}
|
||||
|
||||
partSize := opts.PartSize
|
||||
@@ -196,8 +174,8 @@ func (c Client) putObjectCommon(ctx context.Context, bucketName, objectName stri
|
||||
}
|
||||
|
||||
if c.overrideSignerType.IsV2() {
|
||||
if size >= 0 && size < int64(partSize) || opts.DisableMultipart {
|
||||
return c.putObject(ctx, bucketName, objectName, reader, size, opts)
|
||||
if size >= 0 && size < int64(partSize) {
|
||||
return c.putObjectNoChecksum(ctx, bucketName, objectName, reader, size, opts)
|
||||
}
|
||||
return c.putObjectMultipart(ctx, bucketName, objectName, reader, size, opts)
|
||||
}
|
||||
@@ -205,10 +183,11 @@ func (c Client) putObjectCommon(ctx context.Context, bucketName, objectName stri
|
||||
return c.putObjectMultipartStreamNoLength(ctx, bucketName, objectName, reader, opts)
|
||||
}
|
||||
|
||||
if size < int64(partSize) || opts.DisableMultipart {
|
||||
return c.putObject(ctx, bucketName, objectName, reader, size, opts)
|
||||
if size < int64(partSize) {
|
||||
return c.putObjectNoChecksum(ctx, bucketName, objectName, reader, size, opts)
|
||||
}
|
||||
|
||||
// For all sizes greater than 128MiB do multipart.
|
||||
return c.putObjectMultipartStream(ctx, bucketName, objectName, reader, size, opts)
|
||||
}
|
||||
|
||||
@@ -264,21 +243,13 @@ func (c Client) putObjectMultipartStreamNoLength(ctx context.Context, bucketName
|
||||
return 0, rerr
|
||||
}
|
||||
|
||||
var md5Base64 string
|
||||
if opts.SendContentMd5 {
|
||||
// Calculate md5sum.
|
||||
hash := md5.New()
|
||||
hash.Write(buf[:length])
|
||||
md5Base64 = base64.StdEncoding.EncodeToString(hash.Sum(nil))
|
||||
}
|
||||
|
||||
// Update progress reader appropriately to the latest offset
|
||||
// as we read from the source.
|
||||
rd := newHook(bytes.NewReader(buf[:length]), opts.Progress)
|
||||
|
||||
// Proceed to upload the part.
|
||||
objPart, uerr := c.uploadPart(ctx, bucketName, objectName, uploadID, rd, partNumber,
|
||||
md5Base64, "", int64(length), opts.ServerSideEncryption)
|
||||
"", "", int64(length), opts.ServerSideEncryption)
|
||||
if uerr != nil {
|
||||
return totalUploadedSize, uerr
|
||||
}
|
||||
|
||||
164
vendor/github.com/minio/minio-go/v6/api-remove.go
сгенерированный
поставляемый
164
vendor/github.com/minio/minio-go/v6/api-remove.go
сгенерированный
поставляемый
@@ -63,7 +63,7 @@ func (c Client) RemoveObject(bucketName, objectName string) error {
|
||||
return c.RemoveObjectWithOptions(bucketName, objectName, RemoveObjectOptions{})
|
||||
}
|
||||
|
||||
// RemoveObjectOptions represents options specified by user for RemoveObject call
|
||||
// RemoveObjectOptions represents options specified by user for PutObject call
|
||||
type RemoveObjectOptions struct {
|
||||
GovernanceBypass bool
|
||||
VersionID string
|
||||
@@ -92,7 +92,7 @@ func (c Client) RemoveObjectWithOptions(bucketName, objectName string, opts Remo
|
||||
|
||||
if opts.GovernanceBypass {
|
||||
// Set the bypass goverenance retention header
|
||||
headers.Set(amzBypassGovernance, "true")
|
||||
headers.Set("x-amz-bypass-governance-retention", "True")
|
||||
}
|
||||
// Execute DELETE on objectName.
|
||||
resp, err := c.executeMethod(context.Background(), "DELETE", requestMetadata{
|
||||
@@ -179,107 +179,71 @@ func (c Client) RemoveObjectsWithContext(ctx context.Context, bucketName string,
|
||||
return errorCh
|
||||
}
|
||||
|
||||
go c.removeObjects(ctx, bucketName, objectsCh, errorCh, RemoveObjectsOptions{})
|
||||
return errorCh
|
||||
}
|
||||
// Generate and call MultiDelete S3 requests based on entries received from objectsCh
|
||||
go func(errorCh chan<- RemoveObjectError) {
|
||||
maxEntries := 1000
|
||||
finish := false
|
||||
urlValues := make(url.Values)
|
||||
urlValues.Set("delete", "")
|
||||
|
||||
// RemoveObjectsWithOptionsContext - Identical to RemoveObjects call, but accepts context to
|
||||
// facilitate request cancellation and options to bypass governance retention
|
||||
func (c Client) RemoveObjectsWithOptionsContext(ctx context.Context, bucketName string, objectsCh <-chan string, opts RemoveObjectsOptions) <-chan RemoveObjectError {
|
||||
errorCh := make(chan RemoveObjectError, 1)
|
||||
|
||||
// Validate if bucket name is valid.
|
||||
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
|
||||
// Close error channel when Multi delete finishes.
|
||||
defer close(errorCh)
|
||||
errorCh <- RemoveObjectError{
|
||||
Err: err,
|
||||
}
|
||||
return errorCh
|
||||
}
|
||||
// Validate objects channel to be properly allocated.
|
||||
if objectsCh == nil {
|
||||
defer close(errorCh)
|
||||
errorCh <- RemoveObjectError{
|
||||
Err: ErrInvalidArgument("Objects channel cannot be nil"),
|
||||
}
|
||||
return errorCh
|
||||
}
|
||||
|
||||
go c.removeObjects(ctx, bucketName, objectsCh, errorCh, opts)
|
||||
return errorCh
|
||||
}
|
||||
|
||||
// Generate and call MultiDelete S3 requests based on entries received from objectsCh
|
||||
func (c Client) removeObjects(ctx context.Context, bucketName string, objectsCh <-chan string, errorCh chan<- RemoveObjectError, opts RemoveObjectsOptions) {
|
||||
maxEntries := 1000
|
||||
finish := false
|
||||
urlValues := make(url.Values)
|
||||
urlValues.Set("delete", "")
|
||||
|
||||
// Close error channel when Multi delete finishes.
|
||||
defer close(errorCh)
|
||||
|
||||
// Loop over entries by 1000 and call MultiDelete requests
|
||||
for {
|
||||
if finish {
|
||||
break
|
||||
}
|
||||
count := 0
|
||||
var batch []string
|
||||
|
||||
// Try to gather 1000 entries
|
||||
for object := range objectsCh {
|
||||
batch = append(batch, object)
|
||||
if count++; count >= maxEntries {
|
||||
// Loop over entries by 1000 and call MultiDelete requests
|
||||
for {
|
||||
if finish {
|
||||
break
|
||||
}
|
||||
}
|
||||
if count == 0 {
|
||||
// Multi Objects Delete API doesn't accept empty object list, quit immediately
|
||||
break
|
||||
}
|
||||
if count < maxEntries {
|
||||
// We didn't have 1000 entries, so this is the last batch
|
||||
finish = true
|
||||
}
|
||||
count := 0
|
||||
var batch []string
|
||||
|
||||
// Build headers.
|
||||
headers := make(http.Header)
|
||||
if opts.GovernanceBypass {
|
||||
// Set the bypass goverenance retention header
|
||||
headers.Set(amzBypassGovernance, "true")
|
||||
}
|
||||
|
||||
// Generate remove multi objects XML request
|
||||
removeBytes := generateRemoveMultiObjectsRequest(batch)
|
||||
// Execute GET on bucket to list objects.
|
||||
resp, err := c.executeMethod(ctx, http.MethodPost, requestMetadata{
|
||||
bucketName: bucketName,
|
||||
queryValues: urlValues,
|
||||
contentBody: bytes.NewReader(removeBytes),
|
||||
contentLength: int64(len(removeBytes)),
|
||||
contentMD5Base64: sumMD5Base64(removeBytes),
|
||||
contentSHA256Hex: sum256Hex(removeBytes),
|
||||
customHeader: headers,
|
||||
})
|
||||
if resp != nil {
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
e := httpRespToErrorResponse(resp, bucketName, "")
|
||||
errorCh <- RemoveObjectError{ObjectName: "", Err: e}
|
||||
// Try to gather 1000 entries
|
||||
for object := range objectsCh {
|
||||
batch = append(batch, object)
|
||||
if count++; count >= maxEntries {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
for _, b := range batch {
|
||||
errorCh <- RemoveObjectError{ObjectName: b, Err: err}
|
||||
if count == 0 {
|
||||
// Multi Objects Delete API doesn't accept empty object list, quit immediately
|
||||
break
|
||||
}
|
||||
continue
|
||||
if count < maxEntries {
|
||||
// We didn't have 1000 entries, so this is the last batch
|
||||
finish = true
|
||||
}
|
||||
|
||||
// Generate remove multi objects XML request
|
||||
removeBytes := generateRemoveMultiObjectsRequest(batch)
|
||||
// Execute GET on bucket to list objects.
|
||||
resp, err := c.executeMethod(ctx, "POST", requestMetadata{
|
||||
bucketName: bucketName,
|
||||
queryValues: urlValues,
|
||||
contentBody: bytes.NewReader(removeBytes),
|
||||
contentLength: int64(len(removeBytes)),
|
||||
contentMD5Base64: sumMD5Base64(removeBytes),
|
||||
contentSHA256Hex: sum256Hex(removeBytes),
|
||||
})
|
||||
if resp != nil {
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
e := httpRespToErrorResponse(resp, bucketName, "")
|
||||
errorCh <- RemoveObjectError{ObjectName: "", Err: e}
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
for _, b := range batch {
|
||||
errorCh <- RemoveObjectError{ObjectName: b, Err: err}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Process multiobjects remove xml response
|
||||
processRemoveMultiObjectsResponse(resp.Body, batch, errorCh)
|
||||
|
||||
closeResponse(resp)
|
||||
}
|
||||
|
||||
// Process multiobjects remove xml response
|
||||
processRemoveMultiObjectsResponse(resp.Body, batch, errorCh)
|
||||
|
||||
closeResponse(resp)
|
||||
}
|
||||
}(errorCh)
|
||||
return errorCh
|
||||
}
|
||||
|
||||
// RemoveObjects removes multiple objects from a bucket.
|
||||
@@ -289,18 +253,6 @@ func (c Client) RemoveObjects(bucketName string, objectsCh <-chan string) <-chan
|
||||
return c.RemoveObjectsWithContext(context.Background(), bucketName, objectsCh)
|
||||
}
|
||||
|
||||
// RemoveObjectsOptions represents options specified by user for RemoveObjects call
|
||||
type RemoveObjectsOptions struct {
|
||||
GovernanceBypass bool
|
||||
}
|
||||
|
||||
// RemoveObjectsWithOptions removes multiple objects from a bucket.
|
||||
// The list of objects to remove are received from objectsCh.
|
||||
// Remove failures are sent back via error channel.
|
||||
func (c Client) RemoveObjectsWithOptions(bucketName string, objectsCh <-chan string, opts RemoveObjectsOptions) <-chan RemoveObjectError {
|
||||
return c.RemoveObjectsWithOptionsContext(context.Background(), bucketName, objectsCh, opts)
|
||||
}
|
||||
|
||||
// RemoveIncompleteUpload aborts an partially uploaded object.
|
||||
func (c Client) RemoveIncompleteUpload(bucketName, objectName string) error {
|
||||
// Input validation.
|
||||
|
||||
109
vendor/github.com/minio/minio-go/v6/api-stat.go
сгенерированный
поставляемый
109
vendor/github.com/minio/minio-go/v6/api-stat.go
сгенерированный
поставляемый
@@ -20,6 +20,9 @@ package minio
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio-go/v6/pkg/s3utils"
|
||||
)
|
||||
@@ -61,6 +64,39 @@ func (c Client) BucketExistsWithContext(ctx context.Context, bucketName string)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// List of header keys to be filtered, usually
|
||||
// from all S3 API http responses.
|
||||
var defaultFilterKeys = []string{
|
||||
"Connection",
|
||||
"Transfer-Encoding",
|
||||
"Accept-Ranges",
|
||||
"Date",
|
||||
"Server",
|
||||
"Vary",
|
||||
"x-amz-bucket-region",
|
||||
"x-amz-request-id",
|
||||
"x-amz-id-2",
|
||||
"Content-Security-Policy",
|
||||
"X-Xss-Protection",
|
||||
amzTaggingHeaderCount,
|
||||
// Add new headers to be ignored.
|
||||
}
|
||||
|
||||
// Extract only necessary metadata header key/values by
|
||||
// filtering them out with a list of custom header keys.
|
||||
func extractObjMetadata(header http.Header) http.Header {
|
||||
filterKeys := append([]string{
|
||||
"ETag",
|
||||
"Content-Length",
|
||||
"Last-Modified",
|
||||
"Content-Type",
|
||||
"Expires",
|
||||
"X-Cache",
|
||||
"X-Cache-Lookup",
|
||||
}, defaultFilterKeys...)
|
||||
return filterHeader(header, filterKeys)
|
||||
}
|
||||
|
||||
// StatObject verifies if object exists and you have permission to access.
|
||||
func (c Client) StatObject(bucketName, objectName string, opts StatObjectOptions) (ObjectInfo, error) {
|
||||
return c.StatObjectWithContext(context.Background(), bucketName, objectName, opts)
|
||||
@@ -106,5 +142,76 @@ func (c Client) statObject(ctx context.Context, bucketName, objectName string, o
|
||||
}
|
||||
}
|
||||
|
||||
return ToObjectInfo(bucketName, objectName, resp.Header)
|
||||
// Trim off the odd double quotes from ETag in the beginning and end.
|
||||
md5sum := trimEtag(resp.Header.Get("ETag"))
|
||||
|
||||
// Parse content length is exists
|
||||
var size int64 = -1
|
||||
contentLengthStr := resp.Header.Get("Content-Length")
|
||||
if contentLengthStr != "" {
|
||||
size, err = strconv.ParseInt(contentLengthStr, 10, 64)
|
||||
if err != nil {
|
||||
// Content-Length is not valid
|
||||
return ObjectInfo{}, ErrorResponse{
|
||||
Code: "InternalError",
|
||||
Message: "Content-Length is invalid. " + reportIssue,
|
||||
BucketName: bucketName,
|
||||
Key: objectName,
|
||||
RequestID: resp.Header.Get("x-amz-request-id"),
|
||||
HostID: resp.Header.Get("x-amz-id-2"),
|
||||
Region: resp.Header.Get("x-amz-bucket-region"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse Last-Modified has http time format.
|
||||
date, err := time.Parse(http.TimeFormat, resp.Header.Get("Last-Modified"))
|
||||
if err != nil {
|
||||
return ObjectInfo{}, ErrorResponse{
|
||||
Code: "InternalError",
|
||||
Message: "Last-Modified time format is invalid. " + reportIssue,
|
||||
BucketName: bucketName,
|
||||
Key: objectName,
|
||||
RequestID: resp.Header.Get("x-amz-request-id"),
|
||||
HostID: resp.Header.Get("x-amz-id-2"),
|
||||
Region: resp.Header.Get("x-amz-bucket-region"),
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch content type if any present.
|
||||
contentType := strings.TrimSpace(resp.Header.Get("Content-Type"))
|
||||
if contentType == "" {
|
||||
contentType = "application/octet-stream"
|
||||
}
|
||||
|
||||
expiryStr := resp.Header.Get("Expires")
|
||||
var expTime time.Time
|
||||
if t, err := time.Parse(http.TimeFormat, expiryStr); err == nil {
|
||||
expTime = t.UTC()
|
||||
}
|
||||
|
||||
metadata := extractObjMetadata(resp.Header)
|
||||
userMetadata := map[string]string{}
|
||||
const xamzmeta = "x-amz-meta-"
|
||||
const xamzmetaLen = len(xamzmeta)
|
||||
for k, v := range metadata {
|
||||
if strings.HasPrefix(strings.ToLower(k), xamzmeta) {
|
||||
userMetadata[k[xamzmetaLen:]] = v[0]
|
||||
}
|
||||
}
|
||||
|
||||
// Save object metadata info.
|
||||
return ObjectInfo{
|
||||
ETag: md5sum,
|
||||
Key: objectName,
|
||||
Size: size,
|
||||
LastModified: date,
|
||||
ContentType: contentType,
|
||||
Expires: expTime,
|
||||
// Extract only the relevant header keys describing the object.
|
||||
// following function filters out a list of standard set of keys
|
||||
// which are not part of object metadata.
|
||||
Metadata: metadata,
|
||||
UserMetadata: userMetadata,
|
||||
}, nil
|
||||
}
|
||||
|
||||
41
vendor/github.com/minio/minio-go/v6/api.go
сгенерированный
поставляемый
41
vendor/github.com/minio/minio-go/v6/api.go
сгенерированный
поставляемый
@@ -104,7 +104,7 @@ type Options struct {
|
||||
// Global constants.
|
||||
const (
|
||||
libraryName = "minio-go"
|
||||
libraryVersion = "v6.0.52"
|
||||
libraryVersion = "v6.0.45"
|
||||
)
|
||||
|
||||
// User Agent should always following the below style.
|
||||
@@ -413,7 +413,7 @@ func (c *Client) SetS3TransferAccelerate(accelerateEndpoint string) {
|
||||
// - For signature v4 request if the connection is insecure compute only sha256.
|
||||
// - For signature v4 request if the connection is secure compute only md5.
|
||||
// - For anonymous request compute md5.
|
||||
func (c *Client) hashMaterials(isMd5Requested bool) (hashAlgos map[string]hash.Hash, hashSums map[string][]byte) {
|
||||
func (c *Client) hashMaterials() (hashAlgos map[string]hash.Hash, hashSums map[string][]byte) {
|
||||
hashSums = make(map[string][]byte)
|
||||
hashAlgos = make(map[string]hash.Hash)
|
||||
if c.overrideSignerType.IsV4() {
|
||||
@@ -427,9 +427,6 @@ func (c *Client) hashMaterials(isMd5Requested bool) (hashAlgos map[string]hash.H
|
||||
hashAlgos["md5"] = md5.New()
|
||||
}
|
||||
}
|
||||
if isMd5Requested {
|
||||
hashAlgos["md5"] = md5.New()
|
||||
}
|
||||
return hashAlgos, hashSums
|
||||
}
|
||||
|
||||
@@ -591,16 +588,16 @@ func (c Client) executeMethod(ctx context.Context, method string, metadata reque
|
||||
}
|
||||
}
|
||||
|
||||
// Create cancel context to control 'newRetryTimer' go routine.
|
||||
retryCtx, cancel := context.WithCancel(ctx)
|
||||
// Create a done channel to control 'newRetryTimer' go routine.
|
||||
doneCh := make(chan struct{}, 1)
|
||||
|
||||
// Indicate to our routine to exit cleanly upon return.
|
||||
defer cancel()
|
||||
defer close(doneCh)
|
||||
|
||||
// Blank indentifier is kept here on purpose since 'range' without
|
||||
// blank identifiers is only supported since go1.4
|
||||
// https://golang.org/doc/go1.4#forrange.
|
||||
for range c.newRetryTimer(retryCtx, reqRetry, DefaultRetryUnit, DefaultRetryCap, MaxJitter) {
|
||||
for range c.newRetryTimer(reqRetry, DefaultRetryUnit, DefaultRetryCap, MaxJitter, doneCh) {
|
||||
// Retry executes the following function body if request has an
|
||||
// error until maxRetries have been exhausted, retry attempts are
|
||||
// performed after waiting for a given period of time in a
|
||||
@@ -630,9 +627,6 @@ func (c Client) executeMethod(ctx context.Context, method string, metadata reque
|
||||
// Initiate the request.
|
||||
res, err = c.do(req)
|
||||
if err != nil {
|
||||
if err == context.Canceled || err == context.DeadlineExceeded {
|
||||
return nil, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -675,23 +669,20 @@ func (c Client) executeMethod(ctx context.Context, method string, metadata reque
|
||||
case "InvalidRegion":
|
||||
fallthrough
|
||||
case "AccessDenied":
|
||||
if errResponse.Region == "" {
|
||||
// Region is empty we simply return the error.
|
||||
return res, err
|
||||
}
|
||||
// Region is not empty figure out a way to
|
||||
// handle this appropriately.
|
||||
if metadata.bucketName != "" {
|
||||
if metadata.bucketName != "" && errResponse.Region != "" {
|
||||
// Gather Cached location only if bucketName is present.
|
||||
if _, cachedOk := c.bucketLocCache.Get(metadata.bucketName); cachedOk {
|
||||
c.bucketLocCache.Set(metadata.bucketName, errResponse.Region)
|
||||
continue // Retry.
|
||||
}
|
||||
} else {
|
||||
// This is for ListBuckets() fallback.
|
||||
// Most probably for ListBuckets()
|
||||
if errResponse.Region != metadata.bucketLocation {
|
||||
// Retry if the error response has a different region
|
||||
// than the request we just made.
|
||||
// Retry if the error
|
||||
// response has a
|
||||
// different region
|
||||
// than the request we
|
||||
// just made.
|
||||
metadata.bucketLocation = errResponse.Region
|
||||
continue // Retry
|
||||
}
|
||||
@@ -712,12 +703,6 @@ func (c Client) executeMethod(ctx context.Context, method string, metadata reque
|
||||
// For all other cases break out of the retry loop.
|
||||
break
|
||||
}
|
||||
|
||||
// Return an error when retry is canceled or deadlined
|
||||
if e := retryCtx.Err(); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
|
||||
16
vendor/github.com/minio/minio-go/v6/bucket-cache.go
сгенерированный
поставляемый
16
vendor/github.com/minio/minio-go/v6/bucket-cache.go
сгенерированный
поставляемый
@@ -183,21 +183,11 @@ func (c Client) getBucketLocationRequest(bucketName string) (*http.Request, erro
|
||||
}
|
||||
}
|
||||
|
||||
isVirtualHost := s3utils.IsVirtualHostSupported(targetURL, bucketName)
|
||||
|
||||
var urlStr string
|
||||
|
||||
//only suport Aliyun OSS for virtual hosted path, compatible Amazon & Google Endpoint
|
||||
if isVirtualHost && s3utils.IsAliyunOSSEndpoint(targetURL) {
|
||||
urlStr = c.endpointURL.Scheme + "://" + bucketName + "." + targetURL.Host + "/?location"
|
||||
} else {
|
||||
targetURL.Path = path.Join(bucketName, "") + "/"
|
||||
targetURL.RawQuery = urlValues.Encode()
|
||||
urlStr = targetURL.String()
|
||||
}
|
||||
targetURL.Path = path.Join(bucketName, "") + "/"
|
||||
targetURL.RawQuery = urlValues.Encode()
|
||||
|
||||
// Get a new HTTP request for the method.
|
||||
req, err := http.NewRequest("GET", urlStr, nil)
|
||||
req, err := http.NewRequest("GET", targetURL.String(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
2
vendor/github.com/minio/minio-go/v6/bucket-notification.go
сгенерированный
поставляемый
2
vendor/github.com/minio/minio-go/v6/bucket-notification.go
сгенерированный
поставляемый
@@ -81,7 +81,7 @@ func NewArn(partition, service, region, accountID, resource string) Arn {
|
||||
Resource: resource}
|
||||
}
|
||||
|
||||
// String returns the string format of the ARN
|
||||
// Return the string format of the ARN
|
||||
func (arn Arn) String() string {
|
||||
return "arn:" + arn.Partition + ":" + arn.Service + ":" + arn.Region + ":" + arn.AccountID + ":" + arn.Resource
|
||||
}
|
||||
|
||||
25
vendor/github.com/minio/minio-go/v6/constants.go
сгенерированный
поставляемый
25
vendor/github.com/minio/minio-go/v6/constants.go
сгенерированный
поставляемый
@@ -55,22 +55,13 @@ const (
|
||||
iso8601DateFormat = "20060102T150405Z"
|
||||
)
|
||||
|
||||
const (
|
||||
// Storage class header.
|
||||
amzStorageClass = "X-Amz-Storage-Class"
|
||||
// Storage class header constant.
|
||||
const amzStorageClass = "X-Amz-Storage-Class"
|
||||
|
||||
// Website redirect location header
|
||||
amzWebsiteRedirectLocation = "X-Amz-Website-Redirect-Location"
|
||||
// Website redirect location header constant
|
||||
const amzWebsiteRedirectLocation = "X-Amz-Website-Redirect-Location"
|
||||
|
||||
// Object Tagging headers
|
||||
amzTaggingHeader = "X-Amz-Tagging"
|
||||
amzTaggingHeaderDirective = "X-Amz-Tagging-Directive"
|
||||
|
||||
// Object legal hold header
|
||||
amzLegalHoldHeader = "X-Amz-Object-Lock-Legal-Hold"
|
||||
|
||||
// Object retention header
|
||||
amzLockMode = "X-Amz-Object-Lock-Mode"
|
||||
amzLockRetainUntil = "X-Amz-Object-Lock-Retain-Until-Date"
|
||||
amzBypassGovernance = "X-Amz-Bypass-Governance-Retention"
|
||||
)
|
||||
// Tagging header constants
|
||||
const amzTaggingHeader = "X-Amz-Tagging"
|
||||
const amzTaggingHeaderDirective = "X-Amz-Tagging-Directive"
|
||||
const amzTaggingHeaderCount = "X-Amz-Tagging-Count"
|
||||
|
||||
2
vendor/github.com/minio/minio-go/v6/go.mod
сгенерированный
поставляемый
2
vendor/github.com/minio/minio-go/v6/go.mod
сгенерированный
поставляемый
@@ -6,7 +6,7 @@ require (
|
||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||
github.com/minio/sha256-simd v0.1.1
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/sirupsen/logrus v1.5.0 // indirect
|
||||
github.com/sirupsen/logrus v1.4.2 // indirect
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a // indirect
|
||||
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092
|
||||
|
||||
8
vendor/github.com/minio/minio-go/v6/go.sum
сгенерированный
поставляемый
8
vendor/github.com/minio/minio-go/v6/go.sum
сгенерированный
поставляемый
@@ -1,3 +1,4 @@
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
@@ -10,13 +11,16 @@ github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKU
|
||||
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q=
|
||||
github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo=
|
||||
|
||||
26
vendor/github.com/minio/minio-go/v6/pkg/credentials/file_aws_credentials.go
сгенерированный
поставляемый
26
vendor/github.com/minio/minio-go/v6/pkg/credentials/file_aws_credentials.go
сгенерированный
поставляемый
@@ -36,12 +36,12 @@ type FileAWSCredentials struct {
|
||||
// env value is empty will default to current user's home directory.
|
||||
// Linux/OSX: "$HOME/.aws/credentials"
|
||||
// Windows: "%USERPROFILE%\.aws\credentials"
|
||||
Filename string
|
||||
filename string
|
||||
|
||||
// AWS Profile to extract credentials from the shared credentials file. If empty
|
||||
// will default to environment variable "AWS_PROFILE" or "default" if
|
||||
// environment variable is also not set.
|
||||
Profile string
|
||||
profile string
|
||||
|
||||
// retrieved states if the credentials have been successfully retrieved.
|
||||
retrieved bool
|
||||
@@ -51,34 +51,34 @@ type FileAWSCredentials struct {
|
||||
// wrapping the Profile file provider.
|
||||
func NewFileAWSCredentials(filename string, profile string) *Credentials {
|
||||
return New(&FileAWSCredentials{
|
||||
Filename: filename,
|
||||
Profile: profile,
|
||||
filename: filename,
|
||||
profile: profile,
|
||||
})
|
||||
}
|
||||
|
||||
// Retrieve reads and extracts the shared credentials from the current
|
||||
// users home directory.
|
||||
func (p *FileAWSCredentials) Retrieve() (Value, error) {
|
||||
if p.Filename == "" {
|
||||
p.Filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE")
|
||||
if p.Filename == "" {
|
||||
if p.filename == "" {
|
||||
p.filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE")
|
||||
if p.filename == "" {
|
||||
homeDir, err := homedir.Dir()
|
||||
if err != nil {
|
||||
return Value{}, err
|
||||
}
|
||||
p.Filename = filepath.Join(homeDir, ".aws", "credentials")
|
||||
p.filename = filepath.Join(homeDir, ".aws", "credentials")
|
||||
}
|
||||
}
|
||||
if p.Profile == "" {
|
||||
p.Profile = os.Getenv("AWS_PROFILE")
|
||||
if p.Profile == "" {
|
||||
p.Profile = "default"
|
||||
if p.profile == "" {
|
||||
p.profile = os.Getenv("AWS_PROFILE")
|
||||
if p.profile == "" {
|
||||
p.profile = "default"
|
||||
}
|
||||
}
|
||||
|
||||
p.retrieved = false
|
||||
|
||||
iniProfile, err := loadProfile(p.Filename, p.Profile)
|
||||
iniProfile, err := loadProfile(p.filename, p.profile)
|
||||
if err != nil {
|
||||
return Value{}, err
|
||||
}
|
||||
|
||||
26
vendor/github.com/minio/minio-go/v6/pkg/credentials/file_minio_client.go
сгенерированный
поставляемый
26
vendor/github.com/minio/minio-go/v6/pkg/credentials/file_minio_client.go
сгенерированный
поставляемый
@@ -38,12 +38,12 @@ type FileMinioClient struct {
|
||||
// env value is empty will default to current user's home directory.
|
||||
// Linux/OSX: "$HOME/.mc/config.json"
|
||||
// Windows: "%USERALIAS%\mc\config.json"
|
||||
Filename string
|
||||
filename string
|
||||
|
||||
// MinIO Alias to extract credentials from the shared credentials file. If empty
|
||||
// will default to environment variable "MINIO_ALIAS" or "default" if
|
||||
// environment variable is also not set.
|
||||
Alias string
|
||||
alias string
|
||||
|
||||
// retrieved states if the credentials have been successfully retrieved.
|
||||
retrieved bool
|
||||
@@ -53,39 +53,39 @@ type FileMinioClient struct {
|
||||
// wrapping the Alias file provider.
|
||||
func NewFileMinioClient(filename string, alias string) *Credentials {
|
||||
return New(&FileMinioClient{
|
||||
Filename: filename,
|
||||
Alias: alias,
|
||||
filename: filename,
|
||||
alias: alias,
|
||||
})
|
||||
}
|
||||
|
||||
// Retrieve reads and extracts the shared credentials from the current
|
||||
// users home directory.
|
||||
func (p *FileMinioClient) Retrieve() (Value, error) {
|
||||
if p.Filename == "" {
|
||||
if p.filename == "" {
|
||||
if value, ok := os.LookupEnv("MINIO_SHARED_CREDENTIALS_FILE"); ok {
|
||||
p.Filename = value
|
||||
p.filename = value
|
||||
} else {
|
||||
homeDir, err := homedir.Dir()
|
||||
if err != nil {
|
||||
return Value{}, err
|
||||
}
|
||||
p.Filename = filepath.Join(homeDir, ".mc", "config.json")
|
||||
p.filename = filepath.Join(homeDir, ".mc", "config.json")
|
||||
if runtime.GOOS == "windows" {
|
||||
p.Filename = filepath.Join(homeDir, "mc", "config.json")
|
||||
p.filename = filepath.Join(homeDir, "mc", "config.json")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if p.Alias == "" {
|
||||
p.Alias = os.Getenv("MINIO_ALIAS")
|
||||
if p.Alias == "" {
|
||||
p.Alias = "s3"
|
||||
if p.alias == "" {
|
||||
p.alias = os.Getenv("MINIO_ALIAS")
|
||||
if p.alias == "" {
|
||||
p.alias = "s3"
|
||||
}
|
||||
}
|
||||
|
||||
p.retrieved = false
|
||||
|
||||
hostCfg, err := loadAlias(p.Filename, p.Alias)
|
||||
hostCfg, err := loadAlias(p.filename, p.alias)
|
||||
if err != nil {
|
||||
return Value{}, err
|
||||
}
|
||||
|
||||
4
vendor/github.com/minio/minio-go/v6/pkg/credentials/iam_aws.go
сгенерированный
поставляемый
4
vendor/github.com/minio/minio-go/v6/pkg/credentials/iam_aws.go
сгенерированный
поставляемый
@@ -168,10 +168,6 @@ type ec2RoleCredRespBody struct {
|
||||
// be sent to fetch the rolling access credentials.
|
||||
// http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
|
||||
func getIAMRoleURL(endpoint string) (*url.URL, error) {
|
||||
if endpoint == "" {
|
||||
endpoint = defaultIAMRoleEndpoint
|
||||
}
|
||||
|
||||
u, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
79
vendor/github.com/minio/minio-go/v6/pkg/s3utils/utils.go
сгенерированный
поставляемый
79
vendor/github.com/minio/minio-go/v6/pkg/s3utils/utils.go
сгенерированный
поставляемый
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* MinIO Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* Copyright 2015-2020 MinIO, Inc.
|
||||
* Copyright 2015-2017 MinIO, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -78,28 +78,22 @@ func IsVirtualHostSupported(endpointURL url.URL, bucketName string) bool {
|
||||
return false
|
||||
}
|
||||
// Return true for all other cases
|
||||
return IsAmazonEndpoint(endpointURL) || IsGoogleEndpoint(endpointURL) || IsAliyunOSSEndpoint(endpointURL)
|
||||
return IsAmazonEndpoint(endpointURL) || IsGoogleEndpoint(endpointURL)
|
||||
}
|
||||
|
||||
// Refer for region styles - https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region
|
||||
|
||||
// amazonS3HostHyphen - regular expression used to determine if an arg is s3 host in hyphenated style.
|
||||
var amazonS3HostHyphen = regexp.MustCompile(`^s3-(.*?).amazonaws.com$`)
|
||||
var amazonS3HostHyphen = regexp.MustCompile(`^s3-(.*?)\.amazonaws\.com$`)
|
||||
|
||||
// amazonS3HostDualStack - regular expression used to determine if an arg is s3 host dualstack.
|
||||
var amazonS3HostDualStack = regexp.MustCompile(`^s3.dualstack.(.*?).amazonaws.com$`)
|
||||
var amazonS3HostDualStack = regexp.MustCompile(`^s3\.dualstack\.(.*?)\.amazonaws\.com$`)
|
||||
|
||||
// amazonS3HostDot - regular expression used to determine if an arg is s3 host in . style.
|
||||
var amazonS3HostDot = regexp.MustCompile(`^s3.(.*?).amazonaws.com$`)
|
||||
var amazonS3HostDot = regexp.MustCompile(`^s3\.(.*?)\.amazonaws\.com$`)
|
||||
|
||||
// amazonS3ChinaHost - regular expression used to determine if the arg is s3 china host.
|
||||
var amazonS3ChinaHost = regexp.MustCompile(`^s3.(cn.*?).amazonaws.com.cn$`)
|
||||
|
||||
// Regular expression used to determine if the arg is elb host.
|
||||
var elbAmazonRegex = regexp.MustCompile(`elb(.*?).amazonaws.com$`)
|
||||
|
||||
// Regular expression used to determine if the arg is elb host in china.
|
||||
var elbAmazonCnRegex = regexp.MustCompile(`elb(.*?).amazonaws.com.cn$`)
|
||||
var amazonS3ChinaHost = regexp.MustCompile(`^s3\.(cn.*?)\.amazonaws\.com\.cn$`)
|
||||
|
||||
// GetRegionFromURL - returns a region from url host.
|
||||
func GetRegionFromURL(endpointURL url.URL) string {
|
||||
@@ -112,10 +106,6 @@ func GetRegionFromURL(endpointURL url.URL) string {
|
||||
if IsAmazonGovCloudEndpoint(endpointURL) {
|
||||
return "us-gov-west-1"
|
||||
}
|
||||
// if elb's are used we cannot calculate which region it may be, just return empty.
|
||||
if elbAmazonRegex.MatchString(endpointURL.Host) || elbAmazonCnRegex.MatchString(endpointURL.Host) {
|
||||
return ""
|
||||
}
|
||||
parts := amazonS3HostDualStack.FindStringSubmatch(endpointURL.Host)
|
||||
if len(parts) > 1 {
|
||||
return parts[1]
|
||||
@@ -135,11 +125,6 @@ func GetRegionFromURL(endpointURL url.URL) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// IsAliyunOSSEndpoint - Match if it is exactly Aliyun OSS endpoint.
|
||||
func IsAliyunOSSEndpoint(endpointURL url.URL) bool {
|
||||
return strings.HasSuffix(endpointURL.Host, "aliyuncs.com")
|
||||
}
|
||||
|
||||
// IsAmazonEndpoint - Match if it is exactly Amazon S3 endpoint.
|
||||
func IsAmazonEndpoint(endpointURL url.URL) bool {
|
||||
if endpointURL.Host == "s3-external-1.amazonaws.com" || endpointURL.Host == "s3.amazonaws.com" {
|
||||
@@ -234,39 +219,29 @@ func QueryEncode(v url.Values) string {
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// TagDecode - decodes canonical tag into map of key and value.
|
||||
func TagDecode(ctag string) map[string]string {
|
||||
if ctag == "" {
|
||||
return map[string]string{}
|
||||
}
|
||||
tags := strings.Split(ctag, "&")
|
||||
tagMap := make(map[string]string, len(tags))
|
||||
var err error
|
||||
for _, tag := range tags {
|
||||
kvs := strings.SplitN(tag, "=", 2)
|
||||
if len(kvs) == 0 {
|
||||
return map[string]string{}
|
||||
}
|
||||
if len(kvs) == 1 {
|
||||
return map[string]string{}
|
||||
}
|
||||
tagMap[kvs[0]], err = url.PathUnescape(kvs[1])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return tagMap
|
||||
}
|
||||
|
||||
// TagEncode - encodes tag values in their URL encoded form. In
|
||||
// addition to the percent encoding performed by urlEncodePath() used
|
||||
// here, it also percent encodes '/' (forward slash)
|
||||
func TagEncode(tags map[string]string) string {
|
||||
values := url.Values{}
|
||||
for k, v := range tags {
|
||||
values[k] = []string{v}
|
||||
if tags == nil {
|
||||
return ""
|
||||
}
|
||||
return QueryEncode(values)
|
||||
var buf bytes.Buffer
|
||||
keys := make([]string, 0, len(tags))
|
||||
for k := range tags {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
v := tags[k]
|
||||
prefix := percentEncodeSlash(EncodePath(k)) + "="
|
||||
if buf.Len() > 0 {
|
||||
buf.WriteByte('&')
|
||||
}
|
||||
buf.WriteString(prefix)
|
||||
buf.WriteString(percentEncodeSlash(EncodePath(v)))
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// if object matches reserved string, no need to encode them
|
||||
@@ -324,10 +299,10 @@ func checkBucketNameCommon(bucketName string, strict bool) (err error) {
|
||||
return errors.New("Bucket name cannot be empty")
|
||||
}
|
||||
if len(bucketName) < 3 {
|
||||
return errors.New("Bucket name cannot be shorter than 3 characters")
|
||||
return errors.New("Bucket name cannot be smaller than 3 characters")
|
||||
}
|
||||
if len(bucketName) > 63 {
|
||||
return errors.New("Bucket name cannot be longer than 63 characters")
|
||||
return errors.New("Bucket name cannot be greater than 63 characters")
|
||||
}
|
||||
if ipAddress.MatchString(bucketName) {
|
||||
return errors.New("Bucket name cannot be an ip address")
|
||||
@@ -363,7 +338,7 @@ func CheckValidBucketNameStrict(bucketName string) (err error) {
|
||||
// - http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html
|
||||
func CheckValidObjectNamePrefix(objectName string) error {
|
||||
if len(objectName) > 1024 {
|
||||
return errors.New("Object name cannot be longer than 1024 characters")
|
||||
return errors.New("Object name cannot be greater than 1024 characters")
|
||||
}
|
||||
if !utf8.ValidString(objectName) {
|
||||
return errors.New("Object name with non UTF-8 strings are not supported")
|
||||
|
||||
2
vendor/github.com/minio/minio-go/v6/post-policy.go
сгенерированный
поставляемый
2
vendor/github.com/minio/minio-go/v6/post-policy.go
сгенерированный
поставляемый
@@ -258,7 +258,7 @@ func (p *PostPolicy) addNewPolicy(policyCond policyCondition) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// String function for printing policy in json formatted string.
|
||||
// Stringer interface for printing policy in json formatted string.
|
||||
func (p PostPolicy) String() string {
|
||||
return string(p.marshalJSON())
|
||||
}
|
||||
|
||||
14
vendor/github.com/minio/minio-go/v6/retry.go
сгенерированный
поставляемый
14
vendor/github.com/minio/minio-go/v6/retry.go
сгенерированный
поставляемый
@@ -18,7 +18,6 @@
|
||||
package minio
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
@@ -42,7 +41,7 @@ const DefaultRetryCap = time.Second * 30
|
||||
|
||||
// newRetryTimer creates a timer with exponentially increasing
|
||||
// delays until the maximum retry attempts are reached.
|
||||
func (c Client) newRetryTimer(ctx context.Context, maxRetry int, unit time.Duration, cap time.Duration, jitter float64) <-chan int {
|
||||
func (c Client) newRetryTimer(maxRetry int, unit time.Duration, cap time.Duration, jitter float64, doneCh chan struct{}) <-chan int {
|
||||
attemptCh := make(chan int)
|
||||
|
||||
// computes the exponential backoff duration according to
|
||||
@@ -71,16 +70,13 @@ func (c Client) newRetryTimer(ctx context.Context, maxRetry int, unit time.Durat
|
||||
defer close(attemptCh)
|
||||
for i := 0; i < maxRetry; i++ {
|
||||
select {
|
||||
// Attempts start from 1.
|
||||
case attemptCh <- i + 1:
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
|
||||
select {
|
||||
case <-time.After(exponentialBackoffWait(i)):
|
||||
case <-ctx.Done():
|
||||
case <-doneCh:
|
||||
// Stop the routine.
|
||||
return
|
||||
}
|
||||
time.Sleep(exponentialBackoffWait(i))
|
||||
}
|
||||
}()
|
||||
return attemptCh
|
||||
|
||||
2
vendor/github.com/minio/minio-go/v6/s3-endpoints.go
сгенерированный
поставляемый
2
vendor/github.com/minio/minio-go/v6/s3-endpoints.go
сгенерированный
поставляемый
@@ -35,8 +35,6 @@ var awsS3EndpointMap = map[string]string{
|
||||
"ap-southeast-2": "s3.dualstack.ap-southeast-2.amazonaws.com",
|
||||
"ap-northeast-1": "s3.dualstack.ap-northeast-1.amazonaws.com",
|
||||
"ap-northeast-2": "s3.dualstack.ap-northeast-2.amazonaws.com",
|
||||
"ap-northeast-3": "s3.dualstack.ap-northeast-3.amazonaws.com",
|
||||
"me-south-1": "s3.dualstack.me-south-1.amazonaws.com",
|
||||
"sa-east-1": "s3.dualstack.sa-east-1.amazonaws.com",
|
||||
"us-gov-west-1": "s3.dualstack.us-gov-west-1.amazonaws.com",
|
||||
"us-gov-east-1": "s3.dualstack.us-gov-east-1.amazonaws.com",
|
||||
|
||||
3
vendor/github.com/minio/minio-go/v6/transport.go
сгенерированный
поставляемый
3
vendor/github.com/minio/minio-go/v6/transport.go
сгенерированный
поставляемый
@@ -38,8 +38,7 @@ var DefaultTransport = func(secure bool) (http.RoundTripper, error) {
|
||||
}).DialContext,
|
||||
MaxIdleConns: 1024,
|
||||
MaxIdleConnsPerHost: 1024,
|
||||
ResponseHeaderTimeout: 60 * time.Second,
|
||||
IdleConnTimeout: 60 * time.Second,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
// Set this value so that the underlying transport round-tripper
|
||||
|
||||
128
vendor/github.com/minio/minio-go/v6/utils.go
сгенерированный
поставляемый
128
vendor/github.com/minio/minio-go/v6/utils.go
сгенерированный
поставляемый
@@ -28,7 +28,6 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -160,120 +159,27 @@ func isValidExpiry(expires time.Duration) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Extract only necessary metadata header key/values by
|
||||
// filtering them out with a list of custom header keys.
|
||||
func extractObjMetadata(header http.Header) http.Header {
|
||||
preserveKeys := []string{
|
||||
"Content-Type",
|
||||
"Cache-Control",
|
||||
"Content-Encoding",
|
||||
"Content-Language",
|
||||
"Content-Disposition",
|
||||
"X-Amz-Storage-Class",
|
||||
"X-Amz-Object-Lock-Mode",
|
||||
"X-Amz-Object-Lock-Retain-Until-Date",
|
||||
"X-Amz-Object-Lock-Legal-Hold",
|
||||
"X-Amz-Website-Redirect-Location",
|
||||
"X-Amz-Server-Side-Encryption",
|
||||
"X-Amz-Meta-",
|
||||
// Add new headers to be preserved.
|
||||
// if you add new headers here, please extend
|
||||
// PutObjectOptions{} to preserve them
|
||||
// upon upload as well.
|
||||
// make a copy of http.Header
|
||||
func cloneHeader(h http.Header) http.Header {
|
||||
h2 := make(http.Header, len(h))
|
||||
for k, vv := range h {
|
||||
vv2 := make([]string, len(vv))
|
||||
copy(vv2, vv)
|
||||
h2[k] = vv2
|
||||
}
|
||||
filteredHeader := make(http.Header)
|
||||
for k, v := range header {
|
||||
var found bool
|
||||
for _, prefix := range preserveKeys {
|
||||
if !strings.HasPrefix(k, prefix) {
|
||||
continue
|
||||
}
|
||||
found = true
|
||||
break
|
||||
}
|
||||
if found {
|
||||
filteredHeader[k] = v
|
||||
}
|
||||
}
|
||||
return filteredHeader
|
||||
return h2
|
||||
}
|
||||
|
||||
// ToObjectInfo converts http header values into ObjectInfo type,
|
||||
// extracts metadata and fills in all the necessary fields in ObjectInfo.
|
||||
func ToObjectInfo(bucketName string, objectName string, h http.Header) (ObjectInfo, error) {
|
||||
var err error
|
||||
// Trim off the odd double quotes from ETag in the beginning and end.
|
||||
etag := trimEtag(h.Get("ETag"))
|
||||
|
||||
// Parse content length is exists
|
||||
var size int64 = -1
|
||||
contentLengthStr := h.Get("Content-Length")
|
||||
if contentLengthStr != "" {
|
||||
size, err = strconv.ParseInt(contentLengthStr, 10, 64)
|
||||
if err != nil {
|
||||
// Content-Length is not valid
|
||||
return ObjectInfo{}, ErrorResponse{
|
||||
Code: "InternalError",
|
||||
Message: "Content-Length is invalid. " + reportIssue,
|
||||
BucketName: bucketName,
|
||||
Key: objectName,
|
||||
RequestID: h.Get("x-amz-request-id"),
|
||||
HostID: h.Get("x-amz-id-2"),
|
||||
Region: h.Get("x-amz-bucket-region"),
|
||||
}
|
||||
}
|
||||
// Filter relevant response headers from
|
||||
// the HEAD, GET http response. The function takes
|
||||
// a list of headers which are filtered out and
|
||||
// returned as a new http header.
|
||||
func filterHeader(header http.Header, filterKeys []string) (filteredHeader http.Header) {
|
||||
filteredHeader = cloneHeader(header)
|
||||
for _, key := range filterKeys {
|
||||
filteredHeader.Del(key)
|
||||
}
|
||||
|
||||
// Parse Last-Modified has http time format.
|
||||
date, err := time.Parse(http.TimeFormat, h.Get("Last-Modified"))
|
||||
if err != nil {
|
||||
return ObjectInfo{}, ErrorResponse{
|
||||
Code: "InternalError",
|
||||
Message: "Last-Modified time format is invalid. " + reportIssue,
|
||||
BucketName: bucketName,
|
||||
Key: objectName,
|
||||
RequestID: h.Get("x-amz-request-id"),
|
||||
HostID: h.Get("x-amz-id-2"),
|
||||
Region: h.Get("x-amz-bucket-region"),
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch content type if any present.
|
||||
contentType := strings.TrimSpace(h.Get("Content-Type"))
|
||||
if contentType == "" {
|
||||
contentType = "application/octet-stream"
|
||||
}
|
||||
|
||||
expiryStr := h.Get("Expires")
|
||||
var expTime time.Time
|
||||
if t, err := time.Parse(http.TimeFormat, expiryStr); err == nil {
|
||||
expTime = t.UTC()
|
||||
}
|
||||
|
||||
metadata := extractObjMetadata(h)
|
||||
userMetadata := make(map[string]string)
|
||||
for k, v := range metadata {
|
||||
if strings.HasPrefix(k, "X-Amz-Meta-") {
|
||||
userMetadata[strings.TrimPrefix(k, "X-Amz-Meta-")] = v[0]
|
||||
}
|
||||
}
|
||||
userTags := s3utils.TagDecode(h.Get(amzTaggingHeader))
|
||||
|
||||
// Save object metadata info.
|
||||
return ObjectInfo{
|
||||
ETag: etag,
|
||||
Key: objectName,
|
||||
Size: size,
|
||||
LastModified: date,
|
||||
ContentType: contentType,
|
||||
Expires: expTime,
|
||||
// Extract only the relevant header keys describing the object.
|
||||
// following function filters out a list of standard set of keys
|
||||
// which are not part of object metadata.
|
||||
Metadata: metadata,
|
||||
UserMetadata: userMetadata,
|
||||
UserTags: userTags,
|
||||
}, nil
|
||||
return filteredHeader
|
||||
}
|
||||
|
||||
// regCred matches credential string in HTTP header
|
||||
|
||||
Ссылка в новой задаче
Block a user