@aws-sdk/middleware-bucket-endpoint 3.34.0 → 3.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/dist-cjs/bucketEndpointMiddleware.js +81 -0
- package/dist-cjs/bucketHostname.js +116 -0
- package/dist-cjs/bucketHostnameUtils.js +157 -0
- package/dist-cjs/configurations.js +64 -0
- package/{dist/cjs → dist-cjs}/index.js +0 -1
- package/dist-es/bucketEndpointMiddleware.js +100 -0
- package/dist-es/bucketHostname.js +118 -0
- package/dist-es/bucketHostnameUtils.js +144 -0
- package/dist-es/configurations.js +53 -0
- package/{dist/types/index.d.ts → dist-es/index.js} +0 -0
- package/{dist/types → dist-types}/bucketEndpointMiddleware.d.ts +0 -0
- package/{dist/types → dist-types}/bucketHostname.d.ts +0 -0
- package/{dist/types → dist-types}/bucketHostnameUtils.d.ts +0 -0
- package/{dist/types → dist-types}/configurations.d.ts +0 -0
- package/dist-types/index.d.ts +4 -0
- package/{dist/types → dist-types}/ts3.4/bucketEndpointMiddleware.d.ts +0 -0
- package/{dist/types → dist-types}/ts3.4/bucketHostname.d.ts +0 -0
- package/{dist/types → dist-types}/ts3.4/bucketHostnameUtils.d.ts +13 -62
- package/dist-types/ts3.4/configurations.d.ts +49 -0
- package/{dist/types → dist-types}/ts3.4/index.d.ts +0 -0
- package/package.json +15 -12
- package/dist/cjs/bucketEndpointMiddleware.js +0 -82
- package/dist/cjs/bucketHostname.js +0 -117
- package/dist/cjs/bucketHostnameUtils.js +0 -158
- package/dist/cjs/configurations.js +0 -65
- package/dist/es/bucketEndpointMiddleware.js +0 -103
- package/dist/es/bucketHostname.js +0 -123
- package/dist/es/bucketHostnameUtils.js +0 -210
- package/dist/es/configurations.js +0 -59
- package/dist/es/index.js +0 -5
- package/dist/types/ts3.4/configurations.d.ts +0 -87
- package/src/bucketEndpointMiddleware.ts +0 -101
- package/src/bucketHostname.ts +0 -223
- package/src/bucketHostnameUtils.ts +0 -272
- package/src/configurations.ts +0 -154
- package/src/index.ts +0 -15
- package/tsconfig.cjs.json +0 -9
- package/tsconfig.es.json +0 -10
- package/tsconfig.types.json +0 -9
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,41 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [3.38.0](https://github.com/aws/aws-sdk-js-v3/compare/v3.37.0...v3.38.0) (2021-10-22)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @aws-sdk/middleware-bucket-endpoint
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# [3.37.0](https://github.com/aws/aws-sdk-js-v3/compare/v3.36.1...v3.37.0) (2021-10-15)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @aws-sdk/middleware-bucket-endpoint
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# [3.36.0](https://github.com/aws/aws-sdk-js-v3/compare/v3.35.0...v3.36.0) (2021-10-08)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
|
|
27
|
+
* publish files in dist-* only ([#2873](https://github.com/aws/aws-sdk-js-v3/issues/2873)) ([53b4243](https://github.com/aws/aws-sdk-js-v3/commit/53b4243b066f25ff2412d5f0dea1036054b2df32))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# [3.35.0](https://github.com/aws/aws-sdk-js-v3/compare/v3.34.0...v3.35.0) (2021-10-04)
|
|
34
|
+
|
|
35
|
+
**Note:** Version bump only for package @aws-sdk/middleware-bucket-endpoint
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
6
41
|
# [3.34.0](https://github.com/aws/aws-sdk-js-v3/compare/v3.33.0...v3.34.0) (2021-09-24)
|
|
7
42
|
|
|
8
43
|
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getBucketEndpointPlugin = exports.bucketEndpointMiddlewareOptions = exports.bucketEndpointMiddleware = void 0;
|
|
4
|
+
const protocol_http_1 = require("@aws-sdk/protocol-http");
|
|
5
|
+
const util_arn_parser_1 = require("@aws-sdk/util-arn-parser");
|
|
6
|
+
const bucketHostname_1 = require("./bucketHostname");
|
|
7
|
+
const bucketHostnameUtils_1 = require("./bucketHostnameUtils");
|
|
8
|
+
const bucketEndpointMiddleware = (options) => (next, context) => async (args) => {
|
|
9
|
+
const { Bucket: bucketName } = args.input;
|
|
10
|
+
let replaceBucketInPath = options.bucketEndpoint;
|
|
11
|
+
const request = args.request;
|
|
12
|
+
if (protocol_http_1.HttpRequest.isInstance(request)) {
|
|
13
|
+
if (options.bucketEndpoint) {
|
|
14
|
+
request.hostname = bucketName;
|
|
15
|
+
}
|
|
16
|
+
else if (util_arn_parser_1.validate(bucketName)) {
|
|
17
|
+
const bucketArn = util_arn_parser_1.parse(bucketName);
|
|
18
|
+
const clientRegion = bucketHostnameUtils_1.getPseudoRegion(await options.region());
|
|
19
|
+
const { partition, signingRegion = clientRegion } = (await options.regionInfoProvider(clientRegion)) || {};
|
|
20
|
+
const useArnRegion = await options.useArnRegion();
|
|
21
|
+
const { hostname, bucketEndpoint, signingRegion: modifiedSigningRegion, signingService } = bucketHostname_1.bucketHostname({
|
|
22
|
+
bucketName: bucketArn,
|
|
23
|
+
baseHostname: request.hostname,
|
|
24
|
+
accelerateEndpoint: options.useAccelerateEndpoint,
|
|
25
|
+
dualstackEndpoint: options.useDualstackEndpoint,
|
|
26
|
+
pathStyleEndpoint: options.forcePathStyle,
|
|
27
|
+
tlsCompatible: request.protocol === "https:",
|
|
28
|
+
useArnRegion,
|
|
29
|
+
clientPartition: partition,
|
|
30
|
+
clientSigningRegion: signingRegion,
|
|
31
|
+
clientRegion: clientRegion,
|
|
32
|
+
isCustomEndpoint: options.isCustomEndpoint,
|
|
33
|
+
disableMultiregionAccessPoints: await options.disableMultiregionAccessPoints(),
|
|
34
|
+
});
|
|
35
|
+
if (modifiedSigningRegion && modifiedSigningRegion !== signingRegion) {
|
|
36
|
+
context["signing_region"] = modifiedSigningRegion;
|
|
37
|
+
}
|
|
38
|
+
if (signingService && signingService !== "s3") {
|
|
39
|
+
context["signing_service"] = signingService;
|
|
40
|
+
}
|
|
41
|
+
request.hostname = hostname;
|
|
42
|
+
replaceBucketInPath = bucketEndpoint;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
const clientRegion = bucketHostnameUtils_1.getPseudoRegion(await options.region());
|
|
46
|
+
const { hostname, bucketEndpoint } = bucketHostname_1.bucketHostname({
|
|
47
|
+
bucketName,
|
|
48
|
+
clientRegion,
|
|
49
|
+
baseHostname: request.hostname,
|
|
50
|
+
accelerateEndpoint: options.useAccelerateEndpoint,
|
|
51
|
+
dualstackEndpoint: options.useDualstackEndpoint,
|
|
52
|
+
pathStyleEndpoint: options.forcePathStyle,
|
|
53
|
+
tlsCompatible: request.protocol === "https:",
|
|
54
|
+
isCustomEndpoint: options.isCustomEndpoint,
|
|
55
|
+
});
|
|
56
|
+
request.hostname = hostname;
|
|
57
|
+
replaceBucketInPath = bucketEndpoint;
|
|
58
|
+
}
|
|
59
|
+
if (replaceBucketInPath) {
|
|
60
|
+
request.path = request.path.replace(/^(\/)?[^\/]+/, "");
|
|
61
|
+
if (request.path === "") {
|
|
62
|
+
request.path = "/";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return next({ ...args, request });
|
|
67
|
+
};
|
|
68
|
+
exports.bucketEndpointMiddleware = bucketEndpointMiddleware;
|
|
69
|
+
exports.bucketEndpointMiddlewareOptions = {
|
|
70
|
+
tags: ["BUCKET_ENDPOINT"],
|
|
71
|
+
name: "bucketEndpointMiddleware",
|
|
72
|
+
relation: "before",
|
|
73
|
+
toMiddleware: "hostHeaderMiddleware",
|
|
74
|
+
override: true,
|
|
75
|
+
};
|
|
76
|
+
const getBucketEndpointPlugin = (options) => ({
|
|
77
|
+
applyToStack: (clientStack) => {
|
|
78
|
+
clientStack.addRelativeTo(exports.bucketEndpointMiddleware(options), exports.bucketEndpointMiddlewareOptions);
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
exports.getBucketEndpointPlugin = getBucketEndpointPlugin;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.bucketHostname = void 0;
|
|
4
|
+
const bucketHostnameUtils_1 = require("./bucketHostnameUtils");
|
|
5
|
+
const bucketHostname = (options) => {
|
|
6
|
+
bucketHostnameUtils_1.validateCustomEndpoint(options);
|
|
7
|
+
return bucketHostnameUtils_1.isBucketNameOptions(options)
|
|
8
|
+
?
|
|
9
|
+
getEndpointFromBucketName(options)
|
|
10
|
+
:
|
|
11
|
+
getEndpointFromArn(options);
|
|
12
|
+
};
|
|
13
|
+
exports.bucketHostname = bucketHostname;
|
|
14
|
+
const getEndpointFromBucketName = ({ accelerateEndpoint = false, clientRegion: region, baseHostname, bucketName, dualstackEndpoint = false, pathStyleEndpoint = false, tlsCompatible = true, isCustomEndpoint = false, }) => {
|
|
15
|
+
const [clientRegion, hostnameSuffix] = isCustomEndpoint ? [region, baseHostname] : bucketHostnameUtils_1.getSuffix(baseHostname);
|
|
16
|
+
if (pathStyleEndpoint || !bucketHostnameUtils_1.isDnsCompatibleBucketName(bucketName) || (tlsCompatible && bucketHostnameUtils_1.DOT_PATTERN.test(bucketName))) {
|
|
17
|
+
return {
|
|
18
|
+
bucketEndpoint: false,
|
|
19
|
+
hostname: dualstackEndpoint ? `s3.dualstack.${clientRegion}.${hostnameSuffix}` : baseHostname,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
if (accelerateEndpoint) {
|
|
23
|
+
baseHostname = `s3-accelerate${dualstackEndpoint ? ".dualstack" : ""}.${hostnameSuffix}`;
|
|
24
|
+
}
|
|
25
|
+
else if (dualstackEndpoint) {
|
|
26
|
+
baseHostname = `s3.dualstack.${clientRegion}.${hostnameSuffix}`;
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
bucketEndpoint: true,
|
|
30
|
+
hostname: `${bucketName}.${baseHostname}`,
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
const getEndpointFromArn = (options) => {
|
|
34
|
+
const { isCustomEndpoint, baseHostname, clientRegion } = options;
|
|
35
|
+
const hostnameSuffix = isCustomEndpoint ? baseHostname : bucketHostnameUtils_1.getSuffixForArnEndpoint(baseHostname)[1];
|
|
36
|
+
const { pathStyleEndpoint, accelerateEndpoint = false, tlsCompatible = true, bucketName, clientPartition = "aws", } = options;
|
|
37
|
+
bucketHostnameUtils_1.validateArnEndpointOptions({ pathStyleEndpoint, accelerateEndpoint, tlsCompatible });
|
|
38
|
+
const { service, partition, accountId, region, resource } = bucketName;
|
|
39
|
+
bucketHostnameUtils_1.validateService(service);
|
|
40
|
+
bucketHostnameUtils_1.validatePartition(partition, { clientPartition });
|
|
41
|
+
bucketHostnameUtils_1.validateAccountId(accountId);
|
|
42
|
+
const { accesspointName, outpostId } = bucketHostnameUtils_1.getArnResources(resource);
|
|
43
|
+
if (service === "s3-object-lambda") {
|
|
44
|
+
return getEndpointFromObjectLambdaArn({ ...options, tlsCompatible, bucketName, accesspointName, hostnameSuffix });
|
|
45
|
+
}
|
|
46
|
+
if (region === "") {
|
|
47
|
+
return getEndpointFromMRAPArn({ ...options, clientRegion, mrapAlias: accesspointName, hostnameSuffix });
|
|
48
|
+
}
|
|
49
|
+
if (outpostId) {
|
|
50
|
+
return getEndpointFromOutpostArn({ ...options, clientRegion, outpostId, accesspointName, hostnameSuffix });
|
|
51
|
+
}
|
|
52
|
+
return getEndpointFromAccessPointArn({ ...options, clientRegion, accesspointName, hostnameSuffix });
|
|
53
|
+
};
|
|
54
|
+
const getEndpointFromObjectLambdaArn = ({ dualstackEndpoint = false, tlsCompatible = true, useArnRegion, clientRegion, clientSigningRegion = clientRegion, accesspointName, bucketName, hostnameSuffix, }) => {
|
|
55
|
+
const { accountId, region, service } = bucketName;
|
|
56
|
+
bucketHostnameUtils_1.validateRegionalClient(clientRegion);
|
|
57
|
+
bucketHostnameUtils_1.validateRegion(region, { useArnRegion, clientRegion, clientSigningRegion, allowFipsRegion: true });
|
|
58
|
+
bucketHostnameUtils_1.validateNoDualstack(dualstackEndpoint);
|
|
59
|
+
const DNSHostLabel = `${accesspointName}-${accountId}`;
|
|
60
|
+
bucketHostnameUtils_1.validateDNSHostLabel(DNSHostLabel, { tlsCompatible });
|
|
61
|
+
const endpointRegion = useArnRegion ? region : clientRegion;
|
|
62
|
+
const signingRegion = useArnRegion ? region : clientSigningRegion;
|
|
63
|
+
return {
|
|
64
|
+
bucketEndpoint: true,
|
|
65
|
+
hostname: `${DNSHostLabel}.${service}${bucketHostnameUtils_1.isFipsRegion(clientRegion) ? "-fips" : ""}.${bucketHostnameUtils_1.getPseudoRegion(endpointRegion)}.${hostnameSuffix}`,
|
|
66
|
+
signingRegion,
|
|
67
|
+
signingService: service,
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
const getEndpointFromMRAPArn = ({ disableMultiregionAccessPoints, dualstackEndpoint = false, isCustomEndpoint, mrapAlias, hostnameSuffix, }) => {
|
|
71
|
+
if (disableMultiregionAccessPoints === true) {
|
|
72
|
+
throw new Error("SDK is attempting to use a MRAP ARN. Please enable to feature.");
|
|
73
|
+
}
|
|
74
|
+
bucketHostnameUtils_1.validateMrapAlias(mrapAlias);
|
|
75
|
+
bucketHostnameUtils_1.validateNoDualstack(dualstackEndpoint);
|
|
76
|
+
return {
|
|
77
|
+
bucketEndpoint: true,
|
|
78
|
+
hostname: `${mrapAlias}${isCustomEndpoint ? "" : `.accesspoint.s3-global`}.${hostnameSuffix}`,
|
|
79
|
+
signingRegion: "*",
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
const getEndpointFromOutpostArn = ({ useArnRegion, clientRegion, clientSigningRegion = clientRegion, bucketName, outpostId, dualstackEndpoint = false, tlsCompatible = true, accesspointName, isCustomEndpoint, hostnameSuffix, }) => {
|
|
83
|
+
bucketHostnameUtils_1.validateRegionalClient(clientRegion);
|
|
84
|
+
bucketHostnameUtils_1.validateRegion(bucketName.region, { useArnRegion, clientRegion, clientSigningRegion });
|
|
85
|
+
const DNSHostLabel = `${accesspointName}-${bucketName.accountId}`;
|
|
86
|
+
bucketHostnameUtils_1.validateDNSHostLabel(DNSHostLabel, { tlsCompatible });
|
|
87
|
+
const endpointRegion = useArnRegion ? bucketName.region : clientRegion;
|
|
88
|
+
const signingRegion = useArnRegion ? bucketName.region : clientSigningRegion;
|
|
89
|
+
bucketHostnameUtils_1.validateOutpostService(bucketName.service);
|
|
90
|
+
bucketHostnameUtils_1.validateDNSHostLabel(outpostId, { tlsCompatible });
|
|
91
|
+
bucketHostnameUtils_1.validateNoDualstack(dualstackEndpoint);
|
|
92
|
+
bucketHostnameUtils_1.validateNoFIPS(endpointRegion);
|
|
93
|
+
const hostnamePrefix = `${DNSHostLabel}.${outpostId}`;
|
|
94
|
+
return {
|
|
95
|
+
bucketEndpoint: true,
|
|
96
|
+
hostname: `${hostnamePrefix}${isCustomEndpoint ? "" : `.s3-outposts.${endpointRegion}`}.${hostnameSuffix}`,
|
|
97
|
+
signingRegion,
|
|
98
|
+
signingService: "s3-outposts",
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
const getEndpointFromAccessPointArn = ({ useArnRegion, clientRegion, clientSigningRegion = clientRegion, bucketName, dualstackEndpoint = false, tlsCompatible = true, accesspointName, isCustomEndpoint, hostnameSuffix, }) => {
|
|
102
|
+
bucketHostnameUtils_1.validateRegionalClient(clientRegion);
|
|
103
|
+
bucketHostnameUtils_1.validateRegion(bucketName.region, { useArnRegion, clientRegion, clientSigningRegion, allowFipsRegion: true });
|
|
104
|
+
const hostnamePrefix = `${accesspointName}-${bucketName.accountId}`;
|
|
105
|
+
bucketHostnameUtils_1.validateDNSHostLabel(hostnamePrefix, { tlsCompatible });
|
|
106
|
+
const endpointRegion = useArnRegion ? bucketName.region : clientRegion;
|
|
107
|
+
const signingRegion = useArnRegion ? bucketName.region : clientSigningRegion;
|
|
108
|
+
bucketHostnameUtils_1.validateS3Service(bucketName.service);
|
|
109
|
+
return {
|
|
110
|
+
bucketEndpoint: true,
|
|
111
|
+
hostname: `${hostnamePrefix}${isCustomEndpoint
|
|
112
|
+
? ""
|
|
113
|
+
: `.s3-accesspoint${bucketHostnameUtils_1.isFipsRegion(clientRegion) ? "-fips" : ""}${dualstackEndpoint ? ".dualstack" : ""}.${bucketHostnameUtils_1.getPseudoRegion(endpointRegion)}`}.${hostnameSuffix}`,
|
|
114
|
+
signingRegion,
|
|
115
|
+
};
|
|
116
|
+
};
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateMrapAlias = exports.validateNoFIPS = exports.validateNoDualstack = exports.getArnResources = exports.validateCustomEndpoint = exports.validateDNSHostLabel = exports.validateAccountId = exports.isFipsRegion = exports.validateRegionalClient = exports.validateRegion = exports.validatePartition = exports.validateOutpostService = exports.validateS3Service = exports.validateService = exports.validateArnEndpointOptions = exports.getSuffixForArnEndpoint = exports.getSuffix = exports.isDnsCompatibleBucketName = exports.getPseudoRegion = exports.isBucketNameOptions = exports.S3_HOSTNAME_PATTERN = exports.DOT_PATTERN = void 0;
|
|
4
|
+
const DOMAIN_PATTERN = /^[a-z0-9][a-z0-9\.\-]{1,61}[a-z0-9]$/;
|
|
5
|
+
const IP_ADDRESS_PATTERN = /(\d+\.){3}\d+/;
|
|
6
|
+
const DOTS_PATTERN = /\.\./;
|
|
7
|
+
exports.DOT_PATTERN = /\./;
|
|
8
|
+
exports.S3_HOSTNAME_PATTERN = /^(.+\.)?s3[.-]([a-z0-9-]+)\./;
|
|
9
|
+
const S3_US_EAST_1_ALTNAME_PATTERN = /^s3(-external-1)?\.amazonaws\.com$/;
|
|
10
|
+
const AWS_PARTITION_SUFFIX = "amazonaws.com";
|
|
11
|
+
const isBucketNameOptions = (options) => typeof options.bucketName === "string";
|
|
12
|
+
exports.isBucketNameOptions = isBucketNameOptions;
|
|
13
|
+
const getPseudoRegion = (region) => (exports.isFipsRegion(region) ? region.replace(/fips-|-fips/, "") : region);
|
|
14
|
+
exports.getPseudoRegion = getPseudoRegion;
|
|
15
|
+
const isDnsCompatibleBucketName = (bucketName) => DOMAIN_PATTERN.test(bucketName) && !IP_ADDRESS_PATTERN.test(bucketName) && !DOTS_PATTERN.test(bucketName);
|
|
16
|
+
exports.isDnsCompatibleBucketName = isDnsCompatibleBucketName;
|
|
17
|
+
const getRegionalSuffix = (hostname) => {
|
|
18
|
+
const parts = hostname.match(exports.S3_HOSTNAME_PATTERN);
|
|
19
|
+
return [parts[2], hostname.replace(new RegExp(`^${parts[0]}`), "")];
|
|
20
|
+
};
|
|
21
|
+
const getSuffix = (hostname) => S3_US_EAST_1_ALTNAME_PATTERN.test(hostname) ? ["us-east-1", AWS_PARTITION_SUFFIX] : getRegionalSuffix(hostname);
|
|
22
|
+
exports.getSuffix = getSuffix;
|
|
23
|
+
const getSuffixForArnEndpoint = (hostname) => S3_US_EAST_1_ALTNAME_PATTERN.test(hostname)
|
|
24
|
+
? [hostname.replace(`.${AWS_PARTITION_SUFFIX}`, ""), AWS_PARTITION_SUFFIX]
|
|
25
|
+
: getRegionalSuffix(hostname);
|
|
26
|
+
exports.getSuffixForArnEndpoint = getSuffixForArnEndpoint;
|
|
27
|
+
const validateArnEndpointOptions = (options) => {
|
|
28
|
+
if (options.pathStyleEndpoint) {
|
|
29
|
+
throw new Error("Path-style S3 endpoint is not supported when bucket is an ARN");
|
|
30
|
+
}
|
|
31
|
+
if (options.accelerateEndpoint) {
|
|
32
|
+
throw new Error("Accelerate endpoint is not supported when bucket is an ARN");
|
|
33
|
+
}
|
|
34
|
+
if (!options.tlsCompatible) {
|
|
35
|
+
throw new Error("HTTPS is required when bucket is an ARN");
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
exports.validateArnEndpointOptions = validateArnEndpointOptions;
|
|
39
|
+
const validateService = (service) => {
|
|
40
|
+
if (service !== "s3" && service !== "s3-outposts" && service !== "s3-object-lambda") {
|
|
41
|
+
throw new Error("Expect 's3' or 's3-outposts' or 's3-object-lambda' in ARN service component");
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
exports.validateService = validateService;
|
|
45
|
+
const validateS3Service = (service) => {
|
|
46
|
+
if (service !== "s3") {
|
|
47
|
+
throw new Error("Expect 's3' in Accesspoint ARN service component");
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
exports.validateS3Service = validateS3Service;
|
|
51
|
+
const validateOutpostService = (service) => {
|
|
52
|
+
if (service !== "s3-outposts") {
|
|
53
|
+
throw new Error("Expect 's3-posts' in Outpost ARN service component");
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
exports.validateOutpostService = validateOutpostService;
|
|
57
|
+
const validatePartition = (partition, options) => {
|
|
58
|
+
if (partition !== options.clientPartition) {
|
|
59
|
+
throw new Error(`Partition in ARN is incompatible, got "${partition}" but expected "${options.clientPartition}"`);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
exports.validatePartition = validatePartition;
|
|
63
|
+
const validateRegion = (region, options) => {
|
|
64
|
+
if (region === "") {
|
|
65
|
+
throw new Error("ARN region is empty");
|
|
66
|
+
}
|
|
67
|
+
if (exports.isFipsRegion(options.clientRegion)) {
|
|
68
|
+
if (!options.allowFipsRegion) {
|
|
69
|
+
throw new Error("FIPS region is not supported");
|
|
70
|
+
}
|
|
71
|
+
else if (!isEqualRegions(region, options.clientRegion)) {
|
|
72
|
+
throw new Error(`Client FIPS region ${options.clientRegion} doesn't match region ${region} in ARN`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (!options.useArnRegion &&
|
|
76
|
+
!isEqualRegions(region, options.clientRegion || "") &&
|
|
77
|
+
!isEqualRegions(region, options.clientSigningRegion || "")) {
|
|
78
|
+
throw new Error(`Region in ARN is incompatible, got ${region} but expected ${options.clientRegion}`);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
exports.validateRegion = validateRegion;
|
|
82
|
+
const validateRegionalClient = (region) => {
|
|
83
|
+
if (["s3-external-1", "aws-global"].includes(exports.getPseudoRegion(region))) {
|
|
84
|
+
throw new Error(`Client region ${region} is not regional`);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
exports.validateRegionalClient = validateRegionalClient;
|
|
88
|
+
const isFipsRegion = (region) => region.startsWith("fips-") || region.endsWith("-fips");
|
|
89
|
+
exports.isFipsRegion = isFipsRegion;
|
|
90
|
+
const isEqualRegions = (regionA, regionB) => regionA === regionB || exports.getPseudoRegion(regionA) === regionB || regionA === exports.getPseudoRegion(regionB);
|
|
91
|
+
const validateAccountId = (accountId) => {
|
|
92
|
+
if (!/[0-9]{12}/.exec(accountId)) {
|
|
93
|
+
throw new Error("Access point ARN accountID does not match regex '[0-9]{12}'");
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
exports.validateAccountId = validateAccountId;
|
|
97
|
+
const validateDNSHostLabel = (label, options = { tlsCompatible: true }) => {
|
|
98
|
+
if (label.length >= 64 ||
|
|
99
|
+
!/^[a-z0-9][a-z0-9.-]*[a-z0-9]$/.test(label) ||
|
|
100
|
+
/(\d+\.){3}\d+/.test(label) ||
|
|
101
|
+
/[.-]{2}/.test(label) ||
|
|
102
|
+
((options === null || options === void 0 ? void 0 : options.tlsCompatible) && exports.DOT_PATTERN.test(label))) {
|
|
103
|
+
throw new Error(`Invalid DNS label ${label}`);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
exports.validateDNSHostLabel = validateDNSHostLabel;
|
|
107
|
+
const validateCustomEndpoint = (options) => {
|
|
108
|
+
if (options.isCustomEndpoint) {
|
|
109
|
+
if (options.dualstackEndpoint)
|
|
110
|
+
throw new Error("Dualstack endpoint is not supported with custom endpoint");
|
|
111
|
+
if (options.accelerateEndpoint)
|
|
112
|
+
throw new Error("Accelerate endpoint is not supported with custom endpoint");
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
exports.validateCustomEndpoint = validateCustomEndpoint;
|
|
116
|
+
const getArnResources = (resource) => {
|
|
117
|
+
const delimiter = resource.includes(":") ? ":" : "/";
|
|
118
|
+
const [resourceType, ...rest] = resource.split(delimiter);
|
|
119
|
+
if (resourceType === "accesspoint") {
|
|
120
|
+
if (rest.length !== 1 || rest[0] === "") {
|
|
121
|
+
throw new Error(`Access Point ARN should have one resource accesspoint${delimiter}{accesspointname}`);
|
|
122
|
+
}
|
|
123
|
+
return { accesspointName: rest[0] };
|
|
124
|
+
}
|
|
125
|
+
else if (resourceType === "outpost") {
|
|
126
|
+
if (!rest[0] || rest[1] !== "accesspoint" || !rest[2] || rest.length !== 3) {
|
|
127
|
+
throw new Error(`Outpost ARN should have resource outpost${delimiter}{outpostId}${delimiter}accesspoint${delimiter}{accesspointName}`);
|
|
128
|
+
}
|
|
129
|
+
const [outpostId, _, accesspointName] = rest;
|
|
130
|
+
return { outpostId, accesspointName };
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
throw new Error(`ARN resource should begin with 'accesspoint${delimiter}' or 'outpost${delimiter}'`);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
exports.getArnResources = getArnResources;
|
|
137
|
+
const validateNoDualstack = (dualstackEndpoint) => {
|
|
138
|
+
if (dualstackEndpoint)
|
|
139
|
+
throw new Error("Dualstack endpoint is not supported with Outpost or Multi-region Access Point ARN.");
|
|
140
|
+
};
|
|
141
|
+
exports.validateNoDualstack = validateNoDualstack;
|
|
142
|
+
const validateNoFIPS = (region) => {
|
|
143
|
+
if (exports.isFipsRegion(region !== null && region !== void 0 ? region : ""))
|
|
144
|
+
throw new Error(`FIPS region is not supported with Outpost, got ${region}`);
|
|
145
|
+
};
|
|
146
|
+
exports.validateNoFIPS = validateNoFIPS;
|
|
147
|
+
const validateMrapAlias = (name) => {
|
|
148
|
+
try {
|
|
149
|
+
name.split(".").forEach((label) => {
|
|
150
|
+
exports.validateDNSHostLabel(label);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
catch (e) {
|
|
154
|
+
throw new Error(`"${name}" is not a DNS compatible name.`);
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
exports.validateMrapAlias = validateMrapAlias;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_CONFIG_OPTIONS = exports.NODE_USE_ARN_REGION_CONFIG_OPTIONS = exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_INI_NAME = exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_ENV_NAME = exports.NODE_USE_ARN_REGION_INI_NAME = exports.NODE_USE_ARN_REGION_ENV_NAME = exports.resolveBucketEndpointConfig = void 0;
|
|
4
|
+
function resolveBucketEndpointConfig(input) {
|
|
5
|
+
const { bucketEndpoint = false, forcePathStyle = false, useAccelerateEndpoint = false, useDualstackEndpoint = false, useArnRegion = false, disableMultiregionAccessPoints = false, } = input;
|
|
6
|
+
return {
|
|
7
|
+
...input,
|
|
8
|
+
bucketEndpoint,
|
|
9
|
+
forcePathStyle,
|
|
10
|
+
useAccelerateEndpoint,
|
|
11
|
+
useDualstackEndpoint,
|
|
12
|
+
useArnRegion: typeof useArnRegion === "function" ? useArnRegion : () => Promise.resolve(useArnRegion),
|
|
13
|
+
disableMultiregionAccessPoints: typeof disableMultiregionAccessPoints === "function"
|
|
14
|
+
? disableMultiregionAccessPoints
|
|
15
|
+
: () => Promise.resolve(disableMultiregionAccessPoints),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
exports.resolveBucketEndpointConfig = resolveBucketEndpointConfig;
|
|
19
|
+
exports.NODE_USE_ARN_REGION_ENV_NAME = "AWS_S3_USE_ARN_REGION";
|
|
20
|
+
exports.NODE_USE_ARN_REGION_INI_NAME = "s3_use_arn_region";
|
|
21
|
+
exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_ENV_NAME = "AWS_S3_DISABLE_MULTIREGION_ACCESS_POINTS";
|
|
22
|
+
exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_INI_NAME = "s3_disable_multiregion_access_points";
|
|
23
|
+
exports.NODE_USE_ARN_REGION_CONFIG_OPTIONS = {
|
|
24
|
+
environmentVariableSelector: (env) => {
|
|
25
|
+
if (!Object.prototype.hasOwnProperty.call(env, exports.NODE_USE_ARN_REGION_ENV_NAME))
|
|
26
|
+
return undefined;
|
|
27
|
+
if (env[exports.NODE_USE_ARN_REGION_ENV_NAME] === "true")
|
|
28
|
+
return true;
|
|
29
|
+
if (env[exports.NODE_USE_ARN_REGION_ENV_NAME] === "false")
|
|
30
|
+
return false;
|
|
31
|
+
throw new Error(`Cannot load env ${exports.NODE_USE_ARN_REGION_ENV_NAME}. Expected "true" or "false", got ${env[exports.NODE_USE_ARN_REGION_ENV_NAME]}.`);
|
|
32
|
+
},
|
|
33
|
+
configFileSelector: (profile) => {
|
|
34
|
+
if (!Object.prototype.hasOwnProperty.call(profile, exports.NODE_USE_ARN_REGION_INI_NAME))
|
|
35
|
+
return undefined;
|
|
36
|
+
if (profile[exports.NODE_USE_ARN_REGION_INI_NAME] === "true")
|
|
37
|
+
return true;
|
|
38
|
+
if (profile[exports.NODE_USE_ARN_REGION_INI_NAME] === "false")
|
|
39
|
+
return false;
|
|
40
|
+
throw new Error(`Cannot load shared config entry ${exports.NODE_USE_ARN_REGION_INI_NAME}. Expected "true" or "false", got ${profile[exports.NODE_USE_ARN_REGION_INI_NAME]}.`);
|
|
41
|
+
},
|
|
42
|
+
default: false,
|
|
43
|
+
};
|
|
44
|
+
exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_CONFIG_OPTIONS = {
|
|
45
|
+
environmentVariableSelector: (env) => {
|
|
46
|
+
if (!Object.prototype.hasOwnProperty.call(env, exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_ENV_NAME))
|
|
47
|
+
return undefined;
|
|
48
|
+
if (env[exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_ENV_NAME] === "true")
|
|
49
|
+
return true;
|
|
50
|
+
if (env[exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_ENV_NAME] === "false")
|
|
51
|
+
return false;
|
|
52
|
+
throw new Error(`Cannot load env ${exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_ENV_NAME}. Expected "true" or "false", got ${env[exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_ENV_NAME]}.`);
|
|
53
|
+
},
|
|
54
|
+
configFileSelector: (profile) => {
|
|
55
|
+
if (!Object.prototype.hasOwnProperty.call(profile, exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_INI_NAME))
|
|
56
|
+
return undefined;
|
|
57
|
+
if (profile[exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_INI_NAME] === "true")
|
|
58
|
+
return true;
|
|
59
|
+
if (profile[exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_INI_NAME] === "false")
|
|
60
|
+
return false;
|
|
61
|
+
throw new Error(`Cannot load shared config entry ${exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_INI_NAME}. Expected "true" or "false", got ${profile[exports.NODE_DISABLE_MULTIREGION_ACCESS_POINT_INI_NAME]}.`);
|
|
62
|
+
},
|
|
63
|
+
default: false,
|
|
64
|
+
};
|
|
@@ -16,4 +16,3 @@ Object.defineProperty(exports, "validateRegion", { enumerable: true, get: functi
|
|
|
16
16
|
Object.defineProperty(exports, "validateDNSHostLabel", { enumerable: true, get: function () { return bucketHostnameUtils_1.validateDNSHostLabel; } });
|
|
17
17
|
Object.defineProperty(exports, "validateNoDualstack", { enumerable: true, get: function () { return bucketHostnameUtils_1.validateNoDualstack; } });
|
|
18
18
|
Object.defineProperty(exports, "validateNoFIPS", { enumerable: true, get: function () { return bucketHostnameUtils_1.validateNoFIPS; } });
|
|
19
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLHFFQUEyQztBQUMzQywyREFBaUM7QUFDakMsMkRBQWlDO0FBQ2pDLDZEQVcrQjtBQVY3QixzSEFBQSxlQUFlLE9BQUE7QUFDZixzSEFBQSxlQUFlLE9BQUE7QUFDZiw4SEFBQSx1QkFBdUIsT0FBQTtBQUN2Qiw2SEFBQSxzQkFBc0IsT0FBQTtBQUN0Qix3SEFBQSxpQkFBaUIsT0FBQTtBQUNqQix3SEFBQSxpQkFBaUIsT0FBQTtBQUNqQixxSEFBQSxjQUFjLE9BQUE7QUFDZCwySEFBQSxvQkFBb0IsT0FBQTtBQUNwQiwwSEFBQSxtQkFBbUIsT0FBQTtBQUNuQixxSEFBQSxjQUFjLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tIFwiLi9idWNrZXRFbmRwb2ludE1pZGRsZXdhcmVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2J1Y2tldEhvc3RuYW1lXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb25maWd1cmF0aW9uc1wiO1xuZXhwb3J0IHtcbiAgZ2V0QXJuUmVzb3VyY2VzLFxuICBnZXRQc2V1ZG9SZWdpb24sXG4gIGdldFN1ZmZpeEZvckFybkVuZHBvaW50LFxuICB2YWxpZGF0ZU91dHBvc3RTZXJ2aWNlLFxuICB2YWxpZGF0ZVBhcnRpdGlvbixcbiAgdmFsaWRhdGVBY2NvdW50SWQsXG4gIHZhbGlkYXRlUmVnaW9uLFxuICB2YWxpZGF0ZUROU0hvc3RMYWJlbCxcbiAgdmFsaWRhdGVOb0R1YWxzdGFjayxcbiAgdmFsaWRhdGVOb0ZJUFMsXG59IGZyb20gXCIuL2J1Y2tldEhvc3RuYW1lVXRpbHNcIjtcbiJdfQ==
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { __assign, __awaiter, __generator } from "tslib";
|
|
2
|
+
import { HttpRequest } from "@aws-sdk/protocol-http";
|
|
3
|
+
import { parse as parseArn, validate as validateArn } from "@aws-sdk/util-arn-parser";
|
|
4
|
+
import { bucketHostname } from "./bucketHostname";
|
|
5
|
+
import { getPseudoRegion } from "./bucketHostnameUtils";
|
|
6
|
+
export var bucketEndpointMiddleware = function (options) { return function (next, context) { return function (args) { return __awaiter(void 0, void 0, void 0, function () {
|
|
7
|
+
var bucketName, replaceBucketInPath, request, bucketArn, clientRegion, _a, _b, partition, _c, signingRegion, useArnRegion, _d, hostname, bucketEndpoint, modifiedSigningRegion, signingService, _e, clientRegion, _f, _g, hostname, bucketEndpoint;
|
|
8
|
+
var _h;
|
|
9
|
+
return __generator(this, function (_j) {
|
|
10
|
+
switch (_j.label) {
|
|
11
|
+
case 0:
|
|
12
|
+
bucketName = args.input.Bucket;
|
|
13
|
+
replaceBucketInPath = options.bucketEndpoint;
|
|
14
|
+
request = args.request;
|
|
15
|
+
if (!HttpRequest.isInstance(request)) return [3, 9];
|
|
16
|
+
if (!options.bucketEndpoint) return [3, 1];
|
|
17
|
+
request.hostname = bucketName;
|
|
18
|
+
return [3, 8];
|
|
19
|
+
case 1:
|
|
20
|
+
if (!validateArn(bucketName)) return [3, 6];
|
|
21
|
+
bucketArn = parseArn(bucketName);
|
|
22
|
+
_a = getPseudoRegion;
|
|
23
|
+
return [4, options.region()];
|
|
24
|
+
case 2:
|
|
25
|
+
clientRegion = _a.apply(void 0, [_j.sent()]);
|
|
26
|
+
return [4, options.regionInfoProvider(clientRegion)];
|
|
27
|
+
case 3:
|
|
28
|
+
_b = (_j.sent()) || {}, partition = _b.partition, _c = _b.signingRegion, signingRegion = _c === void 0 ? clientRegion : _c;
|
|
29
|
+
return [4, options.useArnRegion()];
|
|
30
|
+
case 4:
|
|
31
|
+
useArnRegion = _j.sent();
|
|
32
|
+
_e = bucketHostname;
|
|
33
|
+
_h = {
|
|
34
|
+
bucketName: bucketArn,
|
|
35
|
+
baseHostname: request.hostname,
|
|
36
|
+
accelerateEndpoint: options.useAccelerateEndpoint,
|
|
37
|
+
dualstackEndpoint: options.useDualstackEndpoint,
|
|
38
|
+
pathStyleEndpoint: options.forcePathStyle,
|
|
39
|
+
tlsCompatible: request.protocol === "https:",
|
|
40
|
+
useArnRegion: useArnRegion,
|
|
41
|
+
clientPartition: partition,
|
|
42
|
+
clientSigningRegion: signingRegion,
|
|
43
|
+
clientRegion: clientRegion,
|
|
44
|
+
isCustomEndpoint: options.isCustomEndpoint
|
|
45
|
+
};
|
|
46
|
+
return [4, options.disableMultiregionAccessPoints()];
|
|
47
|
+
case 5:
|
|
48
|
+
_d = _e.apply(void 0, [(_h.disableMultiregionAccessPoints = _j.sent(),
|
|
49
|
+
_h)]), hostname = _d.hostname, bucketEndpoint = _d.bucketEndpoint, modifiedSigningRegion = _d.signingRegion, signingService = _d.signingService;
|
|
50
|
+
if (modifiedSigningRegion && modifiedSigningRegion !== signingRegion) {
|
|
51
|
+
context["signing_region"] = modifiedSigningRegion;
|
|
52
|
+
}
|
|
53
|
+
if (signingService && signingService !== "s3") {
|
|
54
|
+
context["signing_service"] = signingService;
|
|
55
|
+
}
|
|
56
|
+
request.hostname = hostname;
|
|
57
|
+
replaceBucketInPath = bucketEndpoint;
|
|
58
|
+
return [3, 8];
|
|
59
|
+
case 6:
|
|
60
|
+
_f = getPseudoRegion;
|
|
61
|
+
return [4, options.region()];
|
|
62
|
+
case 7:
|
|
63
|
+
clientRegion = _f.apply(void 0, [_j.sent()]);
|
|
64
|
+
_g = bucketHostname({
|
|
65
|
+
bucketName: bucketName,
|
|
66
|
+
clientRegion: clientRegion,
|
|
67
|
+
baseHostname: request.hostname,
|
|
68
|
+
accelerateEndpoint: options.useAccelerateEndpoint,
|
|
69
|
+
dualstackEndpoint: options.useDualstackEndpoint,
|
|
70
|
+
pathStyleEndpoint: options.forcePathStyle,
|
|
71
|
+
tlsCompatible: request.protocol === "https:",
|
|
72
|
+
isCustomEndpoint: options.isCustomEndpoint,
|
|
73
|
+
}), hostname = _g.hostname, bucketEndpoint = _g.bucketEndpoint;
|
|
74
|
+
request.hostname = hostname;
|
|
75
|
+
replaceBucketInPath = bucketEndpoint;
|
|
76
|
+
_j.label = 8;
|
|
77
|
+
case 8:
|
|
78
|
+
if (replaceBucketInPath) {
|
|
79
|
+
request.path = request.path.replace(/^(\/)?[^\/]+/, "");
|
|
80
|
+
if (request.path === "") {
|
|
81
|
+
request.path = "/";
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
_j.label = 9;
|
|
85
|
+
case 9: return [2, next(__assign(__assign({}, args), { request: request }))];
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}); }; }; };
|
|
89
|
+
export var bucketEndpointMiddlewareOptions = {
|
|
90
|
+
tags: ["BUCKET_ENDPOINT"],
|
|
91
|
+
name: "bucketEndpointMiddleware",
|
|
92
|
+
relation: "before",
|
|
93
|
+
toMiddleware: "hostHeaderMiddleware",
|
|
94
|
+
override: true,
|
|
95
|
+
};
|
|
96
|
+
export var getBucketEndpointPlugin = function (options) { return ({
|
|
97
|
+
applyToStack: function (clientStack) {
|
|
98
|
+
clientStack.addRelativeTo(bucketEndpointMiddleware(options), bucketEndpointMiddlewareOptions);
|
|
99
|
+
},
|
|
100
|
+
}); };
|