MCPcopy
hub / github.com/scality/cloudserver / objectPutPart

Function objectPutPart

lib/api/objectPutPart.js:61–461  ·  view source on GitHub ↗

* PUT part of object during a multipart upload. Steps include: * validating metadata for authorization, bucket existence * and multipart upload initiation existence, * store object data in datastore upon successful authorization, * store object location returned by datastore in metadata and * r

(authInfo, request, streamingV4Params, log,
    cb)

Source from the content-addressed store, hash-verified

59 * @return {undefined}
60 */
61function objectPutPart(authInfo, request, streamingV4Params, log,
62 cb) {
63 log.debug('processing request', { method: 'objectPutPart' });
64 const size = request.parsedContentLength;
65
66 const putVersionId = request.headers['x-scal-s3-version-id'];
67 const isPutVersion = putVersionId || putVersionId === '';
68
69 if (Number.parseInt(size, 10) > constants.maximumAllowedPartSize) {
70 log.debug('put part size too large', { size });
71 monitoring.promMetrics('PUT', request.bucketName, 400,
72 'putObjectPart');
73 return cb(errors.EntityTooLarge);
74 }
75
76 const checksumHeaderErr = validateChecksumHeaders(request.headers);
77 if (checksumHeaderErr) {
78 return cb(checksumHeaderErr);
79 }
80
81 // Note: Part sizes cannot be less than 5MB in size except for the last.
82 // However, we do not check this value here because we cannot know which
83 // part will be the last until a complete MPU request is made. Thus, we let
84 // the completeMultipartUpload API check that all parts except the last are
85 // at least 5MB.
86
87 const partNumber = Number.parseInt(request.query.partNumber, 10);
88 // AWS caps partNumbers at 10,000
89 if (partNumber > 10000) {
90 monitoring.promMetrics('PUT', request.bucketName, 400,
91 'putObjectPart');
92 return cb(errors.TooManyParts);
93 }
94 if (!Number.isInteger(partNumber) || partNumber < 1) {
95 monitoring.promMetrics('PUT', request.bucketName, 400,
96 'putObjectPart');
97 return cb(errors.InvalidArgument);
98 }
99 const bucketName = request.bucketName;
100 assert.strictEqual(typeof bucketName, 'string');
101 const canonicalID = authInfo.getCanonicalID();
102 assert.strictEqual(typeof canonicalID, 'string');
103 log.trace('owner canonicalid to send to data', {
104 canonicalID: authInfo.getCanonicalID,
105 });
106 // Note that keys in the query object retain their case, so
107 // `request.query.uploadId` must be called with that exact capitalization.
108 const { query: { uploadId } } = request;
109 const mpuBucketName = `${constants.mpuBucketPrefix}${bucketName}`;
110 const { objectKey } = request;
111 const originalIdentityAuthzResults = request.actionImplicitDenies;
112 // For validating the request at the destinationBucket level the
113 // `requestType` is the general 'objectPut'.
114 const requestType = request.apiMethods || 'objectPutPart';
115
116 return async.waterfall([
117 // Get the destination bucket.
118 next => metadata.getBucket(bucketName, log,

Callers 11

createMPUFunction · 0.85
createMPUFunction · 0.85
_createAndAbortMpuFunction · 0.85
objectGet.jsFile · 0.85
transientBucket.jsFile · 0.85
multipartUpload.jsFile · 0.85
putPartFunction · 0.85
objectPutPart.jsFile · 0.85
putPartsFunction · 0.85
multipartUpload.jsFile · 0.85

Calls 15

validateChecksumHeadersFunction · 0.85
storeServerAccessLogInfoFunction · 0.85
isBucketAuthorizedFunction · 0.85
validateQuotasFunction · 0.85
writeContinueFunction · 0.85
_getPaddedPartNumberFunction · 0.85
_getPartKeyFunction · 0.85
dataStoreFunction · 0.85
collectCorsHeadersFunction · 0.85
setSSEHeadersFunction · 0.85
pushMetricFunction · 0.85

Tested by

no test coverage detected