Update dependencies, enable pruning for vendor/
So, `dep` got an nice new feature to remove tests and non-go files from `vendor/`, and this brings the size of the vendor directory from ~300MiB down to ~20MiB. We don that now.
This commit is contained in:
parent
3422c1ca83
commit
bff635bc5f
6741 changed files with 26942 additions and 4902033 deletions
3
vendor/github.com/minio/minio-go/README.md
generated
vendored
3
vendor/github.com/minio/minio-go/README.md
generated
vendored
|
@ -130,7 +130,6 @@ The full API Reference is available here.
|
|||
### API Reference : Bucket policy Operations
|
||||
* [`SetBucketPolicy`](https://docs.minio.io/docs/golang-client-api-reference#SetBucketPolicy)
|
||||
* [`GetBucketPolicy`](https://docs.minio.io/docs/golang-client-api-reference#GetBucketPolicy)
|
||||
* [`ListBucketPolicies`](https://docs.minio.io/docs/golang-client-api-reference#ListBucketPolicies)
|
||||
|
||||
### API Reference : Bucket notification Operations
|
||||
* [`SetBucketNotification`](https://docs.minio.io/docs/golang-client-api-reference#SetBucketNotification)
|
||||
|
@ -140,7 +139,7 @@ The full API Reference is available here.
|
|||
|
||||
### API Reference : File Object Operations
|
||||
* [`FPutObject`](https://docs.minio.io/docs/golang-client-api-reference#FPutObject)
|
||||
* [`FGetObject`](https://docs.minio.io/docs/golang-client-api-reference#FPutObject)
|
||||
* [`FGetObject`](https://docs.minio.io/docs/golang-client-api-reference#FGetObject)
|
||||
* [`FPutObjectWithContext`](https://docs.minio.io/docs/golang-client-api-reference#FPutObjectWithContext)
|
||||
* [`FGetObjectWithContext`](https://docs.minio.io/docs/golang-client-api-reference#FGetObjectWithContext)
|
||||
|
||||
|
|
1
vendor/github.com/minio/minio-go/README_zh_CN.md
generated
vendored
1
vendor/github.com/minio/minio-go/README_zh_CN.md
generated
vendored
|
@ -141,7 +141,6 @@ mc ls play/mymusic/
|
|||
### API文档 : 存储桶策略
|
||||
* [`SetBucketPolicy`](https://docs.minio.io/docs/golang-client-api-reference#SetBucketPolicy)
|
||||
* [`GetBucketPolicy`](https://docs.minio.io/docs/golang-client-api-reference#GetBucketPolicy)
|
||||
* [`ListBucketPolicies`](https://docs.minio.io/docs/golang-client-api-reference#ListBucketPolicies)
|
||||
|
||||
### API文档 : 存储桶通知
|
||||
* [`SetBucketNotification`](https://docs.minio.io/docs/golang-client-api-reference#SetBucketNotification)
|
||||
|
|
73
vendor/github.com/minio/minio-go/api-compose-object.go
generated
vendored
73
vendor/github.com/minio/minio-go/api-compose-object.go
generated
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* Copyright 2017 Minio, Inc.
|
||||
* Copyright 2017, 2018 Minio, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -20,6 +20,8 @@ package minio
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
@ -132,12 +134,6 @@ func NewSourceInfo(bucket, object string, sse encrypt.ServerSide) SourceInfo {
|
|||
|
||||
// Set the source header
|
||||
r.Headers.Set("x-amz-copy-source", s3utils.EncodePath(bucket+"/"+object))
|
||||
|
||||
// Assemble decryption headers for upload-part-copy request
|
||||
if r.encryption != nil {
|
||||
encrypt.SSECopy(r.encryption).Marshal(r.Headers)
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
|
@ -197,7 +193,7 @@ func (s *SourceInfo) getProps(c Client) (size int64, etag string, userMeta map[s
|
|||
// Get object info - need size and etag here. Also, decryption
|
||||
// headers are added to the stat request if given.
|
||||
var objInfo ObjectInfo
|
||||
opts := StatObjectOptions{GetObjectOptions{ServerSideEncryption: s.encryption}}
|
||||
opts := StatObjectOptions{GetObjectOptions{ServerSideEncryption: encrypt.SSE(s.encryption)}}
|
||||
objInfo, err = c.statObject(context.Background(), s.bucket, s.object, opts)
|
||||
if err != nil {
|
||||
err = ErrInvalidArgument(fmt.Sprintf("Could not stat object - %s/%s: %v", s.bucket, s.object, err))
|
||||
|
@ -349,11 +345,12 @@ func (c Client) uploadPartCopy(ctx context.Context, bucket, object, uploadID str
|
|||
return p, nil
|
||||
}
|
||||
|
||||
// ComposeObject - creates an object using server-side copying of
|
||||
// ComposeObjectWithProgress - creates an object using server-side copying of
|
||||
// existing objects. It takes a list of source objects (with optional
|
||||
// offsets) and concatenates them into a new object using only
|
||||
// server-side copying operations.
|
||||
func (c Client) ComposeObject(dst DestinationInfo, srcs []SourceInfo) error {
|
||||
// server-side copying operations. Optionally takes progress reader hook
|
||||
// for applications to look at current progress.
|
||||
func (c Client) ComposeObjectWithProgress(dst DestinationInfo, srcs []SourceInfo, progress io.Reader) error {
|
||||
if len(srcs) < 1 || len(srcs) > maxPartsCount {
|
||||
return ErrInvalidArgument("There must be as least one and up to 10000 source objects.")
|
||||
}
|
||||
|
@ -427,37 +424,7 @@ func (c Client) ComposeObject(dst DestinationInfo, srcs []SourceInfo) error {
|
|||
// involved, it is being copied wholly and at most 5GiB in
|
||||
// size, emptyfiles are also supported).
|
||||
if (totalParts == 1 && srcs[0].start == -1 && totalSize <= maxPartSize) || (totalSize == 0) {
|
||||
h := srcs[0].Headers
|
||||
// Add destination encryption headers
|
||||
if dst.encryption != nil {
|
||||
dst.encryption.Marshal(h)
|
||||
}
|
||||
|
||||
// If no user metadata is specified (and so, the
|
||||
// for-loop below is not entered), metadata from the
|
||||
// source is copied to the destination (due to
|
||||
// single-part copy-object PUT request behaviour).
|
||||
for k, v := range dst.getUserMetaHeadersMap(true) {
|
||||
h.Set(k, v)
|
||||
}
|
||||
|
||||
// Send copy request
|
||||
resp, err := c.executeMethod(ctx, "PUT", requestMetadata{
|
||||
bucketName: dst.bucket,
|
||||
objectName: dst.object,
|
||||
customHeader: h,
|
||||
})
|
||||
defer closeResponse(resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Check if we got an error response.
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return httpRespToErrorResponse(resp, dst.bucket, dst.object)
|
||||
}
|
||||
|
||||
// Return nil on success.
|
||||
return nil
|
||||
return c.CopyObjectWithProgress(dst, srcs[0], progress)
|
||||
}
|
||||
|
||||
// Now, handle multipart-copy cases.
|
||||
|
@ -487,6 +454,9 @@ func (c Client) ComposeObject(dst DestinationInfo, srcs []SourceInfo) error {
|
|||
partIndex := 1
|
||||
for i, src := range srcs {
|
||||
h := src.Headers
|
||||
if src.encryption != nil {
|
||||
src.encryption.Marshal(h)
|
||||
}
|
||||
// Add destination encryption headers
|
||||
if dst.encryption != nil {
|
||||
dst.encryption.Marshal(h)
|
||||
|
@ -509,6 +479,9 @@ func (c Client) ComposeObject(dst DestinationInfo, srcs []SourceInfo) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if progress != nil {
|
||||
io.CopyN(ioutil.Discard, progress, start+end-1)
|
||||
}
|
||||
objParts = append(objParts, complPart)
|
||||
partIndex++
|
||||
}
|
||||
|
@ -523,10 +496,20 @@ func (c Client) ComposeObject(dst DestinationInfo, srcs []SourceInfo) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// partsRequired is ceiling(size / copyPartSize)
|
||||
// ComposeObject - creates an object using server-side copying of
|
||||
// existing objects. It takes a list of source objects (with optional
|
||||
// offsets) and concatenates them into a new object using only
|
||||
// server-side copying operations.
|
||||
func (c Client) ComposeObject(dst DestinationInfo, srcs []SourceInfo) error {
|
||||
return c.ComposeObjectWithProgress(dst, srcs, nil)
|
||||
}
|
||||
|
||||
// partsRequired is maximum parts possible with
|
||||
// max part size of ceiling(maxMultipartPutObjectSize / (maxPartsCount - 1))
|
||||
func partsRequired(size int64) int64 {
|
||||
r := size / copyPartSize
|
||||
if size%copyPartSize > 0 {
|
||||
maxPartSize := maxMultipartPutObjectSize / (maxPartsCount - 1)
|
||||
r := size / int64(maxPartSize)
|
||||
if size%int64(maxPartSize) > 0 {
|
||||
r++
|
||||
}
|
||||
return r
|
||||
|
|
89
vendor/github.com/minio/minio-go/api-compose-object_test.go
generated
vendored
89
vendor/github.com/minio/minio-go/api-compose-object_test.go
generated
vendored
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
gb1 = 1024 * 1024 * 1024
|
||||
gb5 = 5 * gb1
|
||||
gb5p1 = gb5 + 1
|
||||
gb10p1 = 2*gb5 + 1
|
||||
gb10p2 = 2*gb5 + 2
|
||||
)
|
||||
|
||||
func TestPartsRequired(t *testing.T) {
|
||||
testCases := []struct {
|
||||
size, ref int64
|
||||
}{
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{gb5, 1},
|
||||
{2 * gb5, 2},
|
||||
{gb10p1, 3},
|
||||
{gb10p2, 3},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
res := partsRequired(testCase.size)
|
||||
if res != testCase.ref {
|
||||
t.Errorf("Test %d - output did not match with reference results", i+1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCalculateEvenSplits(t *testing.T) {
|
||||
|
||||
testCases := []struct {
|
||||
// input size and source object
|
||||
size int64
|
||||
src SourceInfo
|
||||
|
||||
// output part-indexes
|
||||
starts, ends []int64
|
||||
}{
|
||||
{0, SourceInfo{start: -1}, nil, nil},
|
||||
{1, SourceInfo{start: -1}, []int64{0}, []int64{0}},
|
||||
{1, SourceInfo{start: 0}, []int64{0}, []int64{0}},
|
||||
|
||||
{gb1, SourceInfo{start: -1}, []int64{0}, []int64{gb1 - 1}},
|
||||
{gb5, SourceInfo{start: -1}, []int64{0}, []int64{gb5 - 1}},
|
||||
|
||||
// 2 part splits
|
||||
{gb5p1, SourceInfo{start: -1}, []int64{0, gb5/2 + 1}, []int64{gb5 / 2, gb5}},
|
||||
{gb5p1, SourceInfo{start: -1}, []int64{0, gb5/2 + 1}, []int64{gb5 / 2, gb5}},
|
||||
|
||||
// 3 part splits
|
||||
{gb10p1, SourceInfo{start: -1},
|
||||
[]int64{0, gb10p1/3 + 1, 2*gb10p1/3 + 1},
|
||||
[]int64{gb10p1 / 3, 2 * gb10p1 / 3, gb10p1 - 1}},
|
||||
|
||||
{gb10p2, SourceInfo{start: -1},
|
||||
[]int64{0, gb10p2 / 3, 2 * gb10p2 / 3},
|
||||
[]int64{gb10p2/3 - 1, 2*gb10p2/3 - 1, gb10p2 - 1}},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
resStart, resEnd := calculateEvenSplits(testCase.size, testCase.src)
|
||||
if !reflect.DeepEqual(testCase.starts, resStart) || !reflect.DeepEqual(testCase.ends, resEnd) {
|
||||
t.Errorf("Test %d - output did not match with reference results", i+1)
|
||||
}
|
||||
}
|
||||
}
|
294
vendor/github.com/minio/minio-go/api-error-response_test.go
generated
vendored
294
vendor/github.com/minio/minio-go/api-error-response_test.go
generated
vendored
|
@ -1,294 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Tests validate the Error generator function for http response with error.
|
||||
func TestHttpRespToErrorResponse(t *testing.T) {
|
||||
// 'genAPIErrorResponse' generates ErrorResponse for given APIError.
|
||||
// provides a encodable populated response values.
|
||||
genAPIErrorResponse := func(err APIError, bucketName string) ErrorResponse {
|
||||
return ErrorResponse{
|
||||
Code: err.Code,
|
||||
Message: err.Description,
|
||||
BucketName: bucketName,
|
||||
}
|
||||
}
|
||||
|
||||
// Encodes the response headers into XML format.
|
||||
encodeErr := func(response ErrorResponse) []byte {
|
||||
buf := &bytes.Buffer{}
|
||||
buf.WriteString(xml.Header)
|
||||
encoder := xml.NewEncoder(buf)
|
||||
err := encoder.Encode(response)
|
||||
if err != nil {
|
||||
t.Fatalf("error encoding response: %v", err)
|
||||
}
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// `createAPIErrorResponse` Mocks XML error response from the server.
|
||||
createAPIErrorResponse := func(APIErr APIError, bucketName string) *http.Response {
|
||||
// generate error response.
|
||||
// response body contains the XML error message.
|
||||
resp := &http.Response{}
|
||||
errorResponse := genAPIErrorResponse(APIErr, bucketName)
|
||||
encodedErrorResponse := encodeErr(errorResponse)
|
||||
// write Header.
|
||||
resp.StatusCode = APIErr.HTTPStatusCode
|
||||
resp.Body = ioutil.NopCloser(bytes.NewBuffer(encodedErrorResponse))
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
// 'genErrResponse' contructs error response based http Status Code
|
||||
genErrResponse := func(resp *http.Response, code, message, bucketName, objectName string) ErrorResponse {
|
||||
errResp := ErrorResponse{
|
||||
StatusCode: resp.StatusCode,
|
||||
Code: code,
|
||||
Message: message,
|
||||
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"),
|
||||
Headers: resp.Header,
|
||||
}
|
||||
return errResp
|
||||
}
|
||||
|
||||
// Generate invalid argument error.
|
||||
genInvalidError := func(message string) error {
|
||||
errResp := ErrorResponse{
|
||||
StatusCode: http.StatusBadRequest,
|
||||
Code: "InvalidArgument",
|
||||
Message: message,
|
||||
RequestID: "minio",
|
||||
}
|
||||
return errResp
|
||||
}
|
||||
|
||||
// Set common http response headers.
|
||||
setCommonHeaders := func(resp *http.Response) *http.Response {
|
||||
// set headers.
|
||||
resp.Header = make(http.Header)
|
||||
resp.Header.Set("x-amz-request-id", "xyz")
|
||||
resp.Header.Set("x-amz-id-2", "abc")
|
||||
resp.Header.Set("x-amz-bucket-region", "us-east-1")
|
||||
return resp
|
||||
}
|
||||
|
||||
// Generate http response with empty body.
|
||||
// Set the StatusCode to the argument supplied.
|
||||
// Sets common headers.
|
||||
genEmptyBodyResponse := func(statusCode int) *http.Response {
|
||||
resp := &http.Response{
|
||||
StatusCode: statusCode,
|
||||
Body: ioutil.NopCloser(bytes.NewReader(nil)),
|
||||
}
|
||||
setCommonHeaders(resp)
|
||||
return resp
|
||||
}
|
||||
|
||||
// Decode XML error message from the http response body.
|
||||
decodeXMLError := func(resp *http.Response) error {
|
||||
errResp := ErrorResponse{
|
||||
StatusCode: resp.StatusCode,
|
||||
}
|
||||
err := xmlDecoder(resp.Body, &errResp)
|
||||
if err != nil {
|
||||
t.Fatalf("XML decoding of response body failed: %v", err)
|
||||
}
|
||||
return errResp
|
||||
}
|
||||
|
||||
// List of APIErrors used to generate/mock server side XML error response.
|
||||
APIErrors := []APIError{
|
||||
{
|
||||
Code: "NoSuchBucketPolicy",
|
||||
Description: "The specified bucket does not have a bucket policy.",
|
||||
HTTPStatusCode: http.StatusNotFound,
|
||||
},
|
||||
}
|
||||
|
||||
// List of expected response.
|
||||
// Used for asserting the actual response.
|
||||
expectedErrResponse := []error{
|
||||
genInvalidError("Response is empty. " + "Please report this issue at https://github.com/minio/minio-go/issues."),
|
||||
decodeXMLError(createAPIErrorResponse(APIErrors[0], "minio-bucket")),
|
||||
genErrResponse(setCommonHeaders(&http.Response{StatusCode: http.StatusNotFound}), "NoSuchBucket", "The specified bucket does not exist.", "minio-bucket", ""),
|
||||
genErrResponse(setCommonHeaders(&http.Response{StatusCode: http.StatusNotFound}), "NoSuchKey", "The specified key does not exist.", "minio-bucket", "Asia/"),
|
||||
genErrResponse(setCommonHeaders(&http.Response{StatusCode: http.StatusForbidden}), "AccessDenied", "Access Denied.", "minio-bucket", ""),
|
||||
genErrResponse(setCommonHeaders(&http.Response{StatusCode: http.StatusConflict}), "Conflict", "Bucket not empty.", "minio-bucket", ""),
|
||||
genErrResponse(setCommonHeaders(&http.Response{StatusCode: http.StatusBadRequest}), "Bad Request", "Bad Request", "minio-bucket", ""),
|
||||
}
|
||||
|
||||
// List of http response to be used as input.
|
||||
inputResponses := []*http.Response{
|
||||
nil,
|
||||
createAPIErrorResponse(APIErrors[0], "minio-bucket"),
|
||||
genEmptyBodyResponse(http.StatusNotFound),
|
||||
genEmptyBodyResponse(http.StatusNotFound),
|
||||
genEmptyBodyResponse(http.StatusForbidden),
|
||||
genEmptyBodyResponse(http.StatusConflict),
|
||||
genEmptyBodyResponse(http.StatusBadRequest),
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
bucketName string
|
||||
objectName string
|
||||
inputHTTPResp *http.Response
|
||||
// expected results.
|
||||
expectedResult error
|
||||
// flag indicating whether tests should pass.
|
||||
|
||||
}{
|
||||
{"minio-bucket", "", inputResponses[0], expectedErrResponse[0]},
|
||||
{"minio-bucket", "", inputResponses[1], expectedErrResponse[1]},
|
||||
{"minio-bucket", "", inputResponses[2], expectedErrResponse[2]},
|
||||
{"minio-bucket", "Asia/", inputResponses[3], expectedErrResponse[3]},
|
||||
{"minio-bucket", "", inputResponses[4], expectedErrResponse[4]},
|
||||
{"minio-bucket", "", inputResponses[5], expectedErrResponse[5]},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
actualResult := httpRespToErrorResponse(testCase.inputHTTPResp, testCase.bucketName, testCase.objectName)
|
||||
if !reflect.DeepEqual(testCase.expectedResult, actualResult) {
|
||||
t.Errorf("Test %d: Expected result to be '%#v', but instead got '%#v'", i+1, testCase.expectedResult, actualResult)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test validates 'ErrEntityTooLarge' error response.
|
||||
func TestErrEntityTooLarge(t *testing.T) {
|
||||
msg := fmt.Sprintf("Your proposed upload size ‘%d’ exceeds the maximum allowed object size ‘%d’ for single PUT operation.", 1000000, 99999)
|
||||
expectedResult := ErrorResponse{
|
||||
StatusCode: http.StatusBadRequest,
|
||||
Code: "EntityTooLarge",
|
||||
Message: msg,
|
||||
BucketName: "minio-bucket",
|
||||
Key: "Asia/",
|
||||
}
|
||||
actualResult := ErrEntityTooLarge(1000000, 99999, "minio-bucket", "Asia/")
|
||||
if !reflect.DeepEqual(expectedResult, actualResult) {
|
||||
t.Errorf("Expected result to be '%#v', but instead got '%#v'", expectedResult, actualResult)
|
||||
}
|
||||
}
|
||||
|
||||
// Test validates 'ErrEntityTooSmall' error response.
|
||||
func TestErrEntityTooSmall(t *testing.T) {
|
||||
msg := fmt.Sprintf("Your proposed upload size ‘%d’ is below the minimum allowed object size ‘0B’ for single PUT operation.", -1)
|
||||
expectedResult := ErrorResponse{
|
||||
StatusCode: http.StatusBadRequest,
|
||||
Code: "EntityTooSmall",
|
||||
Message: msg,
|
||||
BucketName: "minio-bucket",
|
||||
Key: "Asia/",
|
||||
}
|
||||
actualResult := ErrEntityTooSmall(-1, "minio-bucket", "Asia/")
|
||||
if !reflect.DeepEqual(expectedResult, actualResult) {
|
||||
t.Errorf("Expected result to be '%#v', but instead got '%#v'", expectedResult, actualResult)
|
||||
}
|
||||
}
|
||||
|
||||
// Test validates 'ErrUnexpectedEOF' error response.
|
||||
func TestErrUnexpectedEOF(t *testing.T) {
|
||||
msg := fmt.Sprintf("Data read ‘%s’ is not equal to the size ‘%s’ of the input Reader.",
|
||||
strconv.FormatInt(100, 10), strconv.FormatInt(101, 10))
|
||||
expectedResult := ErrorResponse{
|
||||
StatusCode: http.StatusBadRequest,
|
||||
Code: "UnexpectedEOF",
|
||||
Message: msg,
|
||||
BucketName: "minio-bucket",
|
||||
Key: "Asia/",
|
||||
}
|
||||
actualResult := ErrUnexpectedEOF(100, 101, "minio-bucket", "Asia/")
|
||||
if !reflect.DeepEqual(expectedResult, actualResult) {
|
||||
t.Errorf("Expected result to be '%#v', but instead got '%#v'", expectedResult, actualResult)
|
||||
}
|
||||
}
|
||||
|
||||
// Test validates 'ErrInvalidBucketName' error response.
|
||||
func TestErrInvalidBucketName(t *testing.T) {
|
||||
expectedResult := ErrorResponse{
|
||||
StatusCode: http.StatusBadRequest,
|
||||
Code: "InvalidBucketName",
|
||||
Message: "Invalid Bucket name",
|
||||
RequestID: "minio",
|
||||
}
|
||||
actualResult := ErrInvalidBucketName("Invalid Bucket name")
|
||||
if !reflect.DeepEqual(expectedResult, actualResult) {
|
||||
t.Errorf("Expected result to be '%#v', but instead got '%#v'", expectedResult, actualResult)
|
||||
}
|
||||
}
|
||||
|
||||
// Test validates 'ErrInvalidObjectName' error response.
|
||||
func TestErrInvalidObjectName(t *testing.T) {
|
||||
expectedResult := ErrorResponse{
|
||||
StatusCode: http.StatusNotFound,
|
||||
Code: "NoSuchKey",
|
||||
Message: "Invalid Object Key",
|
||||
RequestID: "minio",
|
||||
}
|
||||
actualResult := ErrInvalidObjectName("Invalid Object Key")
|
||||
if !reflect.DeepEqual(expectedResult, actualResult) {
|
||||
t.Errorf("Expected result to be '%#v', but instead got '%#v'", expectedResult, actualResult)
|
||||
}
|
||||
}
|
||||
|
||||
// Test validates 'ErrInvalidArgument' response.
|
||||
func TestErrInvalidArgument(t *testing.T) {
|
||||
expectedResult := ErrorResponse{
|
||||
StatusCode: http.StatusBadRequest,
|
||||
Code: "InvalidArgument",
|
||||
Message: "Invalid Argument",
|
||||
RequestID: "minio",
|
||||
}
|
||||
actualResult := ErrInvalidArgument("Invalid Argument")
|
||||
if !reflect.DeepEqual(expectedResult, actualResult) {
|
||||
t.Errorf("Expected result to be '%#v', but instead got '%#v'", expectedResult, actualResult)
|
||||
}
|
||||
}
|
||||
|
||||
// Tests if the Message field is missing.
|
||||
func TestErrWithoutMessage(t *testing.T) {
|
||||
errResp := ErrorResponse{
|
||||
Code: "AccessDenied",
|
||||
RequestID: "minio",
|
||||
}
|
||||
if errResp.Error() != "Access Denied." {
|
||||
t.Errorf("Expected \"Access Denied.\", got %s", errResp)
|
||||
}
|
||||
errResp = ErrorResponse{
|
||||
Code: "InvalidArgument",
|
||||
RequestID: "minio",
|
||||
}
|
||||
if errResp.Error() != "Error response code InvalidArgument." {
|
||||
t.Errorf("Expected \"Error response code InvalidArgument.\", got %s", errResp)
|
||||
}
|
||||
}
|
2
vendor/github.com/minio/minio-go/api-get-options.go
generated
vendored
2
vendor/github.com/minio/minio-go/api-get-options.go
generated
vendored
|
@ -44,7 +44,7 @@ func (o GetObjectOptions) Header() http.Header {
|
|||
for k, v := range o.headers {
|
||||
headers.Set(k, v)
|
||||
}
|
||||
if o.ServerSideEncryption != nil {
|
||||
if o.ServerSideEncryption != nil && o.ServerSideEncryption.Type() != encrypt.S3 {
|
||||
o.ServerSideEncryption.Marshal(headers)
|
||||
}
|
||||
return headers
|
||||
|
|
53
vendor/github.com/minio/minio-go/api-get-policy.go
generated
vendored
53
vendor/github.com/minio/minio-go/api-get-policy.go
generated
vendored
|
@ -19,62 +19,32 @@ package minio
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/minio/minio-go/pkg/policy"
|
||||
"github.com/minio/minio-go/pkg/s3utils"
|
||||
)
|
||||
|
||||
// GetBucketPolicy - get bucket policy at a given path.
|
||||
func (c Client) GetBucketPolicy(bucketName, objectPrefix string) (bucketPolicy policy.BucketPolicy, err error) {
|
||||
func (c Client) GetBucketPolicy(bucketName string) (string, error) {
|
||||
// Input validation.
|
||||
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
|
||||
return policy.BucketPolicyNone, err
|
||||
return "", err
|
||||
}
|
||||
if err := s3utils.CheckValidObjectNamePrefix(objectPrefix); err != nil {
|
||||
return policy.BucketPolicyNone, err
|
||||
}
|
||||
policyInfo, err := c.getBucketPolicy(bucketName)
|
||||
bucketPolicy, err := c.getBucketPolicy(bucketName)
|
||||
if err != nil {
|
||||
errResponse := ToErrorResponse(err)
|
||||
if errResponse.Code == "NoSuchBucketPolicy" {
|
||||
return policy.BucketPolicyNone, nil
|
||||
return "", nil
|
||||
}
|
||||
return policy.BucketPolicyNone, err
|
||||
return "", err
|
||||
}
|
||||
return policy.GetPolicy(policyInfo.Statements, bucketName, objectPrefix), nil
|
||||
}
|
||||
|
||||
// ListBucketPolicies - list all policies for a given prefix and all its children.
|
||||
func (c Client) ListBucketPolicies(bucketName, objectPrefix string) (bucketPolicies map[string]policy.BucketPolicy, err error) {
|
||||
// Input validation.
|
||||
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
|
||||
return map[string]policy.BucketPolicy{}, err
|
||||
}
|
||||
if err := s3utils.CheckValidObjectNamePrefix(objectPrefix); err != nil {
|
||||
return map[string]policy.BucketPolicy{}, err
|
||||
}
|
||||
policyInfo, err := c.getBucketPolicy(bucketName)
|
||||
if err != nil {
|
||||
errResponse := ToErrorResponse(err)
|
||||
if errResponse.Code == "NoSuchBucketPolicy" {
|
||||
return map[string]policy.BucketPolicy{}, nil
|
||||
}
|
||||
return map[string]policy.BucketPolicy{}, err
|
||||
}
|
||||
return policy.GetPolicies(policyInfo.Statements, bucketName, objectPrefix), nil
|
||||
}
|
||||
|
||||
// Default empty bucket access policy.
|
||||
var emptyBucketAccessPolicy = policy.BucketAccessPolicy{
|
||||
Version: "2012-10-17",
|
||||
return bucketPolicy, nil
|
||||
}
|
||||
|
||||
// Request server for current bucket policy.
|
||||
func (c Client) getBucketPolicy(bucketName string) (policy.BucketAccessPolicy, error) {
|
||||
func (c Client) getBucketPolicy(bucketName string) (string, error) {
|
||||
// Get resources properly escaped and lined up before
|
||||
// using them in http request.
|
||||
urlValues := make(url.Values)
|
||||
|
@ -89,21 +59,20 @@ func (c Client) getBucketPolicy(bucketName string) (policy.BucketAccessPolicy, e
|
|||
|
||||
defer closeResponse(resp)
|
||||
if err != nil {
|
||||
return emptyBucketAccessPolicy, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
if resp != nil {
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return emptyBucketAccessPolicy, httpRespToErrorResponse(resp, bucketName, "")
|
||||
return "", httpRespToErrorResponse(resp, bucketName, "")
|
||||
}
|
||||
}
|
||||
|
||||
bucketPolicyBuf, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return emptyBucketAccessPolicy, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
policy := policy.BucketAccessPolicy{}
|
||||
err = json.Unmarshal(bucketPolicyBuf, &policy)
|
||||
policy := string(bucketPolicyBuf)
|
||||
return policy, err
|
||||
}
|
||||
|
|
27
vendor/github.com/minio/minio-go/api-list.go
generated
vendored
27
vendor/github.com/minio/minio-go/api-list.go
generated
vendored
|
@ -118,7 +118,7 @@ func (c Client) ListObjectsV2(bucketName, objectPrefix string, recursive bool, d
|
|||
var continuationToken string
|
||||
for {
|
||||
// Get list of objects a maximum of 1000 per request.
|
||||
result, err := c.listObjectsV2Query(bucketName, objectPrefix, continuationToken, fetchOwner, delimiter, 1000)
|
||||
result, err := c.listObjectsV2Query(bucketName, objectPrefix, continuationToken, fetchOwner, delimiter, 1000, "")
|
||||
if err != nil {
|
||||
objectStatCh <- ObjectInfo{
|
||||
Err: err,
|
||||
|
@ -171,11 +171,12 @@ func (c Client) ListObjectsV2(bucketName, objectPrefix string, recursive bool, d
|
|||
// You can use the request parameters as selection criteria to return a subset of the objects in a bucket.
|
||||
// request parameters :-
|
||||
// ---------
|
||||
// ?continuation-token - Specifies the key to start with when listing objects in a bucket.
|
||||
// ?continuation-token - Used to continue iterating over a set of objects
|
||||
// ?delimiter - A delimiter is a character you use to group keys.
|
||||
// ?prefix - Limits the response to keys that begin with the specified prefix.
|
||||
// ?max-keys - Sets the maximum number of keys returned in the response body.
|
||||
func (c Client) listObjectsV2Query(bucketName, objectPrefix, continuationToken string, fetchOwner bool, delimiter string, maxkeys int) (ListBucketV2Result, error) {
|
||||
// ?start-after - Specifies the key to start after when listing objects in a bucket.
|
||||
func (c Client) listObjectsV2Query(bucketName, objectPrefix, continuationToken string, fetchOwner bool, delimiter string, maxkeys int, startAfter string) (ListBucketV2Result, error) {
|
||||
// Validate bucket name.
|
||||
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
|
||||
return ListBucketV2Result{}, err
|
||||
|
@ -216,6 +217,11 @@ func (c Client) listObjectsV2Query(bucketName, objectPrefix, continuationToken s
|
|||
// Set max keys.
|
||||
urlValues.Set("max-keys", fmt.Sprintf("%d", maxkeys))
|
||||
|
||||
// Set start-after
|
||||
if startAfter != "" {
|
||||
urlValues.Set("start-after", startAfter)
|
||||
}
|
||||
|
||||
// Execute GET on bucket to list objects.
|
||||
resp, err := c.executeMethod(context.Background(), "GET", requestMetadata{
|
||||
bucketName: bucketName,
|
||||
|
@ -627,30 +633,27 @@ func (c Client) listObjectParts(bucketName, objectName, uploadID string) (partsI
|
|||
return partsInfo, nil
|
||||
}
|
||||
|
||||
// findUploadID lists all incomplete uploads and finds the uploadID of the matching object name.
|
||||
func (c Client) findUploadID(bucketName, objectName string) (uploadID string, err error) {
|
||||
// findUploadIDs lists all incomplete uploads and find the uploadIDs of the matching object name.
|
||||
func (c Client) findUploadIDs(bucketName, objectName string) ([]string, error) {
|
||||
var uploadIDs []string
|
||||
// Make list incomplete uploads recursive.
|
||||
isRecursive := true
|
||||
// Turn off size aggregation of individual parts, in this request.
|
||||
isAggregateSize := false
|
||||
// latestUpload to track the latest multipart info for objectName.
|
||||
var latestUpload ObjectMultipartInfo
|
||||
// Create done channel to cleanup the routine.
|
||||
doneCh := make(chan struct{})
|
||||
defer close(doneCh)
|
||||
// List all incomplete uploads.
|
||||
for mpUpload := range c.listIncompleteUploads(bucketName, objectName, isRecursive, isAggregateSize, doneCh) {
|
||||
if mpUpload.Err != nil {
|
||||
return "", mpUpload.Err
|
||||
return nil, mpUpload.Err
|
||||
}
|
||||
if objectName == mpUpload.Key {
|
||||
if mpUpload.Initiated.Sub(latestUpload.Initiated) > 0 {
|
||||
latestUpload = mpUpload
|
||||
}
|
||||
uploadIDs = append(uploadIDs, mpUpload.UploadID)
|
||||
}
|
||||
}
|
||||
// Return the latest upload id.
|
||||
return latestUpload.UploadID, nil
|
||||
return uploadIDs, nil
|
||||
}
|
||||
|
||||
// getTotalMultipartSize - calculate total uploaded size for the a given multipart object.
|
||||
|
|
60
vendor/github.com/minio/minio-go/api-put-bucket.go
generated
vendored
60
vendor/github.com/minio/minio-go/api-put-bucket.go
generated
vendored
|
@ -20,13 +20,12 @@ package minio
|
|||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/minio/minio-go/pkg/policy"
|
||||
"github.com/minio/minio-go/pkg/s3utils"
|
||||
)
|
||||
|
||||
|
@ -100,74 +99,45 @@ func (c Client) MakeBucket(bucketName string, location string) (err error) {
|
|||
}
|
||||
|
||||
// SetBucketPolicy set the access permissions on an existing bucket.
|
||||
//
|
||||
// For example
|
||||
//
|
||||
// none - owner gets full access [default].
|
||||
// readonly - anonymous get access for everyone at a given object prefix.
|
||||
// readwrite - anonymous list/put/delete access to a given object prefix.
|
||||
// writeonly - anonymous put/delete access to a given object prefix.
|
||||
func (c Client) SetBucketPolicy(bucketName string, objectPrefix string, bucketPolicy policy.BucketPolicy) error {
|
||||
func (c Client) SetBucketPolicy(bucketName, policy string) error {
|
||||
// Input validation.
|
||||
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s3utils.CheckValidObjectNamePrefix(objectPrefix); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !bucketPolicy.IsValidBucketPolicy() {
|
||||
return ErrInvalidArgument(fmt.Sprintf("Invalid bucket policy provided. %s", bucketPolicy))
|
||||
// If policy is empty then delete the bucket policy.
|
||||
if policy == "" {
|
||||
return c.removeBucketPolicy(bucketName)
|
||||
}
|
||||
|
||||
policyInfo, err := c.getBucketPolicy(bucketName)
|
||||
errResponse := ToErrorResponse(err)
|
||||
if err != nil && errResponse.Code != "NoSuchBucketPolicy" {
|
||||
return err
|
||||
}
|
||||
|
||||
if bucketPolicy == policy.BucketPolicyNone && policyInfo.Statements == nil {
|
||||
// As the request is for removing policy and the bucket
|
||||
// has empty policy statements, just return success.
|
||||
return nil
|
||||
}
|
||||
|
||||
policyInfo.Statements = policy.SetPolicy(policyInfo.Statements, bucketPolicy, bucketName, objectPrefix)
|
||||
|
||||
// Save the updated policies.
|
||||
return c.putBucketPolicy(bucketName, policyInfo)
|
||||
return c.putBucketPolicy(bucketName, policy)
|
||||
}
|
||||
|
||||
// Saves a new bucket policy.
|
||||
func (c Client) putBucketPolicy(bucketName string, policyInfo policy.BucketAccessPolicy) error {
|
||||
func (c Client) putBucketPolicy(bucketName, policy string) error {
|
||||
// Input validation.
|
||||
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If there are no policy statements, we should remove entire policy.
|
||||
if len(policyInfo.Statements) == 0 {
|
||||
return c.removeBucketPolicy(bucketName)
|
||||
}
|
||||
|
||||
// Get resources properly escaped and lined up before
|
||||
// using them in http request.
|
||||
urlValues := make(url.Values)
|
||||
urlValues.Set("policy", "")
|
||||
|
||||
policyBytes, err := json.Marshal(&policyInfo)
|
||||
// Content-length is mandatory for put policy request
|
||||
policyReader := strings.NewReader(policy)
|
||||
b, err := ioutil.ReadAll(policyReader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
policyBuffer := bytes.NewReader(policyBytes)
|
||||
reqMetadata := requestMetadata{
|
||||
bucketName: bucketName,
|
||||
queryValues: urlValues,
|
||||
contentBody: policyBuffer,
|
||||
contentLength: int64(len(policyBytes)),
|
||||
contentMD5Base64: sumMD5Base64(policyBytes),
|
||||
contentSHA256Hex: sum256Hex(policyBytes),
|
||||
bucketName: bucketName,
|
||||
queryValues: urlValues,
|
||||
contentBody: policyReader,
|
||||
contentLength: int64(len(b)),
|
||||
}
|
||||
|
||||
// Execute PUT to upload a new bucket policy.
|
||||
|
|
64
vendor/github.com/minio/minio-go/api-put-object-copy.go
generated
vendored
64
vendor/github.com/minio/minio-go/api-put-object-copy.go
generated
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* Copyright 2017 Minio, Inc.
|
||||
* Copyright 2017, 2018 Minio, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -17,7 +17,67 @@
|
|||
|
||||
package minio
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/minio/minio-go/pkg/encrypt"
|
||||
)
|
||||
|
||||
// CopyObject - copy a source object into a new object
|
||||
func (c Client) CopyObject(dst DestinationInfo, src SourceInfo) error {
|
||||
return c.ComposeObject(dst, []SourceInfo{src})
|
||||
return c.CopyObjectWithProgress(dst, src, nil)
|
||||
}
|
||||
|
||||
// CopyObjectWithProgress - copy a source object into a new object, optionally takes
|
||||
// progress bar input to notify current progress.
|
||||
func (c Client) CopyObjectWithProgress(dst DestinationInfo, src SourceInfo, progress io.Reader) error {
|
||||
header := make(http.Header)
|
||||
for k, v := range src.Headers {
|
||||
header[k] = v
|
||||
}
|
||||
|
||||
var err error
|
||||
var size int64
|
||||
// If progress bar is specified, size should be requested as well initiate a StatObject request.
|
||||
if progress != nil {
|
||||
size, _, _, err = src.getProps(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if src.encryption != nil {
|
||||
encrypt.SSECopy(src.encryption).Marshal(header)
|
||||
}
|
||||
|
||||
if dst.encryption != nil {
|
||||
dst.encryption.Marshal(header)
|
||||
}
|
||||
for k, v := range dst.getUserMetaHeadersMap(true) {
|
||||
header.Set(k, v)
|
||||
}
|
||||
|
||||
resp, err := c.executeMethod(context.Background(), "PUT", requestMetadata{
|
||||
bucketName: dst.bucket,
|
||||
objectName: dst.object,
|
||||
customHeader: header,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closeResponse(resp)
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return httpRespToErrorResponse(resp, dst.bucket, dst.object)
|
||||
}
|
||||
|
||||
// Update the progress properly after successful copy.
|
||||
if progress != nil {
|
||||
io.CopyN(ioutil.Discard, progress, size)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
2
vendor/github.com/minio/minio-go/api-put-object-multipart.go
generated
vendored
2
vendor/github.com/minio/minio-go/api-put-object-multipart.go
generated
vendored
|
@ -259,7 +259,7 @@ func (c Client) uploadPart(ctx context.Context, bucketName, objectName, uploadID
|
|||
|
||||
// Set encryption headers, if any.
|
||||
customHeader := make(http.Header)
|
||||
if sse != nil {
|
||||
if sse != nil && sse.Type() != encrypt.S3 && sse.Type() != encrypt.KMS {
|
||||
sse.Marshal(customHeader)
|
||||
}
|
||||
|
||||
|
|
32
vendor/github.com/minio/minio-go/api-put-object.go
generated
vendored
32
vendor/github.com/minio/minio-go/api-put-object.go
generated
vendored
|
@ -28,21 +28,22 @@ import (
|
|||
|
||||
"github.com/minio/minio-go/pkg/encrypt"
|
||||
"github.com/minio/minio-go/pkg/s3utils"
|
||||
"golang.org/x/net/lex/httplex"
|
||||
"golang.org/x/net/http/httpguts"
|
||||
)
|
||||
|
||||
// PutObjectOptions represents options specified by user for PutObject call
|
||||
type PutObjectOptions struct {
|
||||
UserMetadata map[string]string
|
||||
Progress io.Reader
|
||||
ContentType string
|
||||
ContentEncoding string
|
||||
ContentDisposition string
|
||||
ContentLanguage string
|
||||
CacheControl string
|
||||
ServerSideEncryption encrypt.ServerSide
|
||||
NumThreads uint
|
||||
StorageClass string
|
||||
UserMetadata map[string]string
|
||||
Progress io.Reader
|
||||
ContentType string
|
||||
ContentEncoding string
|
||||
ContentDisposition string
|
||||
ContentLanguage string
|
||||
CacheControl string
|
||||
ServerSideEncryption encrypt.ServerSide
|
||||
NumThreads uint
|
||||
StorageClass string
|
||||
WebsiteRedirectLocation string
|
||||
}
|
||||
|
||||
// getNumThreads - gets the number of threads to be used in the multipart
|
||||
|
@ -84,6 +85,9 @@ func (opts PutObjectOptions) Header() (header http.Header) {
|
|||
if opts.StorageClass != "" {
|
||||
header[amzStorageClass] = []string{opts.StorageClass}
|
||||
}
|
||||
if opts.WebsiteRedirectLocation != "" {
|
||||
header[amzWebsiteRedirectLocation] = []string{opts.WebsiteRedirectLocation}
|
||||
}
|
||||
for k, v := range opts.UserMetadata {
|
||||
if !isAmzHeader(k) && !isStandardHeader(k) && !isStorageClassHeader(k) {
|
||||
header["X-Amz-Meta-"+k] = []string{v}
|
||||
|
@ -97,10 +101,10 @@ func (opts PutObjectOptions) Header() (header http.Header) {
|
|||
// validate() checks if the UserMetadata map has standard headers or and raises an error if so.
|
||||
func (opts PutObjectOptions) validate() (err error) {
|
||||
for k, v := range opts.UserMetadata {
|
||||
if !httplex.ValidHeaderFieldName(k) || isStandardHeader(k) || isSSEHeader(k) || isStorageClassHeader(k) {
|
||||
if !httpguts.ValidHeaderFieldName(k) || isStandardHeader(k) || isSSEHeader(k) || isStorageClassHeader(k) {
|
||||
return ErrInvalidArgument(k + " unsupported user defined metadata name")
|
||||
}
|
||||
if !httplex.ValidHeaderFieldValue(v) {
|
||||
if !httpguts.ValidHeaderFieldValue(v) {
|
||||
return ErrInvalidArgument(v + " unsupported user defined metadata value")
|
||||
}
|
||||
}
|
||||
|
@ -208,7 +212,7 @@ func (c Client) putObjectMultipartStreamNoLength(ctx context.Context, bucketName
|
|||
if rErr == io.EOF && partNumber > 1 {
|
||||
break
|
||||
}
|
||||
if rErr != nil && rErr != io.ErrUnexpectedEOF {
|
||||
if rErr != nil && rErr != io.ErrUnexpectedEOF && rErr != io.EOF {
|
||||
return 0, rErr
|
||||
}
|
||||
// Update progress reader appropriately to the latest offset
|
||||
|
|
63
vendor/github.com/minio/minio-go/api-put-object_test.go
generated
vendored
63
vendor/github.com/minio/minio-go/api-put-object_test.go
generated
vendored
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPutObjectOptionsValidate(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name, value string
|
||||
shouldPass bool
|
||||
}{
|
||||
// Invalid cases.
|
||||
{"X-Amz-Matdesc", "blah", false},
|
||||
{"x-amz-meta-X-Amz-Iv", "blah", false},
|
||||
{"x-amz-meta-X-Amz-Key", "blah", false},
|
||||
{"x-amz-meta-X-Amz-Matdesc", "blah", false},
|
||||
{"It has spaces", "v", false},
|
||||
{"It,has@illegal=characters", "v", false},
|
||||
{"X-Amz-Iv", "blah", false},
|
||||
{"X-Amz-Key", "blah", false},
|
||||
{"X-Amz-Key-prefixed-header", "blah", false},
|
||||
{"Content-Type", "custom/content-type", false},
|
||||
{"content-type", "custom/content-type", false},
|
||||
{"Content-Encoding", "gzip", false},
|
||||
{"Cache-Control", "blah", false},
|
||||
{"Content-Disposition", "something", false},
|
||||
{"Content-Language", "somelanguage", false},
|
||||
|
||||
// Valid metadata names.
|
||||
{"my-custom-header", "blah", true},
|
||||
{"custom-X-Amz-Key-middle", "blah", true},
|
||||
{"my-custom-header-X-Amz-Key", "blah", true},
|
||||
{"blah-X-Amz-Matdesc", "blah", true},
|
||||
{"X-Amz-MatDesc-suffix", "blah", true},
|
||||
{"It-Is-Fine", "v", true},
|
||||
{"Numbers-098987987-Should-Work", "v", true},
|
||||
{"Crazy-!#$%&'*+-.^_`|~-Should-193832-Be-Fine", "v", true},
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
err := PutObjectOptions{UserMetadata: map[string]string{
|
||||
testCase.name: testCase.value,
|
||||
}}.validate()
|
||||
if testCase.shouldPass && err != nil {
|
||||
t.Errorf("Test %d - output did not match with reference results, %s", i+1, err)
|
||||
}
|
||||
}
|
||||
}
|
16
vendor/github.com/minio/minio-go/api-remove.go
generated
vendored
16
vendor/github.com/minio/minio-go/api-remove.go
generated
vendored
|
@ -195,6 +195,12 @@ func (c Client) RemoveObjectsWithContext(ctx context.Context, bucketName string,
|
|||
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}
|
||||
|
@ -227,18 +233,20 @@ func (c Client) RemoveIncompleteUpload(bucketName, objectName string) error {
|
|||
if err := s3utils.CheckValidObjectName(objectName); err != nil {
|
||||
return err
|
||||
}
|
||||
// Find multipart upload id of the object to be aborted.
|
||||
uploadID, err := c.findUploadID(bucketName, objectName)
|
||||
// Find multipart upload ids of the object to be aborted.
|
||||
uploadIDs, err := c.findUploadIDs(bucketName, objectName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if uploadID != "" {
|
||||
// Upload id found, abort the incomplete multipart upload.
|
||||
|
||||
for _, uploadID := range uploadIDs {
|
||||
// abort incomplete multipart upload, based on the upload id passed.
|
||||
err := c.abortMultipartUpload(context.Background(), bucketName, objectName, uploadID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
3
vendor/github.com/minio/minio-go/api-stat.go
generated
vendored
3
vendor/github.com/minio/minio-go/api-stat.go
generated
vendored
|
@ -66,6 +66,9 @@ var defaultFilterKeys = []string{
|
|||
"x-amz-bucket-region",
|
||||
"x-amz-request-id",
|
||||
"x-amz-id-2",
|
||||
"Content-Security-Policy",
|
||||
"X-Xss-Protection",
|
||||
|
||||
// Add new headers to be ignored.
|
||||
}
|
||||
|
||||
|
|
2
vendor/github.com/minio/minio-go/api.go
generated
vendored
2
vendor/github.com/minio/minio-go/api.go
generated
vendored
|
@ -99,7 +99,7 @@ type Options struct {
|
|||
// Global constants.
|
||||
const (
|
||||
libraryName = "minio-go"
|
||||
libraryVersion = "5.0.0"
|
||||
libraryVersion = "v6.0.5"
|
||||
)
|
||||
|
||||
// User Agent should always following the below style.
|
||||
|
|
210
vendor/github.com/minio/minio-go/api_unit_test.go
generated
vendored
210
vendor/github.com/minio/minio-go/api_unit_test.go
generated
vendored
|
@ -1,210 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/minio/minio-go/pkg/credentials"
|
||||
"github.com/minio/minio-go/pkg/policy"
|
||||
)
|
||||
|
||||
type customReader struct{}
|
||||
|
||||
func (c *customReader) Read(p []byte) (n int, err error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (c *customReader) Size() (n int64) {
|
||||
return 10
|
||||
}
|
||||
|
||||
// Tests valid hosts for location.
|
||||
func TestValidBucketLocation(t *testing.T) {
|
||||
s3Hosts := []struct {
|
||||
bucketLocation string
|
||||
endpoint string
|
||||
}{
|
||||
{"us-east-1", "s3.amazonaws.com"},
|
||||
{"unknown", "s3.amazonaws.com"},
|
||||
{"ap-southeast-1", "s3-ap-southeast-1.amazonaws.com"},
|
||||
}
|
||||
for _, s3Host := range s3Hosts {
|
||||
endpoint := getS3Endpoint(s3Host.bucketLocation)
|
||||
if endpoint != s3Host.endpoint {
|
||||
t.Fatal("Error: invalid bucket location", endpoint)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests error response structure.
|
||||
func TestErrorResponse(t *testing.T) {
|
||||
var err error
|
||||
err = ErrorResponse{
|
||||
Code: "Testing",
|
||||
}
|
||||
errResp := ToErrorResponse(err)
|
||||
if errResp.Code != "Testing" {
|
||||
t.Fatal("Type conversion failed, we have an empty struct.")
|
||||
}
|
||||
|
||||
// Test http response decoding.
|
||||
var httpResponse *http.Response
|
||||
// Set empty variables
|
||||
httpResponse = nil
|
||||
var bucketName, objectName string
|
||||
|
||||
// Should fail with invalid argument.
|
||||
err = httpRespToErrorResponse(httpResponse, bucketName, objectName)
|
||||
errResp = ToErrorResponse(err)
|
||||
if errResp.Code != "InvalidArgument" {
|
||||
t.Fatal("Empty response input should return invalid argument.")
|
||||
}
|
||||
}
|
||||
|
||||
// Tests signature type.
|
||||
func TestSignatureType(t *testing.T) {
|
||||
clnt := Client{}
|
||||
if !clnt.overrideSignerType.IsV4() {
|
||||
t.Fatal("Error")
|
||||
}
|
||||
clnt.overrideSignerType = credentials.SignatureV2
|
||||
if !clnt.overrideSignerType.IsV2() {
|
||||
t.Fatal("Error")
|
||||
}
|
||||
if clnt.overrideSignerType.IsV4() {
|
||||
t.Fatal("Error")
|
||||
}
|
||||
clnt.overrideSignerType = credentials.SignatureV4
|
||||
if !clnt.overrideSignerType.IsV4() {
|
||||
t.Fatal("Error")
|
||||
}
|
||||
}
|
||||
|
||||
// Tests bucket policy types.
|
||||
func TestBucketPolicyTypes(t *testing.T) {
|
||||
want := map[string]bool{
|
||||
"none": true,
|
||||
"readonly": true,
|
||||
"writeonly": true,
|
||||
"readwrite": true,
|
||||
"invalid": false,
|
||||
}
|
||||
for bucketPolicy, ok := range want {
|
||||
if policy.BucketPolicy(bucketPolicy).IsValidBucketPolicy() != ok {
|
||||
t.Fatal("Error")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests optimal part size.
|
||||
func TestPartSize(t *testing.T) {
|
||||
_, _, _, err := optimalPartInfo(5000000000000000000)
|
||||
if err == nil {
|
||||
t.Fatal("Error: should fail")
|
||||
}
|
||||
totalPartsCount, partSize, lastPartSize, err := optimalPartInfo(5497558138880)
|
||||
if err != nil {
|
||||
t.Fatal("Error: ", err)
|
||||
}
|
||||
if totalPartsCount != 9103 {
|
||||
t.Fatalf("Error: expecting total parts count of 9987: got %v instead", totalPartsCount)
|
||||
}
|
||||
if partSize != 603979776 {
|
||||
t.Fatalf("Error: expecting part size of 550502400: got %v instead", partSize)
|
||||
}
|
||||
if lastPartSize != 134217728 {
|
||||
t.Fatalf("Error: expecting last part size of 241172480: got %v instead", lastPartSize)
|
||||
}
|
||||
_, partSize, _, err = optimalPartInfo(5000000000)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err)
|
||||
}
|
||||
if partSize != minPartSize {
|
||||
t.Fatalf("Error: expecting part size of %v: got %v instead", minPartSize, partSize)
|
||||
}
|
||||
totalPartsCount, partSize, lastPartSize, err = optimalPartInfo(-1)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err)
|
||||
}
|
||||
if totalPartsCount != 9103 {
|
||||
t.Fatalf("Error: expecting total parts count of 9987: got %v instead", totalPartsCount)
|
||||
}
|
||||
if partSize != 603979776 {
|
||||
t.Fatalf("Error: expecting part size of 550502400: got %v instead", partSize)
|
||||
}
|
||||
if lastPartSize != 134217728 {
|
||||
t.Fatalf("Error: expecting last part size of 241172480: got %v instead", lastPartSize)
|
||||
}
|
||||
}
|
||||
|
||||
// TestMakeTargetURL - testing makeTargetURL()
|
||||
func TestMakeTargetURL(t *testing.T) {
|
||||
testCases := []struct {
|
||||
addr string
|
||||
secure bool
|
||||
bucketName string
|
||||
objectName string
|
||||
bucketLocation string
|
||||
queryValues map[string][]string
|
||||
expectedURL url.URL
|
||||
expectedErr error
|
||||
}{
|
||||
// Test 1
|
||||
{"localhost:9000", false, "", "", "", nil, url.URL{Host: "localhost:9000", Scheme: "http", Path: "/"}, nil},
|
||||
// Test 2
|
||||
{"localhost", true, "", "", "", nil, url.URL{Host: "localhost", Scheme: "https", Path: "/"}, nil},
|
||||
// Test 3
|
||||
{"localhost:9000", true, "mybucket", "", "", nil, url.URL{Host: "localhost:9000", Scheme: "https", Path: "/mybucket/"}, nil},
|
||||
// Test 4, testing against google storage API
|
||||
{"storage.googleapis.com", true, "mybucket", "", "", nil, url.URL{Host: "mybucket.storage.googleapis.com", Scheme: "https", Path: "/"}, nil},
|
||||
// Test 5, testing against AWS S3 API
|
||||
{"s3.amazonaws.com", true, "mybucket", "myobject", "", nil, url.URL{Host: "mybucket.s3.amazonaws.com", Scheme: "https", Path: "/myobject"}, nil},
|
||||
// Test 6
|
||||
{"localhost:9000", false, "mybucket", "myobject", "", nil, url.URL{Host: "localhost:9000", Scheme: "http", Path: "/mybucket/myobject"}, nil},
|
||||
// Test 7, testing with query
|
||||
{"localhost:9000", false, "mybucket", "myobject", "", map[string][]string{"param": {"val"}}, url.URL{Host: "localhost:9000", Scheme: "http", Path: "/mybucket/myobject", RawQuery: "param=val"}, nil},
|
||||
// Test 8, testing with port 80
|
||||
{"localhost:80", false, "mybucket", "myobject", "", nil, url.URL{Host: "localhost", Scheme: "http", Path: "/mybucket/myobject"}, nil},
|
||||
// Test 9, testing with port 443
|
||||
{"localhost:443", true, "mybucket", "myobject", "", nil, url.URL{Host: "localhost", Scheme: "https", Path: "/mybucket/myobject"}, nil},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
// Initialize a Minio client
|
||||
c, _ := New(testCase.addr, "foo", "bar", testCase.secure)
|
||||
isVirtualHost := c.isVirtualHostStyleRequest(*c.endpointURL, testCase.bucketName)
|
||||
u, err := c.makeTargetURL(testCase.bucketName, testCase.objectName, testCase.bucketLocation, isVirtualHost, testCase.queryValues)
|
||||
// Check the returned error
|
||||
if testCase.expectedErr == nil && err != nil {
|
||||
t.Fatalf("Test %d: Should succeed but failed with err = %v", i+1, err)
|
||||
}
|
||||
if testCase.expectedErr != nil && err == nil {
|
||||
t.Fatalf("Test %d: Should fail but succeeded", i+1)
|
||||
}
|
||||
if err == nil {
|
||||
// Check if the returned url is equal to what we expect
|
||||
if u.String() != testCase.expectedURL.String() {
|
||||
t.Fatalf("Test %d: Mismatched target url: expected = `%v`, found = `%v`",
|
||||
i+1, testCase.expectedURL.String(), u.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
351
vendor/github.com/minio/minio-go/bucket-cache_test.go
generated
vendored
351
vendor/github.com/minio/minio-go/bucket-cache_test.go
generated
vendored
|
@ -1,351 +0,0 @@
|
|||
/*
|
||||
* Copyright
|
||||
* 2015, 2016, 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.
|
||||
* 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"
|
||||
"encoding/xml"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/minio/minio-go/pkg/credentials"
|
||||
"github.com/minio/minio-go/pkg/s3signer"
|
||||
)
|
||||
|
||||
// Test validates `newBucketLocationCache`.
|
||||
func TestNewBucketLocationCache(t *testing.T) {
|
||||
expectedBucketLocationcache := &bucketLocationCache{
|
||||
items: make(map[string]string),
|
||||
}
|
||||
actualBucketLocationCache := newBucketLocationCache()
|
||||
|
||||
if !reflect.DeepEqual(actualBucketLocationCache, expectedBucketLocationcache) {
|
||||
t.Errorf("Unexpected return value")
|
||||
}
|
||||
}
|
||||
|
||||
// Tests validate bucketLocationCache operations.
|
||||
func TestBucketLocationCacheOps(t *testing.T) {
|
||||
testBucketLocationCache := newBucketLocationCache()
|
||||
expectedBucketName := "minio-bucket"
|
||||
expectedLocation := "us-east-1"
|
||||
testBucketLocationCache.Set(expectedBucketName, expectedLocation)
|
||||
actualLocation, ok := testBucketLocationCache.Get(expectedBucketName)
|
||||
if !ok {
|
||||
t.Errorf("Bucket location cache not set")
|
||||
}
|
||||
if expectedLocation != actualLocation {
|
||||
t.Errorf("Bucket location cache not set to expected value")
|
||||
}
|
||||
testBucketLocationCache.Delete(expectedBucketName)
|
||||
_, ok = testBucketLocationCache.Get(expectedBucketName)
|
||||
if ok {
|
||||
t.Errorf("Bucket location cache not deleted as expected")
|
||||
}
|
||||
}
|
||||
|
||||
// Tests validate http request generation for 'getBucketLocation'.
|
||||
func TestGetBucketLocationRequest(t *testing.T) {
|
||||
// Generates expected http request for getBucketLocation.
|
||||
// Used for asserting with the actual request generated.
|
||||
createExpectedRequest := func(c *Client, bucketName string, req *http.Request) (*http.Request, error) {
|
||||
// Set location query.
|
||||
urlValues := make(url.Values)
|
||||
urlValues.Set("location", "")
|
||||
|
||||
// Set get bucket location always as path style.
|
||||
targetURL := c.endpointURL
|
||||
targetURL.Path = path.Join(bucketName, "") + "/"
|
||||
targetURL.RawQuery = urlValues.Encode()
|
||||
|
||||
// Get a new HTTP request for the method.
|
||||
var err error
|
||||
req, err = http.NewRequest("GET", targetURL.String(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set UserAgent for the request.
|
||||
c.setUserAgent(req)
|
||||
|
||||
// Get credentials from the configured credentials provider.
|
||||
value, err := c.credsProvider.Get()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var (
|
||||
signerType = value.SignerType
|
||||
accessKeyID = value.AccessKeyID
|
||||
secretAccessKey = value.SecretAccessKey
|
||||
sessionToken = value.SessionToken
|
||||
)
|
||||
|
||||
// Custom signer set then override the behavior.
|
||||
if c.overrideSignerType != credentials.SignatureDefault {
|
||||
signerType = c.overrideSignerType
|
||||
}
|
||||
|
||||
// If signerType returned by credentials helper is anonymous,
|
||||
// then do not sign regardless of signerType override.
|
||||
if value.SignerType == credentials.SignatureAnonymous {
|
||||
signerType = credentials.SignatureAnonymous
|
||||
}
|
||||
|
||||
// Set sha256 sum for signature calculation only
|
||||
// with signature version '4'.
|
||||
switch {
|
||||
case signerType.IsV4():
|
||||
contentSha256 := emptySHA256Hex
|
||||
if c.secure {
|
||||
contentSha256 = unsignedPayload
|
||||
}
|
||||
req.Header.Set("X-Amz-Content-Sha256", contentSha256)
|
||||
req = s3signer.SignV4(*req, accessKeyID, secretAccessKey, sessionToken, "us-east-1")
|
||||
case signerType.IsV2():
|
||||
req = s3signer.SignV2(*req, accessKeyID, secretAccessKey, false)
|
||||
}
|
||||
|
||||
return req, nil
|
||||
|
||||
}
|
||||
// Info for 'Client' creation.
|
||||
// Will be used as arguments for 'NewClient'.
|
||||
type infoForClient struct {
|
||||
endPoint string
|
||||
accessKey string
|
||||
secretKey string
|
||||
enableInsecure bool
|
||||
}
|
||||
// dataset for 'NewClient' call.
|
||||
info := []infoForClient{
|
||||
// endpoint localhost.
|
||||
// both access-key and secret-key are empty.
|
||||
{"localhost:9000", "", "", false},
|
||||
// both access-key are secret-key exists.
|
||||
{"localhost:9000", "my-access-key", "my-secret-key", false},
|
||||
// one of acess-key and secret-key are empty.
|
||||
{"localhost:9000", "", "my-secret-key", false},
|
||||
|
||||
// endpoint amazon s3.
|
||||
{"s3.amazonaws.com", "", "", false},
|
||||
{"s3.amazonaws.com", "my-access-key", "my-secret-key", false},
|
||||
{"s3.amazonaws.com", "my-acess-key", "", false},
|
||||
|
||||
// endpoint google cloud storage.
|
||||
{"storage.googleapis.com", "", "", false},
|
||||
{"storage.googleapis.com", "my-access-key", "my-secret-key", false},
|
||||
{"storage.googleapis.com", "", "my-secret-key", false},
|
||||
|
||||
// endpoint custom domain running Minio server.
|
||||
{"play.minio.io", "", "", false},
|
||||
{"play.minio.io", "my-access-key", "my-secret-key", false},
|
||||
{"play.minio.io", "my-acess-key", "", false},
|
||||
}
|
||||
testCases := []struct {
|
||||
bucketName string
|
||||
// data for new client creation.
|
||||
info infoForClient
|
||||
// error in the output.
|
||||
err error
|
||||
// flag indicating whether tests should pass.
|
||||
shouldPass bool
|
||||
}{
|
||||
// Client is constructed using the info struct.
|
||||
// case with empty location.
|
||||
{"my-bucket", info[0], nil, true},
|
||||
// case with location set to standard 'us-east-1'.
|
||||
{"my-bucket", info[0], nil, true},
|
||||
// case with location set to a value different from 'us-east-1'.
|
||||
{"my-bucket", info[0], nil, true},
|
||||
|
||||
{"my-bucket", info[1], nil, true},
|
||||
{"my-bucket", info[1], nil, true},
|
||||
{"my-bucket", info[1], nil, true},
|
||||
|
||||
{"my-bucket", info[2], nil, true},
|
||||
{"my-bucket", info[2], nil, true},
|
||||
{"my-bucket", info[2], nil, true},
|
||||
|
||||
{"my-bucket", info[3], nil, true},
|
||||
{"my-bucket", info[3], nil, true},
|
||||
{"my-bucket", info[3], nil, true},
|
||||
|
||||
{"my-bucket", info[4], nil, true},
|
||||
{"my-bucket", info[4], nil, true},
|
||||
{"my-bucket", info[4], nil, true},
|
||||
|
||||
{"my-bucket", info[5], nil, true},
|
||||
{"my-bucket", info[5], nil, true},
|
||||
{"my-bucket", info[5], nil, true},
|
||||
|
||||
{"my-bucket", info[6], nil, true},
|
||||
{"my-bucket", info[6], nil, true},
|
||||
{"my-bucket", info[6], nil, true},
|
||||
|
||||
{"my-bucket", info[7], nil, true},
|
||||
{"my-bucket", info[7], nil, true},
|
||||
{"my-bucket", info[7], nil, true},
|
||||
|
||||
{"my-bucket", info[8], nil, true},
|
||||
{"my-bucket", info[8], nil, true},
|
||||
{"my-bucket", info[8], nil, true},
|
||||
|
||||
{"my-bucket", info[9], nil, true},
|
||||
{"my-bucket", info[9], nil, true},
|
||||
{"my-bucket", info[9], nil, true},
|
||||
|
||||
{"my-bucket", info[10], nil, true},
|
||||
{"my-bucket", info[10], nil, true},
|
||||
{"my-bucket", info[10], nil, true},
|
||||
|
||||
{"my-bucket", info[11], nil, true},
|
||||
{"my-bucket", info[11], nil, true},
|
||||
{"my-bucket", info[11], nil, true},
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
// cannot create a newclient with empty endPoint value.
|
||||
// validates and creates a new client only if the endPoint value is not empty.
|
||||
client := &Client{}
|
||||
var err error
|
||||
if testCase.info.endPoint != "" {
|
||||
|
||||
client, err = New(testCase.info.endPoint, testCase.info.accessKey, testCase.info.secretKey, testCase.info.enableInsecure)
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d: Failed to create new Client: %s", i+1, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
actualReq, err := client.getBucketLocationRequest(testCase.bucketName)
|
||||
if err != nil && testCase.shouldPass {
|
||||
t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, err.Error())
|
||||
}
|
||||
if err == nil && !testCase.shouldPass {
|
||||
t.Errorf("Test %d: Expected to fail with <ERROR> \"%s\", but passed instead", i+1, testCase.err.Error())
|
||||
}
|
||||
// Failed as expected, but does it fail for the expected reason.
|
||||
if err != nil && !testCase.shouldPass {
|
||||
if err.Error() != testCase.err.Error() {
|
||||
t.Errorf("Test %d: Expected to fail with error \"%s\", but instead failed with error \"%s\" instead", i+1, testCase.err.Error(), err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// Test passes as expected, but the output values are verified for correctness here.
|
||||
if err == nil && testCase.shouldPass {
|
||||
expectedReq := &http.Request{}
|
||||
expectedReq, err = createExpectedRequest(client, testCase.bucketName, expectedReq)
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d: Expected request Creation failed", i+1)
|
||||
}
|
||||
if expectedReq.Method != actualReq.Method {
|
||||
t.Errorf("Test %d: The expected Request method doesn't match with the actual one", i+1)
|
||||
}
|
||||
if expectedReq.URL.String() != actualReq.URL.String() {
|
||||
t.Errorf("Test %d: Expected the request URL to be '%s', but instead found '%s'", i+1, expectedReq.URL.String(), actualReq.URL.String())
|
||||
}
|
||||
if expectedReq.ContentLength != actualReq.ContentLength {
|
||||
t.Errorf("Test %d: Expected the request body Content-Length to be '%d', but found '%d' instead", i+1, expectedReq.ContentLength, actualReq.ContentLength)
|
||||
}
|
||||
|
||||
if expectedReq.Header.Get("X-Amz-Content-Sha256") != actualReq.Header.Get("X-Amz-Content-Sha256") {
|
||||
t.Errorf("Test %d: 'X-Amz-Content-Sha256' header of the expected request doesn't match with that of the actual request", i+1)
|
||||
}
|
||||
if expectedReq.Header.Get("User-Agent") != actualReq.Header.Get("User-Agent") {
|
||||
t.Errorf("Test %d: Expected 'User-Agent' header to be \"%s\",but found \"%s\" instead", i+1, expectedReq.Header.Get("User-Agent"), actualReq.Header.Get("User-Agent"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// generates http response with bucket location set in the body.
|
||||
func generateLocationResponse(resp *http.Response, bodyContent []byte) (*http.Response, error) {
|
||||
resp.StatusCode = http.StatusOK
|
||||
resp.Body = ioutil.NopCloser(bytes.NewBuffer(bodyContent))
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Tests the processing of GetPolicy response from server.
|
||||
func TestProcessBucketLocationResponse(t *testing.T) {
|
||||
// LocationResponse - format for location response.
|
||||
type LocationResponse struct {
|
||||
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LocationConstraint" json:"-"`
|
||||
Location string `xml:",chardata"`
|
||||
}
|
||||
|
||||
APIErrors := []APIError{
|
||||
{
|
||||
Code: "AccessDenied",
|
||||
Description: "Access Denied",
|
||||
HTTPStatusCode: http.StatusUnauthorized,
|
||||
},
|
||||
}
|
||||
testCases := []struct {
|
||||
bucketName string
|
||||
inputLocation string
|
||||
isAPIError bool
|
||||
apiErr APIError
|
||||
// expected results.
|
||||
expectedResult string
|
||||
err error
|
||||
// flag indicating whether tests should pass.
|
||||
shouldPass bool
|
||||
}{
|
||||
{"my-bucket", "", true, APIErrors[0], "us-east-1", nil, true},
|
||||
{"my-bucket", "", false, APIError{}, "us-east-1", nil, true},
|
||||
{"my-bucket", "EU", false, APIError{}, "eu-west-1", nil, true},
|
||||
{"my-bucket", "eu-central-1", false, APIError{}, "eu-central-1", nil, true},
|
||||
{"my-bucket", "us-east-1", false, APIError{}, "us-east-1", nil, true},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
inputResponse := &http.Response{}
|
||||
var err error
|
||||
if testCase.isAPIError {
|
||||
inputResponse = generateErrorResponse(inputResponse, testCase.apiErr, testCase.bucketName)
|
||||
} else {
|
||||
inputResponse, err = generateLocationResponse(inputResponse, encodeResponse(LocationResponse{
|
||||
Location: testCase.inputLocation,
|
||||
}))
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d: Creation of valid response failed", i+1)
|
||||
}
|
||||
}
|
||||
actualResult, err := processBucketLocationResponse(inputResponse, "my-bucket")
|
||||
if err != nil && testCase.shouldPass {
|
||||
t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, err.Error())
|
||||
}
|
||||
if err == nil && !testCase.shouldPass {
|
||||
t.Errorf("Test %d: Expected to fail with <ERROR> \"%s\", but passed instead", i+1, testCase.err.Error())
|
||||
}
|
||||
// Failed as expected, but does it fail for the expected reason.
|
||||
if err != nil && !testCase.shouldPass {
|
||||
if err.Error() != testCase.err.Error() {
|
||||
t.Errorf("Test %d: Expected to fail with error \"%s\", but instead failed with error \"%s\" instead", i+1, testCase.err.Error(), err.Error())
|
||||
}
|
||||
}
|
||||
if err == nil && testCase.shouldPass {
|
||||
if !reflect.DeepEqual(testCase.expectedResult, actualResult) {
|
||||
t.Errorf("Test %d: The expected BucketPolicy doesn't match the actual BucketPolicy", i+1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
7
vendor/github.com/minio/minio-go/constants.go
generated
vendored
7
vendor/github.com/minio/minio-go/constants.go
generated
vendored
|
@ -27,10 +27,6 @@ const absMinPartSize = 1024 * 1024 * 5
|
|||
// putObject behaves internally as multipart.
|
||||
const minPartSize = 1024 * 1024 * 64
|
||||
|
||||
// copyPartSize - default (and maximum) part size to copy in a
|
||||
// copy-object request (5GiB)
|
||||
const copyPartSize = 1024 * 1024 * 1024 * 5
|
||||
|
||||
// maxPartsCount - maximum number of parts for a single multipart session.
|
||||
const maxPartsCount = 10000
|
||||
|
||||
|
@ -61,3 +57,6 @@ const (
|
|||
|
||||
// Storage class header constant.
|
||||
const amzStorageClass = "X-Amz-Storage-Class"
|
||||
|
||||
// Website redirect location header constant
|
||||
const amzWebsiteRedirectLocation = "X-Amz-Website-Redirect-Location"
|
||||
|
|
14
vendor/github.com/minio/minio-go/core.go
generated
vendored
14
vendor/github.com/minio/minio-go/core.go
generated
vendored
|
@ -21,8 +21,6 @@ import (
|
|||
"context"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/minio/minio-go/pkg/policy"
|
||||
)
|
||||
|
||||
// Core - Inherits Client and adds new methods to expose the low level S3 APIs.
|
||||
|
@ -50,9 +48,9 @@ func (c Core) ListObjects(bucket, prefix, marker, delimiter string, maxKeys int)
|
|||
}
|
||||
|
||||
// ListObjectsV2 - Lists all the objects at a prefix, similar to ListObjects() but uses
|
||||
// continuationToken instead of marker to further filter the results.
|
||||
func (c Core) ListObjectsV2(bucketName, objectPrefix, continuationToken string, fetchOwner bool, delimiter string, maxkeys int) (ListBucketV2Result, error) {
|
||||
return c.listObjectsV2Query(bucketName, objectPrefix, continuationToken, fetchOwner, delimiter, maxkeys)
|
||||
// continuationToken instead of marker to support iteration over the results.
|
||||
func (c Core) ListObjectsV2(bucketName, objectPrefix, continuationToken string, fetchOwner bool, delimiter string, maxkeys int, startAfter string) (ListBucketV2Result, error) {
|
||||
return c.listObjectsV2Query(bucketName, objectPrefix, continuationToken, fetchOwner, delimiter, maxkeys, startAfter)
|
||||
}
|
||||
|
||||
// CopyObject - copies an object from source object to destination object on server side.
|
||||
|
@ -84,6 +82,8 @@ func (c Core) PutObject(bucket, object string, data io.Reader, size int64, md5Ba
|
|||
opts.ContentType = v
|
||||
} else if strings.ToLower(k) == "cache-control" {
|
||||
opts.CacheControl = v
|
||||
} else if strings.ToLower(k) == strings.ToLower(amzWebsiteRedirectLocation) {
|
||||
opts.WebsiteRedirectLocation = v
|
||||
} else {
|
||||
m[k] = metadata[k]
|
||||
}
|
||||
|
@ -127,12 +127,12 @@ func (c Core) AbortMultipartUpload(bucket, object, uploadID string) error {
|
|||
}
|
||||
|
||||
// GetBucketPolicy - fetches bucket access policy for a given bucket.
|
||||
func (c Core) GetBucketPolicy(bucket string) (policy.BucketAccessPolicy, error) {
|
||||
func (c Core) GetBucketPolicy(bucket string) (string, error) {
|
||||
return c.getBucketPolicy(bucket)
|
||||
}
|
||||
|
||||
// PutBucketPolicy - applies a new bucket access policy for a given bucket.
|
||||
func (c Core) PutBucketPolicy(bucket string, bucketPolicy policy.BucketAccessPolicy) error {
|
||||
func (c Core) PutBucketPolicy(bucket, bucketPolicy string) error {
|
||||
return c.putBucketPolicy(bucket, bucketPolicy)
|
||||
}
|
||||
|
||||
|
|
771
vendor/github.com/minio/minio-go/core_test.go
generated
vendored
771
vendor/github.com/minio/minio-go/core_test.go
generated
vendored
|
@ -1,771 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
const (
|
||||
serverEndpoint = "SERVER_ENDPOINT"
|
||||
accessKey = "ACCESS_KEY"
|
||||
secretKey = "SECRET_KEY"
|
||||
enableSecurity = "ENABLE_HTTPS"
|
||||
)
|
||||
|
||||
// Minimum part size
|
||||
const MinPartSize = 1024 * 1024 * 64
|
||||
const letterBytes = "abcdefghijklmnopqrstuvwxyz01234569"
|
||||
const (
|
||||
letterIdxBits = 6 // 6 bits to represent a letter index
|
||||
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
|
||||
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
|
||||
)
|
||||
|
||||
// randString generates random names and prepends them with a known prefix.
|
||||
func randString(n int, src rand.Source, prefix string) string {
|
||||
b := make([]byte, n)
|
||||
// A rand.Int63() generates 63 random bits, enough for letterIdxMax letters!
|
||||
for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; {
|
||||
if remain == 0 {
|
||||
cache, remain = src.Int63(), letterIdxMax
|
||||
}
|
||||
if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
|
||||
b[i] = letterBytes[idx]
|
||||
i--
|
||||
}
|
||||
cache >>= letterIdxBits
|
||||
remain--
|
||||
}
|
||||
return prefix + string(b[0:30-len(prefix)])
|
||||
}
|
||||
|
||||
// Tests for Core GetObject() function.
|
||||
func TestGetObjectCore(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping functional tests for the short runs")
|
||||
}
|
||||
|
||||
// Seed random based on current time.
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
// Instantiate new minio core client object.
|
||||
c, err := NewCore(
|
||||
os.Getenv(serverEndpoint),
|
||||
os.Getenv(accessKey),
|
||||
os.Getenv(secretKey),
|
||||
mustParseBool(os.Getenv(enableSecurity)),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err)
|
||||
}
|
||||
|
||||
// Enable tracing, write to stderr.
|
||||
// c.TraceOn(os.Stderr)
|
||||
|
||||
// Set user agent.
|
||||
c.SetAppInfo("Minio-go-FunctionalTest", "0.1.0")
|
||||
|
||||
// Generate a new random bucket name.
|
||||
bucketName := randString(60, rand.NewSource(time.Now().UnixNano()), "minio-go-test")
|
||||
|
||||
// Make a new bucket.
|
||||
err = c.MakeBucket(bucketName, "us-east-1")
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, bucketName)
|
||||
}
|
||||
|
||||
// Generate data more than 32K
|
||||
buf := bytes.Repeat([]byte("3"), rand.Intn(1<<20)+32*1024)
|
||||
|
||||
// Save the data
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
n, err := c.Client.PutObject(bucketName, objectName, bytes.NewReader(buf), int64(len(buf)), PutObjectOptions{
|
||||
ContentType: "binary/octet-stream",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, bucketName, objectName)
|
||||
}
|
||||
|
||||
if n != int64(len(buf)) {
|
||||
t.Fatalf("Error: number of bytes does not match, want %v, got %v\n", len(buf), n)
|
||||
}
|
||||
|
||||
offset := int64(2048)
|
||||
|
||||
// read directly
|
||||
buf1 := make([]byte, 512)
|
||||
buf2 := make([]byte, 512)
|
||||
buf3 := make([]byte, n)
|
||||
buf4 := make([]byte, 1)
|
||||
|
||||
opts := GetObjectOptions{}
|
||||
opts.SetRange(offset, offset+int64(len(buf1))-1)
|
||||
reader, objectInfo, err := c.GetObject(bucketName, objectName, opts)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
m, err := io.ReadFull(reader, buf1)
|
||||
reader.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if objectInfo.Size != int64(m) {
|
||||
t.Fatalf("Error: GetObject read shorter bytes before reaching EOF, want %v, got %v\n", objectInfo.Size, m)
|
||||
}
|
||||
if !bytes.Equal(buf1, buf[offset:offset+512]) {
|
||||
t.Fatal("Error: Incorrect read between two GetObject from same offset.")
|
||||
}
|
||||
offset += 512
|
||||
|
||||
opts.SetRange(offset, offset+int64(len(buf2))-1)
|
||||
reader, objectInfo, err = c.GetObject(bucketName, objectName, opts)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
m, err = io.ReadFull(reader, buf2)
|
||||
reader.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if objectInfo.Size != int64(m) {
|
||||
t.Fatalf("Error: GetObject read shorter bytes before reaching EOF, want %v, got %v\n", objectInfo.Size, m)
|
||||
}
|
||||
if !bytes.Equal(buf2, buf[offset:offset+512]) {
|
||||
t.Fatal("Error: Incorrect read between two GetObject from same offset.")
|
||||
}
|
||||
|
||||
opts.SetRange(0, int64(len(buf3)))
|
||||
reader, objectInfo, err = c.GetObject(bucketName, objectName, opts)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
m, err = io.ReadFull(reader, buf3)
|
||||
if err != nil {
|
||||
reader.Close()
|
||||
t.Fatal(err)
|
||||
}
|
||||
reader.Close()
|
||||
|
||||
if objectInfo.Size != int64(m) {
|
||||
t.Fatalf("Error: GetObject read shorter bytes before reaching EOF, want %v, got %v\n", objectInfo.Size, m)
|
||||
}
|
||||
if !bytes.Equal(buf3, buf) {
|
||||
t.Fatal("Error: Incorrect data read in GetObject, than what was previously upoaded.")
|
||||
}
|
||||
|
||||
opts = GetObjectOptions{}
|
||||
opts.SetMatchETag("etag")
|
||||
_, _, err = c.GetObject(bucketName, objectName, opts)
|
||||
if err == nil {
|
||||
t.Fatal("Unexpected GetObject should fail with mismatching etags")
|
||||
}
|
||||
if errResp := ToErrorResponse(err); errResp.Code != "PreconditionFailed" {
|
||||
t.Fatalf("Expected \"PreconditionFailed\" as code, got %s instead", errResp.Code)
|
||||
}
|
||||
|
||||
opts = GetObjectOptions{}
|
||||
opts.SetMatchETagExcept("etag")
|
||||
reader, objectInfo, err = c.GetObject(bucketName, objectName, opts)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
m, err = io.ReadFull(reader, buf3)
|
||||
reader.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if objectInfo.Size != int64(m) {
|
||||
t.Fatalf("Error: GetObject read shorter bytes before reaching EOF, want %v, got %v\n", objectInfo.Size, m)
|
||||
}
|
||||
if !bytes.Equal(buf3, buf) {
|
||||
t.Fatal("Error: Incorrect data read in GetObject, than what was previously upoaded.")
|
||||
}
|
||||
|
||||
opts = GetObjectOptions{}
|
||||
opts.SetRange(0, 0)
|
||||
reader, objectInfo, err = c.GetObject(bucketName, objectName, opts)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
m, err = io.ReadFull(reader, buf4)
|
||||
reader.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if objectInfo.Size != int64(m) {
|
||||
t.Fatalf("Error: GetObject read shorter bytes before reaching EOF, want %v, got %v\n", objectInfo.Size, m)
|
||||
}
|
||||
|
||||
err = c.RemoveObject(bucketName, objectName)
|
||||
if err != nil {
|
||||
t.Fatal("Error: ", err)
|
||||
}
|
||||
err = c.RemoveBucket(bucketName)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Tests GetObject to return Content-Encoding properly set
|
||||
// and overrides any auto decoding.
|
||||
func TestGetObjectContentEncoding(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping functional tests for the short runs")
|
||||
}
|
||||
|
||||
// Seed random based on current time.
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
// Instantiate new minio core client object.
|
||||
c, err := NewCore(
|
||||
os.Getenv(serverEndpoint),
|
||||
os.Getenv(accessKey),
|
||||
os.Getenv(secretKey),
|
||||
mustParseBool(os.Getenv(enableSecurity)),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err)
|
||||
}
|
||||
|
||||
// Enable tracing, write to stderr.
|
||||
// c.TraceOn(os.Stderr)
|
||||
|
||||
// Set user agent.
|
||||
c.SetAppInfo("Minio-go-FunctionalTest", "0.1.0")
|
||||
|
||||
// Generate a new random bucket name.
|
||||
bucketName := randString(60, rand.NewSource(time.Now().UnixNano()), "minio-go-test")
|
||||
|
||||
// Make a new bucket.
|
||||
err = c.MakeBucket(bucketName, "us-east-1")
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, bucketName)
|
||||
}
|
||||
|
||||
// Generate data more than 32K
|
||||
buf := bytes.Repeat([]byte("3"), rand.Intn(1<<20)+32*1024)
|
||||
|
||||
// Save the data
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
n, err := c.Client.PutObject(bucketName, objectName, bytes.NewReader(buf), int64(len(buf)), PutObjectOptions{
|
||||
ContentEncoding: "gzip",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, bucketName, objectName)
|
||||
}
|
||||
|
||||
if n != int64(len(buf)) {
|
||||
t.Fatalf("Error: number of bytes does not match, want %v, got %v\n", len(buf), n)
|
||||
}
|
||||
|
||||
rwc, objInfo, err := c.GetObject(bucketName, objectName, GetObjectOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("Error: %v", err)
|
||||
}
|
||||
rwc.Close()
|
||||
if objInfo.Size <= 0 {
|
||||
t.Fatalf("Unexpected size of the object %v, expected %v", objInfo.Size, n)
|
||||
}
|
||||
value, ok := objInfo.Metadata["Content-Encoding"]
|
||||
if !ok {
|
||||
t.Fatalf("Expected Content-Encoding metadata to be set.")
|
||||
}
|
||||
if value[0] != "gzip" {
|
||||
t.Fatalf("Unexpected content-encoding found, want gzip, got %v", value)
|
||||
}
|
||||
}
|
||||
|
||||
// Tests get bucket policy core API.
|
||||
func TestGetBucketPolicy(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping functional tests for short runs")
|
||||
}
|
||||
|
||||
// Seed random based on current time.
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
// Instantiate new minio client object.
|
||||
c, err := NewCore(
|
||||
os.Getenv(serverEndpoint),
|
||||
os.Getenv(accessKey),
|
||||
os.Getenv(secretKey),
|
||||
mustParseBool(os.Getenv(enableSecurity)),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err)
|
||||
}
|
||||
|
||||
// Enable to debug
|
||||
// c.TraceOn(os.Stderr)
|
||||
|
||||
// Set user agent.
|
||||
c.SetAppInfo("Minio-go-FunctionalTest", "0.1.0")
|
||||
|
||||
// Generate a new random bucket name.
|
||||
bucketName := randString(60, rand.NewSource(time.Now().UnixNano()), "minio-go-test")
|
||||
|
||||
// Make a new bucket.
|
||||
err = c.MakeBucket(bucketName, "us-east-1")
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, bucketName)
|
||||
}
|
||||
|
||||
// Verify if bucket exits and you have access.
|
||||
var exists bool
|
||||
exists, err = c.BucketExists(bucketName)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, bucketName)
|
||||
}
|
||||
if !exists {
|
||||
t.Fatal("Error: could not find ", bucketName)
|
||||
}
|
||||
|
||||
// Asserting the default bucket policy.
|
||||
bucketPolicy, err := c.GetBucketPolicy(bucketName)
|
||||
if err != nil {
|
||||
errResp := ToErrorResponse(err)
|
||||
if errResp.Code != "NoSuchBucketPolicy" {
|
||||
t.Error("Error:", err, bucketName)
|
||||
}
|
||||
}
|
||||
if !reflect.DeepEqual(bucketPolicy, emptyBucketAccessPolicy) {
|
||||
t.Errorf("Bucket policy expected %#v, got %#v", emptyBucketAccessPolicy, bucketPolicy)
|
||||
}
|
||||
|
||||
err = c.RemoveBucket(bucketName)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Tests Core CopyObject API implementation.
|
||||
func TestCoreCopyObject(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping functional tests for short runs")
|
||||
}
|
||||
|
||||
// Seed random based on current time.
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
// Instantiate new minio client object.
|
||||
c, err := NewCore(
|
||||
os.Getenv(serverEndpoint),
|
||||
os.Getenv(accessKey),
|
||||
os.Getenv(secretKey),
|
||||
mustParseBool(os.Getenv(enableSecurity)),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err)
|
||||
}
|
||||
|
||||
// Enable tracing, write to stderr.
|
||||
// c.TraceOn(os.Stderr)
|
||||
|
||||
// Set user agent.
|
||||
c.SetAppInfo("Minio-go-FunctionalTest", "0.1.0")
|
||||
|
||||
// Generate a new random bucket name.
|
||||
bucketName := randString(60, rand.NewSource(time.Now().UnixNano()), "minio-go-test")
|
||||
|
||||
// Make a new bucket.
|
||||
err = c.MakeBucket(bucketName, "us-east-1")
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, bucketName)
|
||||
}
|
||||
|
||||
buf := bytes.Repeat([]byte("a"), 32*1024)
|
||||
|
||||
// Save the data
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
objInfo, err := c.PutObject(bucketName, objectName, bytes.NewReader(buf), int64(len(buf)), "", "", map[string]string{
|
||||
"Content-Type": "binary/octet-stream",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, bucketName, objectName)
|
||||
}
|
||||
|
||||
if objInfo.Size != int64(len(buf)) {
|
||||
t.Fatalf("Error: number of bytes does not match, want %v, got %v\n", len(buf), objInfo.Size)
|
||||
}
|
||||
|
||||
destBucketName := bucketName
|
||||
destObjectName := objectName + "-dest"
|
||||
|
||||
cobjInfo, err := c.CopyObject(bucketName, objectName, destBucketName, destObjectName, map[string]string{
|
||||
"X-Amz-Metadata-Directive": "REPLACE",
|
||||
"Content-Type": "application/javascript",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, bucketName, objectName, destBucketName, destObjectName)
|
||||
}
|
||||
if cobjInfo.ETag != objInfo.ETag {
|
||||
t.Fatalf("Error: expected etag to be same as source object %s, but found different etag :%s", objInfo.ETag, cobjInfo.ETag)
|
||||
}
|
||||
|
||||
// Attempt to read from destBucketName and object name.
|
||||
r, err := c.Client.GetObject(destBucketName, destObjectName, GetObjectOptions{})
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, bucketName, objectName)
|
||||
}
|
||||
|
||||
st, err := r.Stat()
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, bucketName, objectName)
|
||||
}
|
||||
|
||||
if st.Size != int64(len(buf)) {
|
||||
t.Fatalf("Error: number of bytes in stat does not match, want %v, got %v\n",
|
||||
len(buf), st.Size)
|
||||
}
|
||||
|
||||
if st.ContentType != "application/javascript" {
|
||||
t.Fatalf("Error: Content types don't match, expected: application/javascript, found: %+v\n", st.ContentType)
|
||||
}
|
||||
|
||||
if st.ETag != objInfo.ETag {
|
||||
t.Fatalf("Error: expected etag to be same as source object %s, but found different etag :%s", objInfo.ETag, st.ETag)
|
||||
}
|
||||
|
||||
if err := r.Close(); err != nil {
|
||||
t.Fatal("Error:", err)
|
||||
}
|
||||
|
||||
if err := r.Close(); err == nil {
|
||||
t.Fatal("Error: object is already closed, should return error")
|
||||
}
|
||||
|
||||
err = c.RemoveObject(bucketName, objectName)
|
||||
if err != nil {
|
||||
t.Fatal("Error: ", err)
|
||||
}
|
||||
|
||||
err = c.RemoveObject(destBucketName, destObjectName)
|
||||
if err != nil {
|
||||
t.Fatal("Error: ", err)
|
||||
}
|
||||
|
||||
err = c.RemoveBucket(bucketName)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err)
|
||||
}
|
||||
|
||||
// Do not need to remove destBucketName its same as bucketName.
|
||||
}
|
||||
|
||||
// Test Core CopyObjectPart implementation
|
||||
func TestCoreCopyObjectPart(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping functional tests for short runs")
|
||||
}
|
||||
|
||||
// Seed random based on current time.
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
// Instantiate new minio client object.
|
||||
c, err := NewCore(
|
||||
os.Getenv(serverEndpoint),
|
||||
os.Getenv(accessKey),
|
||||
os.Getenv(secretKey),
|
||||
mustParseBool(os.Getenv(enableSecurity)),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err)
|
||||
}
|
||||
|
||||
// Enable tracing, write to stderr.
|
||||
// c.TraceOn(os.Stderr)
|
||||
|
||||
// Set user agent.
|
||||
c.SetAppInfo("Minio-go-FunctionalTest", "0.1.0")
|
||||
|
||||
// Generate a new random bucket name.
|
||||
bucketName := randString(60, rand.NewSource(time.Now().UnixNano()), "minio-go-test")
|
||||
|
||||
// Make a new bucket.
|
||||
err = c.MakeBucket(bucketName, "us-east-1")
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, bucketName)
|
||||
}
|
||||
|
||||
// Make a buffer with 5MB of data
|
||||
buf := bytes.Repeat([]byte("abcde"), 1024*1024)
|
||||
|
||||
// Save the data
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
objInfo, err := c.PutObject(bucketName, objectName, bytes.NewReader(buf), int64(len(buf)), "", "", map[string]string{
|
||||
"Content-Type": "binary/octet-stream",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, bucketName, objectName)
|
||||
}
|
||||
|
||||
if objInfo.Size != int64(len(buf)) {
|
||||
t.Fatalf("Error: number of bytes does not match, want %v, got %v\n", len(buf), objInfo.Size)
|
||||
}
|
||||
|
||||
destBucketName := bucketName
|
||||
destObjectName := objectName + "-dest"
|
||||
|
||||
uploadID, err := c.NewMultipartUpload(destBucketName, destObjectName, PutObjectOptions{})
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, bucketName, objectName)
|
||||
}
|
||||
|
||||
// Content of the destination object will be two copies of
|
||||
// `objectName` concatenated, followed by first byte of
|
||||
// `objectName`.
|
||||
|
||||
// First of three parts
|
||||
fstPart, err := c.CopyObjectPart(bucketName, objectName, destBucketName, destObjectName, uploadID, 1, 0, -1, nil)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, destBucketName, destObjectName)
|
||||
}
|
||||
|
||||
// Second of three parts
|
||||
sndPart, err := c.CopyObjectPart(bucketName, objectName, destBucketName, destObjectName, uploadID, 2, 0, -1, nil)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, destBucketName, destObjectName)
|
||||
}
|
||||
|
||||
// Last of three parts
|
||||
lstPart, err := c.CopyObjectPart(bucketName, objectName, destBucketName, destObjectName, uploadID, 3, 0, 1, nil)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, destBucketName, destObjectName)
|
||||
}
|
||||
|
||||
// Complete the multipart upload
|
||||
err = c.CompleteMultipartUpload(destBucketName, destObjectName, uploadID, []CompletePart{fstPart, sndPart, lstPart})
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, destBucketName, destObjectName)
|
||||
}
|
||||
|
||||
// Stat the object and check its length matches
|
||||
objInfo, err = c.StatObject(destBucketName, destObjectName, StatObjectOptions{})
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, destBucketName, destObjectName)
|
||||
}
|
||||
|
||||
if objInfo.Size != (5*1024*1024)*2+1 {
|
||||
t.Fatal("Destination object has incorrect size!")
|
||||
}
|
||||
|
||||
// Now we read the data back
|
||||
getOpts := GetObjectOptions{}
|
||||
getOpts.SetRange(0, 5*1024*1024-1)
|
||||
r, _, err := c.GetObject(destBucketName, destObjectName, getOpts)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, destBucketName, destObjectName)
|
||||
}
|
||||
getBuf := make([]byte, 5*1024*1024)
|
||||
_, err = io.ReadFull(r, getBuf)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, destBucketName, destObjectName)
|
||||
}
|
||||
if !bytes.Equal(getBuf, buf) {
|
||||
t.Fatal("Got unexpected data in first 5MB")
|
||||
}
|
||||
|
||||
getOpts.SetRange(5*1024*1024, 0)
|
||||
r, _, err = c.GetObject(destBucketName, destObjectName, getOpts)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, destBucketName, destObjectName)
|
||||
}
|
||||
getBuf = make([]byte, 5*1024*1024+1)
|
||||
_, err = io.ReadFull(r, getBuf)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, destBucketName, destObjectName)
|
||||
}
|
||||
if !bytes.Equal(getBuf[:5*1024*1024], buf) {
|
||||
t.Fatal("Got unexpected data in second 5MB")
|
||||
}
|
||||
if getBuf[5*1024*1024] != buf[0] {
|
||||
t.Fatal("Got unexpected data in last byte of copied object!")
|
||||
}
|
||||
|
||||
if err := c.RemoveObject(destBucketName, destObjectName); err != nil {
|
||||
t.Fatal("Error: ", err)
|
||||
}
|
||||
|
||||
if err := c.RemoveObject(bucketName, objectName); err != nil {
|
||||
t.Fatal("Error: ", err)
|
||||
}
|
||||
|
||||
if err := c.RemoveBucket(bucketName); err != nil {
|
||||
t.Fatal("Error: ", err)
|
||||
}
|
||||
|
||||
// Do not need to remove destBucketName its same as bucketName.
|
||||
}
|
||||
|
||||
// Test Core PutObject.
|
||||
func TestCorePutObject(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping functional tests for short runs")
|
||||
}
|
||||
|
||||
// Seed random based on current time.
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
// Instantiate new minio client object.
|
||||
c, err := NewCore(
|
||||
os.Getenv(serverEndpoint),
|
||||
os.Getenv(accessKey),
|
||||
os.Getenv(secretKey),
|
||||
mustParseBool(os.Getenv(enableSecurity)),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err)
|
||||
}
|
||||
|
||||
// Enable tracing, write to stderr.
|
||||
// c.TraceOn(os.Stderr)
|
||||
|
||||
// Set user agent.
|
||||
c.SetAppInfo("Minio-go-FunctionalTest", "0.1.0")
|
||||
|
||||
// Generate a new random bucket name.
|
||||
bucketName := randString(60, rand.NewSource(time.Now().UnixNano()), "minio-go-test")
|
||||
|
||||
// Make a new bucket.
|
||||
err = c.MakeBucket(bucketName, "us-east-1")
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, bucketName)
|
||||
}
|
||||
|
||||
buf := bytes.Repeat([]byte("a"), 32*1024)
|
||||
|
||||
// Save the data
|
||||
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
// Object content type
|
||||
objectContentType := "binary/octet-stream"
|
||||
metadata := make(map[string]string)
|
||||
metadata["Content-Type"] = objectContentType
|
||||
|
||||
objInfo, err := c.PutObject(bucketName, objectName, bytes.NewReader(buf), int64(len(buf)), "1B2M2Y8AsgTpgAmY7PhCfg==", "", metadata)
|
||||
if err == nil {
|
||||
t.Fatal("Error expected: error, got: nil(success)")
|
||||
}
|
||||
|
||||
objInfo, err = c.PutObject(bucketName, objectName, bytes.NewReader(buf), int64(len(buf)), "", "", metadata)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, bucketName, objectName)
|
||||
}
|
||||
|
||||
if objInfo.Size != int64(len(buf)) {
|
||||
t.Fatalf("Error: number of bytes does not match, want %v, got %v\n", len(buf), objInfo.Size)
|
||||
}
|
||||
|
||||
// Read the data back
|
||||
r, err := c.Client.GetObject(bucketName, objectName, GetObjectOptions{})
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, bucketName, objectName)
|
||||
}
|
||||
|
||||
st, err := r.Stat()
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, bucketName, objectName)
|
||||
}
|
||||
|
||||
if st.Size != int64(len(buf)) {
|
||||
t.Fatalf("Error: number of bytes in stat does not match, want %v, got %v\n",
|
||||
len(buf), st.Size)
|
||||
}
|
||||
|
||||
if st.ContentType != objectContentType {
|
||||
t.Fatalf("Error: Content types don't match, expected: %+v, found: %+v\n", objectContentType, st.ContentType)
|
||||
}
|
||||
|
||||
if err := r.Close(); err != nil {
|
||||
t.Fatal("Error:", err)
|
||||
}
|
||||
|
||||
if err := r.Close(); err == nil {
|
||||
t.Fatal("Error: object is already closed, should return error")
|
||||
}
|
||||
|
||||
err = c.RemoveObject(bucketName, objectName)
|
||||
if err != nil {
|
||||
t.Fatal("Error: ", err)
|
||||
}
|
||||
|
||||
err = c.RemoveBucket(bucketName)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCoreGetObjectMetadata(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping functional tests for the short runs")
|
||||
}
|
||||
|
||||
core, err := NewCore(
|
||||
os.Getenv(serverEndpoint),
|
||||
os.Getenv(accessKey),
|
||||
os.Getenv(secretKey),
|
||||
mustParseBool(os.Getenv(enableSecurity)))
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// Generate a new random bucket name.
|
||||
bucketName := randString(60, rand.NewSource(time.Now().UnixNano()), "minio-go-test")
|
||||
|
||||
// Make a new bucket.
|
||||
err = core.MakeBucket(bucketName, "us-east-1")
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err, bucketName)
|
||||
}
|
||||
|
||||
metadata := map[string]string{
|
||||
"X-Amz-Meta-Key-1": "Val-1",
|
||||
}
|
||||
|
||||
_, err = core.PutObject(bucketName, "my-objectname",
|
||||
bytes.NewReader([]byte("hello")), 5, "", "", metadata)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
reader, objInfo, err := core.GetObject(bucketName, "my-objectname", GetObjectOptions{})
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
if objInfo.Metadata.Get("X-Amz-Meta-Key-1") != "Val-1" {
|
||||
log.Fatalln("Expected metadata to be available but wasn't")
|
||||
}
|
||||
}
|
1561
vendor/github.com/minio/minio-go/docs/API.md
generated
vendored
1561
vendor/github.com/minio/minio-go/docs/API.md
generated
vendored
File diff suppressed because it is too large
Load diff
21
vendor/github.com/minio/minio-go/docs/checker.go.template
generated
vendored
21
vendor/github.com/minio/minio-go/docs/checker.go.template
generated
vendored
|
@ -1,21 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Use a secure connection.
|
||||
ssl := true
|
||||
|
||||
// Initialize minio client object.
|
||||
minioClient, err := minio.New("play.minio.io:9000", "Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG", ssl)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
{{.Text}}
|
||||
}
|
227
vendor/github.com/minio/minio-go/docs/validator.go
generated
vendored
227
vendor/github.com/minio/minio-go/docs/validator.go
generated
vendored
|
@ -1,227 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/a8m/mark"
|
||||
"github.com/gernest/wow"
|
||||
"github.com/gernest/wow/spin"
|
||||
"github.com/minio/cli"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Validate go binary.
|
||||
if _, err := exec.LookPath("go"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
var globalFlags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "m",
|
||||
Value: "API.md",
|
||||
Usage: "Path to markdown api documentation.",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "t",
|
||||
Value: "checker.go.template",
|
||||
Usage: "Template used for generating the programs.",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "skip",
|
||||
Value: 2,
|
||||
Usage: "Skip entries before validating the code.",
|
||||
},
|
||||
}
|
||||
|
||||
func runGofmt(path string) (msg string, err error) {
|
||||
cmdArgs := []string{"-s", "-w", "-l", path}
|
||||
cmd := exec.Command("gofmt", cmdArgs...)
|
||||
stdoutStderr, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(stdoutStderr), nil
|
||||
}
|
||||
|
||||
func runGoImports(path string) (msg string, err error) {
|
||||
cmdArgs := []string{"-w", path}
|
||||
cmd := exec.Command("goimports", cmdArgs...)
|
||||
stdoutStderr, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return string(stdoutStderr), err
|
||||
}
|
||||
return string(stdoutStderr), nil
|
||||
}
|
||||
|
||||
func runGoBuild(path string) (msg string, err error) {
|
||||
// Go build the path.
|
||||
cmdArgs := []string{"build", "-o", "/dev/null", path}
|
||||
cmd := exec.Command("go", cmdArgs...)
|
||||
stdoutStderr, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return string(stdoutStderr), err
|
||||
}
|
||||
return string(stdoutStderr), nil
|
||||
}
|
||||
|
||||
func validatorAction(ctx *cli.Context) error {
|
||||
if !ctx.IsSet("m") || !ctx.IsSet("t") {
|
||||
return nil
|
||||
}
|
||||
docPath := ctx.String("m")
|
||||
var err error
|
||||
docPath, err = filepath.Abs(docPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data, err := ioutil.ReadFile(docPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
templatePath := ctx.String("t")
|
||||
templatePath, err = filepath.Abs(templatePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
skipEntries := ctx.Int("skip")
|
||||
m := mark.New(string(data), &mark.Options{
|
||||
Gfm: true, // Github markdown support is enabled by default.
|
||||
})
|
||||
|
||||
t, err := template.ParseFiles(templatePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpDir, err := ioutil.TempDir("", "md-verifier")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
entryN := 1
|
||||
for i := mark.NodeText; i < mark.NodeCheckbox; i++ {
|
||||
if mark.NodeCode != mark.NodeType(i) {
|
||||
m.AddRenderFn(mark.NodeType(i), func(node mark.Node) (s string) {
|
||||
return ""
|
||||
})
|
||||
continue
|
||||
}
|
||||
m.AddRenderFn(mark.NodeCode, func(node mark.Node) (s string) {
|
||||
p, ok := node.(*mark.CodeNode)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
p.Text = strings.NewReplacer("<", "<", ">", ">", """, `"`, "&", "&").Replace(p.Text)
|
||||
if skipEntries > 0 {
|
||||
skipEntries--
|
||||
return
|
||||
}
|
||||
|
||||
testFilePath := filepath.Join(tmpDir, "example.go")
|
||||
w, werr := os.Create(testFilePath)
|
||||
if werr != nil {
|
||||
panic(werr)
|
||||
}
|
||||
t.Execute(w, p)
|
||||
w.Sync()
|
||||
w.Close()
|
||||
entryN++
|
||||
|
||||
msg, err := runGofmt(testFilePath)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed running gofmt on %s, with (%s):(%s)\n", testFilePath, msg, err)
|
||||
os.Exit(-1)
|
||||
}
|
||||
|
||||
msg, err = runGoImports(testFilePath)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed running gofmt on %s, with (%s):(%s)\n", testFilePath, msg, err)
|
||||
os.Exit(-1)
|
||||
}
|
||||
|
||||
msg, err = runGoBuild(testFilePath)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed running gobuild on %s, with (%s):(%s)\n", testFilePath, msg, err)
|
||||
fmt.Printf("Code with possible issue in %s:\n%s", docPath, p.Text)
|
||||
fmt.Printf("To test `go build %s`\n", testFilePath)
|
||||
os.Exit(-1)
|
||||
}
|
||||
|
||||
// Once successfully built remove the test file
|
||||
os.Remove(testFilePath)
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
w := wow.New(os.Stdout, spin.Get(spin.Moon), fmt.Sprintf(" Running validation tests in %s", tmpDir))
|
||||
|
||||
w.Start()
|
||||
// Render markdown executes our checker on each code blocks.
|
||||
_ = m.Render()
|
||||
w.PersistWith(spin.Get(spin.Runner), " Successfully finished tests")
|
||||
w.Stop()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := cli.NewApp()
|
||||
app.Action = validatorAction
|
||||
app.HideVersion = true
|
||||
app.HideHelpCommand = true
|
||||
app.Usage = "Validates code block sections inside API.md"
|
||||
app.Author = "Minio.io"
|
||||
app.Flags = globalFlags
|
||||
// Help template for validator
|
||||
app.CustomAppHelpTemplate = `NAME:
|
||||
{{.Name}} - {{.Usage}}
|
||||
|
||||
USAGE:
|
||||
{{.Name}} {{if .VisibleFlags}}[FLAGS] {{end}}COMMAND{{if .VisibleFlags}} [COMMAND FLAGS | -h]{{end}} [ARGUMENTS...]
|
||||
|
||||
COMMANDS:
|
||||
{{range .VisibleCommands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
|
||||
{{end}}{{if .VisibleFlags}}
|
||||
FLAGS:
|
||||
{{range .VisibleFlags}}{{.}}
|
||||
{{end}}{{end}}
|
||||
TEMPLATE:
|
||||
Validator uses Go's 'text/template' formatting so you need to ensure
|
||||
your template is formatted correctly, check 'docs/checker.go.template'
|
||||
|
||||
USAGE:
|
||||
go run docs/validator.go -m docs/API.md -t /tmp/mycode.go.template
|
||||
|
||||
`
|
||||
app.Run(os.Args)
|
||||
|
||||
}
|
1820
vendor/github.com/minio/minio-go/docs/zh_CN/API.md
generated
vendored
1820
vendor/github.com/minio/minio-go/docs/zh_CN/API.md
generated
vendored
File diff suppressed because it is too large
Load diff
22
vendor/github.com/minio/minio-go/docs/zh_CN/CONTRIBUTING.md
generated
vendored
22
vendor/github.com/minio/minio-go/docs/zh_CN/CONTRIBUTING.md
generated
vendored
|
@ -1,22 +0,0 @@
|
|||
|
||||
### 开发者指南
|
||||
|
||||
``minio-go``欢迎你的贡献。为了让大家配合更加默契,我们做出如下约定:
|
||||
|
||||
* fork项目并修改,我们鼓励大家使用pull requests进行代码相关的讨论。
|
||||
- Fork项目
|
||||
- 创建你的特性分支 (git checkout -b my-new-feature)
|
||||
- Commit你的修改(git commit -am 'Add some feature')
|
||||
- Push到远程分支(git push origin my-new-feature)
|
||||
- 创建一个Pull Request
|
||||
|
||||
* 当你准备创建pull request时,请确保:
|
||||
- 写单元测试,如果你有什么疑问,请在pull request中提出来。
|
||||
- 运行`go fmt`
|
||||
- 将你的多个提交合并成一个提交: `git rebase -i`。你可以强制update你的pull request。
|
||||
- 确保`go test -race ./...`和`go build`完成。
|
||||
注意:go test会进行功能测试,这需要你有一个AWS S3账号。将账户信息设为``ACCESS_KEY``和``SECRET_KEY``环境变量。如果想运行简版测试,请使用``go test -short -race ./...``。
|
||||
|
||||
* 请阅读 [Effective Go](https://github.com/golang/go/wiki/CodeReviewComments)
|
||||
- `minio-go`项目严格符合Golang风格
|
||||
- 如果您看到代码有问题,请随时发一个pull request
|
61
vendor/github.com/minio/minio-go/examples/minio/listenbucketnotification.go
generated
vendored
61
vendor/github.com/minio/minio-go/examples/minio/listenbucketnotification.go
generated
vendored
|
@ -1,61 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are
|
||||
// dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
minioClient, err := minio.New("play.minio.io:9000", "YOUR-ACCESS", "YOUR-SECRET", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// s3Client.TraceOn(os.Stderr)
|
||||
|
||||
// Create a done channel to control 'ListenBucketNotification' go routine.
|
||||
doneCh := make(chan struct{})
|
||||
|
||||
// Indicate to our routine to exit cleanly upon return.
|
||||
defer close(doneCh)
|
||||
|
||||
// Listen for bucket notifications on "mybucket" filtered by prefix, suffix and events.
|
||||
for notificationInfo := range minioClient.ListenBucketNotification("YOUR-BUCKET", "PREFIX", "SUFFIX", []string{
|
||||
"s3:ObjectCreated:*",
|
||||
"s3:ObjectAccessed:*",
|
||||
"s3:ObjectRemoved:*",
|
||||
}, doneCh) {
|
||||
if notificationInfo.Err != nil {
|
||||
log.Fatalln(notificationInfo.Err)
|
||||
}
|
||||
log.Println(notificationInfo)
|
||||
}
|
||||
}
|
52
vendor/github.com/minio/minio-go/examples/s3/bucketexists.go
generated
vendored
52
vendor/github.com/minio/minio-go/examples/s3/bucketexists.go
generated
vendored
|
@ -1,52 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are
|
||||
// dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
found, err := s3Client.BucketExists("my-bucketname")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
if found {
|
||||
log.Println("Bucket found.")
|
||||
} else {
|
||||
log.Println("Bucket not found.")
|
||||
}
|
||||
}
|
78
vendor/github.com/minio/minio-go/examples/s3/composeobject.go
generated
vendored
78
vendor/github.com/minio/minio-go/examples/s3/composeobject.go
generated
vendored
|
@ -1,78 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
minio "github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-testfile, my-bucketname and
|
||||
// my-objectname are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// Enable trace.
|
||||
// s3Client.TraceOn(os.Stderr)
|
||||
|
||||
// Prepare source decryption key (here we assume same key to
|
||||
// decrypt all source objects.)
|
||||
decKey := minio.NewSSEInfo([]byte{1, 2, 3}, "")
|
||||
|
||||
// Source objects to concatenate. We also specify decryption
|
||||
// key for each
|
||||
src1 := minio.NewSourceInfo("bucket1", "object1", &decKey)
|
||||
src1.SetMatchETagCond("31624deb84149d2f8ef9c385918b653a")
|
||||
|
||||
src2 := minio.NewSourceInfo("bucket2", "object2", &decKey)
|
||||
src2.SetMatchETagCond("f8ef9c385918b653a31624deb84149d2")
|
||||
|
||||
src3 := minio.NewSourceInfo("bucket3", "object3", &decKey)
|
||||
src3.SetMatchETagCond("5918b653a31624deb84149d2f8ef9c38")
|
||||
|
||||
// Create slice of sources.
|
||||
srcs := []minio.SourceInfo{src1, src2, src3}
|
||||
|
||||
// Prepare destination encryption key
|
||||
encKey := minio.NewSSEInfo([]byte{8, 9, 0}, "")
|
||||
|
||||
// Create destination info
|
||||
dst, err := minio.NewDestinationInfo("bucket", "object", &encKey, nil)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
err = s3Client.ComposeObject(dst, srcs)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
log.Println("Composed object successfully.")
|
||||
}
|
75
vendor/github.com/minio/minio-go/examples/s3/copyobject.go
generated
vendored
75
vendor/github.com/minio/minio-go/examples/s3/copyobject.go
generated
vendored
|
@ -1,75 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-testfile, my-bucketname and
|
||||
// my-objectname are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// Enable trace.
|
||||
// s3Client.TraceOn(os.Stderr)
|
||||
|
||||
// Source object
|
||||
src := minio.NewSourceInfo("my-sourcebucketname", "my-sourceobjectname", nil)
|
||||
|
||||
// All following conditions are allowed and can be combined together.
|
||||
|
||||
// Set modified condition, copy object modified since 2014 April.
|
||||
src.SetModifiedSinceCond(time.Date(2014, time.April, 0, 0, 0, 0, 0, time.UTC))
|
||||
|
||||
// Set unmodified condition, copy object unmodified since 2014 April.
|
||||
// src.SetUnmodifiedSinceCond(time.Date(2014, time.April, 0, 0, 0, 0, 0, time.UTC))
|
||||
|
||||
// Set matching ETag condition, copy object which matches the following ETag.
|
||||
// src.SetMatchETagCond("31624deb84149d2f8ef9c385918b653a")
|
||||
|
||||
// Set matching ETag except condition, copy object which does not match the following ETag.
|
||||
// src.SetMatchETagExceptCond("31624deb84149d2f8ef9c385918b653a")
|
||||
|
||||
// Destination object
|
||||
dst, err := minio.NewDestinationInfo("my-bucketname", "my-objectname", nil, nil)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// Initiate copy object.
|
||||
err = s3Client.CopyObject(dst, src)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
log.Println("Copied source object /my-sourcebucketname/my-sourceobjectname to destination /my-bucketname/my-objectname Successfully.")
|
||||
}
|
54
vendor/github.com/minio/minio-go/examples/s3/fgetobject-context.go
generated
vendored
54
vendor/github.com/minio/minio-go/examples/s3/fgetobject-context.go
generated
vendored
|
@ -1,54 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"context"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname, my-objectname
|
||||
// and my-filename.csv are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
if err := s3Client.FGetObjectWithContext(ctx, "my-bucketname", "my-objectname", "my-filename.csv", minio.GetObjectOptions{}); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
log.Println("Successfully saved my-filename.csv")
|
||||
|
||||
}
|
46
vendor/github.com/minio/minio-go/examples/s3/fgetobject.go
generated
vendored
46
vendor/github.com/minio/minio-go/examples/s3/fgetobject.go
generated
vendored
|
@ -1,46 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname, my-objectname
|
||||
// and my-filename.csv are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
if err := s3Client.FGetObject("my-bucketname", "my-objectname", "my-filename.csv", minio.GetObjectOptions{}); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
log.Println("Successfully saved my-filename.csv")
|
||||
}
|
59
vendor/github.com/minio/minio-go/examples/s3/fputencrypted-object.go
generated
vendored
59
vendor/github.com/minio/minio-go/examples/s3/fputencrypted-object.go
generated
vendored
|
@ -1,59 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go/pkg/encrypt"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-testfile, my-bucketname and
|
||||
// my-objectname are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
filePath := "my-testfile" // Specify a local file that we will upload
|
||||
bucketname := "my-bucketname" // Specify a bucket name - the bucket must already exist
|
||||
objectName := "my-objectname" // Specify a object name
|
||||
password := "correct horse battery staple" // Specify your password. DO NOT USE THIS ONE - USE YOUR OWN.
|
||||
|
||||
// New SSE-C where the cryptographic key is derived from a password and the objectname + bucketname as salt
|
||||
encryption := encrypt.DefaultPBKDF([]byte(password), []byte(bucketname+objectName))
|
||||
|
||||
// Encrypt file content and upload to the server
|
||||
n, err := s3Client.FPutObject(bucketname, objectName, filePath, minio.PutObjectOptions{ServerSideEncryption: encryption})
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
log.Println("Uploaded", "my-objectname", " of size: ", n, "Successfully.")
|
||||
}
|
53
vendor/github.com/minio/minio-go/examples/s3/fputobject-context.go
generated
vendored
53
vendor/github.com/minio/minio-go/examples/s3/fputobject-context.go
generated
vendored
|
@ -1,53 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"context"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname, my-objectname
|
||||
// and my-filename.csv are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
if _, err := s3Client.FPutObjectWithContext(ctx, "my-bucketname", "my-objectname", "my-filename.csv", minio.PutObjectOptions{ContentType: "application/csv"}); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
log.Println("Successfully uploaded my-filename.csv")
|
||||
}
|
48
vendor/github.com/minio/minio-go/examples/s3/fputobject.go
generated
vendored
48
vendor/github.com/minio/minio-go/examples/s3/fputobject.go
generated
vendored
|
@ -1,48 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname, my-objectname
|
||||
// and my-filename.csv are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
if _, err := s3Client.FPutObject("my-bucketname", "my-objectname", "my-filename.csv", minio.PutObjectOptions{
|
||||
ContentType: "application/csv",
|
||||
}); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
log.Println("Successfully uploaded my-filename.csv")
|
||||
}
|
69
vendor/github.com/minio/minio-go/examples/s3/get-encrypted-object.go
generated
vendored
69
vendor/github.com/minio/minio-go/examples/s3/get-encrypted-object.go
generated
vendored
|
@ -1,69 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
"github.com/minio/minio-go/pkg/encrypt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname, my-objectname and
|
||||
// my-testfile are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESS-KEY-HERE", "YOUR-SECRET-KEY-HERE", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
bucketname := "my-bucketname" // Specify a bucket name - the bucket must already exist
|
||||
objectName := "my-objectname" // Specify a object name - the object must already exist
|
||||
password := "correct horse battery staple" // Specify your password. DO NOT USE THIS ONE - USE YOUR OWN.
|
||||
|
||||
// New SSE-C where the cryptographic key is derived from a password and the objectname + bucketname as salt
|
||||
encryption := encrypt.DefaultPBKDF([]byte(password), []byte(bucketname+objectName))
|
||||
|
||||
// Get the encrypted object
|
||||
reader, err := s3Client.GetObject(bucketname, objectName, minio.GetObjectOptions{ServerSideEncryption: encryption})
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
// Local file which holds plain data
|
||||
localFile, err := os.Create("my-testfile")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer localFile.Close()
|
||||
|
||||
if _, err := io.Copy(localFile, reader); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
56
vendor/github.com/minio/minio-go/examples/s3/getbucketnotification.go
generated
vendored
56
vendor/github.com/minio/minio-go/examples/s3/getbucketnotification.go
generated
vendored
|
@ -1,56 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are
|
||||
// dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// s3Client.TraceOn(os.Stderr)
|
||||
|
||||
notifications, err := s3Client.GetBucketNotification("my-bucketname")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
log.Println("Bucket notification are successfully retrieved.")
|
||||
|
||||
for _, topicConfig := range notifications.TopicConfigs {
|
||||
for _, e := range topicConfig.Events {
|
||||
log.Println(e + " event is enabled.")
|
||||
}
|
||||
}
|
||||
}
|
56
vendor/github.com/minio/minio-go/examples/s3/getbucketpolicy.go
generated
vendored
56
vendor/github.com/minio/minio-go/examples/s3/getbucketpolicy.go
generated
vendored
|
@ -1,56 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are
|
||||
// dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// s3Client.TraceOn(os.Stderr)
|
||||
|
||||
// Fetch the policy at 'my-objectprefix'.
|
||||
policy, err := s3Client.GetBucketPolicy("my-bucketname", "my-objectprefix")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// Description of policy output.
|
||||
// "none" - The specified bucket does not have a bucket policy.
|
||||
// "readonly" - Read only operations are allowed.
|
||||
// "writeonly" - Write only operations are allowed.
|
||||
// "readwrite" - both read and write operations are allowed, the bucket is public.
|
||||
log.Println("Success - ", policy)
|
||||
}
|
73
vendor/github.com/minio/minio-go/examples/s3/getobject-context.go
generated
vendored
73
vendor/github.com/minio/minio-go/examples/s3/getobject-context.go
generated
vendored
|
@ -1,73 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"context"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname, my-objectname and
|
||||
// my-testfile are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESS-KEY-HERE", "YOUR-SECRET-KEY-HERE", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
opts := minio.GetObjectOptions{}
|
||||
opts.SetModified(time.Now().Round(10 * time.Minute)) // get object if was modified within the last 10 minutes
|
||||
reader, err := s3Client.GetObjectWithContext(ctx, "my-bucketname", "my-objectname", opts)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
localFile, err := os.Create("my-testfile")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer localFile.Close()
|
||||
|
||||
stat, err := reader.Stat()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
if _, err := io.CopyN(localFile, reader, stat.Size); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
64
vendor/github.com/minio/minio-go/examples/s3/getobject.go
generated
vendored
64
vendor/github.com/minio/minio-go/examples/s3/getobject.go
generated
vendored
|
@ -1,64 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname, my-objectname and
|
||||
// my-testfile are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESS-KEY-HERE", "YOUR-SECRET-KEY-HERE", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
reader, err := s3Client.GetObject("my-bucketname", "my-objectname", minio.GetObjectOptions{})
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
localFile, err := os.Create("my-testfile")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer localFile.Close()
|
||||
|
||||
stat, err := reader.Stat()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
if _, err := io.CopyN(localFile, reader, stat.Size); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
57
vendor/github.com/minio/minio-go/examples/s3/listbucketpolicies.go
generated
vendored
57
vendor/github.com/minio/minio-go/examples/s3/listbucketpolicies.go
generated
vendored
|
@ -1,57 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are
|
||||
// dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// s3Client.TraceOn(os.Stderr)
|
||||
|
||||
// Fetch the policy at 'my-objectprefix'.
|
||||
policies, err := s3Client.ListBucketPolicies("my-bucketname", "my-objectprefix")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// ListBucketPolicies returns a map of objects policy rules and their associated permissions
|
||||
// e.g. mybucket/downloadfolder/* => readonly
|
||||
// mybucket/shared/* => readwrite
|
||||
|
||||
for resource, permission := range policies {
|
||||
log.Println(resource, " => ", permission)
|
||||
}
|
||||
}
|
49
vendor/github.com/minio/minio-go/examples/s3/listbuckets.go
generated
vendored
49
vendor/github.com/minio/minio-go/examples/s3/listbuckets.go
generated
vendored
|
@ -1,49 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID and YOUR-SECRETACCESSKEY are
|
||||
// dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
buckets, err := s3Client.ListBuckets()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
for _, bucket := range buckets {
|
||||
log.Println(bucket)
|
||||
}
|
||||
}
|
58
vendor/github.com/minio/minio-go/examples/s3/listincompleteuploads.go
generated
vendored
58
vendor/github.com/minio/minio-go/examples/s3/listincompleteuploads.go
generated
vendored
|
@ -1,58 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname and my-prefixname
|
||||
// are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// Create a done channel to control 'ListObjects' go routine.
|
||||
doneCh := make(chan struct{})
|
||||
|
||||
// Indicate to our routine to exit cleanly upon return.
|
||||
defer close(doneCh)
|
||||
|
||||
// List all multipart uploads from a bucket-name with a matching prefix.
|
||||
for multipartObject := range s3Client.ListIncompleteUploads("my-bucketname", "my-prefixname", true, doneCh) {
|
||||
if multipartObject.Err != nil {
|
||||
fmt.Println(multipartObject.Err)
|
||||
return
|
||||
}
|
||||
fmt.Println(multipartObject)
|
||||
}
|
||||
return
|
||||
}
|
77
vendor/github.com/minio/minio-go/examples/s3/listobjects-N.go
generated
vendored
77
vendor/github.com/minio/minio-go/examples/s3/listobjects-N.go
generated
vendored
|
@ -1,77 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname and my-prefixname
|
||||
// are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
// List 'N' number of objects from a bucket-name with a matching prefix.
|
||||
listObjectsN := func(bucket, prefix string, recursive bool, N int) (objsInfo []minio.ObjectInfo, err error) {
|
||||
// Create a done channel to control 'ListObjects' go routine.
|
||||
doneCh := make(chan struct{}, 1)
|
||||
|
||||
// Free the channel upon return.
|
||||
defer close(doneCh)
|
||||
|
||||
i := 1
|
||||
for object := range s3Client.ListObjects(bucket, prefix, recursive, doneCh) {
|
||||
if object.Err != nil {
|
||||
return nil, object.Err
|
||||
}
|
||||
i++
|
||||
// Verify if we have printed N objects.
|
||||
if i == N {
|
||||
// Indicate ListObjects go-routine to exit and stop
|
||||
// feeding the objectInfo channel.
|
||||
doneCh <- struct{}{}
|
||||
}
|
||||
objsInfo = append(objsInfo, object)
|
||||
}
|
||||
return objsInfo, nil
|
||||
}
|
||||
|
||||
// List recursively first 100 entries for prefix 'my-prefixname'.
|
||||
recursive := true
|
||||
objsInfo, err := listObjectsN("my-bucketname", "my-prefixname", recursive, 100)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
// Print all the entries.
|
||||
fmt.Println(objsInfo)
|
||||
}
|
58
vendor/github.com/minio/minio-go/examples/s3/listobjects.go
generated
vendored
58
vendor/github.com/minio/minio-go/examples/s3/listobjects.go
generated
vendored
|
@ -1,58 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname and my-prefixname
|
||||
// are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
// Create a done channel to control 'ListObjects' go routine.
|
||||
doneCh := make(chan struct{})
|
||||
|
||||
// Indicate to our routine to exit cleanly upon return.
|
||||
defer close(doneCh)
|
||||
|
||||
// List all objects from a bucket-name with a matching prefix.
|
||||
for object := range s3Client.ListObjects("my-bucketname", "my-prefixname", true, doneCh) {
|
||||
if object.Err != nil {
|
||||
fmt.Println(object.Err)
|
||||
return
|
||||
}
|
||||
fmt.Println(object)
|
||||
}
|
||||
return
|
||||
}
|
58
vendor/github.com/minio/minio-go/examples/s3/listobjectsV2.go
generated
vendored
58
vendor/github.com/minio/minio-go/examples/s3/listobjectsV2.go
generated
vendored
|
@ -1,58 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname and my-prefixname
|
||||
// are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
// Create a done channel to control 'ListObjects' go routine.
|
||||
doneCh := make(chan struct{})
|
||||
|
||||
// Indicate to our routine to exit cleanly upon return.
|
||||
defer close(doneCh)
|
||||
|
||||
// List all objects from a bucket-name with a matching prefix.
|
||||
for object := range s3Client.ListObjectsV2("my-bucketname", "my-prefixname", true, doneCh) {
|
||||
if object.Err != nil {
|
||||
fmt.Println(object.Err)
|
||||
return
|
||||
}
|
||||
fmt.Println(object)
|
||||
}
|
||||
return
|
||||
}
|
47
vendor/github.com/minio/minio-go/examples/s3/makebucket.go
generated
vendored
47
vendor/github.com/minio/minio-go/examples/s3/makebucket.go
generated
vendored
|
@ -1,47 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are
|
||||
// dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
err = s3Client.MakeBucket("my-bucketname", "us-east-1")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
log.Println("Success")
|
||||
}
|
54
vendor/github.com/minio/minio-go/examples/s3/presignedgetobject.go
generated
vendored
54
vendor/github.com/minio/minio-go/examples/s3/presignedgetobject.go
generated
vendored
|
@ -1,54 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname and my-objectname
|
||||
// are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// Set request parameters
|
||||
reqParams := make(url.Values)
|
||||
reqParams.Set("response-content-disposition", "attachment; filename=\"your-filename.txt\"")
|
||||
|
||||
// Gernerate presigned get object url.
|
||||
presignedURL, err := s3Client.PresignedGetObject("my-bucketname", "my-objectname", time.Duration(1000)*time.Second, reqParams)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
log.Println(presignedURL)
|
||||
}
|
54
vendor/github.com/minio/minio-go/examples/s3/presignedheadobject.go
generated
vendored
54
vendor/github.com/minio/minio-go/examples/s3/presignedheadobject.go
generated
vendored
|
@ -1,54 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname and my-objectname
|
||||
// are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// Set request parameters
|
||||
reqParams := make(url.Values)
|
||||
reqParams.Set("response-content-disposition", "attachment; filename=\"your-filename.txt\"")
|
||||
|
||||
// Gernerate presigned get object url.
|
||||
presignedURL, err := s3Client.PresignedHeadObject("my-bucketname", "my-objectname", time.Duration(1000)*time.Second, reqParams)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
log.Println(presignedURL)
|
||||
}
|
60
vendor/github.com/minio/minio-go/examples/s3/presignedpostpolicy.go
generated
vendored
60
vendor/github.com/minio/minio-go/examples/s3/presignedpostpolicy.go
generated
vendored
|
@ -1,60 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname and my-objectname
|
||||
// are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
policy := minio.NewPostPolicy()
|
||||
policy.SetBucket("my-bucketname")
|
||||
policy.SetKey("my-objectname")
|
||||
// Expires in 10 days.
|
||||
policy.SetExpires(time.Now().UTC().AddDate(0, 0, 10))
|
||||
// Returns form data for POST form request.
|
||||
url, formData, err := s3Client.PresignedPostPolicy(policy)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
fmt.Printf("curl ")
|
||||
for k, v := range formData {
|
||||
fmt.Printf("-F %s=%s ", k, v)
|
||||
}
|
||||
fmt.Printf("-F file=@/etc/bash.bashrc ")
|
||||
fmt.Printf("%s\n", url)
|
||||
}
|
48
vendor/github.com/minio/minio-go/examples/s3/presignedputobject.go
generated
vendored
48
vendor/github.com/minio/minio-go/examples/s3/presignedputobject.go
generated
vendored
|
@ -1,48 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname and my-objectname
|
||||
// are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
presignedURL, err := s3Client.PresignedPutObject("my-bucketname", "my-objectname", time.Duration(1000)*time.Second)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
log.Println(presignedURL)
|
||||
}
|
73
vendor/github.com/minio/minio-go/examples/s3/put-encrypted-object.go
generated
vendored
73
vendor/github.com/minio/minio-go/examples/s3/put-encrypted-object.go
generated
vendored
|
@ -1,73 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
"github.com/minio/minio-go/pkg/encrypt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-testfile, my-bucketname and
|
||||
// my-objectname are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
filePath := "my-testfile" // Specify a local file that we will upload
|
||||
|
||||
// Open a local file that we will upload
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// Get file stats.
|
||||
fstat, err := file.Stat()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
bucketname := "my-bucketname" // Specify a bucket name - the bucket must already exist
|
||||
objectName := "my-objectname" // Specify a object name
|
||||
password := "correct horse battery staple" // Specify your password. DO NOT USE THIS ONE - USE YOUR OWN.
|
||||
|
||||
// New SSE-C where the cryptographic key is derived from a password and the objectname + bucketname as salt
|
||||
encryption := encrypt.DefaultPBKDF([]byte(password), []byte(bucketname+objectName))
|
||||
|
||||
// Encrypt file content and upload to the server
|
||||
n, err := s3Client.PutObject(bucketname, objectName, file, fstat.Size(), minio.PutObjectOptions{ServerSideEncryption: encryption})
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
log.Println("Uploaded", "my-objectname", " of size: ", n, "Successfully.")
|
||||
}
|
68
vendor/github.com/minio/minio-go/examples/s3/putobject-context.go
generated
vendored
68
vendor/github.com/minio/minio-go/examples/s3/putobject-context.go
generated
vendored
|
@ -1,68 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"context"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-testfile, my-bucketname and
|
||||
// my-objectname are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
object, err := os.Open("my-testfile")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer object.Close()
|
||||
|
||||
objectStat, err := object.Stat()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
n, err := s3Client.PutObjectWithContext(ctx, "my-bucketname", "my-objectname", object, objectStat.Size(), minio.PutObjectOptions{
|
||||
ContentType: "application/octet-stream",
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
log.Println("Uploaded", "my-objectname", " of size: ", n, "Successfully.")
|
||||
}
|
68
vendor/github.com/minio/minio-go/examples/s3/putobject-getobject-sse.go
generated
vendored
68
vendor/github.com/minio/minio-go/examples/s3/putobject-getobject-sse.go
generated
vendored
|
@ -1,68 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go/pkg/encrypt"
|
||||
|
||||
minio "github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-testfile, my-bucketname and
|
||||
// my-objectname are dummy values, please replace them with original values.
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
minioClient, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
bucketName := "my-bucket"
|
||||
objectName := "my-encrypted-object"
|
||||
object := []byte("Hello again")
|
||||
|
||||
encryption := encrypt.DefaultPBKDF([]byte("my secret password"), []byte(bucketName+objectName))
|
||||
_, err = minioClient.PutObject(bucketName, objectName, bytes.NewReader(object), int64(len(object)), minio.PutObjectOptions{
|
||||
ServerSideEncryption: encryption,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
reader, err := minioClient.GetObject(bucketName, objectName, minio.GetObjectOptions{ServerSideEncryption: encryption})
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
decBytes, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
if !bytes.Equal(decBytes, object) {
|
||||
log.Fatalln("Expected %s, got %s", string(object), string(decBytes))
|
||||
}
|
||||
}
|
64
vendor/github.com/minio/minio-go/examples/s3/putobject-progress.go
generated
vendored
64
vendor/github.com/minio/minio-go/examples/s3/putobject-progress.go
generated
vendored
|
@ -1,64 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/cheggaaa/pb"
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-testfile, my-bucketname and
|
||||
// my-objectname are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
reader, err := s3Client.GetObject("my-bucketname", "my-objectname", minio.GetObjectOptions{})
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
objectInfo, err := reader.Stat()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// Progress reader is notified as PutObject makes progress with
|
||||
// the Reads inside.
|
||||
progress := pb.New64(objectInfo.Size)
|
||||
progress.Start()
|
||||
n, err := s3Client.PutObject("my-bucketname", "my-objectname-progress", reader, objectInfo.Size, minio.PutObjectOptions{ContentType: "application/octet-stream", Progress: progress})
|
||||
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
log.Println("Uploaded", "my-objectname", " of size: ", n, "Successfully.")
|
||||
}
|
62
vendor/github.com/minio/minio-go/examples/s3/putobject-s3-accelerate.go
generated
vendored
62
vendor/github.com/minio/minio-go/examples/s3/putobject-s3-accelerate.go
generated
vendored
|
@ -1,62 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-testfile, my-bucketname and
|
||||
// my-objectname are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// Enable S3 transfer accelerate endpoint.
|
||||
s3Client.SetS3TransferAccelerate("s3-accelerate.amazonaws.com")
|
||||
|
||||
object, err := os.Open("my-testfile")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer object.Close()
|
||||
|
||||
objectStat, err := object.Stat()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
n, err := s3Client.PutObject("my-bucketname", "my-objectname", object, objectStat.Size(), minio.PutObjectOptions{ContentType: "application/octet-stream"})
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
log.Println("Uploaded", "my-objectname", " of size: ", n, "Successfully.")
|
||||
}
|
55
vendor/github.com/minio/minio-go/examples/s3/putobject-streaming.go
generated
vendored
55
vendor/github.com/minio/minio-go/examples/s3/putobject-streaming.go
generated
vendored
|
@ -1,55 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
minio "github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-testfile, my-bucketname and
|
||||
// my-objectname are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
object, err := os.Open("my-testfile")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer object.Close()
|
||||
|
||||
n, err := s3Client.PutObject("my-bucketname", "my-objectname", object, -1, minio.PutObjectOptions{})
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
log.Println("Uploaded", "my-objectname", " of size: ", n, "Successfully.")
|
||||
}
|
58
vendor/github.com/minio/minio-go/examples/s3/putobject.go
generated
vendored
58
vendor/github.com/minio/minio-go/examples/s3/putobject.go
generated
vendored
|
@ -1,58 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-testfile, my-bucketname and
|
||||
// my-objectname are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
object, err := os.Open("my-testfile")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer object.Close()
|
||||
objectStat, err := object.Stat()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
n, err := s3Client.PutObject("my-bucketname", "my-objectname", object, objectStat.Size(), minio.PutObjectOptions{ContentType: "application/octet-stream"})
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
log.Println("Uploaded", "my-objectname", " of size: ", n, "Successfully.")
|
||||
}
|
50
vendor/github.com/minio/minio-go/examples/s3/removeallbucketnotification.go
generated
vendored
50
vendor/github.com/minio/minio-go/examples/s3/removeallbucketnotification.go
generated
vendored
|
@ -1,50 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are
|
||||
// dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// s3Client.TraceOn(os.Stderr)
|
||||
|
||||
err = s3Client.RemoveAllBucketNotification("my-bucketname")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
log.Println("Bucket notification are successfully removed.")
|
||||
}
|
49
vendor/github.com/minio/minio-go/examples/s3/removebucket.go
generated
vendored
49
vendor/github.com/minio/minio-go/examples/s3/removebucket.go
generated
vendored
|
@ -1,49 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are
|
||||
// dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// This operation will only work if your bucket is empty.
|
||||
err = s3Client.RemoveBucket("my-bucketname")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
log.Println("Success")
|
||||
|
||||
}
|
47
vendor/github.com/minio/minio-go/examples/s3/removeincompleteupload.go
generated
vendored
47
vendor/github.com/minio/minio-go/examples/s3/removeincompleteupload.go
generated
vendored
|
@ -1,47 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname and my-objectname
|
||||
// are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
err = s3Client.RemoveIncompleteUpload("my-bucketname", "my-objectname")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
log.Println("Success")
|
||||
}
|
46
vendor/github.com/minio/minio-go/examples/s3/removeobject.go
generated
vendored
46
vendor/github.com/minio/minio-go/examples/s3/removeobject.go
generated
vendored
|
@ -1,46 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname and my-objectname
|
||||
// are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
err = s3Client.RemoveObject("my-bucketname", "my-objectname")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
log.Println("Success")
|
||||
}
|
65
vendor/github.com/minio/minio-go/examples/s3/removeobjects.go
generated
vendored
65
vendor/github.com/minio/minio-go/examples/s3/removeobjects.go
generated
vendored
|
@ -1,65 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname and my-objectname
|
||||
// are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
objectsCh := make(chan string)
|
||||
|
||||
// Send object names that are needed to be removed to objectsCh
|
||||
go func() {
|
||||
defer close(objectsCh)
|
||||
// List all objects from a bucket-name with a matching prefix.
|
||||
for object := range s3Client.ListObjects("my-bucketname", "my-prefixname", true, doneCh) {
|
||||
if object.Err != nil {
|
||||
log.Fatalln(object.Err)
|
||||
}
|
||||
objectsCh <- object.Key
|
||||
}
|
||||
}()
|
||||
|
||||
// Call RemoveObjects API
|
||||
errorCh := s3Client.RemoveObjects("my-bucketname", objectsCh)
|
||||
|
||||
// Print errors received from RemoveObjects API
|
||||
for e := range errorCh {
|
||||
log.Fatalln("Failed to remove " + e.ObjectName + ", error: " + e.Err.Error())
|
||||
}
|
||||
|
||||
log.Println("Success")
|
||||
}
|
86
vendor/github.com/minio/minio-go/examples/s3/setbucketnotification.go
generated
vendored
86
vendor/github.com/minio/minio-go/examples/s3/setbucketnotification.go
generated
vendored
|
@ -1,86 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are
|
||||
// dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// s3Client.TraceOn(os.Stderr)
|
||||
|
||||
// ARN represents a notification channel that needs to be created in your S3 provider
|
||||
// (e.g. http://docs.aws.amazon.com/sns/latest/dg/CreateTopic.html)
|
||||
|
||||
// An example of an ARN:
|
||||
// arn:aws:sns:us-east-1:804064459714:UploadPhoto
|
||||
// ^ ^ ^ ^ ^
|
||||
// Provider __| | | | |
|
||||
// | Region Account ID |_ Notification Name
|
||||
// Service _|
|
||||
//
|
||||
// You should replace YOUR-PROVIDER, YOUR-SERVICE, YOUR-REGION, YOUR-ACCOUNT-ID and YOUR-RESOURCE
|
||||
// with actual values that you receive from the S3 provider
|
||||
|
||||
// Here you create a new Topic notification
|
||||
topicArn := minio.NewArn("YOUR-PROVIDER", "YOUR-SERVICE", "YOUR-REGION", "YOUR-ACCOUNT-ID", "YOUR-RESOURCE")
|
||||
topicConfig := minio.NewNotificationConfig(topicArn)
|
||||
topicConfig.AddEvents(minio.ObjectCreatedAll, minio.ObjectRemovedAll)
|
||||
topicConfig.AddFilterPrefix("photos/")
|
||||
topicConfig.AddFilterSuffix(".jpg")
|
||||
|
||||
// Create a new Queue notification
|
||||
queueArn := minio.NewArn("YOUR-PROVIDER", "YOUR-SERVICE", "YOUR-REGION", "YOUR-ACCOUNT-ID", "YOUR-RESOURCE")
|
||||
queueConfig := minio.NewNotificationConfig(queueArn)
|
||||
queueConfig.AddEvents(minio.ObjectRemovedAll)
|
||||
|
||||
// Create a new Lambda (CloudFunction)
|
||||
lambdaArn := minio.NewArn("YOUR-PROVIDER", "YOUR-SERVICE", "YOUR-REGION", "YOUR-ACCOUNT-ID", "YOUR-RESOURCE")
|
||||
lambdaConfig := minio.NewNotificationConfig(lambdaArn)
|
||||
lambdaConfig.AddEvents(minio.ObjectRemovedAll)
|
||||
lambdaConfig.AddFilterSuffix(".swp")
|
||||
|
||||
// Now, set all previously created notification configs
|
||||
bucketNotification := minio.BucketNotification{}
|
||||
bucketNotification.AddTopic(topicConfig)
|
||||
bucketNotification.AddQueue(queueConfig)
|
||||
bucketNotification.AddLambda(lambdaConfig)
|
||||
|
||||
err = s3Client.SetBucketNotification("YOUR-BUCKET", bucketNotification)
|
||||
if err != nil {
|
||||
log.Fatalln("Error: " + err.Error())
|
||||
}
|
||||
log.Println("Success")
|
||||
}
|
55
vendor/github.com/minio/minio-go/examples/s3/setbucketpolicy.go
generated
vendored
55
vendor/github.com/minio/minio-go/examples/s3/setbucketpolicy.go
generated
vendored
|
@ -1,55 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
"github.com/minio/minio-go/pkg/policy"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are
|
||||
// dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// s3Client.TraceOn(os.Stderr)
|
||||
|
||||
// Description of policy input.
|
||||
// policy.BucketPolicyNone - Remove any previously applied bucket policy at a prefix.
|
||||
// policy.BucketPolicyReadOnly - Set read-only operations at a prefix.
|
||||
// policy.BucketPolicyWriteOnly - Set write-only operations at a prefix.
|
||||
// policy.BucketPolicyReadWrite - Set read-write operations at a prefix.
|
||||
err = s3Client.SetBucketPolicy("my-bucketname", "my-objectprefix", policy.BucketPolicyReadWrite)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
log.Println("Success")
|
||||
}
|
46
vendor/github.com/minio/minio-go/examples/s3/statobject.go
generated
vendored
46
vendor/github.com/minio/minio-go/examples/s3/statobject.go
generated
vendored
|
@ -1,46 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname and my-objectname
|
||||
// are dummy values, please replace them with original values.
|
||||
|
||||
// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
|
||||
// This boolean value is the last argument for New().
|
||||
|
||||
// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
|
||||
// determined based on the Endpoint value.
|
||||
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
stat, err := s3Client.StatObject("my-bucketname", "my-objectname", minio.StatObjectOptions{})
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
log.Println(stat)
|
||||
}
|
649
vendor/github.com/minio/minio-go/functional_tests.go
generated
vendored
649
vendor/github.com/minio/minio-go/functional_tests.go
generated
vendored
|
@ -44,7 +44,6 @@ import (
|
|||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/minio/minio-go/pkg/encrypt"
|
||||
"github.com/minio/minio-go/pkg/policy"
|
||||
)
|
||||
|
||||
const letterBytes = "abcdefghijklmnopqrstuvwxyz01234569"
|
||||
|
@ -570,7 +569,7 @@ func testPutObjectReadAt() {
|
|||
logError(testName, function, args, startTime, "", fmt.Sprintf("Number of bytes in stat does not match, expected %d got %d", bufSize, st.Size), err)
|
||||
return
|
||||
}
|
||||
if st.ContentType != objectContentType {
|
||||
if st.ContentType != objectContentType && st.ContentType != "application/octet-stream" {
|
||||
logError(testName, function, args, startTime, "", "Content types don't match", err)
|
||||
return
|
||||
}
|
||||
|
@ -684,7 +683,7 @@ func testPutObjectWithMetadata() {
|
|||
logError(testName, function, args, startTime, "", "Number of bytes returned by PutObject does not match GetObject, expected "+string(bufSize)+" got "+string(st.Size), err)
|
||||
return
|
||||
}
|
||||
if st.ContentType != customContentType {
|
||||
if st.ContentType != customContentType && st.ContentType != "application/octet-stream" {
|
||||
logError(testName, function, args, startTime, "", "ContentType does not match, expected "+customContentType+" got "+st.ContentType, err)
|
||||
return
|
||||
}
|
||||
|
@ -706,6 +705,84 @@ func testPutObjectWithMetadata() {
|
|||
successLogger(testName, function, args, startTime).Info()
|
||||
}
|
||||
|
||||
func testPutObjectWithContentLanguage() {
|
||||
// initialize logging params
|
||||
objectName := "test-object"
|
||||
startTime := time.Now()
|
||||
testName := getFuncName()
|
||||
function := "PutObject(bucketName, objectName, reader, size, opts)"
|
||||
args := map[string]interface{}{
|
||||
"bucketName": "",
|
||||
"objectName": objectName,
|
||||
"size": -1,
|
||||
"opts": "",
|
||||
}
|
||||
|
||||
// Seed random based on current time.
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
// Instantiate new minio client object.
|
||||
c, err := minio.NewV4(
|
||||
os.Getenv(serverEndpoint),
|
||||
os.Getenv(accessKey),
|
||||
os.Getenv(secretKey),
|
||||
mustParseBool(os.Getenv(enableHTTPS)),
|
||||
)
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "Minio client object creation failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Enable tracing, write to stderr.
|
||||
// c.TraceOn(os.Stderr)
|
||||
|
||||
// Set user agent.
|
||||
c.SetAppInfo("Minio-go-FunctionalTest", "0.1.0")
|
||||
|
||||
// Generate a new random bucket name.
|
||||
bucketName := randString(60, rand.NewSource(time.Now().UnixNano()), "minio-go-test-")
|
||||
args["bucketName"] = bucketName
|
||||
// Make a new bucket.
|
||||
err = c.MakeBucket(bucketName, "us-east-1")
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "MakeBucket failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
data := bytes.Repeat([]byte("a"), int(0))
|
||||
n, err := c.PutObject(bucketName, objectName, bytes.NewReader(data), int64(0), minio.PutObjectOptions{
|
||||
ContentLanguage: "en",
|
||||
})
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "PutObject failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
if n != 0 {
|
||||
logError(testName, function, args, startTime, "", "Expected upload object '0' doesn't match with PutObject return value", err)
|
||||
return
|
||||
}
|
||||
|
||||
objInfo, err := c.StatObject(bucketName, objectName, minio.StatObjectOptions{})
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "StatObject failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
if objInfo.Metadata.Get("Content-Language") != "en" {
|
||||
logError(testName, function, args, startTime, "", "Expected content-language 'en' doesn't match with StatObject return value", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete all objects and buckets
|
||||
if err = cleanupBucket(bucketName, c); err != nil {
|
||||
logError(testName, function, args, startTime, "", "Cleanup failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
successLogger(testName, function, args, startTime).Info()
|
||||
}
|
||||
|
||||
// Test put object with streaming signature.
|
||||
func testPutObjectStreaming() {
|
||||
// initialize logging params
|
||||
|
@ -777,103 +854,6 @@ func testPutObjectStreaming() {
|
|||
successLogger(testName, function, args, startTime).Info()
|
||||
}
|
||||
|
||||
// Test listing partially uploaded objects.
|
||||
func testListPartiallyUploaded() {
|
||||
// initialize logging params
|
||||
startTime := time.Now()
|
||||
testName := getFuncName()
|
||||
function := "ListIncompleteUploads(bucketName, objectName, isRecursive, doneCh)"
|
||||
args := map[string]interface{}{
|
||||
"bucketName": "",
|
||||
"objectName": "",
|
||||
"isRecursive": "",
|
||||
}
|
||||
|
||||
// Seed random based on current time.
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
// Instantiate new minio client object.
|
||||
c, err := minio.New(
|
||||
os.Getenv(serverEndpoint),
|
||||
os.Getenv(accessKey),
|
||||
os.Getenv(secretKey),
|
||||
mustParseBool(os.Getenv(enableHTTPS)),
|
||||
)
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "Minio client object creation failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Set user agent.
|
||||
c.SetAppInfo("Minio-go-FunctionalTest", "0.1.0")
|
||||
|
||||
// Enable tracing, write to stdout.
|
||||
// c.TraceOn(os.Stderr)
|
||||
|
||||
// Generate a new random bucket name.
|
||||
bucketName := randString(60, rand.NewSource(time.Now().UnixNano()), "minio-go-test-")
|
||||
args["bucketName"] = bucketName
|
||||
|
||||
// Make a new bucket.
|
||||
err = c.MakeBucket(bucketName, "us-east-1")
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "MakeBucket failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
bufSize := dataFileMap["datafile-65-MB"]
|
||||
r := bytes.NewReader(bytes.Repeat([]byte("0"), bufSize*2))
|
||||
|
||||
reader, writer := io.Pipe()
|
||||
go func() {
|
||||
i := 0
|
||||
for i < 25 {
|
||||
_, cerr := io.CopyN(writer, r, (int64(bufSize)*2)/25)
|
||||
if cerr != nil {
|
||||
logError(testName, function, args, startTime, "", "Copy failed", err)
|
||||
return
|
||||
}
|
||||
i++
|
||||
r.Seek(0, 0)
|
||||
}
|
||||
writer.CloseWithError(errors.New("proactively closed to be verified later"))
|
||||
}()
|
||||
|
||||
objectName := bucketName + "-resumable"
|
||||
args["objectName"] = objectName
|
||||
|
||||
_, err = c.PutObject(bucketName, objectName, reader, int64(bufSize*2), minio.PutObjectOptions{ContentType: "application/octet-stream"})
|
||||
if err == nil {
|
||||
logError(testName, function, args, startTime, "", "PutObject should fail", err)
|
||||
return
|
||||
}
|
||||
if !strings.Contains(err.Error(), "proactively closed to be verified later") {
|
||||
logError(testName, function, args, startTime, "", "String not found in PutObject output", err)
|
||||
return
|
||||
}
|
||||
|
||||
doneCh := make(chan struct{})
|
||||
defer close(doneCh)
|
||||
isRecursive := true
|
||||
args["isRecursive"] = isRecursive
|
||||
|
||||
multiPartObjectCh := c.ListIncompleteUploads(bucketName, objectName, isRecursive, doneCh)
|
||||
for multiPartObject := range multiPartObjectCh {
|
||||
if multiPartObject.Err != nil {
|
||||
logError(testName, function, args, startTime, "", "Multipart object error", multiPartObject.Err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Delete all objects and buckets
|
||||
if err = cleanupBucket(bucketName, c); err != nil {
|
||||
logError(testName, function, args, startTime, "", "Cleanup failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
successLogger(testName, function, args, startTime).Info()
|
||||
}
|
||||
|
||||
// Test get object seeker from the end, using whence set to '2'.
|
||||
func testGetObjectSeekEnd() {
|
||||
// initialize logging params
|
||||
|
@ -1280,89 +1260,6 @@ func testRemoveMultipleObjects() {
|
|||
successLogger(testName, function, args, startTime).Info()
|
||||
}
|
||||
|
||||
// Tests removing partially uploaded objects.
|
||||
func testRemovePartiallyUploaded() {
|
||||
// initialize logging params
|
||||
startTime := time.Now()
|
||||
testName := getFuncName()
|
||||
function := "RemoveIncompleteUpload(bucketName, objectName)"
|
||||
args := map[string]interface{}{}
|
||||
|
||||
// Seed random based on current time.
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
// Instantiate new minio client object.
|
||||
c, err := minio.New(
|
||||
os.Getenv(serverEndpoint),
|
||||
os.Getenv(accessKey),
|
||||
os.Getenv(secretKey),
|
||||
mustParseBool(os.Getenv(enableHTTPS)),
|
||||
)
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "Minio client object creation failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Set user agent.
|
||||
c.SetAppInfo("Minio-go-FunctionalTest", "0.1.0")
|
||||
|
||||
// Enable tracing, write to stdout.
|
||||
// c.TraceOn(os.Stderr)
|
||||
|
||||
// Generate a new random bucket name.
|
||||
bucketName := randString(60, rand.NewSource(time.Now().UnixNano()), "minio-go-test-")
|
||||
args["bucketName"] = bucketName
|
||||
|
||||
// Make a new bucket.
|
||||
err = c.MakeBucket(bucketName, "us-east-1")
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "MakeBucket failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
r := bytes.NewReader(bytes.Repeat([]byte("a"), 128*1024))
|
||||
|
||||
reader, writer := io.Pipe()
|
||||
go func() {
|
||||
i := 0
|
||||
for i < 25 {
|
||||
_, cerr := io.CopyN(writer, r, 128*1024)
|
||||
if cerr != nil {
|
||||
logError(testName, function, args, startTime, "", "Copy failed", err)
|
||||
return
|
||||
}
|
||||
i++
|
||||
r.Seek(0, 0)
|
||||
}
|
||||
writer.CloseWithError(errors.New("proactively closed to be verified later"))
|
||||
}()
|
||||
|
||||
objectName := bucketName + "-resumable"
|
||||
args["objectName"] = objectName
|
||||
|
||||
_, err = c.PutObject(bucketName, objectName, reader, 128*1024, minio.PutObjectOptions{ContentType: "application/octet-stream"})
|
||||
if err == nil {
|
||||
logError(testName, function, args, startTime, "", "PutObject should fail", err)
|
||||
return
|
||||
}
|
||||
if !strings.Contains(err.Error(), "proactively closed to be verified later") {
|
||||
logError(testName, function, args, startTime, "", "String not found", err)
|
||||
return
|
||||
}
|
||||
err = c.RemoveIncompleteUpload(bucketName, objectName)
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "RemoveIncompleteUpload failed", err)
|
||||
return
|
||||
}
|
||||
// Delete all objects and buckets
|
||||
if err = cleanupBucket(bucketName, c); err != nil {
|
||||
logError(testName, function, args, startTime, "", "Cleanup failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
successLogger(testName, function, args, startTime).Info()
|
||||
}
|
||||
|
||||
// Tests FPutObject of a big file to trigger multipart
|
||||
func testFPutObjectMultipart() {
|
||||
// initialize logging params
|
||||
|
@ -1462,7 +1359,7 @@ func testFPutObjectMultipart() {
|
|||
logError(testName, function, args, startTime, "", "Number of bytes does not match, expected "+string(int64(totalSize))+" got "+string(objInfo.Size), err)
|
||||
return
|
||||
}
|
||||
if objInfo.ContentType != objectContentType {
|
||||
if objInfo.ContentType != objectContentType && objInfo.ContentType != "application/octet-stream" {
|
||||
logError(testName, function, args, startTime, "", "ContentType doesn't match", err)
|
||||
return
|
||||
}
|
||||
|
@ -1602,6 +1499,7 @@ func testFPutObject() {
|
|||
|
||||
// Perform FPutObject with no contentType provided (Expecting application/x-gtar)
|
||||
args["objectName"] = objectName + "-GTar"
|
||||
args["opts"] = minio.PutObjectOptions{}
|
||||
n, err = c.FPutObject(bucketName, objectName+"-GTar", fName+".gtar", minio.PutObjectOptions{})
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "FPutObject failed", err)
|
||||
|
@ -1644,8 +1542,8 @@ func testFPutObject() {
|
|||
logError(testName, function, args, startTime, "", "StatObject failed", err)
|
||||
return
|
||||
}
|
||||
if rGTar.ContentType != "application/x-gtar" {
|
||||
logError(testName, function, args, startTime, "", "ContentType does not match, expected application/x-gtar, got "+rGTar.ContentType, err)
|
||||
if rGTar.ContentType != "application/x-gtar" && rGTar.ContentType != "application/octet-stream" {
|
||||
logError(testName, function, args, startTime, "", "ContentType does not match, expected application/x-gtar or application/octet-stream, got "+rGTar.ContentType, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -2726,8 +2624,14 @@ func testCopyObject() {
|
|||
return
|
||||
}
|
||||
|
||||
oi, err := c.StatObject(bucketName, objectName, minio.StatObjectOptions{})
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "StatObject failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
stOpts := minio.StatObjectOptions{}
|
||||
stOpts.SetMatchETag(objInfo.ETag)
|
||||
stOpts.SetMatchETag(oi.ETag)
|
||||
objInfo, err = c.StatObject(bucketName, objectName, stOpts)
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "CopyObject ETag should match and not fail", err)
|
||||
|
@ -3558,117 +3462,104 @@ func testFunctional() {
|
|||
}
|
||||
|
||||
// Asserting the default bucket policy.
|
||||
function = "GetBucketPolicy(bucketName, objectPrefix)"
|
||||
function = "GetBucketPolicy(bucketName)"
|
||||
functionAll += ", " + function
|
||||
args = map[string]interface{}{
|
||||
"bucketName": bucketName,
|
||||
"objectPrefix": "",
|
||||
"bucketName": bucketName,
|
||||
}
|
||||
policyAccess, err := c.GetBucketPolicy(bucketName, "")
|
||||
|
||||
nilPolicy, err := c.GetBucketPolicy(bucketName)
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "GetBucketPolicy failed", err)
|
||||
return
|
||||
}
|
||||
if policyAccess != "none" {
|
||||
logError(testName, function, args, startTime, "", "policy should be set to none", err)
|
||||
if nilPolicy != "" {
|
||||
logError(testName, function, args, startTime, "", "policy should be set to nil", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Set the bucket policy to 'public readonly'.
|
||||
function = "SetBucketPolicy(bucketName, objectPrefix, bucketPolicy)"
|
||||
function = "SetBucketPolicy(bucketName, readOnlyPolicy)"
|
||||
functionAll += ", " + function
|
||||
|
||||
readOnlyPolicy := `{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":["*"]},"Action":["s3:ListBucket"],"Resource":["arn:aws:s3:::` + bucketName + `"]}]}`
|
||||
args = map[string]interface{}{
|
||||
"bucketName": bucketName,
|
||||
"objectPrefix": "",
|
||||
"bucketPolicy": policy.BucketPolicyReadOnly,
|
||||
"bucketPolicy": readOnlyPolicy,
|
||||
}
|
||||
err = c.SetBucketPolicy(bucketName, "", policy.BucketPolicyReadOnly)
|
||||
|
||||
err = c.SetBucketPolicy(bucketName, readOnlyPolicy)
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "SetBucketPolicy failed", err)
|
||||
return
|
||||
}
|
||||
// should return policy `readonly`.
|
||||
function = "GetBucketPolicy(bucketName, objectPrefix)"
|
||||
function = "GetBucketPolicy(bucketName)"
|
||||
functionAll += ", " + function
|
||||
args = map[string]interface{}{
|
||||
"bucketName": bucketName,
|
||||
"objectPrefix": "",
|
||||
"bucketName": bucketName,
|
||||
}
|
||||
policyAccess, err = c.GetBucketPolicy(bucketName, "")
|
||||
|
||||
_, err = c.GetBucketPolicy(bucketName)
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "GetBucketPolicy failed", err)
|
||||
return
|
||||
}
|
||||
if policyAccess != "readonly" {
|
||||
logError(testName, function, args, startTime, "", "policy should be set to readonly", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Make the bucket 'public writeonly'.
|
||||
function = "SetBucketPolicy(bucketName, objectPrefix, bucketPolicy)"
|
||||
function = "SetBucketPolicy(bucketName, writeOnlyPolicy)"
|
||||
functionAll += ", " + function
|
||||
|
||||
writeOnlyPolicy := `{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":["*"]},"Action":["s3:ListBucketMultipartUploads"],"Resource":["arn:aws:s3:::` + bucketName + `"]}]}`
|
||||
args = map[string]interface{}{
|
||||
"bucketName": bucketName,
|
||||
"objectPrefix": "",
|
||||
"bucketPolicy": policy.BucketPolicyWriteOnly,
|
||||
"bucketPolicy": writeOnlyPolicy,
|
||||
}
|
||||
err = c.SetBucketPolicy(bucketName, "", policy.BucketPolicyWriteOnly)
|
||||
err = c.SetBucketPolicy(bucketName, writeOnlyPolicy)
|
||||
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "SetBucketPolicy failed", err)
|
||||
return
|
||||
}
|
||||
// should return policy `writeonly`.
|
||||
function = "GetBucketPolicy(bucketName, objectPrefix)"
|
||||
function = "GetBucketPolicy(bucketName)"
|
||||
functionAll += ", " + function
|
||||
args = map[string]interface{}{
|
||||
"bucketName": bucketName,
|
||||
"objectPrefix": "",
|
||||
"bucketName": bucketName,
|
||||
}
|
||||
policyAccess, err = c.GetBucketPolicy(bucketName, "")
|
||||
|
||||
_, err = c.GetBucketPolicy(bucketName)
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "GetBucketPolicy failed", err)
|
||||
return
|
||||
}
|
||||
if policyAccess != "writeonly" {
|
||||
logError(testName, function, args, startTime, "", "policy should be set to writeonly", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Make the bucket 'public read/write'.
|
||||
function = "SetBucketPolicy(bucketName, objectPrefix, bucketPolicy)"
|
||||
function = "SetBucketPolicy(bucketName, readWritePolicy)"
|
||||
functionAll += ", " + function
|
||||
|
||||
readWritePolicy := `{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":["*"]},"Action":["s3:ListBucket","s3:ListBucketMultipartUploads"],"Resource":["arn:aws:s3:::` + bucketName + `"]}]}`
|
||||
|
||||
args = map[string]interface{}{
|
||||
"bucketName": bucketName,
|
||||
"objectPrefix": "",
|
||||
"bucketPolicy": policy.BucketPolicyReadWrite,
|
||||
"bucketPolicy": readWritePolicy,
|
||||
}
|
||||
err = c.SetBucketPolicy(bucketName, "", policy.BucketPolicyReadWrite)
|
||||
err = c.SetBucketPolicy(bucketName, readWritePolicy)
|
||||
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "SetBucketPolicy failed", err)
|
||||
return
|
||||
}
|
||||
// should return policy `readwrite`.
|
||||
function = "GetBucketPolicy(bucketName, objectPrefix)"
|
||||
function = "GetBucketPolicy(bucketName)"
|
||||
functionAll += ", " + function
|
||||
args = map[string]interface{}{
|
||||
"bucketName": bucketName,
|
||||
"objectPrefix": "",
|
||||
"bucketName": bucketName,
|
||||
}
|
||||
policyAccess, err = c.GetBucketPolicy(bucketName, "")
|
||||
|
||||
_, err = c.GetBucketPolicy(bucketName)
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "GetBucketPolicy failed", err)
|
||||
return
|
||||
}
|
||||
if policyAccess != "readwrite" {
|
||||
logError(testName, function, args, startTime, "", "policy should be set to readwrite", err)
|
||||
return
|
||||
}
|
||||
|
||||
// List all buckets.
|
||||
function = "ListBuckets()"
|
||||
functionAll += ", " + function
|
||||
|
@ -4496,89 +4387,6 @@ func testGetObjectClosedTwiceV2() {
|
|||
successLogger(testName, function, args, startTime).Info()
|
||||
}
|
||||
|
||||
// Tests removing partially uploaded objects.
|
||||
func testRemovePartiallyUploadedV2() {
|
||||
// initialize logging params
|
||||
startTime := time.Now()
|
||||
testName := getFuncName()
|
||||
function := "RemoveIncompleteUpload(bucketName, objectName)"
|
||||
args := map[string]interface{}{}
|
||||
|
||||
// Seed random based on current time.
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
// Instantiate new minio client object.
|
||||
c, err := minio.NewV2(
|
||||
os.Getenv(serverEndpoint),
|
||||
os.Getenv(accessKey),
|
||||
os.Getenv(secretKey),
|
||||
mustParseBool(os.Getenv(enableHTTPS)),
|
||||
)
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "Minio v2 client object creation failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Set user agent.
|
||||
c.SetAppInfo("Minio-go-FunctionalTest", "0.1.0")
|
||||
|
||||
// Enable tracing, write to stdout.
|
||||
// c.TraceOn(os.Stderr)
|
||||
|
||||
// Generate a new random bucket name.
|
||||
bucketName := randString(60, rand.NewSource(time.Now().UnixNano()), "minio-go-test-")
|
||||
args["bucketName"] = bucketName
|
||||
|
||||
// make a new bucket.
|
||||
err = c.MakeBucket(bucketName, "us-east-1")
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "MakeBucket failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
r := bytes.NewReader(bytes.Repeat([]byte("a"), 128*1024))
|
||||
|
||||
reader, writer := io.Pipe()
|
||||
go func() {
|
||||
i := 0
|
||||
for i < 25 {
|
||||
_, cerr := io.CopyN(writer, r, 128*1024)
|
||||
if cerr != nil {
|
||||
logError(testName, function, args, startTime, "", "Copy failed", cerr)
|
||||
return
|
||||
}
|
||||
i++
|
||||
r.Seek(0, 0)
|
||||
}
|
||||
writer.CloseWithError(errors.New("proactively closed to be verified later"))
|
||||
}()
|
||||
|
||||
objectName := bucketName + "-resumable"
|
||||
args["objectName"] = objectName
|
||||
|
||||
_, err = c.PutObject(bucketName, objectName, reader, -1, minio.PutObjectOptions{ContentType: "application/octet-stream"})
|
||||
if err == nil {
|
||||
logError(testName, function, args, startTime, "", "PutObject should fail", err)
|
||||
return
|
||||
}
|
||||
if err.Error() != "proactively closed to be verified later" {
|
||||
logError(testName, function, args, startTime, "", "Unexpected error, expected : proactively closed to be verified later", err)
|
||||
return
|
||||
}
|
||||
err = c.RemoveIncompleteUpload(bucketName, objectName)
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "RemoveIncompleteUpload failed", err)
|
||||
return
|
||||
}
|
||||
// Delete all objects and buckets
|
||||
if err = cleanupBucket(bucketName, c); err != nil {
|
||||
logError(testName, function, args, startTime, "", "Cleanup failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
successLogger(testName, function, args, startTime).Info()
|
||||
}
|
||||
|
||||
// Tests FPutObject hidden contentType setting
|
||||
func testFPutObjectV2() {
|
||||
// initialize logging params
|
||||
|
@ -4728,7 +4536,7 @@ func testFPutObjectV2() {
|
|||
logError(testName, function, args, startTime, "", "StatObject failed", err)
|
||||
return
|
||||
}
|
||||
if rGTar.ContentType != "application/x-gtar" {
|
||||
if rGTar.ContentType != "application/x-gtar" && rGTar.ContentType != "application/octet-stream" {
|
||||
logError(testName, function, args, startTime, "", "Content-Type headers mismatched, expected: application/x-gtar , got "+rGTar.ContentType, err)
|
||||
return
|
||||
}
|
||||
|
@ -5829,6 +5637,60 @@ func testEncryptedCopyObjectV2() {
|
|||
testEncryptedCopyObjectWrapper(c)
|
||||
}
|
||||
|
||||
func testDecryptedCopyObject() {
|
||||
// initialize logging params
|
||||
startTime := time.Now()
|
||||
testName := getFuncName()
|
||||
function := "CopyObject(destination, source)"
|
||||
args := map[string]interface{}{}
|
||||
|
||||
// Instantiate new minio client object
|
||||
c, err := minio.New(
|
||||
os.Getenv(serverEndpoint),
|
||||
os.Getenv(accessKey),
|
||||
os.Getenv(secretKey),
|
||||
mustParseBool(os.Getenv(enableHTTPS)),
|
||||
)
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "Minio v2 client object creation failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
bucketName, objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "minio-go-test-"), "object"
|
||||
if err = c.MakeBucket(bucketName, "us-east-1"); err != nil {
|
||||
logError(testName, function, args, startTime, "", "MakeBucket failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
encryption := encrypt.DefaultPBKDF([]byte("correct horse battery staple"), []byte(bucketName+objectName))
|
||||
_, err = c.PutObject(bucketName, objectName, bytes.NewReader(bytes.Repeat([]byte("a"), 1024*1024)), 1024*1024, minio.PutObjectOptions{
|
||||
ServerSideEncryption: encryption,
|
||||
})
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "PutObject call failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
src := minio.NewSourceInfo(bucketName, objectName, encrypt.SSECopy(encryption))
|
||||
args["source"] = src
|
||||
dst, err := minio.NewDestinationInfo(bucketName, "decrypted-"+objectName, nil, nil)
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "NewDestinationInfo failed", err)
|
||||
return
|
||||
}
|
||||
args["destination"] = dst
|
||||
|
||||
if err = c.CopyObject(dst, src); err != nil {
|
||||
logError(testName, function, args, startTime, "", "CopyObject failed", err)
|
||||
return
|
||||
}
|
||||
if _, err = c.GetObject(bucketName, "decrypted-"+objectName, minio.GetObjectOptions{}); err != nil {
|
||||
logError(testName, function, args, startTime, "", "GetObject failed", err)
|
||||
return
|
||||
}
|
||||
successLogger(testName, function, args, startTime).Info()
|
||||
}
|
||||
|
||||
func testUserMetadataCopying() {
|
||||
// initialize logging params
|
||||
startTime := time.Now()
|
||||
|
@ -6121,7 +5983,11 @@ func testStorageClassMetadataPutObject() {
|
|||
logError(testName, function, args, startTime, "", "Metadata verification failed, STANDARD storage class should not be a part of response metadata", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete all objects and buckets
|
||||
if err = cleanupBucket(bucketName, c); err != nil {
|
||||
logError(testName, function, args, startTime, "", "Cleanup failed", err)
|
||||
return
|
||||
}
|
||||
successLogger(testName, function, args, startTime).Info()
|
||||
}
|
||||
|
||||
|
@ -6162,7 +6028,11 @@ func testStorageClassInvalidMetadataPutObject() {
|
|||
logError(testName, function, args, startTime, "", "PutObject with invalid storage class passed, was expected to fail", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete all objects and buckets
|
||||
if err = cleanupBucket(bucketName, c); err != nil {
|
||||
logError(testName, function, args, startTime, "", "Cleanup failed", err)
|
||||
return
|
||||
}
|
||||
successLogger(testName, function, args, startTime).Info()
|
||||
}
|
||||
|
||||
|
@ -6262,7 +6132,11 @@ func testStorageClassMetadataCopyObject() {
|
|||
logError(testName, function, args, startTime, "", "Metadata verification failed, STANDARD storage class should not be a part of response metadata", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete all objects and buckets
|
||||
if err = cleanupBucket(bucketName, c); err != nil {
|
||||
logError(testName, function, args, startTime, "", "Cleanup failed", err)
|
||||
return
|
||||
}
|
||||
successLogger(testName, function, args, startTime).Info()
|
||||
}
|
||||
|
||||
|
@ -6620,14 +6494,17 @@ func testFunctionalV2() {
|
|||
}
|
||||
|
||||
// Make the bucket 'public read/write'.
|
||||
function = "SetBucketPolicy(bucketName, objectPrefix, bucketPolicy)"
|
||||
function = "SetBucketPolicy(bucketName, bucketPolicy)"
|
||||
functionAll += ", " + function
|
||||
|
||||
readWritePolicy := `{"Version": "2012-10-17","Statement": [{"Action": ["s3:ListBucketMultipartUploads", "s3:ListBucket"],"Effect": "Allow","Principal": {"AWS": ["*"]},"Resource": ["arn:aws:s3:::` + bucketName + `"],"Sid": ""}]}`
|
||||
|
||||
args = map[string]interface{}{
|
||||
"bucketName": bucketName,
|
||||
"objectPrefix": "",
|
||||
"bucketPolicy": policy.BucketPolicyReadWrite,
|
||||
"bucketPolicy": readWritePolicy,
|
||||
}
|
||||
err = c.SetBucketPolicy(bucketName, "", policy.BucketPolicyReadWrite)
|
||||
err = c.SetBucketPolicy(bucketName, readWritePolicy)
|
||||
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "SetBucketPolicy failed", err)
|
||||
return
|
||||
|
@ -6681,9 +6558,9 @@ func testFunctionalV2() {
|
|||
return
|
||||
}
|
||||
|
||||
objectName_noLength := objectName + "-nolength"
|
||||
args["objectName"] = objectName_noLength
|
||||
n, err = c.PutObject(bucketName, objectName_noLength, bytes.NewReader(buf), int64(len(buf)), minio.PutObjectOptions{ContentType: "binary/octet-stream"})
|
||||
objectNameNoLength := objectName + "-nolength"
|
||||
args["objectName"] = objectNameNoLength
|
||||
n, err = c.PutObject(bucketName, objectNameNoLength, bytes.NewReader(buf), int64(len(buf)), minio.PutObjectOptions{ContentType: "binary/octet-stream"})
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "PutObject failed", err)
|
||||
return
|
||||
|
@ -7426,6 +7303,120 @@ func testFGetObjectWithContextV2() {
|
|||
|
||||
}
|
||||
|
||||
// Test list object v1 and V2 storage class fields
|
||||
func testListObjects() {
|
||||
// initialize logging params
|
||||
startTime := time.Now()
|
||||
testName := getFuncName()
|
||||
function := "ListObjects(bucketName, objectPrefix, recursive, doneCh)"
|
||||
args := map[string]interface{}{
|
||||
"bucketName": "",
|
||||
"objectPrefix": "",
|
||||
"recursive": "true",
|
||||
}
|
||||
// Seed random based on current time.
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
// Instantiate new minio client object.
|
||||
c, err := minio.New(
|
||||
os.Getenv(serverEndpoint),
|
||||
os.Getenv(accessKey),
|
||||
os.Getenv(secretKey),
|
||||
mustParseBool(os.Getenv(enableHTTPS)),
|
||||
)
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "Minio client v4 object creation failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Enable tracing, write to stderr.
|
||||
// c.TraceOn(os.Stderr)
|
||||
|
||||
// Set user agent.
|
||||
c.SetAppInfo("Minio-go-FunctionalTest", "0.1.0")
|
||||
|
||||
// Generate a new random bucket name.
|
||||
bucketName := randString(60, rand.NewSource(time.Now().UnixNano()), "minio-go-test-")
|
||||
args["bucketName"] = bucketName
|
||||
|
||||
// Make a new bucket.
|
||||
err = c.MakeBucket(bucketName, "us-east-1")
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "MakeBucket failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
bufSize := dataFileMap["datafile-33-kB"]
|
||||
var reader = getDataReader("datafile-33-kB")
|
||||
defer reader.Close()
|
||||
|
||||
// Save the data
|
||||
objectName1 := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
|
||||
_, err = c.PutObject(bucketName, objectName1, reader, int64(bufSize), minio.PutObjectOptions{ContentType: "binary/octet-stream", StorageClass: "STANDARD"})
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "PutObject1 call failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
bufSize1 := dataFileMap["datafile-33-kB"]
|
||||
var reader1 = getDataReader("datafile-33-kB")
|
||||
defer reader1.Close()
|
||||
objectName2 := randString(60, rand.NewSource(time.Now().UnixNano()), "")
|
||||
|
||||
_, err = c.PutObject(bucketName, objectName2, reader1, int64(bufSize1), minio.PutObjectOptions{ContentType: "binary/octet-stream", StorageClass: "REDUCED_REDUNDANCY"})
|
||||
if err != nil {
|
||||
logError(testName, function, args, startTime, "", "PutObject2 call failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Create a done channel to control 'ListObjects' go routine.
|
||||
doneCh := make(chan struct{})
|
||||
// Exit cleanly upon return.
|
||||
defer close(doneCh)
|
||||
|
||||
// check for storage-class from ListObjects result
|
||||
for objInfo := range c.ListObjects(bucketName, "", true, doneCh) {
|
||||
if objInfo.Err != nil {
|
||||
logError(testName, function, args, startTime, "", "ListObjects failed unexpectedly", err)
|
||||
return
|
||||
}
|
||||
if objInfo.Key == objectName1 && objInfo.StorageClass != "STANDARD" {
|
||||
// Ignored as Gateways (Azure/GCS etc) wont return storage class
|
||||
ignoredLog(testName, function, args, startTime, "ListObjects doesn't return expected storage class").Info()
|
||||
}
|
||||
if objInfo.Key == objectName2 && objInfo.StorageClass != "REDUCED_REDUNDANCY" {
|
||||
// Ignored as Gateways (Azure/GCS etc) wont return storage class
|
||||
ignoredLog(testName, function, args, startTime, "ListObjects doesn't return expected storage class").Info()
|
||||
}
|
||||
}
|
||||
|
||||
// check for storage-class from ListObjectsV2 result
|
||||
for objInfo := range c.ListObjectsV2(bucketName, "", true, doneCh) {
|
||||
if objInfo.Err != nil {
|
||||
logError(testName, function, args, startTime, "", "ListObjectsV2 failed unexpectedly", err)
|
||||
return
|
||||
}
|
||||
if objInfo.Key == objectName1 && objInfo.StorageClass != "STANDARD" {
|
||||
// Ignored as Gateways (Azure/GCS etc) wont return storage class
|
||||
ignoredLog(testName, function, args, startTime, "ListObjectsV2 doesn't return expected storage class").Info()
|
||||
}
|
||||
if objInfo.Key == objectName2 && objInfo.StorageClass != "REDUCED_REDUNDANCY" {
|
||||
// Ignored as Gateways (Azure/GCS etc) wont return storage class
|
||||
ignoredLog(testName, function, args, startTime, "ListObjectsV2 doesn't return expected storage class").Info()
|
||||
}
|
||||
}
|
||||
|
||||
// Delete all objects and buckets
|
||||
if err = cleanupBucket(bucketName, c); err != nil {
|
||||
logError(testName, function, args, startTime, "", "Cleanup failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
successLogger(testName, function, args, startTime).Info()
|
||||
|
||||
}
|
||||
|
||||
// Convert string to bool and always return false if any error
|
||||
func mustParseBool(str string) bool {
|
||||
b, err := strconv.ParseBool(str)
|
||||
|
@ -7450,7 +7441,6 @@ func main() {
|
|||
if isFullMode() {
|
||||
testMakeBucketErrorV2()
|
||||
testGetObjectClosedTwiceV2()
|
||||
testRemovePartiallyUploadedV2()
|
||||
testFPutObjectV2()
|
||||
testMakeBucketRegionsV2()
|
||||
testGetObjectReadSeekFunctionalV2()
|
||||
|
@ -7472,11 +7462,9 @@ func main() {
|
|||
testPutObjectWithMetadata()
|
||||
testPutObjectReadAt()
|
||||
testPutObjectStreaming()
|
||||
testListPartiallyUploaded()
|
||||
testGetObjectSeekEnd()
|
||||
testGetObjectClosedTwice()
|
||||
testRemoveMultipleObjects()
|
||||
testRemovePartiallyUploaded()
|
||||
testFPutObjectMultipart()
|
||||
testFPutObject()
|
||||
testGetObjectReadSeekFunctional()
|
||||
|
@ -7497,6 +7485,8 @@ func main() {
|
|||
testStorageClassMetadataPutObject()
|
||||
testStorageClassInvalidMetadataPutObject()
|
||||
testStorageClassMetadataCopyObject()
|
||||
testPutObjectWithContentLanguage()
|
||||
testListObjects()
|
||||
|
||||
// SSE-C tests will only work over TLS connection.
|
||||
if tls {
|
||||
|
@ -7507,6 +7497,7 @@ func main() {
|
|||
testEncryptedCopyObjectV2()
|
||||
testEncryptedCopyObject()
|
||||
testEncryptedEmptyObject()
|
||||
testDecryptedCopyObject()
|
||||
}
|
||||
} else {
|
||||
testFunctional()
|
||||
|
|
57
vendor/github.com/minio/minio-go/get-options_test.go
generated
vendored
57
vendor/github.com/minio/minio-go/get-options_test.go
generated
vendored
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSetHeader(t *testing.T) {
|
||||
testCases := []struct {
|
||||
start int64
|
||||
end int64
|
||||
errVal error
|
||||
expected string
|
||||
}{
|
||||
{0, 10, nil, "bytes=0-10"},
|
||||
{1, 10, nil, "bytes=1-10"},
|
||||
{5, 0, nil, "bytes=5-"},
|
||||
{0, -5, nil, "bytes=-5"},
|
||||
{0, 0, nil, "bytes=0-0"},
|
||||
{11, 10, fmt.Errorf("Invalid range specified: start=11 end=10"),
|
||||
""},
|
||||
{-1, 10, fmt.Errorf("Invalid range specified: start=-1 end=10"), ""},
|
||||
{-1, 0, fmt.Errorf("Invalid range specified: start=-1 end=0"), ""},
|
||||
{1, -5, fmt.Errorf("Invalid range specified: start=1 end=-5"), ""},
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
opts := GetObjectOptions{}
|
||||
err := opts.SetRange(testCase.start, testCase.end)
|
||||
if err == nil && testCase.errVal != nil {
|
||||
t.Errorf("Test %d: Expected to fail with '%v' but it passed",
|
||||
i+1, testCase.errVal)
|
||||
} else if err != nil && testCase.errVal.Error() != err.Error() {
|
||||
t.Errorf("Test %d: Expected error '%v' but got error '%v'",
|
||||
i+1, testCase.errVal, err)
|
||||
} else if err == nil && opts.headers["Range"] != testCase.expected {
|
||||
t.Errorf("Test %d: Expected range header '%s', but got '%s'",
|
||||
i+1, testCase.expected, opts.headers["Range"])
|
||||
}
|
||||
}
|
||||
}
|
144
vendor/github.com/minio/minio-go/pkg/credentials/chain_test.go
generated
vendored
144
vendor/github.com/minio/minio-go/pkg/credentials/chain_test.go
generated
vendored
|
@ -1,144 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 credentials
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testCredProvider struct {
|
||||
creds Value
|
||||
expired bool
|
||||
err error
|
||||
}
|
||||
|
||||
func (s *testCredProvider) Retrieve() (Value, error) {
|
||||
s.expired = false
|
||||
return s.creds, s.err
|
||||
}
|
||||
func (s *testCredProvider) IsExpired() bool {
|
||||
return s.expired
|
||||
}
|
||||
|
||||
func TestChainGet(t *testing.T) {
|
||||
p := &Chain{
|
||||
Providers: []Provider{
|
||||
&credProvider{err: errors.New("FirstError")},
|
||||
&credProvider{err: errors.New("SecondError")},
|
||||
&testCredProvider{
|
||||
creds: Value{
|
||||
AccessKeyID: "AKIF",
|
||||
SecretAccessKey: "NOSECRET",
|
||||
SessionToken: "",
|
||||
},
|
||||
},
|
||||
&credProvider{
|
||||
creds: Value{
|
||||
AccessKeyID: "AKID",
|
||||
SecretAccessKey: "SECRET",
|
||||
SessionToken: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
creds, err := p.Retrieve()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Also check credentials
|
||||
if creds.AccessKeyID != "AKIF" {
|
||||
t.Fatalf("Expected 'AKIF', got %s", creds.AccessKeyID)
|
||||
}
|
||||
if creds.SecretAccessKey != "NOSECRET" {
|
||||
t.Fatalf("Expected 'NOSECRET', got %s", creds.SecretAccessKey)
|
||||
}
|
||||
if creds.SessionToken != "" {
|
||||
t.Fatalf("Expected empty token, got %s", creds.SessionToken)
|
||||
}
|
||||
}
|
||||
|
||||
func TestChainIsExpired(t *testing.T) {
|
||||
credProvider := &credProvider{
|
||||
creds: Value{
|
||||
AccessKeyID: "UXHW",
|
||||
SecretAccessKey: "MYSECRET",
|
||||
SessionToken: "",
|
||||
},
|
||||
expired: true,
|
||||
}
|
||||
p := &Chain{
|
||||
Providers: []Provider{
|
||||
credProvider,
|
||||
},
|
||||
}
|
||||
|
||||
if !p.IsExpired() {
|
||||
t.Fatal("Expected expired to be true before any Retrieve")
|
||||
}
|
||||
|
||||
_, err := p.Retrieve()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if p.IsExpired() {
|
||||
t.Fatal("Expected to be not expired after Retrieve")
|
||||
}
|
||||
}
|
||||
|
||||
func TestChainWithNoProvider(t *testing.T) {
|
||||
p := &Chain{
|
||||
Providers: []Provider{},
|
||||
}
|
||||
if !p.IsExpired() {
|
||||
t.Fatal("Expected to be expired with no providers")
|
||||
}
|
||||
_, err := p.Retrieve()
|
||||
if err != nil {
|
||||
if err.Error() != "No valid providers found []" {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestChainProviderWithNoValidProvider(t *testing.T) {
|
||||
errs := []error{
|
||||
errors.New("FirstError"),
|
||||
errors.New("SecondError"),
|
||||
}
|
||||
p := &Chain{
|
||||
Providers: []Provider{
|
||||
&credProvider{err: errs[0]},
|
||||
&credProvider{err: errs[1]},
|
||||
},
|
||||
}
|
||||
|
||||
if !p.IsExpired() {
|
||||
t.Fatal("Expected to be expired with no providers")
|
||||
}
|
||||
|
||||
_, err := p.Retrieve()
|
||||
if err != nil {
|
||||
if err.Error() != "No valid providers found [FirstError SecondError]" {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
73
vendor/github.com/minio/minio-go/pkg/credentials/credentials_test.go
generated
vendored
73
vendor/github.com/minio/minio-go/pkg/credentials/credentials_test.go
generated
vendored
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 credentials
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type credProvider struct {
|
||||
creds Value
|
||||
expired bool
|
||||
err error
|
||||
}
|
||||
|
||||
func (s *credProvider) Retrieve() (Value, error) {
|
||||
s.expired = false
|
||||
return s.creds, s.err
|
||||
}
|
||||
func (s *credProvider) IsExpired() bool {
|
||||
return s.expired
|
||||
}
|
||||
|
||||
func TestCredentialsGet(t *testing.T) {
|
||||
c := New(&credProvider{
|
||||
creds: Value{
|
||||
AccessKeyID: "UXHW",
|
||||
SecretAccessKey: "MYSECRET",
|
||||
SessionToken: "",
|
||||
},
|
||||
expired: true,
|
||||
})
|
||||
|
||||
creds, err := c.Get()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if "UXHW" != creds.AccessKeyID {
|
||||
t.Errorf("Expected \"UXHW\", got %s", creds.AccessKeyID)
|
||||
}
|
||||
if "MYSECRET" != creds.SecretAccessKey {
|
||||
t.Errorf("Expected \"MYSECRET\", got %s", creds.SecretAccessKey)
|
||||
}
|
||||
if creds.SessionToken != "" {
|
||||
t.Errorf("Expected session token to be empty, got %s", creds.SessionToken)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCredentialsGetWithError(t *testing.T) {
|
||||
c := New(&credProvider{err: errors.New("Custom error")})
|
||||
|
||||
_, err := c.Get()
|
||||
if err != nil {
|
||||
if err.Error() != "Custom error" {
|
||||
t.Errorf("Expected \"Custom error\", got %s", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
105
vendor/github.com/minio/minio-go/pkg/credentials/env_test.go
generated
vendored
105
vendor/github.com/minio/minio-go/pkg/credentials/env_test.go
generated
vendored
|
@ -1,105 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 credentials
|
||||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEnvAWSRetrieve(t *testing.T) {
|
||||
os.Clearenv()
|
||||
os.Setenv("AWS_ACCESS_KEY_ID", "access")
|
||||
os.Setenv("AWS_SECRET_ACCESS_KEY", "secret")
|
||||
os.Setenv("AWS_SESSION_TOKEN", "token")
|
||||
|
||||
e := EnvAWS{}
|
||||
if !e.IsExpired() {
|
||||
t.Error("Expect creds to be expired before retrieve.")
|
||||
}
|
||||
|
||||
creds, err := e.Retrieve()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
expectedCreds := Value{
|
||||
AccessKeyID: "access",
|
||||
SecretAccessKey: "secret",
|
||||
SessionToken: "token",
|
||||
SignerType: SignatureV4,
|
||||
}
|
||||
if !reflect.DeepEqual(creds, expectedCreds) {
|
||||
t.Errorf("Expected %v, got %v", expectedCreds, creds)
|
||||
}
|
||||
|
||||
if e.IsExpired() {
|
||||
t.Error("Expect creds to not be expired after retrieve.")
|
||||
}
|
||||
|
||||
os.Clearenv()
|
||||
os.Setenv("AWS_ACCESS_KEY", "access")
|
||||
os.Setenv("AWS_SECRET_KEY", "secret")
|
||||
|
||||
expectedCreds = Value{
|
||||
AccessKeyID: "access",
|
||||
SecretAccessKey: "secret",
|
||||
SignerType: SignatureV4,
|
||||
}
|
||||
|
||||
creds, err = e.Retrieve()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(creds, expectedCreds) {
|
||||
t.Errorf("Expected %v, got %v", expectedCreds, creds)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestEnvMinioRetrieve(t *testing.T) {
|
||||
os.Clearenv()
|
||||
|
||||
os.Setenv("MINIO_ACCESS_KEY", "access")
|
||||
os.Setenv("MINIO_SECRET_KEY", "secret")
|
||||
|
||||
e := EnvMinio{}
|
||||
if !e.IsExpired() {
|
||||
t.Error("Expect creds to be expired before retrieve.")
|
||||
}
|
||||
|
||||
creds, err := e.Retrieve()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
expectedCreds := Value{
|
||||
AccessKeyID: "access",
|
||||
SecretAccessKey: "secret",
|
||||
SignerType: SignatureV4,
|
||||
}
|
||||
if !reflect.DeepEqual(creds, expectedCreds) {
|
||||
t.Errorf("Expected %v, got %v", expectedCreds, creds)
|
||||
}
|
||||
|
||||
if e.IsExpired() {
|
||||
t.Error("Expect creds to not be expired after retrieve.")
|
||||
}
|
||||
}
|
189
vendor/github.com/minio/minio-go/pkg/credentials/file_test.go
generated
vendored
189
vendor/github.com/minio/minio-go/pkg/credentials/file_test.go
generated
vendored
|
@ -1,189 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 credentials
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFileAWS(t *testing.T) {
|
||||
os.Clearenv()
|
||||
|
||||
creds := NewFileAWSCredentials("credentials.sample", "")
|
||||
credValues, err := creds.Get()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if credValues.AccessKeyID != "accessKey" {
|
||||
t.Errorf("Expected 'accessKey', got %s'", credValues.AccessKeyID)
|
||||
}
|
||||
if credValues.SecretAccessKey != "secret" {
|
||||
t.Errorf("Expected 'secret', got %s'", credValues.SecretAccessKey)
|
||||
}
|
||||
if credValues.SessionToken != "token" {
|
||||
t.Errorf("Expected 'token', got %s'", credValues.SessionToken)
|
||||
}
|
||||
|
||||
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", "credentials.sample")
|
||||
creds = NewFileAWSCredentials("", "")
|
||||
credValues, err = creds.Get()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if credValues.AccessKeyID != "accessKey" {
|
||||
t.Errorf("Expected 'accessKey', got %s'", credValues.AccessKeyID)
|
||||
}
|
||||
if credValues.SecretAccessKey != "secret" {
|
||||
t.Errorf("Expected 'secret', got %s'", credValues.SecretAccessKey)
|
||||
}
|
||||
if credValues.SessionToken != "token" {
|
||||
t.Errorf("Expected 'token', got %s'", credValues.SessionToken)
|
||||
}
|
||||
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", filepath.Join(wd, "credentials.sample"))
|
||||
creds = NewFileAWSCredentials("", "")
|
||||
credValues, err = creds.Get()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if credValues.AccessKeyID != "accessKey" {
|
||||
t.Errorf("Expected 'accessKey', got %s'", credValues.AccessKeyID)
|
||||
}
|
||||
if credValues.SecretAccessKey != "secret" {
|
||||
t.Errorf("Expected 'secret', got %s'", credValues.SecretAccessKey)
|
||||
}
|
||||
if credValues.SessionToken != "token" {
|
||||
t.Errorf("Expected 'token', got %s'", credValues.SessionToken)
|
||||
}
|
||||
|
||||
os.Clearenv()
|
||||
os.Setenv("AWS_PROFILE", "no_token")
|
||||
|
||||
creds = NewFileAWSCredentials("credentials.sample", "")
|
||||
credValues, err = creds.Get()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if credValues.AccessKeyID != "accessKey" {
|
||||
t.Errorf("Expected 'accessKey', got %s'", credValues.AccessKeyID)
|
||||
}
|
||||
if credValues.SecretAccessKey != "secret" {
|
||||
t.Errorf("Expected 'secret', got %s'", credValues.SecretAccessKey)
|
||||
}
|
||||
|
||||
os.Clearenv()
|
||||
|
||||
creds = NewFileAWSCredentials("credentials.sample", "no_token")
|
||||
credValues, err = creds.Get()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if credValues.AccessKeyID != "accessKey" {
|
||||
t.Errorf("Expected 'accessKey', got %s'", credValues.AccessKeyID)
|
||||
}
|
||||
if credValues.SecretAccessKey != "secret" {
|
||||
t.Errorf("Expected 'secret', got %s'", credValues.SecretAccessKey)
|
||||
}
|
||||
|
||||
creds = NewFileAWSCredentials("credentials-non-existent.sample", "no_token")
|
||||
_, err = creds.Get()
|
||||
if !os.IsNotExist(err) {
|
||||
t.Errorf("Expected open non-existent.json: no such file or directory, got %s", err)
|
||||
}
|
||||
if !creds.IsExpired() {
|
||||
t.Error("Should be expired if not loaded")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileMinioClient(t *testing.T) {
|
||||
os.Clearenv()
|
||||
|
||||
creds := NewFileMinioClient("config.json.sample", "")
|
||||
credValues, err := creds.Get()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if credValues.AccessKeyID != "accessKey" {
|
||||
t.Errorf("Expected 'accessKey', got %s'", credValues.AccessKeyID)
|
||||
}
|
||||
if credValues.SecretAccessKey != "secret" {
|
||||
t.Errorf("Expected 'secret', got %s'", credValues.SecretAccessKey)
|
||||
}
|
||||
if credValues.SignerType != SignatureV4 {
|
||||
t.Errorf("Expected 'S3v4', got %s'", credValues.SignerType)
|
||||
}
|
||||
|
||||
os.Clearenv()
|
||||
os.Setenv("MINIO_ALIAS", "play")
|
||||
|
||||
creds = NewFileMinioClient("config.json.sample", "")
|
||||
credValues, err = creds.Get()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if credValues.AccessKeyID != "Q3AM3UQ867SPQQA43P2F" {
|
||||
t.Errorf("Expected 'Q3AM3UQ867SPQQA43P2F', got %s'", credValues.AccessKeyID)
|
||||
}
|
||||
if credValues.SecretAccessKey != "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG" {
|
||||
t.Errorf("Expected 'zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG', got %s'", credValues.SecretAccessKey)
|
||||
}
|
||||
if credValues.SignerType != SignatureV2 {
|
||||
t.Errorf("Expected 'S3v2', got %s'", credValues.SignerType)
|
||||
}
|
||||
|
||||
os.Clearenv()
|
||||
|
||||
creds = NewFileMinioClient("config.json.sample", "play")
|
||||
credValues, err = creds.Get()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if credValues.AccessKeyID != "Q3AM3UQ867SPQQA43P2F" {
|
||||
t.Errorf("Expected 'Q3AM3UQ867SPQQA43P2F', got %s'", credValues.AccessKeyID)
|
||||
}
|
||||
if credValues.SecretAccessKey != "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG" {
|
||||
t.Errorf("Expected 'zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG', got %s'", credValues.SecretAccessKey)
|
||||
}
|
||||
if credValues.SignerType != SignatureV2 {
|
||||
t.Errorf("Expected 'S3v2', got %s'", credValues.SignerType)
|
||||
}
|
||||
|
||||
creds = NewFileMinioClient("non-existent.json", "play")
|
||||
_, err = creds.Get()
|
||||
if !os.IsNotExist(err) {
|
||||
t.Errorf("Expected open non-existent.json: no such file or directory, got %s", err)
|
||||
}
|
||||
if !creds.IsExpired() {
|
||||
t.Error("Should be expired if not loaded")
|
||||
}
|
||||
}
|
197
vendor/github.com/minio/minio-go/pkg/credentials/iam_aws_test.go
generated
vendored
197
vendor/github.com/minio/minio-go/pkg/credentials/iam_aws_test.go
generated
vendored
|
@ -1,197 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 credentials
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
const credsRespTmpl = `{
|
||||
"Code": "Success",
|
||||
"Type": "AWS-HMAC",
|
||||
"AccessKeyId" : "accessKey",
|
||||
"SecretAccessKey" : "secret",
|
||||
"Token" : "token",
|
||||
"Expiration" : "%s",
|
||||
"LastUpdated" : "2009-11-23T0:00:00Z"
|
||||
}`
|
||||
|
||||
const credsFailRespTmpl = `{
|
||||
"Code": "ErrorCode",
|
||||
"Message": "ErrorMsg",
|
||||
"LastUpdated": "2009-11-23T0:00:00Z"
|
||||
}`
|
||||
|
||||
func initTestFailServer() *httptest.Server {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "Not allowed", http.StatusBadRequest)
|
||||
}))
|
||||
return server
|
||||
}
|
||||
|
||||
func initTestServerNoRoles() *httptest.Server {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(""))
|
||||
}))
|
||||
return server
|
||||
}
|
||||
|
||||
func initTestServer(expireOn string, failAssume bool) *httptest.Server {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path == "/latest/meta-data/iam/security-credentials" {
|
||||
fmt.Fprintln(w, "RoleName")
|
||||
} else if r.URL.Path == "/latest/meta-data/iam/security-credentials/RoleName" {
|
||||
if failAssume {
|
||||
fmt.Fprintf(w, credsFailRespTmpl)
|
||||
} else {
|
||||
fmt.Fprintf(w, credsRespTmpl, expireOn)
|
||||
}
|
||||
} else {
|
||||
http.Error(w, "bad request", http.StatusBadRequest)
|
||||
}
|
||||
}))
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
func TestIAMMalformedEndpoint(t *testing.T) {
|
||||
creds := NewIAM("%%%%")
|
||||
_, err := creds.Get()
|
||||
if err == nil {
|
||||
t.Fatal("Unexpected should fail here")
|
||||
}
|
||||
if err.Error() != `parse %%%%: invalid URL escape "%%%"` {
|
||||
t.Fatalf("Expected parse %%%%%%%%: invalid URL escape \"%%%%%%\", got %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIAMFailServer(t *testing.T) {
|
||||
server := initTestFailServer()
|
||||
defer server.Close()
|
||||
|
||||
creds := NewIAM(server.URL)
|
||||
|
||||
_, err := creds.Get()
|
||||
if err == nil {
|
||||
t.Fatal("Unexpected should fail here")
|
||||
}
|
||||
if err.Error() != "400 Bad Request" {
|
||||
t.Fatalf("Expected '400 Bad Request', got %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIAMNoRoles(t *testing.T) {
|
||||
server := initTestServerNoRoles()
|
||||
defer server.Close()
|
||||
|
||||
creds := NewIAM(server.URL)
|
||||
_, err := creds.Get()
|
||||
if err == nil {
|
||||
t.Fatal("Unexpected should fail here")
|
||||
}
|
||||
if err.Error() != "No IAM roles attached to this EC2 service" {
|
||||
t.Fatalf("Expected 'No IAM roles attached to this EC2 service', got %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIAM(t *testing.T) {
|
||||
server := initTestServer("2014-12-16T01:51:37Z", false)
|
||||
defer server.Close()
|
||||
|
||||
p := &IAM{
|
||||
Client: http.DefaultClient,
|
||||
endpoint: server.URL,
|
||||
}
|
||||
|
||||
creds, err := p.Retrieve()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if "accessKey" != creds.AccessKeyID {
|
||||
t.Errorf("Expected \"accessKey\", got %s", creds.AccessKeyID)
|
||||
}
|
||||
|
||||
if "secret" != creds.SecretAccessKey {
|
||||
t.Errorf("Expected \"secret\", got %s", creds.SecretAccessKey)
|
||||
}
|
||||
|
||||
if "token" != creds.SessionToken {
|
||||
t.Errorf("Expected \"token\", got %s", creds.SessionToken)
|
||||
}
|
||||
|
||||
if !p.IsExpired() {
|
||||
t.Error("Expected creds to be expired.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIAMFailAssume(t *testing.T) {
|
||||
server := initTestServer("2014-12-16T01:51:37Z", true)
|
||||
defer server.Close()
|
||||
|
||||
p := &IAM{
|
||||
Client: http.DefaultClient,
|
||||
endpoint: server.URL,
|
||||
}
|
||||
|
||||
_, err := p.Retrieve()
|
||||
if err == nil {
|
||||
t.Fatal("Unexpected success, should fail")
|
||||
}
|
||||
if err.Error() != "ErrorMsg" {
|
||||
t.Errorf("Expected \"ErrorMsg\", got %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIAMIsExpired(t *testing.T) {
|
||||
server := initTestServer("2014-12-16T01:51:37Z", false)
|
||||
defer server.Close()
|
||||
|
||||
p := &IAM{
|
||||
Client: http.DefaultClient,
|
||||
endpoint: server.URL,
|
||||
}
|
||||
p.CurrentTime = func() time.Time {
|
||||
return time.Date(2014, 12, 15, 21, 26, 0, 0, time.UTC)
|
||||
}
|
||||
|
||||
if !p.IsExpired() {
|
||||
t.Error("Expected creds to be expired before retrieve.")
|
||||
}
|
||||
|
||||
_, err := p.Retrieve()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if p.IsExpired() {
|
||||
t.Error("Expected creds to not be expired after retrieve.")
|
||||
}
|
||||
|
||||
p.CurrentTime = func() time.Time {
|
||||
return time.Date(3014, 12, 15, 21, 26, 0, 0, time.UTC)
|
||||
}
|
||||
|
||||
if !p.IsExpired() {
|
||||
t.Error("Expected creds to be expired when curren time has changed")
|
||||
}
|
||||
}
|
68
vendor/github.com/minio/minio-go/pkg/credentials/static_test.go
generated
vendored
68
vendor/github.com/minio/minio-go/pkg/credentials/static_test.go
generated
vendored
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 credentials
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestStaticGet(t *testing.T) {
|
||||
creds := NewStatic("UXHW", "SECRET", "", SignatureV4)
|
||||
credValues, err := creds.Get()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if "UXHW" != credValues.AccessKeyID {
|
||||
t.Errorf("Expected access key ID to match \"UXHW\", got %s", credValues.AccessKeyID)
|
||||
}
|
||||
if "SECRET" != credValues.SecretAccessKey {
|
||||
t.Errorf("Expected secret access key to match \"SECRET\", got %s", credValues.SecretAccessKey)
|
||||
}
|
||||
|
||||
if credValues.SessionToken != "" {
|
||||
t.Error("Expected session token to match")
|
||||
}
|
||||
|
||||
if credValues.SignerType != SignatureV4 {
|
||||
t.Errorf("Expected 'S3v4', got %s", credValues.SignerType)
|
||||
}
|
||||
|
||||
if creds.IsExpired() {
|
||||
t.Error("Static credentials should never expire")
|
||||
}
|
||||
|
||||
creds = NewStatic("", "", "", SignatureDefault)
|
||||
credValues, err = creds.Get()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if "" != credValues.AccessKeyID {
|
||||
t.Errorf("Expected access key ID to match empty string, got %s", credValues.AccessKeyID)
|
||||
}
|
||||
if "" != credValues.SecretAccessKey {
|
||||
t.Errorf("Expected secret access key to match empty string, got %s", credValues.SecretAccessKey)
|
||||
}
|
||||
|
||||
if !credValues.SignerType.IsAnonymous() {
|
||||
t.Errorf("Expected 'Anonymous', got %s", credValues.SignerType)
|
||||
}
|
||||
|
||||
if creds.IsExpired() {
|
||||
t.Error("Static credentials should never expire")
|
||||
}
|
||||
}
|
49
vendor/github.com/minio/minio-go/pkg/encrypt/server-side.go
generated
vendored
49
vendor/github.com/minio/minio-go/pkg/encrypt/server-side.go
generated
vendored
|
@ -20,6 +20,7 @@ package encrypt
|
|||
import (
|
||||
"crypto/md5"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
|
@ -30,6 +31,11 @@ const (
|
|||
// sseGenericHeader is the AWS SSE header used for SSE-S3 and SSE-KMS.
|
||||
sseGenericHeader = "X-Amz-Server-Side-Encryption"
|
||||
|
||||
// sseKmsKeyID is the AWS SSE-KMS key id.
|
||||
sseKmsKeyID = sseGenericHeader + "-Aws-Kms-Key-Id"
|
||||
// sseEncryptionContext is the AWS SSE-KMS Encryption Context data.
|
||||
sseEncryptionContext = sseGenericHeader + "-Encryption-Context"
|
||||
|
||||
// sseCustomerAlgorithm is the AWS SSE-C algorithm HTTP header key.
|
||||
sseCustomerAlgorithm = sseGenericHeader + "-Customer-Algorithm"
|
||||
// sseCustomerKey is the AWS SSE-C encryption key HTTP header key.
|
||||
|
@ -90,6 +96,18 @@ type ServerSide interface {
|
|||
// Using SSE-S3 the server will encrypt the object with server-managed keys.
|
||||
func NewSSE() ServerSide { return s3{} }
|
||||
|
||||
// NewSSEKMS returns a new server-side-encryption using SSE-KMS and the provided Key Id and context.
|
||||
func NewSSEKMS(keyID string, context interface{}) (ServerSide, error) {
|
||||
if context == nil {
|
||||
return kms{key: keyID, hasContext: false}, nil
|
||||
}
|
||||
serializedContext, err := json.Marshal(context)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return kms{key: keyID, context: serializedContext, hasContext: true}, nil
|
||||
}
|
||||
|
||||
// NewSSEC returns a new server-side-encryption using SSE-C and the provided key.
|
||||
// The key must be 32 bytes long.
|
||||
func NewSSEC(key []byte) (ServerSide, error) {
|
||||
|
@ -101,6 +119,21 @@ func NewSSEC(key []byte) (ServerSide, error) {
|
|||
return sse, nil
|
||||
}
|
||||
|
||||
// SSE transforms a SSE-C copy encryption into a SSE-C encryption.
|
||||
// It is the inverse of SSECopy(...).
|
||||
//
|
||||
// If the provided sse is no SSE-C copy encryption SSE returns
|
||||
// sse unmodified.
|
||||
func SSE(sse ServerSide) ServerSide {
|
||||
if sse == nil || sse.Type() != SSEC {
|
||||
return sse
|
||||
}
|
||||
if sse, ok := sse.(ssecCopy); ok {
|
||||
return ssec(sse)
|
||||
}
|
||||
return sse
|
||||
}
|
||||
|
||||
// SSECopy transforms a SSE-C encryption into a SSE-C copy
|
||||
// encryption. This is required for SSE-C key rotation or a SSE-C
|
||||
// copy where the source and the destination should be encrypted.
|
||||
|
@ -144,3 +177,19 @@ type s3 struct{}
|
|||
func (s s3) Type() Type { return S3 }
|
||||
|
||||
func (s s3) Marshal(h http.Header) { h.Set(sseGenericHeader, "AES256") }
|
||||
|
||||
type kms struct {
|
||||
key string
|
||||
context []byte
|
||||
hasContext bool
|
||||
}
|
||||
|
||||
func (s kms) Type() Type { return KMS }
|
||||
|
||||
func (s kms) Marshal(h http.Header) {
|
||||
h.Set(sseGenericHeader, "aws:kms")
|
||||
h.Set(sseKmsKeyID, s.key)
|
||||
if s.hasContext {
|
||||
h.Set(sseEncryptionContext, base64.StdEncoding.EncodeToString(s.context))
|
||||
}
|
||||
}
|
||||
|
|
116
vendor/github.com/minio/minio-go/pkg/policy/bucket-policy-condition.go
generated
vendored
116
vendor/github.com/minio/minio-go/pkg/policy/bucket-policy-condition.go
generated
vendored
|
@ -1,116 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 policy
|
||||
|
||||
import "github.com/minio/minio-go/pkg/set"
|
||||
|
||||
// ConditionKeyMap - map of policy condition key and value.
|
||||
type ConditionKeyMap map[string]set.StringSet
|
||||
|
||||
// Add - adds key and value. The value is appended If key already exists.
|
||||
func (ckm ConditionKeyMap) Add(key string, value set.StringSet) {
|
||||
if v, ok := ckm[key]; ok {
|
||||
ckm[key] = v.Union(value)
|
||||
} else {
|
||||
ckm[key] = set.CopyStringSet(value)
|
||||
}
|
||||
}
|
||||
|
||||
// Remove - removes value of given key. If key has empty after removal, the key is also removed.
|
||||
func (ckm ConditionKeyMap) Remove(key string, value set.StringSet) {
|
||||
if v, ok := ckm[key]; ok {
|
||||
if value != nil {
|
||||
ckm[key] = v.Difference(value)
|
||||
}
|
||||
|
||||
if ckm[key].IsEmpty() {
|
||||
delete(ckm, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveKey - removes key and its value.
|
||||
func (ckm ConditionKeyMap) RemoveKey(key string) {
|
||||
if _, ok := ckm[key]; ok {
|
||||
delete(ckm, key)
|
||||
}
|
||||
}
|
||||
|
||||
// CopyConditionKeyMap - returns new copy of given ConditionKeyMap.
|
||||
func CopyConditionKeyMap(condKeyMap ConditionKeyMap) ConditionKeyMap {
|
||||
out := make(ConditionKeyMap)
|
||||
|
||||
for k, v := range condKeyMap {
|
||||
out[k] = set.CopyStringSet(v)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// mergeConditionKeyMap - returns a new ConditionKeyMap which contains merged key/value of given two ConditionKeyMap.
|
||||
func mergeConditionKeyMap(condKeyMap1 ConditionKeyMap, condKeyMap2 ConditionKeyMap) ConditionKeyMap {
|
||||
out := CopyConditionKeyMap(condKeyMap1)
|
||||
|
||||
for k, v := range condKeyMap2 {
|
||||
if ev, ok := out[k]; ok {
|
||||
out[k] = ev.Union(v)
|
||||
} else {
|
||||
out[k] = set.CopyStringSet(v)
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// ConditionMap - map of condition and conditional values.
|
||||
type ConditionMap map[string]ConditionKeyMap
|
||||
|
||||
// Add - adds condition key and condition value. The value is appended if key already exists.
|
||||
func (cond ConditionMap) Add(condKey string, condKeyMap ConditionKeyMap) {
|
||||
if v, ok := cond[condKey]; ok {
|
||||
cond[condKey] = mergeConditionKeyMap(v, condKeyMap)
|
||||
} else {
|
||||
cond[condKey] = CopyConditionKeyMap(condKeyMap)
|
||||
}
|
||||
}
|
||||
|
||||
// Remove - removes condition key and its value.
|
||||
func (cond ConditionMap) Remove(condKey string) {
|
||||
if _, ok := cond[condKey]; ok {
|
||||
delete(cond, condKey)
|
||||
}
|
||||
}
|
||||
|
||||
// mergeConditionMap - returns new ConditionMap which contains merged key/value of two ConditionMap.
|
||||
func mergeConditionMap(condMap1 ConditionMap, condMap2 ConditionMap) ConditionMap {
|
||||
out := make(ConditionMap)
|
||||
|
||||
for k, v := range condMap1 {
|
||||
out[k] = CopyConditionKeyMap(v)
|
||||
}
|
||||
|
||||
for k, v := range condMap2 {
|
||||
if ev, ok := out[k]; ok {
|
||||
out[k] = mergeConditionKeyMap(ev, v)
|
||||
} else {
|
||||
out[k] = CopyConditionKeyMap(v)
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
290
vendor/github.com/minio/minio-go/pkg/policy/bucket-policy-condition_test.go
generated
vendored
290
vendor/github.com/minio/minio-go/pkg/policy/bucket-policy-condition_test.go
generated
vendored
|
@ -1,290 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 policy
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/minio/minio-go/pkg/set"
|
||||
)
|
||||
|
||||
// ConditionKeyMap.Add() is called and the result is validated.
|
||||
func TestConditionKeyMapAdd(t *testing.T) {
|
||||
condKeyMap := make(ConditionKeyMap)
|
||||
testCases := []struct {
|
||||
key string
|
||||
value set.StringSet
|
||||
expectedResult string
|
||||
}{
|
||||
// Add new key and value.
|
||||
{"s3:prefix", set.CreateStringSet("hello"), `{"s3:prefix":["hello"]}`},
|
||||
// Add existing key and value.
|
||||
{"s3:prefix", set.CreateStringSet("hello"), `{"s3:prefix":["hello"]}`},
|
||||
// Add existing key and not value.
|
||||
{"s3:prefix", set.CreateStringSet("world"), `{"s3:prefix":["hello","world"]}`},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
condKeyMap.Add(testCase.key, testCase.value)
|
||||
if data, err := json.Marshal(condKeyMap); err != nil {
|
||||
t.Fatalf("Unable to marshal ConditionKeyMap to JSON, %s", err)
|
||||
} else {
|
||||
if string(data) != testCase.expectedResult {
|
||||
t.Fatalf("case: %+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ConditionKeyMap.Remove() is called and the result is validated.
|
||||
func TestConditionKeyMapRemove(t *testing.T) {
|
||||
condKeyMap := make(ConditionKeyMap)
|
||||
condKeyMap.Add("s3:prefix", set.CreateStringSet("hello", "world"))
|
||||
|
||||
testCases := []struct {
|
||||
key string
|
||||
value set.StringSet
|
||||
expectedResult string
|
||||
}{
|
||||
// Remove non-existent key and value.
|
||||
{"s3:myprefix", set.CreateStringSet("hello"), `{"s3:prefix":["hello","world"]}`},
|
||||
// Remove existing key and value.
|
||||
{"s3:prefix", set.CreateStringSet("hello"), `{"s3:prefix":["world"]}`},
|
||||
// Remove existing key to make the key also removed.
|
||||
{"s3:prefix", set.CreateStringSet("world"), `{}`},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
condKeyMap.Remove(testCase.key, testCase.value)
|
||||
if data, err := json.Marshal(condKeyMap); err != nil {
|
||||
t.Fatalf("Unable to marshal ConditionKeyMap to JSON, %s", err)
|
||||
} else {
|
||||
if string(data) != testCase.expectedResult {
|
||||
t.Fatalf("case: %+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ConditionKeyMap.RemoveKey() is called and the result is validated.
|
||||
func TestConditionKeyMapRemoveKey(t *testing.T) {
|
||||
condKeyMap := make(ConditionKeyMap)
|
||||
condKeyMap.Add("s3:prefix", set.CreateStringSet("hello", "world"))
|
||||
|
||||
testCases := []struct {
|
||||
key string
|
||||
expectedResult string
|
||||
}{
|
||||
// Remove non-existent key.
|
||||
{"s3:myprefix", `{"s3:prefix":["hello","world"]}`},
|
||||
// Remove existing key.
|
||||
{"s3:prefix", `{}`},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
condKeyMap.RemoveKey(testCase.key)
|
||||
if data, err := json.Marshal(condKeyMap); err != nil {
|
||||
t.Fatalf("Unable to marshal ConditionKeyMap to JSON, %s", err)
|
||||
} else {
|
||||
if string(data) != testCase.expectedResult {
|
||||
t.Fatalf("case: %+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CopyConditionKeyMap() is called and the result is validated.
|
||||
func TestCopyConditionKeyMap(t *testing.T) {
|
||||
emptyCondKeyMap := make(ConditionKeyMap)
|
||||
nonEmptyCondKeyMap := make(ConditionKeyMap)
|
||||
nonEmptyCondKeyMap.Add("s3:prefix", set.CreateStringSet("hello", "world"))
|
||||
|
||||
testCases := []struct {
|
||||
condKeyMap ConditionKeyMap
|
||||
expectedResult string
|
||||
}{
|
||||
// To test empty ConditionKeyMap.
|
||||
{emptyCondKeyMap, `{}`},
|
||||
// To test non-empty ConditionKeyMap.
|
||||
{nonEmptyCondKeyMap, `{"s3:prefix":["hello","world"]}`},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
condKeyMap := CopyConditionKeyMap(testCase.condKeyMap)
|
||||
if data, err := json.Marshal(condKeyMap); err != nil {
|
||||
t.Fatalf("Unable to marshal ConditionKeyMap to JSON, %s", err)
|
||||
} else {
|
||||
if string(data) != testCase.expectedResult {
|
||||
t.Fatalf("case: %+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mergeConditionKeyMap() is called and the result is validated.
|
||||
func TestMergeConditionKeyMap(t *testing.T) {
|
||||
condKeyMap1 := make(ConditionKeyMap)
|
||||
condKeyMap1.Add("s3:prefix", set.CreateStringSet("hello"))
|
||||
|
||||
condKeyMap2 := make(ConditionKeyMap)
|
||||
condKeyMap2.Add("s3:prefix", set.CreateStringSet("world"))
|
||||
|
||||
condKeyMap3 := make(ConditionKeyMap)
|
||||
condKeyMap3.Add("s3:myprefix", set.CreateStringSet("world"))
|
||||
|
||||
testCases := []struct {
|
||||
condKeyMap1 ConditionKeyMap
|
||||
condKeyMap2 ConditionKeyMap
|
||||
expectedResult string
|
||||
}{
|
||||
// Both arguments are empty.
|
||||
{make(ConditionKeyMap), make(ConditionKeyMap), `{}`},
|
||||
// First argument is empty.
|
||||
{make(ConditionKeyMap), condKeyMap1, `{"s3:prefix":["hello"]}`},
|
||||
// Second argument is empty.
|
||||
{condKeyMap1, make(ConditionKeyMap), `{"s3:prefix":["hello"]}`},
|
||||
// Both arguments are same value.
|
||||
{condKeyMap1, condKeyMap1, `{"s3:prefix":["hello"]}`},
|
||||
// Value of second argument will be merged.
|
||||
{condKeyMap1, condKeyMap2, `{"s3:prefix":["hello","world"]}`},
|
||||
// second argument will be added.
|
||||
{condKeyMap1, condKeyMap3, `{"s3:myprefix":["world"],"s3:prefix":["hello"]}`},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
condKeyMap := mergeConditionKeyMap(testCase.condKeyMap1, testCase.condKeyMap2)
|
||||
if data, err := json.Marshal(condKeyMap); err != nil {
|
||||
t.Fatalf("Unable to marshal ConditionKeyMap to JSON, %s", err)
|
||||
} else {
|
||||
if string(data) != testCase.expectedResult {
|
||||
t.Fatalf("case: %+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ConditionMap.Add() is called and the result is validated.
|
||||
func TestConditionMapAdd(t *testing.T) {
|
||||
condMap := make(ConditionMap)
|
||||
|
||||
condKeyMap1 := make(ConditionKeyMap)
|
||||
condKeyMap1.Add("s3:prefix", set.CreateStringSet("hello"))
|
||||
|
||||
condKeyMap2 := make(ConditionKeyMap)
|
||||
condKeyMap2.Add("s3:prefix", set.CreateStringSet("hello", "world"))
|
||||
|
||||
testCases := []struct {
|
||||
key string
|
||||
value ConditionKeyMap
|
||||
expectedResult string
|
||||
}{
|
||||
// Add new key and value.
|
||||
{"StringEquals", condKeyMap1, `{"StringEquals":{"s3:prefix":["hello"]}}`},
|
||||
// Add existing key and value.
|
||||
{"StringEquals", condKeyMap1, `{"StringEquals":{"s3:prefix":["hello"]}}`},
|
||||
// Add existing key and not value.
|
||||
{"StringEquals", condKeyMap2, `{"StringEquals":{"s3:prefix":["hello","world"]}}`},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
condMap.Add(testCase.key, testCase.value)
|
||||
if data, err := json.Marshal(condMap); err != nil {
|
||||
t.Fatalf("Unable to marshal ConditionKeyMap to JSON, %s", err)
|
||||
} else {
|
||||
if string(data) != testCase.expectedResult {
|
||||
t.Fatalf("case: %+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ConditionMap.Remove() is called and the result is validated.
|
||||
func TestConditionMapRemove(t *testing.T) {
|
||||
condMap := make(ConditionMap)
|
||||
condKeyMap := make(ConditionKeyMap)
|
||||
condKeyMap.Add("s3:prefix", set.CreateStringSet("hello", "world"))
|
||||
condMap.Add("StringEquals", condKeyMap)
|
||||
|
||||
testCases := []struct {
|
||||
key string
|
||||
expectedResult string
|
||||
}{
|
||||
// Remove non-existent key.
|
||||
{"StringNotEquals", `{"StringEquals":{"s3:prefix":["hello","world"]}}`},
|
||||
// Remove existing key.
|
||||
{"StringEquals", `{}`},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
condMap.Remove(testCase.key)
|
||||
if data, err := json.Marshal(condMap); err != nil {
|
||||
t.Fatalf("Unable to marshal ConditionKeyMap to JSON, %s", err)
|
||||
} else {
|
||||
if string(data) != testCase.expectedResult {
|
||||
t.Fatalf("case: %+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mergeConditionMap() is called and the result is validated.
|
||||
func TestMergeConditionMap(t *testing.T) {
|
||||
condKeyMap1 := make(ConditionKeyMap)
|
||||
condKeyMap1.Add("s3:prefix", set.CreateStringSet("hello"))
|
||||
condMap1 := make(ConditionMap)
|
||||
condMap1.Add("StringEquals", condKeyMap1)
|
||||
|
||||
condKeyMap2 := make(ConditionKeyMap)
|
||||
condKeyMap2.Add("s3:prefix", set.CreateStringSet("world"))
|
||||
condMap2 := make(ConditionMap)
|
||||
condMap2.Add("StringEquals", condKeyMap2)
|
||||
|
||||
condMap3 := make(ConditionMap)
|
||||
condMap3.Add("StringNotEquals", condKeyMap2)
|
||||
|
||||
testCases := []struct {
|
||||
condMap1 ConditionMap
|
||||
condMap2 ConditionMap
|
||||
expectedResult string
|
||||
}{
|
||||
// Both arguments are empty.
|
||||
{make(ConditionMap), make(ConditionMap), `{}`},
|
||||
// First argument is empty.
|
||||
{make(ConditionMap), condMap1, `{"StringEquals":{"s3:prefix":["hello"]}}`},
|
||||
// Second argument is empty.
|
||||
{condMap1, make(ConditionMap), `{"StringEquals":{"s3:prefix":["hello"]}}`},
|
||||
// Both arguments are same value.
|
||||
{condMap1, condMap1, `{"StringEquals":{"s3:prefix":["hello"]}}`},
|
||||
// Value of second argument will be merged.
|
||||
{condMap1, condMap2, `{"StringEquals":{"s3:prefix":["hello","world"]}}`},
|
||||
// second argument will be added.
|
||||
{condMap1, condMap3, `{"StringEquals":{"s3:prefix":["hello"]},"StringNotEquals":{"s3:prefix":["world"]}}`},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
condMap := mergeConditionMap(testCase.condMap1, testCase.condMap2)
|
||||
if data, err := json.Marshal(condMap); err != nil {
|
||||
t.Fatalf("Unable to marshal ConditionKeyMap to JSON, %s", err)
|
||||
} else {
|
||||
if string(data) != testCase.expectedResult {
|
||||
t.Fatalf("case: %+v: expected: %s, got: %s", testCase, testCase.expectedResult, string(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
664
vendor/github.com/minio/minio-go/pkg/policy/bucket-policy.go
generated
vendored
664
vendor/github.com/minio/minio-go/pkg/policy/bucket-policy.go
generated
vendored
|
@ -1,664 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 policy
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/minio/minio-go/pkg/set"
|
||||
)
|
||||
|
||||
// BucketPolicy - Bucket level policy.
|
||||
type BucketPolicy string
|
||||
|
||||
// Different types of Policies currently supported for buckets.
|
||||
const (
|
||||
BucketPolicyNone BucketPolicy = "none"
|
||||
BucketPolicyReadOnly = "readonly"
|
||||
BucketPolicyReadWrite = "readwrite"
|
||||
BucketPolicyWriteOnly = "writeonly"
|
||||
)
|
||||
|
||||
// IsValidBucketPolicy - returns true if policy is valid and supported, false otherwise.
|
||||
func (p BucketPolicy) IsValidBucketPolicy() bool {
|
||||
switch p {
|
||||
case BucketPolicyNone, BucketPolicyReadOnly, BucketPolicyReadWrite, BucketPolicyWriteOnly:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Resource prefix for all aws resources.
|
||||
const awsResourcePrefix = "arn:aws:s3:::"
|
||||
|
||||
// Common bucket actions for both read and write policies.
|
||||
var commonBucketActions = set.CreateStringSet("s3:GetBucketLocation")
|
||||
|
||||
// Read only bucket actions.
|
||||
var readOnlyBucketActions = set.CreateStringSet("s3:ListBucket")
|
||||
|
||||
// Write only bucket actions.
|
||||
var writeOnlyBucketActions = set.CreateStringSet("s3:ListBucketMultipartUploads")
|
||||
|
||||
// Read only object actions.
|
||||
var readOnlyObjectActions = set.CreateStringSet("s3:GetObject")
|
||||
|
||||
// Write only object actions.
|
||||
var writeOnlyObjectActions = set.CreateStringSet("s3:AbortMultipartUpload", "s3:DeleteObject", "s3:ListMultipartUploadParts", "s3:PutObject")
|
||||
|
||||
// Read and write object actions.
|
||||
var readWriteObjectActions = readOnlyObjectActions.Union(writeOnlyObjectActions)
|
||||
|
||||
// All valid bucket and object actions.
|
||||
var validActions = commonBucketActions.
|
||||
Union(readOnlyBucketActions).
|
||||
Union(writeOnlyBucketActions).
|
||||
Union(readOnlyObjectActions).
|
||||
Union(writeOnlyObjectActions)
|
||||
|
||||
var startsWithFunc = func(resource string, resourcePrefix string) bool {
|
||||
return strings.HasPrefix(resource, resourcePrefix)
|
||||
}
|
||||
|
||||
// User - canonical users list.
|
||||
type User struct {
|
||||
AWS set.StringSet `json:"AWS,omitempty"`
|
||||
CanonicalUser set.StringSet `json:"CanonicalUser,omitempty"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON is a custom json unmarshaler for Principal field,
|
||||
// the reason is that Principal can take a json struct represented by
|
||||
// User string but it can also take a string.
|
||||
func (u *User) UnmarshalJSON(data []byte) error {
|
||||
// Try to unmarshal data in a struct equal to User, we need it
|
||||
// to avoid infinite recursive call of this function
|
||||
type AliasUser User
|
||||
var au AliasUser
|
||||
err := json.Unmarshal(data, &au)
|
||||
if err == nil {
|
||||
*u = User(au)
|
||||
return nil
|
||||
}
|
||||
// Data type is not known, check if it is a json string
|
||||
// which contains a star, which is permitted in the spec
|
||||
var str string
|
||||
err = json.Unmarshal(data, &str)
|
||||
if err == nil {
|
||||
if str != "*" {
|
||||
return errors.New("unrecognized Principal field")
|
||||
}
|
||||
*u = User{AWS: set.CreateStringSet("*")}
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Statement - minio policy statement
|
||||
type Statement struct {
|
||||
Actions set.StringSet `json:"Action"`
|
||||
Conditions ConditionMap `json:"Condition,omitempty"`
|
||||
Effect string
|
||||
Principal User `json:"Principal"`
|
||||
Resources set.StringSet `json:"Resource"`
|
||||
Sid string
|
||||
}
|
||||
|
||||
// BucketAccessPolicy - minio policy collection
|
||||
type BucketAccessPolicy struct {
|
||||
Version string // date in YYYY-MM-DD format
|
||||
Statements []Statement `json:"Statement"`
|
||||
}
|
||||
|
||||
// isValidStatement - returns whether given statement is valid to process for given bucket name.
|
||||
func isValidStatement(statement Statement, bucketName string) bool {
|
||||
if statement.Actions.Intersection(validActions).IsEmpty() {
|
||||
return false
|
||||
}
|
||||
|
||||
if statement.Effect != "Allow" {
|
||||
return false
|
||||
}
|
||||
|
||||
if statement.Principal.AWS == nil || !statement.Principal.AWS.Contains("*") {
|
||||
return false
|
||||
}
|
||||
|
||||
bucketResource := awsResourcePrefix + bucketName
|
||||
if statement.Resources.Contains(bucketResource) {
|
||||
return true
|
||||
}
|
||||
|
||||
if statement.Resources.FuncMatch(startsWithFunc, bucketResource+"/").IsEmpty() {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Returns new statements with bucket actions for given policy.
|
||||
func newBucketStatement(policy BucketPolicy, bucketName string, prefix string) (statements []Statement) {
|
||||
statements = []Statement{}
|
||||
if policy == BucketPolicyNone || bucketName == "" {
|
||||
return statements
|
||||
}
|
||||
|
||||
bucketResource := set.CreateStringSet(awsResourcePrefix + bucketName)
|
||||
|
||||
statement := Statement{
|
||||
Actions: commonBucketActions,
|
||||
Effect: "Allow",
|
||||
Principal: User{AWS: set.CreateStringSet("*")},
|
||||
Resources: bucketResource,
|
||||
Sid: "",
|
||||
}
|
||||
statements = append(statements, statement)
|
||||
|
||||
if policy == BucketPolicyReadOnly || policy == BucketPolicyReadWrite {
|
||||
statement = Statement{
|
||||
Actions: readOnlyBucketActions,
|
||||
Effect: "Allow",
|
||||
Principal: User{AWS: set.CreateStringSet("*")},
|
||||
Resources: bucketResource,
|
||||
Sid: "",
|
||||
}
|
||||
if prefix != "" {
|
||||
condKeyMap := make(ConditionKeyMap)
|
||||
condKeyMap.Add("s3:prefix", set.CreateStringSet(prefix))
|
||||
condMap := make(ConditionMap)
|
||||
condMap.Add("StringEquals", condKeyMap)
|
||||
statement.Conditions = condMap
|
||||
}
|
||||
statements = append(statements, statement)
|
||||
}
|
||||
|
||||
if policy == BucketPolicyWriteOnly || policy == BucketPolicyReadWrite {
|
||||
statement = Statement{
|
||||
Actions: writeOnlyBucketActions,
|
||||
Effect: "Allow",
|
||||
Principal: User{AWS: set.CreateStringSet("*")},
|
||||
Resources: bucketResource,
|
||||
Sid: "",
|
||||
}
|
||||
statements = append(statements, statement)
|
||||
}
|
||||
|
||||
return statements
|
||||
}
|
||||
|
||||
// Returns new statements contains object actions for given policy.
|
||||
func newObjectStatement(policy BucketPolicy, bucketName string, prefix string) (statements []Statement) {
|
||||
statements = []Statement{}
|
||||
if policy == BucketPolicyNone || bucketName == "" {
|
||||
return statements
|
||||
}
|
||||
|
||||
statement := Statement{
|
||||
Effect: "Allow",
|
||||
Principal: User{AWS: set.CreateStringSet("*")},
|
||||
Resources: set.CreateStringSet(awsResourcePrefix + bucketName + "/" + prefix + "*"),
|
||||
Sid: "",
|
||||
}
|
||||
|
||||
if policy == BucketPolicyReadOnly {
|
||||
statement.Actions = readOnlyObjectActions
|
||||
} else if policy == BucketPolicyWriteOnly {
|
||||
statement.Actions = writeOnlyObjectActions
|
||||
} else if policy == BucketPolicyReadWrite {
|
||||
statement.Actions = readWriteObjectActions
|
||||
}
|
||||
|
||||
statements = append(statements, statement)
|
||||
return statements
|
||||
}
|
||||
|
||||
// Returns new statements for given policy, bucket and prefix.
|
||||
func newStatements(policy BucketPolicy, bucketName string, prefix string) (statements []Statement) {
|
||||
statements = []Statement{}
|
||||
ns := newBucketStatement(policy, bucketName, prefix)
|
||||
statements = append(statements, ns...)
|
||||
|
||||
ns = newObjectStatement(policy, bucketName, prefix)
|
||||
statements = append(statements, ns...)
|
||||
|
||||
return statements
|
||||
}
|
||||
|
||||
// Returns whether given bucket statements are used by other than given prefix statements.
|
||||
func getInUsePolicy(statements []Statement, bucketName string, prefix string) (readOnlyInUse, writeOnlyInUse bool) {
|
||||
resourcePrefix := awsResourcePrefix + bucketName + "/"
|
||||
objectResource := awsResourcePrefix + bucketName + "/" + prefix + "*"
|
||||
|
||||
for _, s := range statements {
|
||||
if !s.Resources.Contains(objectResource) && !s.Resources.FuncMatch(startsWithFunc, resourcePrefix).IsEmpty() {
|
||||
if s.Actions.Intersection(readOnlyObjectActions).Equals(readOnlyObjectActions) {
|
||||
readOnlyInUse = true
|
||||
}
|
||||
|
||||
if s.Actions.Intersection(writeOnlyObjectActions).Equals(writeOnlyObjectActions) {
|
||||
writeOnlyInUse = true
|
||||
}
|
||||
}
|
||||
if readOnlyInUse && writeOnlyInUse {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return readOnlyInUse, writeOnlyInUse
|
||||
}
|
||||
|
||||
// Removes object actions in given statement.
|
||||
func removeObjectActions(statement Statement, objectResource string) Statement {
|
||||
if statement.Conditions == nil {
|
||||
if len(statement.Resources) > 1 {
|
||||
statement.Resources.Remove(objectResource)
|
||||
} else {
|
||||
statement.Actions = statement.Actions.Difference(readOnlyObjectActions)
|
||||
statement.Actions = statement.Actions.Difference(writeOnlyObjectActions)
|
||||
}
|
||||
}
|
||||
|
||||
return statement
|
||||
}
|
||||
|
||||
// Removes bucket actions for given policy in given statement.
|
||||
func removeBucketActions(statement Statement, prefix string, bucketResource string, readOnlyInUse, writeOnlyInUse bool) Statement {
|
||||
removeReadOnly := func() {
|
||||
if !statement.Actions.Intersection(readOnlyBucketActions).Equals(readOnlyBucketActions) {
|
||||
return
|
||||
}
|
||||
|
||||
if statement.Conditions == nil {
|
||||
statement.Actions = statement.Actions.Difference(readOnlyBucketActions)
|
||||
return
|
||||
}
|
||||
|
||||
if prefix != "" {
|
||||
stringEqualsValue := statement.Conditions["StringEquals"]
|
||||
values := set.NewStringSet()
|
||||
if stringEqualsValue != nil {
|
||||
values = stringEqualsValue["s3:prefix"]
|
||||
if values == nil {
|
||||
values = set.NewStringSet()
|
||||
}
|
||||
}
|
||||
|
||||
values.Remove(prefix)
|
||||
|
||||
if stringEqualsValue != nil {
|
||||
if values.IsEmpty() {
|
||||
delete(stringEqualsValue, "s3:prefix")
|
||||
}
|
||||
if len(stringEqualsValue) == 0 {
|
||||
delete(statement.Conditions, "StringEquals")
|
||||
}
|
||||
}
|
||||
|
||||
if len(statement.Conditions) == 0 {
|
||||
statement.Conditions = nil
|
||||
statement.Actions = statement.Actions.Difference(readOnlyBucketActions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
removeWriteOnly := func() {
|
||||
if statement.Conditions == nil {
|
||||
statement.Actions = statement.Actions.Difference(writeOnlyBucketActions)
|
||||
}
|
||||
}
|
||||
|
||||
if len(statement.Resources) > 1 {
|
||||
statement.Resources.Remove(bucketResource)
|
||||
} else {
|
||||
if !readOnlyInUse {
|
||||
removeReadOnly()
|
||||
}
|
||||
|
||||
if !writeOnlyInUse {
|
||||
removeWriteOnly()
|
||||
}
|
||||
}
|
||||
|
||||
return statement
|
||||
}
|
||||
|
||||
// Returns statements containing removed actions/statements for given
|
||||
// policy, bucket name and prefix.
|
||||
func removeStatements(statements []Statement, bucketName string, prefix string) []Statement {
|
||||
bucketResource := awsResourcePrefix + bucketName
|
||||
objectResource := awsResourcePrefix + bucketName + "/" + prefix + "*"
|
||||
readOnlyInUse, writeOnlyInUse := getInUsePolicy(statements, bucketName, prefix)
|
||||
|
||||
out := []Statement{}
|
||||
readOnlyBucketStatements := []Statement{}
|
||||
s3PrefixValues := set.NewStringSet()
|
||||
|
||||
for _, statement := range statements {
|
||||
if !isValidStatement(statement, bucketName) {
|
||||
out = append(out, statement)
|
||||
continue
|
||||
}
|
||||
|
||||
if statement.Resources.Contains(bucketResource) {
|
||||
if statement.Conditions != nil {
|
||||
statement = removeBucketActions(statement, prefix, bucketResource, false, false)
|
||||
} else {
|
||||
statement = removeBucketActions(statement, prefix, bucketResource, readOnlyInUse, writeOnlyInUse)
|
||||
}
|
||||
} else if statement.Resources.Contains(objectResource) {
|
||||
statement = removeObjectActions(statement, objectResource)
|
||||
}
|
||||
|
||||
if !statement.Actions.IsEmpty() {
|
||||
if statement.Resources.Contains(bucketResource) &&
|
||||
statement.Actions.Intersection(readOnlyBucketActions).Equals(readOnlyBucketActions) &&
|
||||
statement.Effect == "Allow" &&
|
||||
statement.Principal.AWS.Contains("*") {
|
||||
|
||||
if statement.Conditions != nil {
|
||||
stringEqualsValue := statement.Conditions["StringEquals"]
|
||||
values := set.NewStringSet()
|
||||
if stringEqualsValue != nil {
|
||||
values = stringEqualsValue["s3:prefix"]
|
||||
if values == nil {
|
||||
values = set.NewStringSet()
|
||||
}
|
||||
}
|
||||
s3PrefixValues = s3PrefixValues.Union(values.ApplyFunc(func(v string) string {
|
||||
return bucketResource + "/" + v + "*"
|
||||
}))
|
||||
} else if !s3PrefixValues.IsEmpty() {
|
||||
readOnlyBucketStatements = append(readOnlyBucketStatements, statement)
|
||||
continue
|
||||
}
|
||||
}
|
||||
out = append(out, statement)
|
||||
}
|
||||
}
|
||||
|
||||
skipBucketStatement := true
|
||||
resourcePrefix := awsResourcePrefix + bucketName + "/"
|
||||
for _, statement := range out {
|
||||
if !statement.Resources.FuncMatch(startsWithFunc, resourcePrefix).IsEmpty() &&
|
||||
s3PrefixValues.Intersection(statement.Resources).IsEmpty() {
|
||||
skipBucketStatement = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for _, statement := range readOnlyBucketStatements {
|
||||
if skipBucketStatement &&
|
||||
statement.Resources.Contains(bucketResource) &&
|
||||
statement.Effect == "Allow" &&
|
||||
statement.Principal.AWS.Contains("*") &&
|
||||
statement.Conditions == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
out = append(out, statement)
|
||||
}
|
||||
|
||||
if len(out) == 1 {
|
||||
statement := out[0]
|
||||
if statement.Resources.Contains(bucketResource) &&
|
||||
statement.Actions.Intersection(commonBucketActions).Equals(commonBucketActions) &&
|
||||
statement.Effect == "Allow" &&
|
||||
statement.Principal.AWS.Contains("*") &&
|
||||
statement.Conditions == nil {
|
||||
out = []Statement{}
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// Appends given statement into statement list to have unique statements.
|
||||
// - If statement already exists in statement list, it ignores.
|
||||
// - If statement exists with different conditions, they are merged.
|
||||
// - Else the statement is appended to statement list.
|
||||
func appendStatement(statements []Statement, statement Statement) []Statement {
|
||||
for i, s := range statements {
|
||||
if s.Actions.Equals(statement.Actions) &&
|
||||
s.Effect == statement.Effect &&
|
||||
s.Principal.AWS.Equals(statement.Principal.AWS) &&
|
||||
reflect.DeepEqual(s.Conditions, statement.Conditions) {
|
||||
statements[i].Resources = s.Resources.Union(statement.Resources)
|
||||
return statements
|
||||
} else if s.Resources.Equals(statement.Resources) &&
|
||||
s.Effect == statement.Effect &&
|
||||
s.Principal.AWS.Equals(statement.Principal.AWS) &&
|
||||
reflect.DeepEqual(s.Conditions, statement.Conditions) {
|
||||
statements[i].Actions = s.Actions.Union(statement.Actions)
|
||||
return statements
|
||||
}
|
||||
|
||||
if s.Resources.Intersection(statement.Resources).Equals(statement.Resources) &&
|
||||
s.Actions.Intersection(statement.Actions).Equals(statement.Actions) &&
|
||||
s.Effect == statement.Effect &&
|
||||
s.Principal.AWS.Intersection(statement.Principal.AWS).Equals(statement.Principal.AWS) {
|
||||
if reflect.DeepEqual(s.Conditions, statement.Conditions) {
|
||||
return statements
|
||||
}
|
||||
if s.Conditions != nil && statement.Conditions != nil {
|
||||
if s.Resources.Equals(statement.Resources) {
|
||||
statements[i].Conditions = mergeConditionMap(s.Conditions, statement.Conditions)
|
||||
return statements
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !(statement.Actions.IsEmpty() && statement.Resources.IsEmpty()) {
|
||||
return append(statements, statement)
|
||||
}
|
||||
|
||||
return statements
|
||||
}
|
||||
|
||||
// Appends two statement lists.
|
||||
func appendStatements(statements []Statement, appendStatements []Statement) []Statement {
|
||||
for _, s := range appendStatements {
|
||||
statements = appendStatement(statements, s)
|
||||
}
|
||||
|
||||
return statements
|
||||
}
|
||||
|
||||
// Returns policy of given bucket statement.
|
||||
func getBucketPolicy(statement Statement, prefix string) (commonFound, readOnly, writeOnly bool) {
|
||||
if !(statement.Effect == "Allow" && statement.Principal.AWS.Contains("*")) {
|
||||
return commonFound, readOnly, writeOnly
|
||||
}
|
||||
|
||||
if statement.Actions.Intersection(commonBucketActions).Equals(commonBucketActions) &&
|
||||
statement.Conditions == nil {
|
||||
commonFound = true
|
||||
}
|
||||
|
||||
if statement.Actions.Intersection(writeOnlyBucketActions).Equals(writeOnlyBucketActions) &&
|
||||
statement.Conditions == nil {
|
||||
writeOnly = true
|
||||
}
|
||||
|
||||
if statement.Actions.Intersection(readOnlyBucketActions).Equals(readOnlyBucketActions) {
|
||||
if prefix != "" && statement.Conditions != nil {
|
||||
if stringEqualsValue, ok := statement.Conditions["StringEquals"]; ok {
|
||||
if s3PrefixValues, ok := stringEqualsValue["s3:prefix"]; ok {
|
||||
if s3PrefixValues.Contains(prefix) {
|
||||
readOnly = true
|
||||
}
|
||||
}
|
||||
} else if stringNotEqualsValue, ok := statement.Conditions["StringNotEquals"]; ok {
|
||||
if s3PrefixValues, ok := stringNotEqualsValue["s3:prefix"]; ok {
|
||||
if !s3PrefixValues.Contains(prefix) {
|
||||
readOnly = true
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if prefix == "" && statement.Conditions == nil {
|
||||
readOnly = true
|
||||
} else if prefix != "" && statement.Conditions == nil {
|
||||
readOnly = true
|
||||
}
|
||||
}
|
||||
|
||||
return commonFound, readOnly, writeOnly
|
||||
}
|
||||
|
||||
// Returns policy of given object statement.
|
||||
func getObjectPolicy(statement Statement) (readOnly bool, writeOnly bool) {
|
||||
if statement.Effect == "Allow" &&
|
||||
statement.Principal.AWS.Contains("*") &&
|
||||
statement.Conditions == nil {
|
||||
if statement.Actions.Intersection(readOnlyObjectActions).Equals(readOnlyObjectActions) {
|
||||
readOnly = true
|
||||
}
|
||||
if statement.Actions.Intersection(writeOnlyObjectActions).Equals(writeOnlyObjectActions) {
|
||||
writeOnly = true
|
||||
}
|
||||
}
|
||||
|
||||
return readOnly, writeOnly
|
||||
}
|
||||
|
||||
// GetPolicy - Returns policy of given bucket name, prefix in given statements.
|
||||
func GetPolicy(statements []Statement, bucketName string, prefix string) BucketPolicy {
|
||||
bucketResource := awsResourcePrefix + bucketName
|
||||
objectResource := awsResourcePrefix + bucketName + "/" + prefix + "*"
|
||||
|
||||
bucketCommonFound := false
|
||||
bucketReadOnly := false
|
||||
bucketWriteOnly := false
|
||||
matchedResource := ""
|
||||
objReadOnly := false
|
||||
objWriteOnly := false
|
||||
|
||||
for _, s := range statements {
|
||||
matchedObjResources := set.NewStringSet()
|
||||
if s.Resources.Contains(objectResource) {
|
||||
matchedObjResources.Add(objectResource)
|
||||
} else {
|
||||
matchedObjResources = s.Resources.FuncMatch(resourceMatch, objectResource)
|
||||
}
|
||||
|
||||
if !matchedObjResources.IsEmpty() {
|
||||
readOnly, writeOnly := getObjectPolicy(s)
|
||||
for resource := range matchedObjResources {
|
||||
if len(matchedResource) < len(resource) {
|
||||
objReadOnly = readOnly
|
||||
objWriteOnly = writeOnly
|
||||
matchedResource = resource
|
||||
} else if len(matchedResource) == len(resource) {
|
||||
objReadOnly = objReadOnly || readOnly
|
||||
objWriteOnly = objWriteOnly || writeOnly
|
||||
matchedResource = resource
|
||||
}
|
||||
}
|
||||
} else if s.Resources.Contains(bucketResource) {
|
||||
commonFound, readOnly, writeOnly := getBucketPolicy(s, prefix)
|
||||
bucketCommonFound = bucketCommonFound || commonFound
|
||||
bucketReadOnly = bucketReadOnly || readOnly
|
||||
bucketWriteOnly = bucketWriteOnly || writeOnly
|
||||
}
|
||||
}
|
||||
|
||||
policy := BucketPolicyNone
|
||||
if bucketCommonFound {
|
||||
if bucketReadOnly && bucketWriteOnly && objReadOnly && objWriteOnly {
|
||||
policy = BucketPolicyReadWrite
|
||||
} else if bucketReadOnly && objReadOnly {
|
||||
policy = BucketPolicyReadOnly
|
||||
} else if bucketWriteOnly && objWriteOnly {
|
||||
policy = BucketPolicyWriteOnly
|
||||
}
|
||||
}
|
||||
|
||||
return policy
|
||||
}
|
||||
|
||||
// GetPolicies - returns a map of policies of given bucket name, prefix in given statements.
|
||||
func GetPolicies(statements []Statement, bucketName, prefix string) map[string]BucketPolicy {
|
||||
policyRules := map[string]BucketPolicy{}
|
||||
objResources := set.NewStringSet()
|
||||
// Search all resources related to objects policy
|
||||
for _, s := range statements {
|
||||
for r := range s.Resources {
|
||||
if strings.HasPrefix(r, awsResourcePrefix+bucketName+"/"+prefix) {
|
||||
objResources.Add(r)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Pretend that policy resource as an actual object and fetch its policy
|
||||
for r := range objResources {
|
||||
// Put trailing * if exists in asterisk
|
||||
asterisk := ""
|
||||
if strings.HasSuffix(r, "*") {
|
||||
r = r[:len(r)-1]
|
||||
asterisk = "*"
|
||||
}
|
||||
objectPath := r[len(awsResourcePrefix+bucketName)+1:]
|
||||
p := GetPolicy(statements, bucketName, objectPath)
|
||||
policyRules[bucketName+"/"+objectPath+asterisk] = p
|
||||
}
|
||||
return policyRules
|
||||
}
|
||||
|
||||
// SetPolicy - Returns new statements containing policy of given bucket name and prefix are appended.
|
||||
func SetPolicy(statements []Statement, policy BucketPolicy, bucketName string, prefix string) []Statement {
|
||||
out := removeStatements(statements, bucketName, prefix)
|
||||
// fmt.Println("out = ")
|
||||
// printstatement(out)
|
||||
ns := newStatements(policy, bucketName, prefix)
|
||||
// fmt.Println("ns = ")
|
||||
// printstatement(ns)
|
||||
|
||||
rv := appendStatements(out, ns)
|
||||
// fmt.Println("rv = ")
|
||||
// printstatement(rv)
|
||||
|
||||
return rv
|
||||
}
|
||||
|
||||
// Match function matches wild cards in 'pattern' for resource.
|
||||
func resourceMatch(pattern, resource string) bool {
|
||||
if pattern == "" {
|
||||
return resource == pattern
|
||||
}
|
||||
if pattern == "*" {
|
||||
return true
|
||||
}
|
||||
parts := strings.Split(pattern, "*")
|
||||
if len(parts) == 1 {
|
||||
return resource == pattern
|
||||
}
|
||||
tGlob := strings.HasSuffix(pattern, "*")
|
||||
end := len(parts) - 1
|
||||
if !strings.HasPrefix(resource, parts[0]) {
|
||||
return false
|
||||
}
|
||||
for i := 1; i < end; i++ {
|
||||
if !strings.Contains(resource, parts[i]) {
|
||||
return false
|
||||
}
|
||||
idx := strings.Index(resource, parts[i]) + len(parts[i])
|
||||
resource = resource[idx:]
|
||||
}
|
||||
return tGlob || strings.HasSuffix(resource, parts[end])
|
||||
}
|
2022
vendor/github.com/minio/minio-go/pkg/policy/bucket-policy_test.go
generated
vendored
2022
vendor/github.com/minio/minio-go/pkg/policy/bucket-policy_test.go
generated
vendored
File diff suppressed because it is too large
Load diff
109
vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-streaming_test.go
generated
vendored
109
vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-streaming_test.go
generated
vendored
|
@ -1,109 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 s3signer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestGetSeedSignature(t *testing.T) {
|
||||
accessKeyID := "AKIAIOSFODNN7EXAMPLE"
|
||||
secretAccessKeyID := "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
||||
dataLen := 66560
|
||||
data := bytes.Repeat([]byte("a"), dataLen)
|
||||
body := ioutil.NopCloser(bytes.NewReader(data))
|
||||
|
||||
req := NewRequest("PUT", "/examplebucket/chunkObject.txt", body)
|
||||
req.Header.Set("x-amz-storage-class", "REDUCED_REDUNDANCY")
|
||||
req.Host = "s3.amazonaws.com"
|
||||
|
||||
reqTime, err := time.Parse("20060102T150405Z", "20130524T000000Z")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse time - %v", err)
|
||||
}
|
||||
|
||||
req = StreamingSignV4(req, accessKeyID, secretAccessKeyID, "", "us-east-1", int64(dataLen), reqTime)
|
||||
actualSeedSignature := req.Body.(*StreamingReader).seedSignature
|
||||
|
||||
expectedSeedSignature := "38cab3af09aa15ddf29e26e36236f60fb6bfb6243a20797ae9a8183674526079"
|
||||
if actualSeedSignature != expectedSeedSignature {
|
||||
t.Errorf("Expected %s but received %s", expectedSeedSignature, actualSeedSignature)
|
||||
}
|
||||
}
|
||||
|
||||
func TestChunkSignature(t *testing.T) {
|
||||
chunkData := bytes.Repeat([]byte("a"), 65536)
|
||||
reqTime, _ := time.Parse(iso8601DateFormat, "20130524T000000Z")
|
||||
previousSignature := "4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9"
|
||||
location := "us-east-1"
|
||||
secretAccessKeyID := "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
||||
expectedSignature := "ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648"
|
||||
actualSignature := buildChunkSignature(chunkData, reqTime, location, previousSignature, secretAccessKeyID)
|
||||
if actualSignature != expectedSignature {
|
||||
t.Errorf("Expected %s but received %s", expectedSignature, actualSignature)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetStreamingAuthorization(t *testing.T) {
|
||||
location := "us-east-1"
|
||||
secretAccessKeyID := "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
||||
accessKeyID := "AKIAIOSFODNN7EXAMPLE"
|
||||
|
||||
req := NewRequest("PUT", "/examplebucket/chunkObject.txt", nil)
|
||||
req.Header.Set("x-amz-storage-class", "REDUCED_REDUNDANCY")
|
||||
req.Host = ""
|
||||
req.URL.Host = "s3.amazonaws.com"
|
||||
|
||||
dataLen := int64(65 * 1024)
|
||||
reqTime, _ := time.Parse(iso8601DateFormat, "20130524T000000Z")
|
||||
req = StreamingSignV4(req, accessKeyID, secretAccessKeyID, "", location, dataLen, reqTime)
|
||||
|
||||
expectedAuthorization := "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-storage-class,Signature=38cab3af09aa15ddf29e26e36236f60fb6bfb6243a20797ae9a8183674526079"
|
||||
|
||||
actualAuthorization := req.Header.Get("Authorization")
|
||||
if actualAuthorization != expectedAuthorization {
|
||||
t.Errorf("Expected %s but received %s", expectedAuthorization, actualAuthorization)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStreamingReader(t *testing.T) {
|
||||
reqTime, _ := time.Parse("20060102T150405Z", "20130524T000000Z")
|
||||
location := "us-east-1"
|
||||
secretAccessKeyID := "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
||||
accessKeyID := "AKIAIOSFODNN7EXAMPLE"
|
||||
dataLen := int64(65 * 1024)
|
||||
|
||||
req := NewRequest("PUT", "/examplebucket/chunkObject.txt", nil)
|
||||
req.Header.Set("x-amz-storage-class", "REDUCED_REDUNDANCY")
|
||||
req.ContentLength = 65 * 1024
|
||||
req.Host = ""
|
||||
req.URL.Host = "s3.amazonaws.com"
|
||||
|
||||
baseReader := ioutil.NopCloser(bytes.NewReader(bytes.Repeat([]byte("a"), 65*1024)))
|
||||
req.Body = baseReader
|
||||
req = StreamingSignV4(req, accessKeyID, secretAccessKeyID, "", location, dataLen, reqTime)
|
||||
|
||||
b, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error but received %v %d", err, len(b))
|
||||
}
|
||||
req.Body.Close()
|
||||
}
|
36
vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-v2_test.go
generated
vendored
36
vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-v2_test.go
generated
vendored
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 s3signer
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Tests for 'func TestResourceListSorting(t *testing.T)'.
|
||||
func TestResourceListSorting(t *testing.T) {
|
||||
sortedResourceList := make([]string, len(resourceList))
|
||||
copy(sortedResourceList, resourceList)
|
||||
sort.Strings(sortedResourceList)
|
||||
for i := 0; i < len(resourceList); i++ {
|
||||
if resourceList[i] != sortedResourceList[i] {
|
||||
t.Errorf("Expected resourceList[%d] = \"%s\", resourceList is not correctly sorted.", i, sortedResourceList[i])
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
50
vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-v4_test.go
generated
vendored
50
vendor/github.com/minio/minio-go/pkg/s3signer/request-signature-v4_test.go
generated
vendored
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 s3signer
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRequestHost(t *testing.T) {
|
||||
req, _ := buildRequest("dynamodb", "us-east-1", "{}")
|
||||
req.URL.RawQuery = "Foo=z&Foo=o&Foo=m&Foo=a"
|
||||
req.Host = "myhost"
|
||||
canonicalHeaders := getCanonicalHeaders(*req, v4IgnoredHeaders)
|
||||
|
||||
if !strings.Contains(canonicalHeaders, "host:"+req.Host) {
|
||||
t.Errorf("canonical host header invalid")
|
||||
}
|
||||
}
|
||||
|
||||
func buildRequest(serviceName, region, body string) (*http.Request, io.ReadSeeker) {
|
||||
endpoint := "https://" + serviceName + "." + region + ".amazonaws.com"
|
||||
reader := strings.NewReader(body)
|
||||
req, _ := http.NewRequest("POST", endpoint, reader)
|
||||
req.URL.Opaque = "//example.org/bucket/key-._~,!@#$%^&*()"
|
||||
req.Header.Add("X-Amz-Target", "prefix.Operation")
|
||||
req.Header.Add("Content-Type", "application/x-amz-json-1.0")
|
||||
req.Header.Add("Content-Length", string(len(body)))
|
||||
req.Header.Add("X-Amz-Meta-Other-Header", "some-value=!@#$%^&* (+)")
|
||||
req.Header.Add("X-Amz-Meta-Other-Header_With_Underscore", "some-value=!@#$%^&* (+)")
|
||||
req.Header.Add("X-amz-Meta-Other-Header_With_Underscore", "some-value=!@#$%^&* (+)")
|
||||
return req, reader
|
||||
}
|
89
vendor/github.com/minio/minio-go/pkg/s3signer/request-signature_test.go
generated
vendored
89
vendor/github.com/minio/minio-go/pkg/s3signer/request-signature_test.go
generated
vendored
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 s3signer
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Tests signature calculation.
|
||||
func TestSignatureCalculationV4(t *testing.T) {
|
||||
req, err := http.NewRequest("GET", "https://s3.amazonaws.com", nil)
|
||||
if err != nil {
|
||||
t.Fatal("Error:", err)
|
||||
}
|
||||
req = SignV4(*req, "", "", "", "us-east-1")
|
||||
if req.Header.Get("Authorization") != "" {
|
||||
t.Fatal("Error: anonymous credentials should not have Authorization header.")
|
||||
}
|
||||
|
||||
req = PreSignV4(*req, "", "", "", "us-east-1", 0)
|
||||
if strings.Contains(req.URL.RawQuery, "X-Amz-Signature") {
|
||||
t.Fatal("Error: anonymous credentials should not have Signature query resource.")
|
||||
}
|
||||
|
||||
req = SignV4(*req, "ACCESS-KEY", "SECRET-KEY", "", "us-east-1")
|
||||
if req.Header.Get("Authorization") == "" {
|
||||
t.Fatal("Error: normal credentials should have Authorization header.")
|
||||
}
|
||||
|
||||
req = PreSignV4(*req, "ACCESS-KEY", "SECRET-KEY", "", "us-east-1", 0)
|
||||
if !strings.Contains(req.URL.RawQuery, "X-Amz-Signature") {
|
||||
t.Fatal("Error: normal credentials should have Signature query resource.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignatureCalculationV2(t *testing.T) {
|
||||
|
||||
var testCases = []struct {
|
||||
endpointURL string
|
||||
virtualHost bool
|
||||
}{
|
||||
{endpointURL: "https://s3.amazonaws.com/", virtualHost: false},
|
||||
{endpointURL: "https://testbucket.s3.amazonaws.com/", virtualHost: true},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
req, err := http.NewRequest("GET", testCase.endpointURL, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d, Error: %v", i+1, err)
|
||||
}
|
||||
|
||||
req = SignV2(*req, "", "", testCase.virtualHost)
|
||||
if req.Header.Get("Authorization") != "" {
|
||||
t.Fatalf("Test %d, Error: anonymous credentials should not have Authorization header.", i+1)
|
||||
}
|
||||
|
||||
req = PreSignV2(*req, "", "", 0, testCase.virtualHost)
|
||||
if strings.Contains(req.URL.RawQuery, "Signature") {
|
||||
t.Fatalf("Test %d, Error: anonymous credentials should not have Signature query resource.", i+1)
|
||||
}
|
||||
|
||||
req = SignV2(*req, "ACCESS-KEY", "SECRET-KEY", testCase.virtualHost)
|
||||
if req.Header.Get("Authorization") == "" {
|
||||
t.Fatalf("Test %d, Error: normal credentials should have Authorization header.", i+1)
|
||||
}
|
||||
|
||||
req = PreSignV2(*req, "ACCESS-KEY", "SECRET-KEY", 0, testCase.virtualHost)
|
||||
if !strings.Contains(req.URL.RawQuery, "Signature") {
|
||||
t.Fatalf("Test %d, Error: normal credentials should not have Signature query resource.", i+1)
|
||||
}
|
||||
}
|
||||
}
|
104
vendor/github.com/minio/minio-go/pkg/s3signer/test-utils_test.go
generated
vendored
104
vendor/github.com/minio/minio-go/pkg/s3signer/test-utils_test.go
generated
vendored
|
@ -1,104 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 s3signer
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// N B minio-go should compile on go1.5.3 onwards and httptest package is
|
||||
// available only from go.1.7.x. The following function is taken from
|
||||
// Go httptest package to be able to build on older versions of Go.
|
||||
|
||||
// NewRequest returns a new incoming server Request, suitable
|
||||
// for passing to an http.Handler for testing.
|
||||
//
|
||||
// The target is the RFC 7230 "request-target": it may be either a
|
||||
// path or an absolute URL. If target is an absolute URL, the host name
|
||||
// from the URL is used. Otherwise, "example.com" is used.
|
||||
//
|
||||
// The TLS field is set to a non-nil dummy value if target has scheme
|
||||
// "https".
|
||||
//
|
||||
// The Request.Proto is always HTTP/1.1.
|
||||
//
|
||||
// An empty method means "GET".
|
||||
//
|
||||
// The provided body may be nil. If the body is of type *bytes.Reader,
|
||||
// *strings.Reader, or *bytes.Buffer, the Request.ContentLength is
|
||||
// set.
|
||||
//
|
||||
// NewRequest panics on error for ease of use in testing, where a
|
||||
// panic is acceptable.
|
||||
func NewRequest(method, target string, body io.Reader) *http.Request {
|
||||
if method == "" {
|
||||
method = "GET"
|
||||
}
|
||||
req, err := http.ReadRequest(bufio.NewReader(strings.NewReader(method + " " + target + " HTTP/1.0\r\n\r\n")))
|
||||
if err != nil {
|
||||
panic("invalid NewRequest arguments; " + err.Error())
|
||||
}
|
||||
|
||||
// HTTP/1.0 was used above to avoid needing a Host field. Change it to 1.1 here.
|
||||
req.Proto = "HTTP/1.1"
|
||||
req.ProtoMinor = 1
|
||||
req.Close = false
|
||||
|
||||
if body != nil {
|
||||
switch v := body.(type) {
|
||||
case *bytes.Buffer:
|
||||
req.ContentLength = int64(v.Len())
|
||||
case *bytes.Reader:
|
||||
req.ContentLength = int64(v.Len())
|
||||
case *strings.Reader:
|
||||
req.ContentLength = int64(v.Len())
|
||||
default:
|
||||
req.ContentLength = -1
|
||||
}
|
||||
if rc, ok := body.(io.ReadCloser); ok {
|
||||
req.Body = rc
|
||||
} else {
|
||||
req.Body = ioutil.NopCloser(body)
|
||||
}
|
||||
}
|
||||
|
||||
// 192.0.2.0/24 is "TEST-NET" in RFC 5737 for use solely in
|
||||
// documentation and example source code and should not be
|
||||
// used publicly.
|
||||
req.RemoteAddr = "192.0.2.1:1234"
|
||||
|
||||
if req.Host == "" {
|
||||
req.Host = "example.com"
|
||||
}
|
||||
|
||||
if strings.HasPrefix(target, "https://") {
|
||||
req.TLS = &tls.ConnectionState{
|
||||
Version: tls.VersionTLS12,
|
||||
HandshakeComplete: true,
|
||||
ServerName: req.Host,
|
||||
}
|
||||
}
|
||||
|
||||
return req
|
||||
}
|
86
vendor/github.com/minio/minio-go/pkg/s3signer/utils_test.go
generated
vendored
86
vendor/github.com/minio/minio-go/pkg/s3signer/utils_test.go
generated
vendored
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 s3signer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Tests url encoding.
|
||||
func TestEncodeURL2Path(t *testing.T) {
|
||||
type urlStrings struct {
|
||||
virtualHost bool
|
||||
bucketName string
|
||||
objName string
|
||||
encodedObjName string
|
||||
}
|
||||
|
||||
want := []urlStrings{
|
||||
{
|
||||
virtualHost: true,
|
||||
bucketName: "bucketName",
|
||||
objName: "本語",
|
||||
encodedObjName: "%E6%9C%AC%E8%AA%9E",
|
||||
},
|
||||
{
|
||||
virtualHost: true,
|
||||
bucketName: "bucketName",
|
||||
objName: "本語.1",
|
||||
encodedObjName: "%E6%9C%AC%E8%AA%9E.1",
|
||||
},
|
||||
{
|
||||
virtualHost: true,
|
||||
objName: ">123>3123123",
|
||||
bucketName: "bucketName",
|
||||
encodedObjName: "%3E123%3E3123123",
|
||||
},
|
||||
{
|
||||
virtualHost: true,
|
||||
bucketName: "bucketName",
|
||||
objName: "test 1 2.txt",
|
||||
encodedObjName: "test%201%202.txt",
|
||||
},
|
||||
{
|
||||
virtualHost: false,
|
||||
bucketName: "test.bucketName",
|
||||
objName: "test++ 1.txt",
|
||||
encodedObjName: "test%2B%2B%201.txt",
|
||||
},
|
||||
}
|
||||
|
||||
for i, o := range want {
|
||||
var hostURL string
|
||||
if o.virtualHost {
|
||||
hostURL = fmt.Sprintf("https://%s.s3.amazonaws.com/%s", o.bucketName, o.objName)
|
||||
} else {
|
||||
hostURL = fmt.Sprintf("https://s3.amazonaws.com/%s/%s", o.bucketName, o.objName)
|
||||
}
|
||||
u, err := url.Parse(hostURL)
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d, Error: %v", i+1, err)
|
||||
}
|
||||
expectedPath := "/" + o.bucketName + "/" + o.encodedObjName
|
||||
if foundPath := encodeURL2Path(&http.Request{URL: u}, o.virtualHost); foundPath != expectedPath {
|
||||
t.Fatalf("Test %d, Error: expected = `%v`, found = `%v`", i+1, expectedPath, foundPath)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
408
vendor/github.com/minio/minio-go/pkg/s3utils/utils_test.go
generated
vendored
408
vendor/github.com/minio/minio-go/pkg/s3utils/utils_test.go
generated
vendored
|
@ -1,408 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 s3utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Tests get region from host URL.
|
||||
func TestGetRegionFromURL(t *testing.T) {
|
||||
testCases := []struct {
|
||||
u url.URL
|
||||
expectedRegion string
|
||||
}{
|
||||
{
|
||||
u: url.URL{Host: "storage.googleapis.com"},
|
||||
expectedRegion: "",
|
||||
},
|
||||
{
|
||||
u: url.URL{Host: "s3.cn-north-1.amazonaws.com.cn"},
|
||||
expectedRegion: "cn-north-1",
|
||||
},
|
||||
{
|
||||
u: url.URL{Host: "s3.cn-northwest-1.amazonaws.com.cn"},
|
||||
expectedRegion: "cn-northwest-1",
|
||||
},
|
||||
{
|
||||
u: url.URL{Host: "s3-fips-us-gov-west-1.amazonaws.com"},
|
||||
expectedRegion: "us-gov-west-1",
|
||||
},
|
||||
{
|
||||
u: url.URL{Host: "s3-us-gov-west-1.amazonaws.com"},
|
||||
expectedRegion: "us-gov-west-1",
|
||||
},
|
||||
{
|
||||
u: url.URL{Host: "192.168.1.1"},
|
||||
expectedRegion: "",
|
||||
},
|
||||
{
|
||||
u: url.URL{Host: "s3-eu-west-1.amazonaws.com"},
|
||||
expectedRegion: "eu-west-1",
|
||||
},
|
||||
{
|
||||
u: url.URL{Host: "s3.eu-west-1.amazonaws.com"},
|
||||
expectedRegion: "eu-west-1",
|
||||
},
|
||||
{
|
||||
u: url.URL{Host: "s3.dualstack.eu-west-1.amazonaws.com"},
|
||||
expectedRegion: "eu-west-1",
|
||||
},
|
||||
{
|
||||
u: url.URL{Host: "s3.amazonaws.com"},
|
||||
expectedRegion: "",
|
||||
},
|
||||
{
|
||||
u: url.URL{Host: "s3-external-1.amazonaws.com"},
|
||||
expectedRegion: "",
|
||||
},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
region := GetRegionFromURL(testCase.u)
|
||||
if testCase.expectedRegion != region {
|
||||
t.Errorf("Test %d: Expected region %s, got %s", i+1, testCase.expectedRegion, region)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests for 'isValidDomain(host string) bool'.
|
||||
func TestIsValidDomain(t *testing.T) {
|
||||
testCases := []struct {
|
||||
// Input.
|
||||
host string
|
||||
// Expected result.
|
||||
result bool
|
||||
}{
|
||||
{"s3.amazonaws.com", true},
|
||||
{"s3.cn-north-1.amazonaws.com.cn", true},
|
||||
{"s3.cn-northwest-1.amazonaws.com.cn", true},
|
||||
{"s3.amazonaws.com_", false},
|
||||
{"%$$$", false},
|
||||
{"s3.amz.test.com", true},
|
||||
{"s3.%%", false},
|
||||
{"localhost", true},
|
||||
{"-localhost", false},
|
||||
{"", false},
|
||||
{"\n \t", false},
|
||||
{" ", false},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
result := IsValidDomain(testCase.host)
|
||||
if testCase.result != result {
|
||||
t.Errorf("Test %d: Expected isValidDomain test to be '%v', but found '%v' instead", i+1, testCase.result, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests validate IP address validator.
|
||||
func TestIsValidIP(t *testing.T) {
|
||||
testCases := []struct {
|
||||
// Input.
|
||||
ip string
|
||||
// Expected result.
|
||||
result bool
|
||||
}{
|
||||
{"192.168.1.1", true},
|
||||
{"192.168.1", false},
|
||||
{"192.168.1.1.1", false},
|
||||
{"-192.168.1.1", false},
|
||||
{"260.192.1.1", false},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
result := IsValidIP(testCase.ip)
|
||||
if testCase.result != result {
|
||||
t.Errorf("Test %d: Expected isValidIP to be '%v' for input \"%s\", but found it to be '%v' instead", i+1, testCase.result, testCase.ip, result)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Tests validate virtual host validator.
|
||||
func TestIsVirtualHostSupported(t *testing.T) {
|
||||
testCases := []struct {
|
||||
url string
|
||||
bucket string
|
||||
// Expeceted result.
|
||||
result bool
|
||||
}{
|
||||
{"https://s3.amazonaws.com", "my-bucket", true},
|
||||
{"https://s3.cn-north-1.amazonaws.com.cn", "my-bucket", true},
|
||||
{"https://s3.amazonaws.com", "my-bucket.", false},
|
||||
{"https://amazons3.amazonaws.com", "my-bucket.", false},
|
||||
{"https://storage.googleapis.com/", "my-bucket", true},
|
||||
{"https://mystorage.googleapis.com/", "my-bucket", false},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
u, err := url.Parse(testCase.url)
|
||||
if err != nil {
|
||||
t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, err)
|
||||
}
|
||||
result := IsVirtualHostSupported(*u, testCase.bucket)
|
||||
if testCase.result != result {
|
||||
t.Errorf("Test %d: Expected isVirtualHostSupported to be '%v' for input url \"%s\" and bucket \"%s\", but found it to be '%v' instead", i+1, testCase.result, testCase.url, testCase.bucket, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests validate Amazon endpoint validator.
|
||||
func TestIsAmazonEndpoint(t *testing.T) {
|
||||
testCases := []struct {
|
||||
url string
|
||||
// Expected result.
|
||||
result bool
|
||||
}{
|
||||
{"https://192.168.1.1", false},
|
||||
{"192.168.1.1", false},
|
||||
{"http://storage.googleapis.com", false},
|
||||
{"https://storage.googleapis.com", false},
|
||||
{"storage.googleapis.com", false},
|
||||
{"s3.amazonaws.com", false},
|
||||
{"https://amazons3.amazonaws.com", false},
|
||||
{"-192.168.1.1", false},
|
||||
{"260.192.1.1", false},
|
||||
{"https://s3-.amazonaws.com", false},
|
||||
{"https://s3..amazonaws.com", false},
|
||||
{"https://s3.dualstack.us-west-1.amazonaws.com.cn", false},
|
||||
{"https://s3..us-west-1.amazonaws.com.cn", false},
|
||||
// valid inputs.
|
||||
{"https://s3.amazonaws.com", true},
|
||||
{"https://s3-external-1.amazonaws.com", true},
|
||||
{"https://s3.cn-north-1.amazonaws.com.cn", true},
|
||||
{"https://s3-us-west-1.amazonaws.com", true},
|
||||
{"https://s3.us-west-1.amazonaws.com", true},
|
||||
{"https://s3.dualstack.us-west-1.amazonaws.com", true},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
u, err := url.Parse(testCase.url)
|
||||
if err != nil {
|
||||
t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, err)
|
||||
}
|
||||
result := IsAmazonEndpoint(*u)
|
||||
if testCase.result != result {
|
||||
t.Errorf("Test %d: Expected isAmazonEndpoint to be '%v' for input \"%s\", but found it to be '%v' instead", i+1, testCase.result, testCase.url, result)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Tests validate Google Cloud end point validator.
|
||||
func TestIsGoogleEndpoint(t *testing.T) {
|
||||
testCases := []struct {
|
||||
url string
|
||||
// Expected result.
|
||||
result bool
|
||||
}{
|
||||
{"192.168.1.1", false},
|
||||
{"https://192.168.1.1", false},
|
||||
{"s3.amazonaws.com", false},
|
||||
{"http://s3.amazonaws.com", false},
|
||||
{"https://s3.amazonaws.com", false},
|
||||
{"https://s3.cn-north-1.amazonaws.com.cn", false},
|
||||
{"-192.168.1.1", false},
|
||||
{"260.192.1.1", false},
|
||||
// valid inputs.
|
||||
{"http://storage.googleapis.com", true},
|
||||
{"https://storage.googleapis.com", true},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
u, err := url.Parse(testCase.url)
|
||||
if err != nil {
|
||||
t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, err)
|
||||
}
|
||||
result := IsGoogleEndpoint(*u)
|
||||
if testCase.result != result {
|
||||
t.Errorf("Test %d: Expected isGoogleEndpoint to be '%v' for input \"%s\", but found it to be '%v' instead", i+1, testCase.result, testCase.url, result)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestPercentEncodeSlash(t *testing.T) {
|
||||
testCases := []struct {
|
||||
input string
|
||||
output string
|
||||
}{
|
||||
{"test123", "test123"},
|
||||
{"abc,+_1", "abc,+_1"},
|
||||
{"%40prefix=test%40123", "%40prefix=test%40123"},
|
||||
{"key1=val1/val2", "key1=val1%2Fval2"},
|
||||
{"%40prefix=test%40123/", "%40prefix=test%40123%2F"},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
receivedOutput := percentEncodeSlash(testCase.input)
|
||||
if testCase.output != receivedOutput {
|
||||
t.Errorf(
|
||||
"Test %d: Input: \"%s\" --> Expected percentEncodeSlash to return \"%s\", but it returned \"%s\" instead!",
|
||||
i+1, testCase.input, testCase.output,
|
||||
receivedOutput,
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests validate the query encoder.
|
||||
func TestQueryEncode(t *testing.T) {
|
||||
testCases := []struct {
|
||||
queryKey string
|
||||
valueToEncode []string
|
||||
// Expected result.
|
||||
result string
|
||||
}{
|
||||
{"prefix", []string{"test@123", "test@456"}, "prefix=test%40123&prefix=test%40456"},
|
||||
{"@prefix", []string{"test@123"}, "%40prefix=test%40123"},
|
||||
{"@prefix", []string{"a/b/c/"}, "%40prefix=a%2Fb%2Fc%2F"},
|
||||
{"prefix", []string{"test#123"}, "prefix=test%23123"},
|
||||
{"prefix#", []string{"test#123"}, "prefix%23=test%23123"},
|
||||
{"prefix", []string{"test123"}, "prefix=test123"},
|
||||
{"prefix", []string{"test本語123", "test123"}, "prefix=test%E6%9C%AC%E8%AA%9E123&prefix=test123"},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
urlValues := make(url.Values)
|
||||
for _, valueToEncode := range testCase.valueToEncode {
|
||||
urlValues.Add(testCase.queryKey, valueToEncode)
|
||||
}
|
||||
result := QueryEncode(urlValues)
|
||||
if testCase.result != result {
|
||||
t.Errorf("Test %d: Expected queryEncode result to be \"%s\", but found it to be \"%s\" instead", i+1, testCase.result, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests validate the URL path encoder.
|
||||
func TestEncodePath(t *testing.T) {
|
||||
testCases := []struct {
|
||||
// Input.
|
||||
inputStr string
|
||||
// Expected result.
|
||||
result string
|
||||
}{
|
||||
{"thisisthe%url", "thisisthe%25url"},
|
||||
{"本語", "%E6%9C%AC%E8%AA%9E"},
|
||||
{"本語.1", "%E6%9C%AC%E8%AA%9E.1"},
|
||||
{">123", "%3E123"},
|
||||
{"myurl#link", "myurl%23link"},
|
||||
{"space in url", "space%20in%20url"},
|
||||
{"url+path", "url%2Bpath"},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
result := EncodePath(testCase.inputStr)
|
||||
if testCase.result != result {
|
||||
t.Errorf("Test %d: Expected queryEncode result to be \"%s\", but found it to be \"%s\" instead", i+1, testCase.result, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests validate the bucket name validator.
|
||||
func TestIsValidBucketName(t *testing.T) {
|
||||
testCases := []struct {
|
||||
// Input.
|
||||
bucketName string
|
||||
// Expected result.
|
||||
err error
|
||||
// Flag to indicate whether test should Pass.
|
||||
shouldPass bool
|
||||
}{
|
||||
{".mybucket", errors.New("Bucket name contains invalid characters"), false},
|
||||
{"$mybucket", errors.New("Bucket name contains invalid characters"), false},
|
||||
{"mybucket-", errors.New("Bucket name contains invalid characters"), false},
|
||||
{"my", errors.New("Bucket name cannot be smaller than 3 characters"), false},
|
||||
{"", errors.New("Bucket name cannot be empty"), false},
|
||||
{"my..bucket", errors.New("Bucket name contains invalid characters"), false},
|
||||
{"192.168.1.168", errors.New("Bucket name cannot be an ip address"), false},
|
||||
{":bucketname", errors.New("Bucket name contains invalid characters"), false},
|
||||
{"_bucketName", errors.New("Bucket name contains invalid characters"), false},
|
||||
{"my.bucket.com", nil, true},
|
||||
{"my-bucket", nil, true},
|
||||
{"123my-bucket", nil, true},
|
||||
{"Mybucket", nil, true},
|
||||
{"My_bucket", nil, true},
|
||||
{"My:bucket", nil, true},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
err := CheckValidBucketName(testCase.bucketName)
|
||||
if err != nil && testCase.shouldPass {
|
||||
t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, err.Error())
|
||||
}
|
||||
if err == nil && !testCase.shouldPass {
|
||||
t.Errorf("Test %d: Expected to fail with <ERROR> \"%s\", but passed instead", i+1, testCase.err.Error())
|
||||
}
|
||||
// Failed as expected, but does it fail for the expected reason.
|
||||
if err != nil && !testCase.shouldPass {
|
||||
if err.Error() != testCase.err.Error() {
|
||||
t.Errorf("Test %d: Expected to fail with error \"%s\", but instead failed with error \"%s\" instead", i+1, testCase.err.Error(), err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Tests validate the bucket name validator stricter.
|
||||
func TestIsValidBucketNameStrict(t *testing.T) {
|
||||
testCases := []struct {
|
||||
// Input.
|
||||
bucketName string
|
||||
// Expected result.
|
||||
err error
|
||||
// Flag to indicate whether test should Pass.
|
||||
shouldPass bool
|
||||
}{
|
||||
{".mybucket", errors.New("Bucket name contains invalid characters"), false},
|
||||
{"$mybucket", errors.New("Bucket name contains invalid characters"), false},
|
||||
{"mybucket-", errors.New("Bucket name contains invalid characters"), false},
|
||||
{"my", errors.New("Bucket name cannot be smaller than 3 characters"), false},
|
||||
{"", errors.New("Bucket name cannot be empty"), false},
|
||||
{"my..bucket", errors.New("Bucket name contains invalid characters"), false},
|
||||
{"192.168.1.168", errors.New("Bucket name cannot be an ip address"), false},
|
||||
{"Mybucket", errors.New("Bucket name contains invalid characters"), false},
|
||||
{"my.bucket.com", nil, true},
|
||||
{"my-bucket", nil, true},
|
||||
{"123my-bucket", nil, true},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
err := CheckValidBucketNameStrict(testCase.bucketName)
|
||||
if err != nil && testCase.shouldPass {
|
||||
t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, err.Error())
|
||||
}
|
||||
if err == nil && !testCase.shouldPass {
|
||||
t.Errorf("Test %d: Expected to fail with <ERROR> \"%s\", but passed instead", i+1, testCase.err.Error())
|
||||
}
|
||||
// Failed as expected, but does it fail for the expected reason.
|
||||
if err != nil && !testCase.shouldPass {
|
||||
if err.Error() != testCase.err.Error() {
|
||||
t.Errorf("Test %d: Expected to fail with error \"%s\", but instead failed with error \"%s\" instead", i+1, testCase.err.Error(), err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
348
vendor/github.com/minio/minio-go/pkg/set/stringset_test.go
generated
vendored
348
vendor/github.com/minio/minio-go/pkg/set/stringset_test.go
generated
vendored
|
@ -1,348 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 set
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// NewStringSet() is called and the result is validated.
|
||||
func TestNewStringSet(t *testing.T) {
|
||||
if ss := NewStringSet(); !ss.IsEmpty() {
|
||||
t.Fatalf("expected: true, got: false")
|
||||
}
|
||||
}
|
||||
|
||||
// CreateStringSet() is called and the result is validated.
|
||||
func TestCreateStringSet(t *testing.T) {
|
||||
ss := CreateStringSet("foo")
|
||||
if str := ss.String(); str != `[foo]` {
|
||||
t.Fatalf("expected: %s, got: %s", `["foo"]`, str)
|
||||
}
|
||||
}
|
||||
|
||||
// CopyStringSet() is called and the result is validated.
|
||||
func TestCopyStringSet(t *testing.T) {
|
||||
ss := CreateStringSet("foo")
|
||||
sscopy := CopyStringSet(ss)
|
||||
if !ss.Equals(sscopy) {
|
||||
t.Fatalf("expected: %s, got: %s", ss, sscopy)
|
||||
}
|
||||
}
|
||||
|
||||
// StringSet.Add() is called with series of cases for valid and erroneous inputs and the result is validated.
|
||||
func TestStringSetAdd(t *testing.T) {
|
||||
testCases := []struct {
|
||||
value string
|
||||
expectedResult string
|
||||
}{
|
||||
// Test first addition.
|
||||
{"foo", `[foo]`},
|
||||
// Test duplicate addition.
|
||||
{"foo", `[foo]`},
|
||||
// Test new addition.
|
||||
{"bar", `[bar foo]`},
|
||||
}
|
||||
|
||||
ss := NewStringSet()
|
||||
for _, testCase := range testCases {
|
||||
ss.Add(testCase.value)
|
||||
if str := ss.String(); str != testCase.expectedResult {
|
||||
t.Fatalf("expected: %s, got: %s", testCase.expectedResult, str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StringSet.Remove() is called with series of cases for valid and erroneous inputs and the result is validated.
|
||||
func TestStringSetRemove(t *testing.T) {
|
||||
ss := CreateStringSet("foo", "bar")
|
||||
testCases := []struct {
|
||||
value string
|
||||
expectedResult string
|
||||
}{
|
||||
// Test removing non-existen item.
|
||||
{"baz", `[bar foo]`},
|
||||
// Test remove existing item.
|
||||
{"foo", `[bar]`},
|
||||
// Test remove existing item again.
|
||||
{"foo", `[bar]`},
|
||||
// Test remove to make set to empty.
|
||||
{"bar", `[]`},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
ss.Remove(testCase.value)
|
||||
if str := ss.String(); str != testCase.expectedResult {
|
||||
t.Fatalf("expected: %s, got: %s", testCase.expectedResult, str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StringSet.Contains() is called with series of cases for valid and erroneous inputs and the result is validated.
|
||||
func TestStringSetContains(t *testing.T) {
|
||||
ss := CreateStringSet("foo")
|
||||
testCases := []struct {
|
||||
value string
|
||||
expectedResult bool
|
||||
}{
|
||||
// Test to check non-existent item.
|
||||
{"bar", false},
|
||||
// Test to check existent item.
|
||||
{"foo", true},
|
||||
// Test to verify case sensitivity.
|
||||
{"Foo", false},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
if result := ss.Contains(testCase.value); result != testCase.expectedResult {
|
||||
t.Fatalf("expected: %t, got: %t", testCase.expectedResult, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StringSet.FuncMatch() is called with series of cases for valid and erroneous inputs and the result is validated.
|
||||
func TestStringSetFuncMatch(t *testing.T) {
|
||||
ss := CreateStringSet("foo", "bar")
|
||||
testCases := []struct {
|
||||
matchFn func(string, string) bool
|
||||
value string
|
||||
expectedResult string
|
||||
}{
|
||||
// Test to check match function doing case insensive compare.
|
||||
{func(setValue string, compareValue string) bool {
|
||||
return strings.ToUpper(setValue) == strings.ToUpper(compareValue)
|
||||
}, "Bar", `[bar]`},
|
||||
// Test to check match function doing prefix check.
|
||||
{func(setValue string, compareValue string) bool {
|
||||
return strings.HasPrefix(compareValue, setValue)
|
||||
}, "foobar", `[foo]`},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
s := ss.FuncMatch(testCase.matchFn, testCase.value)
|
||||
if result := s.String(); result != testCase.expectedResult {
|
||||
t.Fatalf("expected: %s, got: %s", testCase.expectedResult, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StringSet.ApplyFunc() is called with series of cases for valid and erroneous inputs and the result is validated.
|
||||
func TestStringSetApplyFunc(t *testing.T) {
|
||||
ss := CreateStringSet("foo", "bar")
|
||||
testCases := []struct {
|
||||
applyFn func(string) string
|
||||
expectedResult string
|
||||
}{
|
||||
// Test to apply function prepending a known string.
|
||||
{func(setValue string) string { return "mybucket/" + setValue }, `[mybucket/bar mybucket/foo]`},
|
||||
// Test to apply function modifying values.
|
||||
{func(setValue string) string { return setValue[1:] }, `[ar oo]`},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
s := ss.ApplyFunc(testCase.applyFn)
|
||||
if result := s.String(); result != testCase.expectedResult {
|
||||
t.Fatalf("expected: %s, got: %s", testCase.expectedResult, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StringSet.Equals() is called with series of cases for valid and erroneous inputs and the result is validated.
|
||||
func TestStringSetEquals(t *testing.T) {
|
||||
testCases := []struct {
|
||||
set1 StringSet
|
||||
set2 StringSet
|
||||
expectedResult bool
|
||||
}{
|
||||
// Test equal set
|
||||
{CreateStringSet("foo", "bar"), CreateStringSet("foo", "bar"), true},
|
||||
// Test second set with more items
|
||||
{CreateStringSet("foo", "bar"), CreateStringSet("foo", "bar", "baz"), false},
|
||||
// Test second set with less items
|
||||
{CreateStringSet("foo", "bar"), CreateStringSet("bar"), false},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
if result := testCase.set1.Equals(testCase.set2); result != testCase.expectedResult {
|
||||
t.Fatalf("expected: %t, got: %t", testCase.expectedResult, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StringSet.Intersection() is called with series of cases for valid and erroneous inputs and the result is validated.
|
||||
func TestStringSetIntersection(t *testing.T) {
|
||||
testCases := []struct {
|
||||
set1 StringSet
|
||||
set2 StringSet
|
||||
expectedResult StringSet
|
||||
}{
|
||||
// Test intersecting all values.
|
||||
{CreateStringSet("foo", "bar"), CreateStringSet("foo", "bar"), CreateStringSet("foo", "bar")},
|
||||
// Test intersecting all values in second set.
|
||||
{CreateStringSet("foo", "bar", "baz"), CreateStringSet("foo", "bar"), CreateStringSet("foo", "bar")},
|
||||
// Test intersecting different values in second set.
|
||||
{CreateStringSet("foo", "baz"), CreateStringSet("baz", "bar"), CreateStringSet("baz")},
|
||||
// Test intersecting none.
|
||||
{CreateStringSet("foo", "baz"), CreateStringSet("poo", "bar"), NewStringSet()},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
if result := testCase.set1.Intersection(testCase.set2); !result.Equals(testCase.expectedResult) {
|
||||
t.Fatalf("expected: %s, got: %s", testCase.expectedResult, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StringSet.Difference() is called with series of cases for valid and erroneous inputs and the result is validated.
|
||||
func TestStringSetDifference(t *testing.T) {
|
||||
testCases := []struct {
|
||||
set1 StringSet
|
||||
set2 StringSet
|
||||
expectedResult StringSet
|
||||
}{
|
||||
// Test differing none.
|
||||
{CreateStringSet("foo", "bar"), CreateStringSet("foo", "bar"), NewStringSet()},
|
||||
// Test differing in first set.
|
||||
{CreateStringSet("foo", "bar", "baz"), CreateStringSet("foo", "bar"), CreateStringSet("baz")},
|
||||
// Test differing values in both set.
|
||||
{CreateStringSet("foo", "baz"), CreateStringSet("baz", "bar"), CreateStringSet("foo")},
|
||||
// Test differing all values.
|
||||
{CreateStringSet("foo", "baz"), CreateStringSet("poo", "bar"), CreateStringSet("foo", "baz")},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
if result := testCase.set1.Difference(testCase.set2); !result.Equals(testCase.expectedResult) {
|
||||
t.Fatalf("expected: %s, got: %s", testCase.expectedResult, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StringSet.Union() is called with series of cases for valid and erroneous inputs and the result is validated.
|
||||
func TestStringSetUnion(t *testing.T) {
|
||||
testCases := []struct {
|
||||
set1 StringSet
|
||||
set2 StringSet
|
||||
expectedResult StringSet
|
||||
}{
|
||||
// Test union same values.
|
||||
{CreateStringSet("foo", "bar"), CreateStringSet("foo", "bar"), CreateStringSet("foo", "bar")},
|
||||
// Test union same values in second set.
|
||||
{CreateStringSet("foo", "bar", "baz"), CreateStringSet("foo", "bar"), CreateStringSet("foo", "bar", "baz")},
|
||||
// Test union different values in both set.
|
||||
{CreateStringSet("foo", "baz"), CreateStringSet("baz", "bar"), CreateStringSet("foo", "baz", "bar")},
|
||||
// Test union all different values.
|
||||
{CreateStringSet("foo", "baz"), CreateStringSet("poo", "bar"), CreateStringSet("foo", "baz", "poo", "bar")},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
if result := testCase.set1.Union(testCase.set2); !result.Equals(testCase.expectedResult) {
|
||||
t.Fatalf("expected: %s, got: %s", testCase.expectedResult, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StringSet.MarshalJSON() is called with series of cases for valid and erroneous inputs and the result is validated.
|
||||
func TestStringSetMarshalJSON(t *testing.T) {
|
||||
testCases := []struct {
|
||||
set StringSet
|
||||
expectedResult string
|
||||
}{
|
||||
// Test set with values.
|
||||
{CreateStringSet("foo", "bar"), `["bar","foo"]`},
|
||||
// Test empty set.
|
||||
{NewStringSet(), "[]"},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
if result, _ := testCase.set.MarshalJSON(); string(result) != testCase.expectedResult {
|
||||
t.Fatalf("expected: %s, got: %s", testCase.expectedResult, string(result))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StringSet.UnmarshalJSON() is called with series of cases for valid and erroneous inputs and the result is validated.
|
||||
func TestStringSetUnmarshalJSON(t *testing.T) {
|
||||
testCases := []struct {
|
||||
data []byte
|
||||
expectedResult string
|
||||
}{
|
||||
// Test to convert JSON array to set.
|
||||
{[]byte(`["bar","foo"]`), `[bar foo]`},
|
||||
// Test to convert JSON string to set.
|
||||
{[]byte(`"bar"`), `[bar]`},
|
||||
// Test to convert JSON empty array to set.
|
||||
{[]byte(`[]`), `[]`},
|
||||
// Test to convert JSON empty string to set.
|
||||
{[]byte(`""`), `[]`},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
var set StringSet
|
||||
set.UnmarshalJSON(testCase.data)
|
||||
if result := set.String(); result != testCase.expectedResult {
|
||||
t.Fatalf("expected: %s, got: %s", testCase.expectedResult, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StringSet.String() is called with series of cases for valid and erroneous inputs and the result is validated.
|
||||
func TestStringSetString(t *testing.T) {
|
||||
testCases := []struct {
|
||||
set StringSet
|
||||
expectedResult string
|
||||
}{
|
||||
// Test empty set.
|
||||
{NewStringSet(), `[]`},
|
||||
// Test set with empty value.
|
||||
{CreateStringSet(""), `[]`},
|
||||
// Test set with value.
|
||||
{CreateStringSet("foo"), `[foo]`},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
if str := testCase.set.String(); str != testCase.expectedResult {
|
||||
t.Fatalf("expected: %s, got: %s", testCase.expectedResult, str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StringSet.ToSlice() is called with series of cases for valid and erroneous inputs and the result is validated.
|
||||
func TestStringSetToSlice(t *testing.T) {
|
||||
testCases := []struct {
|
||||
set StringSet
|
||||
expectedResult string
|
||||
}{
|
||||
// Test empty set.
|
||||
{NewStringSet(), `[]`},
|
||||
// Test set with empty value.
|
||||
{CreateStringSet(""), `[]`},
|
||||
// Test set with value.
|
||||
{CreateStringSet("foo"), `[foo]`},
|
||||
// Test set with value.
|
||||
{CreateStringSet("foo", "bar"), `[bar foo]`},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
sslice := testCase.set.ToSlice()
|
||||
if str := fmt.Sprintf("%s", sslice); str != testCase.expectedResult {
|
||||
t.Fatalf("expected: %s, got: %s", testCase.expectedResult, str)
|
||||
}
|
||||
}
|
||||
}
|
4
vendor/github.com/minio/minio-go/retry.go
generated
vendored
4
vendor/github.com/minio/minio-go/retry.go
generated
vendored
|
@ -111,6 +111,9 @@ func isNetErrorRetryable(err error) bool {
|
|||
} else if strings.Contains(err.Error(), "connection timed out") {
|
||||
// If err is a net.Dial timeout, retry.
|
||||
return true
|
||||
} else if strings.Contains(err.Error(), "net/http: HTTP/1.x transport connection broken") {
|
||||
// If error is transport connection broken, retry.
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -128,6 +131,7 @@ var retryableS3Codes = map[string]struct{}{
|
|||
"InternalError": {},
|
||||
"ExpiredToken": {},
|
||||
"ExpiredTokenException": {},
|
||||
"SlowDown": {},
|
||||
// Add more AWS S3 codes here.
|
||||
}
|
||||
|
||||
|
|
75
vendor/github.com/minio/minio-go/test-utils_test.go
generated
vendored
75
vendor/github.com/minio/minio-go/test-utils_test.go
generated
vendored
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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"
|
||||
"encoding/xml"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Contains common used utilities for tests.
|
||||
|
||||
// APIError Used for mocking error response from server.
|
||||
type APIError struct {
|
||||
Code string
|
||||
Description string
|
||||
HTTPStatusCode int
|
||||
}
|
||||
|
||||
// Mocks XML error response from the server.
|
||||
func generateErrorResponse(resp *http.Response, APIErr APIError, bucketName string) *http.Response {
|
||||
// generate error response.
|
||||
errorResponse := getAPIErrorResponse(APIErr, bucketName)
|
||||
encodedErrorResponse := encodeResponse(errorResponse)
|
||||
// write Header.
|
||||
resp.StatusCode = APIErr.HTTPStatusCode
|
||||
resp.Body = ioutil.NopCloser(bytes.NewBuffer(encodedErrorResponse))
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
// getErrorResponse gets in standard error and resource value and
|
||||
// provides a encodable populated response values.
|
||||
func getAPIErrorResponse(err APIError, bucketName string) ErrorResponse {
|
||||
var errResp = ErrorResponse{}
|
||||
errResp.Code = err.Code
|
||||
errResp.Message = err.Description
|
||||
errResp.BucketName = bucketName
|
||||
return errResp
|
||||
}
|
||||
|
||||
// Encodes the response headers into XML format.
|
||||
func encodeResponse(response interface{}) []byte {
|
||||
var bytesBuffer bytes.Buffer
|
||||
bytesBuffer.WriteString(xml.Header)
|
||||
encode := xml.NewEncoder(&bytesBuffer)
|
||||
encode.Encode(response)
|
||||
return bytesBuffer.Bytes()
|
||||
}
|
||||
|
||||
// Convert string to bool and always return false if any error
|
||||
func mustParseBool(str string) bool {
|
||||
b, err := strconv.ParseBool(str)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return b
|
||||
}
|
1
vendor/github.com/minio/minio-go/utils.go
generated
vendored
1
vendor/github.com/minio/minio-go/utils.go
generated
vendored
|
@ -222,6 +222,7 @@ var supportedHeaders = []string{
|
|||
"content-encoding",
|
||||
"content-disposition",
|
||||
"content-language",
|
||||
"x-amz-website-redirect-location",
|
||||
// Add more supported headers here.
|
||||
}
|
||||
|
||||
|
|
378
vendor/github.com/minio/minio-go/utils_test.go
generated
vendored
378
vendor/github.com/minio/minio-go/utils_test.go
generated
vendored
|
@ -1,378 +0,0 @@
|
|||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* 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.
|
||||
* 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 (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio-go/pkg/s3utils"
|
||||
)
|
||||
|
||||
// Tests signature redacting function used
|
||||
// in filtering on-wire Authorization header.
|
||||
func TestRedactSignature(t *testing.T) {
|
||||
testCases := []struct {
|
||||
authValue string
|
||||
expectedRedactedAuthValue string
|
||||
}{
|
||||
{
|
||||
authValue: "AWS 1231313:888x000231==",
|
||||
expectedRedactedAuthValue: "AWS **REDACTED**:**REDACTED**",
|
||||
},
|
||||
{
|
||||
authValue: "AWS4-HMAC-SHA256 Credential=12312313/20170613/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=02131231312313213",
|
||||
expectedRedactedAuthValue: "AWS4-HMAC-SHA256 Credential=**REDACTED**/20170613/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=**REDACTED**",
|
||||
},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
redactedAuthValue := redactSignature(testCase.authValue)
|
||||
if redactedAuthValue != testCase.expectedRedactedAuthValue {
|
||||
t.Errorf("Test %d: Expected %s, got %s", i+1, testCase.expectedRedactedAuthValue, redactedAuthValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests filter header function by filtering out
|
||||
// some custom header keys.
|
||||
func TestFilterHeader(t *testing.T) {
|
||||
header := http.Header{}
|
||||
header.Set("Content-Type", "binary/octet-stream")
|
||||
header.Set("Content-Encoding", "gzip")
|
||||
newHeader := filterHeader(header, []string{"Content-Type"})
|
||||
if len(newHeader) > 1 {
|
||||
t.Fatalf("Unexpected size of the returned header, should be 1, got %d", len(newHeader))
|
||||
}
|
||||
if newHeader.Get("Content-Encoding") != "gzip" {
|
||||
t.Fatalf("Unexpected content-encoding value, expected 'gzip', got %s", newHeader.Get("Content-Encoding"))
|
||||
}
|
||||
}
|
||||
|
||||
// Tests for 'getEndpointURL(endpoint string, inSecure bool)'.
|
||||
func TestGetEndpointURL(t *testing.T) {
|
||||
testCases := []struct {
|
||||
// Inputs.
|
||||
endPoint string
|
||||
secure bool
|
||||
|
||||
// Expected result.
|
||||
result string
|
||||
err error
|
||||
// Flag indicating whether the test is expected to pass or not.
|
||||
shouldPass bool
|
||||
}{
|
||||
{"s3.amazonaws.com", true, "https://s3.amazonaws.com", nil, true},
|
||||
{"s3.cn-north-1.amazonaws.com.cn", true, "https://s3.cn-north-1.amazonaws.com.cn", nil, true},
|
||||
{"s3.cn-northwest-1.amazonaws.com.cn", true, "https://s3.cn-northwest-1.amazonaws.com.cn", nil, true},
|
||||
{"s3.amazonaws.com", false, "http://s3.amazonaws.com", nil, true},
|
||||
{"s3.cn-north-1.amazonaws.com.cn", false, "http://s3.cn-north-1.amazonaws.com.cn", nil, true},
|
||||
{"s3.cn-northwest-1.amazonaws.com.cn", false, "http://s3.cn-northwest-1.amazonaws.com.cn", nil, true},
|
||||
{"192.168.1.1:9000", false, "http://192.168.1.1:9000", nil, true},
|
||||
{"192.168.1.1:9000", true, "https://192.168.1.1:9000", nil, true},
|
||||
{"s3.amazonaws.com:443", true, "https://s3.amazonaws.com:443", nil, true},
|
||||
{"13333.123123.-", true, "", ErrInvalidArgument(fmt.Sprintf("Endpoint: %s does not follow ip address or domain name standards.", "13333.123123.-")), false},
|
||||
{"13333.123123.-", true, "", ErrInvalidArgument(fmt.Sprintf("Endpoint: %s does not follow ip address or domain name standards.", "13333.123123.-")), false},
|
||||
{"storage.googleapis.com:4000", true, "", ErrInvalidArgument("Google Cloud Storage endpoint should be 'storage.googleapis.com'."), false},
|
||||
{"s3.aamzza.-", true, "", ErrInvalidArgument(fmt.Sprintf("Endpoint: %s does not follow ip address or domain name standards.", "s3.aamzza.-")), false},
|
||||
{"", true, "", ErrInvalidArgument("Endpoint: does not follow ip address or domain name standards."), false},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
result, err := getEndpointURL(testCase.endPoint, testCase.secure)
|
||||
if err != nil && testCase.shouldPass {
|
||||
t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, err.Error())
|
||||
}
|
||||
if err == nil && !testCase.shouldPass {
|
||||
t.Errorf("Test %d: Expected to fail with <ERROR> \"%s\", but passed instead", i+1, testCase.err.Error())
|
||||
}
|
||||
// Failed as expected, but does it fail for the expected reason.
|
||||
if err != nil && !testCase.shouldPass {
|
||||
if err.Error() != testCase.err.Error() {
|
||||
t.Errorf("Test %d: Expected to fail with error \"%s\", but instead failed with error \"%s\" instead", i+1, testCase.err.Error(), err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// Test passes as expected, but the output values are verified for correctness here.
|
||||
if err == nil && testCase.shouldPass {
|
||||
if testCase.result != result.String() {
|
||||
t.Errorf("Test %d: Expected the result Url to be \"%s\", but found \"%s\" instead", i+1, testCase.result, result.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests validate end point validator.
|
||||
func TestIsValidEndpointURL(t *testing.T) {
|
||||
testCases := []struct {
|
||||
url string
|
||||
err error
|
||||
// Flag indicating whether the test is expected to pass or not.
|
||||
shouldPass bool
|
||||
}{
|
||||
{"", ErrInvalidArgument("Endpoint url cannot be empty."), false},
|
||||
{"/", nil, true},
|
||||
{"https://s3.amazonaws.com", nil, true},
|
||||
{"https://s3.cn-north-1.amazonaws.com.cn", nil, true},
|
||||
{"https://s3-us-gov-west-1.amazonaws.com", nil, true},
|
||||
{"https://s3-fips-us-gov-west-1.amazonaws.com", nil, true},
|
||||
{"https://s3.amazonaws.com/", nil, true},
|
||||
{"https://storage.googleapis.com/", nil, true},
|
||||
{"https://z3.amazonaws.com", nil, true},
|
||||
{"https://mybalancer.us-east-1.elb.amazonaws.com", nil, true},
|
||||
{"192.168.1.1", ErrInvalidArgument("Endpoint url cannot have fully qualified paths."), false},
|
||||
{"https://amazon.googleapis.com/", ErrInvalidArgument("Google Cloud Storage endpoint should be 'storage.googleapis.com'."), false},
|
||||
{"https://storage.googleapis.com/bucket/", ErrInvalidArgument("Endpoint url cannot have fully qualified paths."), false},
|
||||
{"https://s3.amazonaws.com/bucket/object", ErrInvalidArgument("Endpoint url cannot have fully qualified paths."), false},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
var u url.URL
|
||||
if testCase.url == "" {
|
||||
u = sentinelURL
|
||||
} else {
|
||||
u1, err := url.Parse(testCase.url)
|
||||
if err != nil {
|
||||
t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, err)
|
||||
}
|
||||
u = *u1
|
||||
}
|
||||
err := isValidEndpointURL(u)
|
||||
if err != nil && testCase.shouldPass {
|
||||
t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, err)
|
||||
}
|
||||
if err == nil && !testCase.shouldPass {
|
||||
t.Errorf("Test %d: Expected to fail with <ERROR> \"%s\", but passed instead", i+1, testCase.err)
|
||||
}
|
||||
// Failed as expected, but does it fail for the expected reason.
|
||||
if err != nil && !testCase.shouldPass {
|
||||
if err.Error() != testCase.err.Error() {
|
||||
t.Errorf("Test %d: Expected to fail with error \"%s\", but instead failed with error \"%s\" instead", i+1, testCase.err, err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultBucketLocation(t *testing.T) {
|
||||
testCases := []struct {
|
||||
endpointURL url.URL
|
||||
regionOverride string
|
||||
expectedLocation string
|
||||
}{
|
||||
// Region override is set URL is ignored. - Test 1.
|
||||
{
|
||||
endpointURL: url.URL{Host: "s3-fips-us-gov-west-1.amazonaws.com"},
|
||||
regionOverride: "us-west-1",
|
||||
expectedLocation: "us-west-1",
|
||||
},
|
||||
// No region override, url based preferenced is honored - Test 2.
|
||||
{
|
||||
endpointURL: url.URL{Host: "s3-fips-us-gov-west-1.amazonaws.com"},
|
||||
regionOverride: "",
|
||||
expectedLocation: "us-gov-west-1",
|
||||
},
|
||||
// Region override is honored - Test 3.
|
||||
{
|
||||
endpointURL: url.URL{Host: "s3.amazonaws.com"},
|
||||
regionOverride: "us-west-1",
|
||||
expectedLocation: "us-west-1",
|
||||
},
|
||||
// China region should be honored, region override not provided. - Test 4.
|
||||
{
|
||||
endpointURL: url.URL{Host: "s3.cn-north-1.amazonaws.com.cn"},
|
||||
regionOverride: "",
|
||||
expectedLocation: "cn-north-1",
|
||||
},
|
||||
// China region should be honored, region override not provided. - Test 5.
|
||||
{
|
||||
endpointURL: url.URL{Host: "s3.cn-northwest-1.amazonaws.com.cn"},
|
||||
regionOverride: "",
|
||||
expectedLocation: "cn-northwest-1",
|
||||
},
|
||||
// No region provided, no standard region strings provided as well. - Test 6.
|
||||
{
|
||||
endpointURL: url.URL{Host: "s3.amazonaws.com"},
|
||||
regionOverride: "",
|
||||
expectedLocation: "us-east-1",
|
||||
},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
retLocation := getDefaultLocation(testCase.endpointURL, testCase.regionOverride)
|
||||
if testCase.expectedLocation != retLocation {
|
||||
t.Errorf("Test %d: Expected location %s, got %s", i+1, testCase.expectedLocation, retLocation)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests validate the expiry time validator.
|
||||
func TestIsValidExpiry(t *testing.T) {
|
||||
testCases := []struct {
|
||||
// Input.
|
||||
duration time.Duration
|
||||
// Expected result.
|
||||
err error
|
||||
// Flag to indicate whether the test should pass.
|
||||
shouldPass bool
|
||||
}{
|
||||
{100 * time.Millisecond, ErrInvalidArgument("Expires cannot be lesser than 1 second."), false},
|
||||
{604801 * time.Second, ErrInvalidArgument("Expires cannot be greater than 7 days."), false},
|
||||
{0 * time.Second, ErrInvalidArgument("Expires cannot be lesser than 1 second."), false},
|
||||
{1 * time.Second, nil, true},
|
||||
{10000 * time.Second, nil, true},
|
||||
{999 * time.Second, nil, true},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
err := isValidExpiry(testCase.duration)
|
||||
if err != nil && testCase.shouldPass {
|
||||
t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, err.Error())
|
||||
}
|
||||
if err == nil && !testCase.shouldPass {
|
||||
t.Errorf("Test %d: Expected to fail with <ERROR> \"%s\", but passed instead", i+1, testCase.err.Error())
|
||||
}
|
||||
// Failed as expected, but does it fail for the expected reason.
|
||||
if err != nil && !testCase.shouldPass {
|
||||
if err.Error() != testCase.err.Error() {
|
||||
t.Errorf("Test %d: Expected to fail with error \"%s\", but instead failed with error \"%s\" instead", i+1, testCase.err.Error(), err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Tests validate the bucket name validator.
|
||||
func TestIsValidBucketName(t *testing.T) {
|
||||
testCases := []struct {
|
||||
// Input.
|
||||
bucketName string
|
||||
// Expected result.
|
||||
err error
|
||||
// Flag to indicate whether test should Pass.
|
||||
shouldPass bool
|
||||
}{
|
||||
{".mybucket", ErrInvalidBucketName("Bucket name contains invalid characters"), false},
|
||||
{"mybucket.", ErrInvalidBucketName("Bucket name contains invalid characters"), false},
|
||||
{"mybucket-", ErrInvalidBucketName("Bucket name contains invalid characters"), false},
|
||||
{"my", ErrInvalidBucketName("Bucket name cannot be smaller than 3 characters"), false},
|
||||
{"", ErrInvalidBucketName("Bucket name cannot be empty"), false},
|
||||
{"my..bucket", ErrInvalidBucketName("Bucket name contains invalid characters"), false},
|
||||
{"my.bucket.com", nil, true},
|
||||
{"my-bucket", nil, true},
|
||||
{"123my-bucket", nil, true},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
err := s3utils.CheckValidBucketName(testCase.bucketName)
|
||||
if err != nil && testCase.shouldPass {
|
||||
t.Errorf("Test %d: Expected to pass, but failed with: <ERROR> %s", i+1, err.Error())
|
||||
}
|
||||
if err == nil && !testCase.shouldPass {
|
||||
t.Errorf("Test %d: Expected to fail with <ERROR> \"%s\", but passed instead", i+1, testCase.err.Error())
|
||||
}
|
||||
// Failed as expected, but does it fail for the expected reason.
|
||||
if err != nil && !testCase.shouldPass {
|
||||
if err.Error() != testCase.err.Error() {
|
||||
t.Errorf("Test %d: Expected to fail with error \"%s\", but instead failed with error \"%s\" instead", i+1, testCase.err.Error(), err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Tests if header is standard supported header
|
||||
func TestIsStandardHeader(t *testing.T) {
|
||||
testCases := []struct {
|
||||
// Input.
|
||||
header string
|
||||
// Expected result.
|
||||
expectedValue bool
|
||||
}{
|
||||
{"content-encoding", true},
|
||||
{"content-type", true},
|
||||
{"cache-control", true},
|
||||
{"content-disposition", true},
|
||||
{"content-language", true},
|
||||
{"random-header", false},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
actual := isStandardHeader(testCase.header)
|
||||
if actual != testCase.expectedValue {
|
||||
t.Errorf("Test %d: Expected to pass, but failed", i+1)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Tests if header is server encryption header
|
||||
func TestIsSSEHeader(t *testing.T) {
|
||||
testCases := []struct {
|
||||
// Input.
|
||||
header string
|
||||
// Expected result.
|
||||
expectedValue bool
|
||||
}{
|
||||
{"x-amz-server-side-encryption", true},
|
||||
{"x-amz-server-side-encryption-aws-kms-key-id", true},
|
||||
{"x-amz-server-side-encryption-context", true},
|
||||
{"x-amz-server-side-encryption-customer-algorithm", true},
|
||||
{"x-amz-server-side-encryption-customer-key", true},
|
||||
{"x-amz-server-side-encryption-customer-key-MD5", true},
|
||||
{"random-header", false},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
actual := isSSEHeader(testCase.header)
|
||||
if actual != testCase.expectedValue {
|
||||
t.Errorf("Test %d: Expected to pass, but failed", i+1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests if header is x-amz-meta or x-amz-acl
|
||||
func TestIsAmzHeader(t *testing.T) {
|
||||
testCases := []struct {
|
||||
// Input.
|
||||
header string
|
||||
// Expected result.
|
||||
expectedValue bool
|
||||
}{
|
||||
{"x-amz-iv", false},
|
||||
{"x-amz-key", false},
|
||||
{"x-amz-matdesc", false},
|
||||
{"x-amz-meta-x-amz-iv", true},
|
||||
{"x-amz-meta-x-amz-key", true},
|
||||
{"x-amz-meta-x-amz-matdesc", true},
|
||||
{"x-amz-acl", true},
|
||||
{"random-header", false},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
actual := isAmzHeader(testCase.header)
|
||||
if actual != testCase.expectedValue {
|
||||
t.Errorf("Test %d: Expected to pass, but failed", i+1)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue