123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- var AWS = require('../core');
- var s3util = require('./s3util');
- var regionUtil = require('../region_config');
- AWS.util.update(AWS.S3Control.prototype, {
- /**
- * @api private
- */
- setupRequestListeners: function setupRequestListeners(request) {
- request.addListener('extractError', this.extractHostId);
- request.addListener('extractData', this.extractHostId);
- request.addListener('validate', this.validateAccountId);
- var isArnInBucket = s3util.isArnInParam(request, 'Bucket');
- var isArnInName = s3util.isArnInParam(request, 'Name');
- if (isArnInBucket) {
- request._parsedArn = AWS.util.ARN.parse(request.params['Bucket']);
- request.addListener('validate', this.validateOutpostsBucketArn);
- request.addListener('validate', s3util.validateOutpostsArn);
- request.addListener('afterBuild', this.addOutpostIdHeader);
- } else if (isArnInName) {
- request._parsedArn = AWS.util.ARN.parse(request.params['Name']);
- request.addListener('validate', s3util.validateOutpostsAccessPointArn);
- request.addListener('validate', s3util.validateOutpostsArn);
- request.addListener('afterBuild', this.addOutpostIdHeader);
- }
- if (isArnInBucket || isArnInName) {
- request.addListener('validate', this.validateArnRegion);
- request.addListener('validate', this.validateArnAccountWithParams, true);
- request.addListener('validate', s3util.validateArnAccount);
- request.addListener('validate', s3util.validateArnService);
- request.addListener('build', this.populateParamFromArn, true);
- request.addListener('build', this.populateUriFromArn);
- request.addListener('build', s3util.validatePopulateUriFromArn);
- }
- if (request.params.OutpostId &&
- (request.operation === 'createBucket' ||
- request.operation === 'listRegionalBuckets')) {
- request.addListener('build', this.populateEndpointForOutpostId);
- }
- },
- /**
- * Adds outpostId header
- */
- addOutpostIdHeader: function addOutpostIdHeader(req) {
- req.httpRequest.headers['x-amz-outpost-id'] = req._parsedArn.outpostId;
- },
- /**
- * Validate Outposts ARN supplied in Bucket parameter is a valid bucket name
- */
- validateOutpostsBucketArn: function validateOutpostsBucketArn(req) {
- var parsedArn = req._parsedArn;
- //can be ':' or '/'
- var delimiter = parsedArn.resource['outpost'.length];
- if (parsedArn.resource.split(delimiter).length !== 4) {
- throw AWS.util.error(new Error(), {
- code: 'InvalidARN',
- message: 'Bucket ARN should have two resources outpost/{outpostId}/bucket/{accesspointName}'
- });
- }
- var bucket = parsedArn.resource.split(delimiter)[3];
- if (!s3util.dnsCompatibleBucketName(bucket) || bucket.match(/\./)) {
- throw AWS.util.error(new Error(), {
- code: 'InvalidARN',
- message: 'Bucket ARN is not DNS compatible. Got ' + bucket
- });
- }
- //set parsed valid bucket
- req._parsedArn.bucket = bucket;
- },
- /**
- * @api private
- */
- populateParamFromArn: function populateParamFromArn(req) {
- var parsedArn = req._parsedArn;
- if (s3util.isArnInParam(req, 'Bucket')) {
- req.params.Bucket = parsedArn.bucket;
- } else if (s3util.isArnInParam(req, 'Name')) {
- req.params.Name = parsedArn.accessPoint;
- }
- },
- /**
- * Populate URI according to the ARN
- */
- populateUriFromArn: function populateUriFromArn(req) {
- var parsedArn = req._parsedArn;
- var endpoint = req.httpRequest.endpoint;
- var useArnRegion = req.service.config.s3UseArnRegion;
- var useFipsEndpoint = req.service.config.useFipsEndpoint;
- endpoint.hostname = [
- 's3-outposts' + (useFipsEndpoint ? '-fips': ''),
- useArnRegion ? parsedArn.region : req.service.config.region,
- 'amazonaws.com'
- ].join('.');
- endpoint.host = endpoint.hostname;
- },
- /**
- * @api private
- */
- populateEndpointForOutpostId: function populateEndpointForOutpostId(req) {
- var endpoint = req.httpRequest.endpoint;
- var useFipsEndpoint = req.service.config.useFipsEndpoint;
- endpoint.hostname = [
- 's3-outposts' + (useFipsEndpoint ? '-fips': ''),
- req.service.config.region,
- 'amazonaws.com'
- ].join('.');
- endpoint.host = endpoint.hostname;
- },
- /**
- * @api private
- */
- extractHostId: function(response) {
- var hostId = response.httpResponse.headers ? response.httpResponse.headers['x-amz-id-2'] : null;
- response.extendedRequestId = hostId;
- if (response.error) {
- response.error.extendedRequestId = hostId;
- }
- },
- /**
- * @api private
- */
- validateArnRegion: function validateArnRegion(req) {
- s3util.validateArnRegion(req, { allowFipsEndpoint: true });
- },
- /**
- * @api private
- */
- validateArnAccountWithParams: function validateArnAccountWithParams(req) {
- var params = req.params;
- var inputModel = req.service.api.operations[req.operation].input;
- if (inputModel.members.AccountId) {
- var parsedArn = req._parsedArn;
- if (parsedArn.accountId) {
- if (params.AccountId) {
- if (params.AccountId !== parsedArn.accountId) {
- throw AWS.util.error(
- new Error(),
- {code: 'ValidationError', message: 'AccountId in ARN and request params should be same.'}
- );
- }
- } else {
- // Store accountId from ARN in params
- params.AccountId = parsedArn.accountId;
- }
- }
- }
- },
- /**
- * @api private
- */
- validateAccountId: function(request) {
- var params = request.params;
- if (!Object.prototype.hasOwnProperty.call(params, 'AccountId')) return;
- var accountId = params.AccountId;
- //validate type
- if (typeof accountId !== 'string') {
- throw AWS.util.error(
- new Error(),
- {code: 'ValidationError', message: 'AccountId must be a string.'}
- );
- }
- //validate length
- if (accountId.length < 1 || accountId.length > 63) {
- throw AWS.util.error(
- new Error(),
- {code: 'ValidationError', message: 'AccountId length should be between 1 to 63 characters, inclusive.'}
- );
- }
- //validate pattern
- var hostPattern = /^[a-zA-Z0-9]{1}$|^[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]$/;
- if (!hostPattern.test(accountId)) {
- throw AWS.util.error(new Error(),
- {code: 'ValidationError', message: 'AccountId should be hostname compatible. AccountId: ' + accountId});
- }
- },
- /**
- * @api private
- */
- getSigningName: function getSigningName(req) {
- var _super = AWS.Service.prototype.getSigningName;
- if (req && req._parsedArn && req._parsedArn.service) {
- return req._parsedArn.service;
- } else if (req.params.OutpostId &&
- (req.operation === 'createBucket' ||
- req.operation === 'listRegionalBuckets')) {
- return 's3-outposts';
- } else {
- return _super.call(this, req);
- }
- },
- });
|