putObject special function used Google Cloud Storage. This special function is used for Google Cloud Storage since Google's multipart API is not S3 compatible.
(ctx context.Context, bucketName, objectName string, reader io.Reader, size int64, opts PutObjectOptions)
| 656 | // putObject special function used Google Cloud Storage. This special function |
| 657 | // is used for Google Cloud Storage since Google's multipart API is not S3 compatible. |
| 658 | func (c *Client) putObject(ctx context.Context, bucketName, objectName string, reader io.Reader, size int64, opts PutObjectOptions) (info UploadInfo, err error) { |
| 659 | // Input validation. |
| 660 | if err := s3utils.CheckValidBucketName(bucketName); err != nil { |
| 661 | return UploadInfo{}, err |
| 662 | } |
| 663 | if err := s3utils.CheckValidObjectName(objectName); err != nil { |
| 664 | return UploadInfo{}, err |
| 665 | } |
| 666 | |
| 667 | // Size -1 is only supported on Google Cloud Storage, we error |
| 668 | // out in all other situations. |
| 669 | if size < 0 && !s3utils.IsGoogleEndpoint(*c.endpointURL) { |
| 670 | return UploadInfo{}, errEntityTooSmall(size, bucketName, objectName) |
| 671 | } |
| 672 | |
| 673 | if opts.SendContentMd5 && s3utils.IsGoogleEndpoint(*c.endpointURL) && size < 0 { |
| 674 | return UploadInfo{}, errInvalidArgument("MD5Sum cannot be calculated with size '-1'") |
| 675 | } |
| 676 | |
| 677 | var readSeeker io.Seeker |
| 678 | if size > 0 { |
| 679 | if isReadAt(reader) && !isObject(reader) { |
| 680 | seeker, ok := reader.(io.Seeker) |
| 681 | if ok { |
| 682 | offset, err := seeker.Seek(0, io.SeekCurrent) |
| 683 | if err != nil { |
| 684 | return UploadInfo{}, errInvalidArgument(err.Error()) |
| 685 | } |
| 686 | reader = io.NewSectionReader(reader.(io.ReaderAt), offset, size) |
| 687 | readSeeker = reader.(io.Seeker) |
| 688 | } |
| 689 | } |
| 690 | } |
| 691 | |
| 692 | var md5Base64 string |
| 693 | if opts.SendContentMd5 { |
| 694 | // Calculate md5sum. |
| 695 | hash := c.md5Hasher() |
| 696 | |
| 697 | if readSeeker != nil { |
| 698 | if _, err := io.Copy(hash, reader); err != nil { |
| 699 | return UploadInfo{}, err |
| 700 | } |
| 701 | // Seek back to beginning of io.NewSectionReader's offset. |
| 702 | _, err = readSeeker.Seek(0, io.SeekStart) |
| 703 | if err != nil { |
| 704 | return UploadInfo{}, errInvalidArgument(err.Error()) |
| 705 | } |
| 706 | } else { |
| 707 | // Create a buffer. |
| 708 | buf := make([]byte, size) |
| 709 | |
| 710 | length, err := readFull(reader, buf) |
| 711 | if err != nil && err != io.ErrUnexpectedEOF && err != io.EOF { |
| 712 | return UploadInfo{}, err |
| 713 | } |
| 714 | |
| 715 | hash.Write(buf[:length]) |
no test coverage detected