MCPcopy
hub / github.com/minio/minio-go / PutObjectAnnotation

Method PutObjectAnnotation

api-object-annotation.go:119–171  ·  view source on GitHub ↗

PutObjectAnnotation creates or overwrites a named annotation on an object version. The payload (1 byte to 1 MiB) is streamed directly from the supplied ReadSeeker: its size is taken from a seek to the end, so the body is sent with an exact Content-Length and never buffered in memory. It returns the

(ctx context.Context, bucketName, objectName, annotationName string, payload io.ReadSeeker, opts PutObjectAnnotationOptions)

Source from the content-addressed store, hash-verified

117// an exact Content-Length and never buffered in memory. It returns the
118// annotation's ETag. The parent object's ETag is never modified.
119func (c *Client) PutObjectAnnotation(ctx context.Context, bucketName, objectName, annotationName string, payload io.ReadSeeker, opts PutObjectAnnotationOptions) (string, error) {
120 if err := s3utils.CheckValidBucketName(bucketName); err != nil {
121 return "", err
122 }
123 if err := s3utils.CheckValidObjectName(objectName); err != nil {
124 return "", err
125 }
126 if err := validateAnnotationName(annotationName); err != nil {
127 return "", err
128 }
129 if payload == nil {
130 return "", errInvalidArgument("annotation payload must not be nil")
131 }
132
133 // Derive the payload size from the seeker and enforce the limits before
134 // uploading; the server reads the body raw, so it is sent with UNSIGNED-PAYLOAD
135 // (no streaming-chunked signature) and streamed without buffering.
136 size, err := payload.Seek(0, io.SeekEnd)
137 if err != nil {
138 return "", err
139 }
140 if _, err := payload.Seek(0, io.SeekStart); err != nil {
141 return "", err
142 }
143 if size == 0 {
144 return "", errInvalidArgument("annotation payload must be at least 1 byte")
145 }
146 if size > maxAnnotationPayloadBytes {
147 return "", errInvalidArgument("annotation payload exceeds the 1 MiB maximum")
148 }
149
150 headers := make(http.Header)
151 if opts.IfMatch != "" {
152 headers.Set(amzObjectIfMatchHeader, opts.IfMatch)
153 }
154
155 resp, err := c.executeMethod(ctx, http.MethodPut, requestMetadata{
156 bucketName: bucketName,
157 objectName: objectName,
158 queryValues: annotationQueryValues(annotationName, opts.VersionID),
159 contentBody: payload,
160 contentLength: size,
161 customHeader: headers,
162 })
163 defer closeResponse(resp)
164 if err != nil {
165 return "", err
166 }
167 if resp != nil && resp.StatusCode != http.StatusOK {
168 return "", httpRespToErrorResponse(resp, bucketName, objectName)
169 }
170 return trimEtag(resp.Header.Get("ETag")), nil
171}
172
173// GetObjectAnnotation returns the payload of a single named annotation as a
174// stream. The returned ReadCloser is the response body; the caller must Close it

Callers 2

testObjectAnnotationsFunction · 0.95
mainFunction · 0.80

Calls 12

executeMethodMethod · 0.95
CheckValidBucketNameFunction · 0.92
CheckValidObjectNameFunction · 0.92
validateAnnotationNameFunction · 0.85
errInvalidArgumentFunction · 0.85
annotationQueryValuesFunction · 0.85
httpRespToErrorResponseFunction · 0.85
trimEtagFunction · 0.85
closeResponseFunction · 0.70
SeekMethod · 0.45
SetMethod · 0.45
GetMethod · 0.45

Tested by

no test coverage detected