* Recursive function with 1 recursive call to look for index * in case of error for potential redirect to folder notation * if there is not already an index appended * @param {Error} [originalError] - presence of this argument * differentiates original user reques
(originalError)
| 201 | * @returns {undefined} |
| 202 | */ |
| 203 | function runWebsite(originalError) { |
| 204 | // get object metadata and check authorization and header |
| 205 | // validation |
| 206 | return metadata.getObjectMD(bucketName, request.objectKey, {}, log, |
| 207 | (err, objMD) => { |
| 208 | // Note: In case of error, we intentionally send the original |
| 209 | // object key to _errorActions as in case of a redirect, we do |
| 210 | // not want to append index key to redirect location |
| 211 | if (err) { |
| 212 | log.trace('error retrieving object metadata', |
| 213 | { error: err }); |
| 214 | let returnErr = err; |
| 215 | const bucketAuthorized = isBucketAuthorized(bucket, request.apiMethods || 'bucketGet', |
| 216 | constants.publicId, null, log, request, request.actionImplicitDenies, true); |
| 217 | // if index object does not exist and bucket is private AWS |
| 218 | // returns 403 - AccessDenied error. |
| 219 | if (err.is.NoSuchKey && !bucketAuthorized) { |
| 220 | returnErr = errors.AccessDenied; |
| 221 | } |
| 222 | |
| 223 | // Check if key is a folder containing index for redirect 302 |
| 224 | // https://docs.aws.amazon.com/AmazonS3/latest/userguide/IndexDocumentSupport.html |
| 225 | if (!originalError && reqObjectKey && !reqObjectKey.endsWith('/')) { |
| 226 | appendWebsiteIndexDocument(request, websiteConfig.getIndexDocument(), true); |
| 227 | // propagate returnErr as originalError to be used if index is not found |
| 228 | return runWebsite(returnErr); |
| 229 | } |
| 230 | |
| 231 | return _errorActions(originalError || returnErr, |
| 232 | websiteConfig.getErrorDocument(), routingRules, |
| 233 | bucket, reqObjectKey, corsHeaders, request, log, |
| 234 | callback); |
| 235 | } |
| 236 | if (!isObjAuthorized(bucket, objMD, request.apiMethods || 'objectGet', |
| 237 | constants.publicId, null, log, request, request.actionImplicitDenies, true)) { |
| 238 | const err = errors.AccessDenied; |
| 239 | log.trace('request not authorized', { error: err }); |
| 240 | return _errorActions(err, websiteConfig.getErrorDocument(), |
| 241 | routingRules, bucket, |
| 242 | reqObjectKey, corsHeaders, request, log, callback); |
| 243 | } |
| 244 | |
| 245 | // access granted to index document, needs a redirect 302 |
| 246 | // to the original key with trailing / |
| 247 | if (originalError) { |
| 248 | const redirectInfo = { withError: true, |
| 249 | location: `/${reqObjectKey}/` }; |
| 250 | return callback(errors.Found, false, null, corsHeaders, |
| 251 | redirectInfo, ''); |
| 252 | } |
| 253 | |
| 254 | const headerValResult = validateHeaders(request.headers, |
| 255 | objMD['last-modified'], objMD['content-md5']); |
| 256 | if (headerValResult.error) { |
| 257 | const err = headerValResult.error; |
| 258 | log.trace('header validation error', { error: err }); |
| 259 | return _errorActions(err, websiteConfig.getErrorDocument(), |
| 260 | routingRules, bucket, reqObjectKey, |
no test coverage detected