gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

api-get-options.go (5999B)


      1 /*
      2  * MinIO Go Library for Amazon S3 Compatible Cloud Storage
      3  * Copyright 2015-2020 MinIO, Inc.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package minio
     19 
     20 import (
     21 	"fmt"
     22 	"net/http"
     23 	"net/url"
     24 	"strconv"
     25 	"time"
     26 
     27 	"github.com/minio/minio-go/v7/pkg/encrypt"
     28 )
     29 
     30 // AdvancedGetOptions for internal use by MinIO server - not intended for client use.
     31 type AdvancedGetOptions struct {
     32 	ReplicationDeleteMarker           bool
     33 	IsReplicationReadyForDeleteMarker bool
     34 	ReplicationProxyRequest           string
     35 }
     36 
     37 // GetObjectOptions are used to specify additional headers or options
     38 // during GET requests.
     39 type GetObjectOptions struct {
     40 	headers              map[string]string
     41 	reqParams            url.Values
     42 	ServerSideEncryption encrypt.ServerSide
     43 	VersionID            string
     44 	PartNumber           int
     45 
     46 	// Include any checksums, if object was uploaded with checksum.
     47 	// For multipart objects this is a checksum of part checksums.
     48 	// https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html
     49 	Checksum bool
     50 
     51 	// To be not used by external applications
     52 	Internal AdvancedGetOptions
     53 }
     54 
     55 // StatObjectOptions are used to specify additional headers or options
     56 // during GET info/stat requests.
     57 type StatObjectOptions = GetObjectOptions
     58 
     59 // Header returns the http.Header representation of the GET options.
     60 func (o GetObjectOptions) Header() http.Header {
     61 	headers := make(http.Header, len(o.headers))
     62 	for k, v := range o.headers {
     63 		headers.Set(k, v)
     64 	}
     65 	if o.ServerSideEncryption != nil && o.ServerSideEncryption.Type() == encrypt.SSEC {
     66 		o.ServerSideEncryption.Marshal(headers)
     67 	}
     68 	// this header is set for active-active replication scenario where GET/HEAD
     69 	// to site A is proxy'd to site B if object/version missing on site A.
     70 	if o.Internal.ReplicationProxyRequest != "" {
     71 		headers.Set(minIOBucketReplicationProxyRequest, o.Internal.ReplicationProxyRequest)
     72 	}
     73 	if o.Checksum {
     74 		headers.Set("x-amz-checksum-mode", "ENABLED")
     75 	}
     76 	return headers
     77 }
     78 
     79 // Set adds a key value pair to the options. The
     80 // key-value pair will be part of the HTTP GET request
     81 // headers.
     82 func (o *GetObjectOptions) Set(key, value string) {
     83 	if o.headers == nil {
     84 		o.headers = make(map[string]string)
     85 	}
     86 	o.headers[http.CanonicalHeaderKey(key)] = value
     87 }
     88 
     89 // SetReqParam - set request query string parameter
     90 // supported key: see supportedQueryValues.
     91 // If an unsupported key is passed in, it will be ignored and nothing will be done.
     92 func (o *GetObjectOptions) SetReqParam(key, value string) {
     93 	if !isStandardQueryValue(key) {
     94 		// do nothing
     95 		return
     96 	}
     97 	if o.reqParams == nil {
     98 		o.reqParams = make(url.Values)
     99 	}
    100 	o.reqParams.Set(key, value)
    101 }
    102 
    103 // AddReqParam - add request query string parameter
    104 // supported key: see supportedQueryValues.
    105 // If an unsupported key is passed in, it will be ignored and nothing will be done.
    106 func (o *GetObjectOptions) AddReqParam(key, value string) {
    107 	if !isStandardQueryValue(key) {
    108 		// do nothing
    109 		return
    110 	}
    111 	if o.reqParams == nil {
    112 		o.reqParams = make(url.Values)
    113 	}
    114 	o.reqParams.Add(key, value)
    115 }
    116 
    117 // SetMatchETag - set match etag.
    118 func (o *GetObjectOptions) SetMatchETag(etag string) error {
    119 	if etag == "" {
    120 		return errInvalidArgument("ETag cannot be empty.")
    121 	}
    122 	o.Set("If-Match", "\""+etag+"\"")
    123 	return nil
    124 }
    125 
    126 // SetMatchETagExcept - set match etag except.
    127 func (o *GetObjectOptions) SetMatchETagExcept(etag string) error {
    128 	if etag == "" {
    129 		return errInvalidArgument("ETag cannot be empty.")
    130 	}
    131 	o.Set("If-None-Match", "\""+etag+"\"")
    132 	return nil
    133 }
    134 
    135 // SetUnmodified - set unmodified time since.
    136 func (o *GetObjectOptions) SetUnmodified(modTime time.Time) error {
    137 	if modTime.IsZero() {
    138 		return errInvalidArgument("Modified since cannot be empty.")
    139 	}
    140 	o.Set("If-Unmodified-Since", modTime.Format(http.TimeFormat))
    141 	return nil
    142 }
    143 
    144 // SetModified - set modified time since.
    145 func (o *GetObjectOptions) SetModified(modTime time.Time) error {
    146 	if modTime.IsZero() {
    147 		return errInvalidArgument("Modified since cannot be empty.")
    148 	}
    149 	o.Set("If-Modified-Since", modTime.Format(http.TimeFormat))
    150 	return nil
    151 }
    152 
    153 // SetRange - set the start and end offset of the object to be read.
    154 // See https://tools.ietf.org/html/rfc7233#section-3.1 for reference.
    155 func (o *GetObjectOptions) SetRange(start, end int64) error {
    156 	switch {
    157 	case start == 0 && end < 0:
    158 		// Read last '-end' bytes. `bytes=-N`.
    159 		o.Set("Range", fmt.Sprintf("bytes=%d", end))
    160 	case 0 < start && end == 0:
    161 		// Read everything starting from offset
    162 		// 'start'. `bytes=N-`.
    163 		o.Set("Range", fmt.Sprintf("bytes=%d-", start))
    164 	case 0 <= start && start <= end:
    165 		// Read everything starting at 'start' till the
    166 		// 'end'. `bytes=N-M`
    167 		o.Set("Range", fmt.Sprintf("bytes=%d-%d", start, end))
    168 	default:
    169 		// All other cases such as
    170 		// bytes=-3-
    171 		// bytes=5-3
    172 		// bytes=-2-4
    173 		// bytes=-3-0
    174 		// bytes=-3--2
    175 		// are invalid.
    176 		return errInvalidArgument(
    177 			fmt.Sprintf(
    178 				"Invalid range specified: start=%d end=%d",
    179 				start, end))
    180 	}
    181 	return nil
    182 }
    183 
    184 // toQueryValues - Convert the versionId, partNumber, and reqParams in Options to query string parameters.
    185 func (o *GetObjectOptions) toQueryValues() url.Values {
    186 	urlValues := make(url.Values)
    187 	if o.VersionID != "" {
    188 		urlValues.Set("versionId", o.VersionID)
    189 	}
    190 	if o.PartNumber > 0 {
    191 		urlValues.Set("partNumber", strconv.Itoa(o.PartNumber))
    192 	}
    193 
    194 	if o.reqParams != nil {
    195 		for key, values := range o.reqParams {
    196 			for _, value := range values {
    197 				urlValues.Add(key, value)
    198 			}
    199 		}
    200 	}
    201 
    202 	return urlValues
    203 }