|
|
@ -17,7 +17,6 @@ |
|
|
|
package main |
|
|
|
package main |
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
import ( |
|
|
|
"crypto/sha256" |
|
|
|
|
|
|
|
"encoding/hex" |
|
|
|
"encoding/hex" |
|
|
|
"encoding/xml" |
|
|
|
"encoding/xml" |
|
|
|
"fmt" |
|
|
|
"fmt" |
|
|
@ -30,6 +29,8 @@ import ( |
|
|
|
"strings" |
|
|
|
"strings" |
|
|
|
"time" |
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fastSha256 "github.com/minio/minio/pkg/crypto/sha256" |
|
|
|
|
|
|
|
|
|
|
|
mux "github.com/gorilla/mux" |
|
|
|
mux "github.com/gorilla/mux" |
|
|
|
"github.com/minio/minio/pkg/probe" |
|
|
|
"github.com/minio/minio/pkg/probe" |
|
|
|
) |
|
|
|
) |
|
|
@ -619,22 +620,13 @@ func (api objectStorageAPI) PutObjectHandler(w http.ResponseWriter, r *http.Requ |
|
|
|
} |
|
|
|
} |
|
|
|
// Create anonymous object.
|
|
|
|
// Create anonymous object.
|
|
|
|
objInfo, err = api.ObjectAPI.PutObject(bucket, object, size, r.Body, nil) |
|
|
|
objInfo, err = api.ObjectAPI.PutObject(bucket, object, size, r.Body, nil) |
|
|
|
case authTypePresigned: |
|
|
|
case authTypePresigned, authTypeSigned: |
|
|
|
validateRegion := true // Validate region.
|
|
|
|
|
|
|
|
// For presigned requests verify them right here.
|
|
|
|
|
|
|
|
if apiErr := doesPresignedSignatureMatch(r, validateRegion); apiErr != ErrNone { |
|
|
|
|
|
|
|
writeErrorResponse(w, r, apiErr, r.URL.Path) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// Create presigned object.
|
|
|
|
|
|
|
|
objInfo, err = api.ObjectAPI.PutObject(bucket, object, size, r.Body, nil) |
|
|
|
|
|
|
|
case authTypeSigned: |
|
|
|
|
|
|
|
// Initialize a pipe for data pipe line.
|
|
|
|
// Initialize a pipe for data pipe line.
|
|
|
|
reader, writer := io.Pipe() |
|
|
|
reader, writer := io.Pipe() |
|
|
|
|
|
|
|
|
|
|
|
// Start writing in a routine.
|
|
|
|
// Start writing in a routine.
|
|
|
|
go func() { |
|
|
|
go func() { |
|
|
|
shaWriter := sha256.New() |
|
|
|
shaWriter := fastSha256.New() |
|
|
|
multiWriter := io.MultiWriter(shaWriter, writer) |
|
|
|
multiWriter := io.MultiWriter(shaWriter, writer) |
|
|
|
if _, e := io.CopyN(multiWriter, r.Body, size); e != nil { |
|
|
|
if _, e := io.CopyN(multiWriter, r.Body, size); e != nil { |
|
|
|
errorIf(probe.NewError(e), "Unable to read HTTP body.", nil) |
|
|
|
errorIf(probe.NewError(e), "Unable to read HTTP body.", nil) |
|
|
@ -643,14 +635,21 @@ func (api objectStorageAPI) PutObjectHandler(w http.ResponseWriter, r *http.Requ |
|
|
|
} |
|
|
|
} |
|
|
|
shaPayload := shaWriter.Sum(nil) |
|
|
|
shaPayload := shaWriter.Sum(nil) |
|
|
|
validateRegion := true // Validate region.
|
|
|
|
validateRegion := true // Validate region.
|
|
|
|
if apiErr := doesSignatureMatch(hex.EncodeToString(shaPayload), r, validateRegion); apiErr != ErrNone { |
|
|
|
var s3Error APIErrorCode |
|
|
|
if apiErr == ErrSignatureDoesNotMatch { |
|
|
|
if isRequestSignatureV4(r) { |
|
|
|
|
|
|
|
s3Error = doesSignatureMatch(hex.EncodeToString(shaPayload), r, validateRegion) |
|
|
|
|
|
|
|
} else if isRequestPresignedSignatureV4(r) { |
|
|
|
|
|
|
|
s3Error = doesPresignedSignatureMatch(hex.EncodeToString(shaPayload), r, validateRegion) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if s3Error != ErrNone { |
|
|
|
|
|
|
|
if s3Error == ErrSignatureDoesNotMatch { |
|
|
|
writer.CloseWithError(errSignatureMismatch) |
|
|
|
writer.CloseWithError(errSignatureMismatch) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
writer.CloseWithError(fmt.Errorf("%v", getAPIError(apiErr))) |
|
|
|
writer.CloseWithError(fmt.Errorf("%v", getAPIError(s3Error))) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Close the writer.
|
|
|
|
writer.Close() |
|
|
|
writer.Close() |
|
|
|
}() |
|
|
|
}() |
|
|
|
|
|
|
|
|
|
|
@ -799,22 +798,14 @@ func (api objectStorageAPI) PutObjectPartHandler(w http.ResponseWriter, r *http. |
|
|
|
// No need to verify signature, anonymous request access is
|
|
|
|
// No need to verify signature, anonymous request access is
|
|
|
|
// already allowed.
|
|
|
|
// already allowed.
|
|
|
|
partMD5, err = api.ObjectAPI.PutObjectPart(bucket, object, uploadID, partID, size, r.Body, hex.EncodeToString(md5Bytes)) |
|
|
|
partMD5, err = api.ObjectAPI.PutObjectPart(bucket, object, uploadID, partID, size, r.Body, hex.EncodeToString(md5Bytes)) |
|
|
|
case authTypePresigned: |
|
|
|
case authTypePresigned, authTypeSigned: |
|
|
|
validateRegion := true // Validate region.
|
|
|
|
validateRegion := true // Validate region.
|
|
|
|
// For presigned requests verify right here.
|
|
|
|
|
|
|
|
apiErr := doesPresignedSignatureMatch(r, validateRegion) |
|
|
|
|
|
|
|
if apiErr != ErrNone { |
|
|
|
|
|
|
|
writeErrorResponse(w, r, apiErr, r.URL.Path) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
partMD5, err = api.ObjectAPI.PutObjectPart(bucket, object, uploadID, partID, size, r.Body, hex.EncodeToString(md5Bytes)) |
|
|
|
|
|
|
|
case authTypeSigned: |
|
|
|
|
|
|
|
// Initialize a pipe for data pipe line.
|
|
|
|
// Initialize a pipe for data pipe line.
|
|
|
|
reader, writer := io.Pipe() |
|
|
|
reader, writer := io.Pipe() |
|
|
|
|
|
|
|
|
|
|
|
// Start writing in a routine.
|
|
|
|
// Start writing in a routine.
|
|
|
|
go func() { |
|
|
|
go func() { |
|
|
|
shaWriter := sha256.New() |
|
|
|
shaWriter := fastSha256.New() |
|
|
|
multiWriter := io.MultiWriter(shaWriter, writer) |
|
|
|
multiWriter := io.MultiWriter(shaWriter, writer) |
|
|
|
if _, e := io.CopyN(multiWriter, r.Body, size); e != nil { |
|
|
|
if _, e := io.CopyN(multiWriter, r.Body, size); e != nil { |
|
|
|
errorIf(probe.NewError(e), "Unable to read HTTP body.", nil) |
|
|
|
errorIf(probe.NewError(e), "Unable to read HTTP body.", nil) |
|
|
@ -822,15 +813,21 @@ func (api objectStorageAPI) PutObjectPartHandler(w http.ResponseWriter, r *http. |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
shaPayload := shaWriter.Sum(nil) |
|
|
|
shaPayload := shaWriter.Sum(nil) |
|
|
|
validateRegion := true // Validate region.
|
|
|
|
var s3Error APIErrorCode |
|
|
|
if apiErr := doesSignatureMatch(hex.EncodeToString(shaPayload), r, validateRegion); apiErr != ErrNone { |
|
|
|
if isRequestSignatureV4(r) { |
|
|
|
if apiErr == ErrSignatureDoesNotMatch { |
|
|
|
s3Error = doesSignatureMatch(hex.EncodeToString(shaPayload), r, validateRegion) |
|
|
|
|
|
|
|
} else if isRequestPresignedSignatureV4(r) { |
|
|
|
|
|
|
|
s3Error = doesPresignedSignatureMatch(hex.EncodeToString(shaPayload), r, validateRegion) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if s3Error != ErrNone { |
|
|
|
|
|
|
|
if s3Error == ErrSignatureDoesNotMatch { |
|
|
|
writer.CloseWithError(errSignatureMismatch) |
|
|
|
writer.CloseWithError(errSignatureMismatch) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
writer.CloseWithError(fmt.Errorf("%v", getAPIError(apiErr))) |
|
|
|
writer.CloseWithError(fmt.Errorf("%v", getAPIError(s3Error))) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Close the writer.
|
|
|
|
writer.Close() |
|
|
|
writer.Close() |
|
|
|
}() |
|
|
|
}() |
|
|
|
partMD5, err = api.ObjectAPI.PutObjectPart(bucket, object, uploadID, partID, size, reader, hex.EncodeToString(md5Bytes)) |
|
|
|
partMD5, err = api.ObjectAPI.PutObjectPart(bucket, object, uploadID, partID, size, reader, hex.EncodeToString(md5Bytes)) |
|
|
|