github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/cmd/copy-part-range.go (about)

     1  // Copyright (c) 2015-2021 MinIO, Inc.
     2  //
     3  // This file is part of MinIO Object Storage stack
     4  //
     5  // This program is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Affero General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // This program is distributed in the hope that it will be useful
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU Affero General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Affero General Public License
    16  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package cmd
    19  
    20  import (
    21  	"context"
    22  	"net/http"
    23  	"net/url"
    24  )
    25  
    26  // Writes S3 compatible copy part range error.
    27  func writeCopyPartErr(ctx context.Context, w http.ResponseWriter, err error, url *url.URL) {
    28  	switch err {
    29  	case errInvalidRange:
    30  		writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidCopyPartRange), url)
    31  		return
    32  	case errInvalidRangeSource:
    33  		writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidCopyPartRangeSource), url)
    34  		return
    35  	default:
    36  		apiErr := errorCodes.ToAPIErr(ErrInvalidCopyPartRangeSource)
    37  		apiErr.Description = err.Error()
    38  		writeErrorResponse(ctx, w, apiErr, url)
    39  		return
    40  	}
    41  }
    42  
    43  // Parses x-amz-copy-source-range for CopyObjectPart API. Its behavior
    44  // is different from regular HTTP range header. It only supports the
    45  // form `bytes=first-last` where first and last are zero-based byte
    46  // offsets. See
    47  // http://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPartCopy.html
    48  // for full details. This function treats an empty rangeString as
    49  // referring to the whole resource.
    50  func parseCopyPartRangeSpec(rangeString string) (hrange *HTTPRangeSpec, err error) {
    51  	hrange, err = parseRequestRangeSpec(rangeString)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  	if hrange.IsSuffixLength || hrange.Start < 0 || hrange.End < 0 {
    56  		return nil, errInvalidRange
    57  	}
    58  	return hrange, nil
    59  }
    60  
    61  // checkCopyPartRangeWithSize adds more check to the range string in case of
    62  // copy object part. This API requires having specific start and end  range values
    63  // e.g. 'bytes=3-10'. Other use cases will be rejected.
    64  func checkCopyPartRangeWithSize(rs *HTTPRangeSpec, resourceSize int64) (err error) {
    65  	if rs == nil {
    66  		return nil
    67  	}
    68  	if rs.IsSuffixLength || rs.Start >= resourceSize || rs.End >= resourceSize {
    69  		return errInvalidRangeSource
    70  	}
    71  	return nil
    72  }