* PUT Object Copy in the requested bucket. * @param {AuthInfo} authInfo - Instance of AuthInfo class with * requester's info * @param {request} request - request object given by router, * includes normalized headers * @param {string} sourceBucket - name of source buck
(authInfo, request, sourceBucket,
sourceObject, sourceVersionId, log, callback)
| 216 | * @return {undefined} |
| 217 | */ |
| 218 | function objectCopy(authInfo, request, sourceBucket, |
| 219 | sourceObject, sourceVersionId, log, callback) { |
| 220 | log.debug('processing request', { method: 'objectCopy' }); |
| 221 | const destBucketName = request.bucketName; |
| 222 | const destObjectKey = request.objectKey; |
| 223 | |
| 224 | const keyLengthError = validateObjectKeyLength(destObjectKey, config.objectKeyByteLimit); |
| 225 | if (keyLengthError) { |
| 226 | return callback(keyLengthError); |
| 227 | } |
| 228 | |
| 229 | const sourceIsDestination = |
| 230 | destBucketName === sourceBucket && destObjectKey === sourceObject; |
| 231 | const valGetParams = { |
| 232 | authInfo, |
| 233 | bucketName: sourceBucket, |
| 234 | objectKey: sourceObject, |
| 235 | versionId: sourceVersionId, |
| 236 | getDeleteMarker: true, |
| 237 | requestType: 'objectGet', |
| 238 | /** |
| 239 | * Authorization will first check the target object, with an objectPut |
| 240 | * action. But in this context, the source object metadata is still |
| 241 | * unknown. In the context of quotas, to know the number of bytes that |
| 242 | * are being written, we explicitly enable the quota evaluation logic |
| 243 | * during the objectGet action instead. |
| 244 | */ |
| 245 | checkQuota: true, |
| 246 | request, |
| 247 | }; |
| 248 | const valPutParams = { |
| 249 | authInfo, |
| 250 | bucketName: destBucketName, |
| 251 | objectKey: destObjectKey, |
| 252 | requestType: 'objectPut', |
| 253 | checkQuota: false, |
| 254 | request, |
| 255 | }; |
| 256 | const dataStoreContext = { |
| 257 | bucketName: destBucketName, |
| 258 | owner: authInfo.getCanonicalID(), |
| 259 | namespace: request.namespace, |
| 260 | objectKey: destObjectKey, |
| 261 | }; |
| 262 | const websiteRedirectHeader = |
| 263 | request.headers['x-amz-website-redirect-location']; |
| 264 | const responseHeaders = {}; |
| 265 | |
| 266 | if (request.headers['x-amz-storage-class'] && |
| 267 | !constants.validStorageClasses.includes(request.headers['x-amz-storage-class'])) { |
| 268 | log.trace('invalid storage-class header'); |
| 269 | monitoring.promMetrics('PUT', destBucketName, |
| 270 | errorInstances.InvalidStorageClass.code, 'copyObject'); |
| 271 | return callback(errors.InvalidStorageClass); |
| 272 | } |
| 273 | if (!validateWebsiteHeader(websiteRedirectHeader)) { |
| 274 | const err = errors.InvalidRedirectLocation; |
| 275 | log.debug('invalid x-amz-website-redirect-location' + |
no test coverage detected