@aws-sdk/middleware-bucket-endpoint 3.171.0 → 3.183.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 +16 -0
- package/dist-es/NodeDisableMultiregionAccessPointConfigOptions.js +5 -9
- package/dist-es/NodeUseArnRegionConfigOptions.js +5 -7
- package/dist-es/bucketEndpointMiddleware.js +68 -101
- package/dist-es/bucketHostname.js +53 -59
- package/dist-es/bucketHostnameUtils.js +48 -56
- package/dist-es/configurations.js +10 -4
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,22 @@
|
|
|
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.183.0](https://github.com/aws/aws-sdk-js-v3/compare/v3.182.0...v3.183.0) (2022-10-03)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @aws-sdk/middleware-bucket-endpoint
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# [3.178.0](https://github.com/aws/aws-sdk-js-v3/compare/v3.177.0...v3.178.0) (2022-09-23)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @aws-sdk/middleware-bucket-endpoint
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
6
22
|
# [3.171.0](https://github.com/aws/aws-sdk-js-v3/compare/v3.170.0...v3.171.0) (2022-09-14)
|
|
7
23
|
|
|
8
24
|
**Note:** Version bump only for package @aws-sdk/middleware-bucket-endpoint
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import { booleanSelector, SelectorType } from "@aws-sdk/util-config-provider";
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
environmentVariableSelector:
|
|
6
|
-
|
|
7
|
-
},
|
|
8
|
-
configFileSelector: function (profile) {
|
|
9
|
-
return booleanSelector(profile, NODE_DISABLE_MULTIREGION_ACCESS_POINT_INI_NAME, SelectorType.CONFIG);
|
|
10
|
-
},
|
|
2
|
+
export const NODE_DISABLE_MULTIREGION_ACCESS_POINT_ENV_NAME = "AWS_S3_DISABLE_MULTIREGION_ACCESS_POINTS";
|
|
3
|
+
export const NODE_DISABLE_MULTIREGION_ACCESS_POINT_INI_NAME = "s3_disable_multiregion_access_points";
|
|
4
|
+
export const NODE_DISABLE_MULTIREGION_ACCESS_POINT_CONFIG_OPTIONS = {
|
|
5
|
+
environmentVariableSelector: (env) => booleanSelector(env, NODE_DISABLE_MULTIREGION_ACCESS_POINT_ENV_NAME, SelectorType.ENV),
|
|
6
|
+
configFileSelector: (profile) => booleanSelector(profile, NODE_DISABLE_MULTIREGION_ACCESS_POINT_INI_NAME, SelectorType.CONFIG),
|
|
11
7
|
default: false,
|
|
12
8
|
};
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { booleanSelector, SelectorType } from "@aws-sdk/util-config-provider";
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
environmentVariableSelector:
|
|
6
|
-
|
|
7
|
-
},
|
|
8
|
-
configFileSelector: function (profile) { return booleanSelector(profile, NODE_USE_ARN_REGION_INI_NAME, SelectorType.CONFIG); },
|
|
2
|
+
export const NODE_USE_ARN_REGION_ENV_NAME = "AWS_S3_USE_ARN_REGION";
|
|
3
|
+
export const NODE_USE_ARN_REGION_INI_NAME = "s3_use_arn_region";
|
|
4
|
+
export const NODE_USE_ARN_REGION_CONFIG_OPTIONS = {
|
|
5
|
+
environmentVariableSelector: (env) => booleanSelector(env, NODE_USE_ARN_REGION_ENV_NAME, SelectorType.ENV),
|
|
6
|
+
configFileSelector: (profile) => booleanSelector(profile, NODE_USE_ARN_REGION_INI_NAME, SelectorType.CONFIG),
|
|
9
7
|
default: false,
|
|
10
8
|
};
|
|
@@ -1,114 +1,81 @@
|
|
|
1
|
-
import { __assign, __awaiter, __generator } from "tslib";
|
|
2
1
|
import { HttpRequest } from "@aws-sdk/protocol-http";
|
|
3
2
|
import { parse as parseArn, validate as validateArn } from "@aws-sdk/util-arn-parser";
|
|
4
3
|
import { bucketHostname } from "./bucketHostname";
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
_a = (_g.sent()) || {}, partition = _a.partition, _b = _a.signingRegion, signingRegion = _b === void 0 ? clientRegion : _b;
|
|
35
|
-
return [4, options.useArnRegion()];
|
|
36
|
-
case 6:
|
|
37
|
-
useArnRegion = _g.sent();
|
|
38
|
-
_d = bucketHostname;
|
|
39
|
-
_f = {
|
|
40
|
-
bucketName: bucketArn,
|
|
41
|
-
baseHostname: request.hostname,
|
|
42
|
-
accelerateEndpoint: options.useAccelerateEndpoint,
|
|
43
|
-
dualstackEndpoint: useDualstackEndpoint,
|
|
44
|
-
fipsEndpoint: useFipsEndpoint,
|
|
45
|
-
pathStyleEndpoint: options.forcePathStyle,
|
|
46
|
-
tlsCompatible: request.protocol === "https:",
|
|
47
|
-
useArnRegion: useArnRegion,
|
|
48
|
-
clientPartition: partition,
|
|
49
|
-
clientSigningRegion: signingRegion,
|
|
50
|
-
clientRegion: clientRegion,
|
|
51
|
-
isCustomEndpoint: options.isCustomEndpoint
|
|
52
|
-
};
|
|
53
|
-
return [4, options.disableMultiregionAccessPoints()];
|
|
54
|
-
case 7:
|
|
55
|
-
_c = _d.apply(void 0, [(_f.disableMultiregionAccessPoints = _g.sent(),
|
|
56
|
-
_f)]), hostname = _c.hostname, bucketEndpoint = _c.bucketEndpoint, modifiedSigningRegion = _c.signingRegion, signingService = _c.signingService;
|
|
57
|
-
if (modifiedSigningRegion && modifiedSigningRegion !== signingRegion) {
|
|
58
|
-
context["signing_region"] = modifiedSigningRegion;
|
|
59
|
-
}
|
|
60
|
-
if (signingService && signingService !== "s3") {
|
|
61
|
-
context["signing_service"] = signingService;
|
|
62
|
-
}
|
|
63
|
-
request.hostname = hostname;
|
|
64
|
-
replaceBucketInPath = bucketEndpoint;
|
|
65
|
-
return [3, 12];
|
|
66
|
-
case 8: return [4, options.region()];
|
|
67
|
-
case 9:
|
|
68
|
-
clientRegion = _g.sent();
|
|
69
|
-
return [4, options.useDualstackEndpoint()];
|
|
70
|
-
case 10:
|
|
71
|
-
dualstackEndpoint = _g.sent();
|
|
72
|
-
return [4, options.useFipsEndpoint()];
|
|
73
|
-
case 11:
|
|
74
|
-
fipsEndpoint = _g.sent();
|
|
75
|
-
_e = bucketHostname({
|
|
76
|
-
bucketName: bucketName,
|
|
77
|
-
clientRegion: clientRegion,
|
|
78
|
-
baseHostname: request.hostname,
|
|
79
|
-
accelerateEndpoint: options.useAccelerateEndpoint,
|
|
80
|
-
dualstackEndpoint: dualstackEndpoint,
|
|
81
|
-
fipsEndpoint: fipsEndpoint,
|
|
82
|
-
pathStyleEndpoint: options.forcePathStyle,
|
|
83
|
-
tlsCompatible: request.protocol === "https:",
|
|
84
|
-
isCustomEndpoint: options.isCustomEndpoint,
|
|
85
|
-
}), hostname = _e.hostname, bucketEndpoint = _e.bucketEndpoint;
|
|
86
|
-
request.hostname = hostname;
|
|
87
|
-
replaceBucketInPath = bucketEndpoint;
|
|
88
|
-
_g.label = 12;
|
|
89
|
-
case 12:
|
|
90
|
-
if (replaceBucketInPath) {
|
|
91
|
-
request.path = request.path.replace(/^(\/)?[^\/]+/, "");
|
|
92
|
-
if (request.path === "") {
|
|
93
|
-
request.path = "/";
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
_g.label = 13;
|
|
97
|
-
case 13: return [2, next(__assign(__assign({}, args), { request: request }))];
|
|
98
|
-
}
|
|
4
|
+
export const bucketEndpointMiddleware = (options) => (next, context) => async (args) => {
|
|
5
|
+
const { Bucket: bucketName } = args.input;
|
|
6
|
+
let replaceBucketInPath = options.bucketEndpoint;
|
|
7
|
+
const request = args.request;
|
|
8
|
+
if (HttpRequest.isInstance(request)) {
|
|
9
|
+
if (options.bucketEndpoint) {
|
|
10
|
+
request.hostname = bucketName;
|
|
11
|
+
}
|
|
12
|
+
else if (validateArn(bucketName)) {
|
|
13
|
+
const bucketArn = parseArn(bucketName);
|
|
14
|
+
const clientRegion = await options.region();
|
|
15
|
+
const useDualstackEndpoint = await options.useDualstackEndpoint();
|
|
16
|
+
const useFipsEndpoint = await options.useFipsEndpoint();
|
|
17
|
+
const { partition, signingRegion = clientRegion } = (await options.regionInfoProvider(clientRegion, { useDualstackEndpoint, useFipsEndpoint })) || {};
|
|
18
|
+
const useArnRegion = await options.useArnRegion();
|
|
19
|
+
const { hostname, bucketEndpoint, signingRegion: modifiedSigningRegion, signingService, } = bucketHostname({
|
|
20
|
+
bucketName: bucketArn,
|
|
21
|
+
baseHostname: request.hostname,
|
|
22
|
+
accelerateEndpoint: options.useAccelerateEndpoint,
|
|
23
|
+
dualstackEndpoint: useDualstackEndpoint,
|
|
24
|
+
fipsEndpoint: useFipsEndpoint,
|
|
25
|
+
pathStyleEndpoint: options.forcePathStyle,
|
|
26
|
+
tlsCompatible: request.protocol === "https:",
|
|
27
|
+
useArnRegion,
|
|
28
|
+
clientPartition: partition,
|
|
29
|
+
clientSigningRegion: signingRegion,
|
|
30
|
+
clientRegion: clientRegion,
|
|
31
|
+
isCustomEndpoint: options.isCustomEndpoint,
|
|
32
|
+
disableMultiregionAccessPoints: await options.disableMultiregionAccessPoints(),
|
|
99
33
|
});
|
|
100
|
-
|
|
101
|
-
|
|
34
|
+
if (modifiedSigningRegion && modifiedSigningRegion !== signingRegion) {
|
|
35
|
+
context["signing_region"] = modifiedSigningRegion;
|
|
36
|
+
}
|
|
37
|
+
if (signingService && signingService !== "s3") {
|
|
38
|
+
context["signing_service"] = signingService;
|
|
39
|
+
}
|
|
40
|
+
request.hostname = hostname;
|
|
41
|
+
replaceBucketInPath = bucketEndpoint;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const clientRegion = await options.region();
|
|
45
|
+
const dualstackEndpoint = await options.useDualstackEndpoint();
|
|
46
|
+
const fipsEndpoint = await options.useFipsEndpoint();
|
|
47
|
+
const { hostname, bucketEndpoint } = bucketHostname({
|
|
48
|
+
bucketName,
|
|
49
|
+
clientRegion,
|
|
50
|
+
baseHostname: request.hostname,
|
|
51
|
+
accelerateEndpoint: options.useAccelerateEndpoint,
|
|
52
|
+
dualstackEndpoint,
|
|
53
|
+
fipsEndpoint,
|
|
54
|
+
pathStyleEndpoint: options.forcePathStyle,
|
|
55
|
+
tlsCompatible: request.protocol === "https:",
|
|
56
|
+
isCustomEndpoint: options.isCustomEndpoint,
|
|
57
|
+
});
|
|
58
|
+
request.hostname = hostname;
|
|
59
|
+
replaceBucketInPath = bucketEndpoint;
|
|
60
|
+
}
|
|
61
|
+
if (replaceBucketInPath) {
|
|
62
|
+
request.path = request.path.replace(/^(\/)?[^\/]+/, "");
|
|
63
|
+
if (request.path === "") {
|
|
64
|
+
request.path = "/";
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return next({ ...args, request });
|
|
102
69
|
};
|
|
103
|
-
export
|
|
70
|
+
export const bucketEndpointMiddlewareOptions = {
|
|
104
71
|
tags: ["BUCKET_ENDPOINT"],
|
|
105
72
|
name: "bucketEndpointMiddleware",
|
|
106
73
|
relation: "before",
|
|
107
74
|
toMiddleware: "hostHeaderMiddleware",
|
|
108
75
|
override: true,
|
|
109
76
|
};
|
|
110
|
-
export
|
|
111
|
-
applyToStack:
|
|
77
|
+
export const getBucketEndpointPlugin = (options) => ({
|
|
78
|
+
applyToStack: (clientStack) => {
|
|
112
79
|
clientStack.addRelativeTo(bucketEndpointMiddleware(options), bucketEndpointMiddlewareOptions);
|
|
113
80
|
},
|
|
114
|
-
});
|
|
81
|
+
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { __assign, __read } from "tslib";
|
|
2
1
|
import { DOT_PATTERN, getArnResources, getSuffix, getSuffixForArnEndpoint, isBucketNameOptions, isDnsCompatibleBucketName, validateAccountId, validateArnEndpointOptions, validateCustomEndpoint, validateDNSHostLabel, validateMrapAlias, validateNoDualstack, validateNoFIPS, validateOutpostService, validatePartition, validateRegion, validateRegionalClient, validateS3Service, validateService, } from "./bucketHostnameUtils";
|
|
3
|
-
export
|
|
2
|
+
export const bucketHostname = (options) => {
|
|
4
3
|
validateCustomEndpoint(options);
|
|
5
4
|
return isBucketNameOptions(options)
|
|
6
5
|
?
|
|
@@ -8,72 +7,69 @@ export var bucketHostname = function (options) {
|
|
|
8
7
|
:
|
|
9
8
|
getEndpointFromArn(options);
|
|
10
9
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
var _h = __read(isCustomEndpoint ? [region, baseHostname] : getSuffix(baseHostname), 2), clientRegion = _h[0], hostnameSuffix = _h[1];
|
|
10
|
+
const getEndpointFromBucketName = ({ accelerateEndpoint = false, clientRegion: region, baseHostname, bucketName, dualstackEndpoint = false, fipsEndpoint = false, pathStyleEndpoint = false, tlsCompatible = true, isCustomEndpoint = false, }) => {
|
|
11
|
+
const [clientRegion, hostnameSuffix] = isCustomEndpoint ? [region, baseHostname] : getSuffix(baseHostname);
|
|
14
12
|
if (pathStyleEndpoint || !isDnsCompatibleBucketName(bucketName) || (tlsCompatible && DOT_PATTERN.test(bucketName))) {
|
|
15
13
|
return {
|
|
16
14
|
bucketEndpoint: false,
|
|
17
|
-
hostname: dualstackEndpoint ?
|
|
15
|
+
hostname: dualstackEndpoint ? `s3.dualstack.${clientRegion}.${hostnameSuffix}` : baseHostname,
|
|
18
16
|
};
|
|
19
17
|
}
|
|
20
18
|
if (accelerateEndpoint) {
|
|
21
|
-
baseHostname =
|
|
19
|
+
baseHostname = `s3-accelerate${dualstackEndpoint ? ".dualstack" : ""}.${hostnameSuffix}`;
|
|
22
20
|
}
|
|
23
21
|
else if (dualstackEndpoint) {
|
|
24
|
-
baseHostname =
|
|
22
|
+
baseHostname = `s3.dualstack.${clientRegion}.${hostnameSuffix}`;
|
|
25
23
|
}
|
|
26
24
|
return {
|
|
27
25
|
bucketEndpoint: true,
|
|
28
|
-
hostname:
|
|
26
|
+
hostname: `${bucketName}.${baseHostname}`,
|
|
29
27
|
};
|
|
30
28
|
};
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
validateArnEndpointOptions({ pathStyleEndpoint
|
|
36
|
-
|
|
29
|
+
const getEndpointFromArn = (options) => {
|
|
30
|
+
const { isCustomEndpoint, baseHostname, clientRegion } = options;
|
|
31
|
+
const hostnameSuffix = isCustomEndpoint ? baseHostname : getSuffixForArnEndpoint(baseHostname)[1];
|
|
32
|
+
const { pathStyleEndpoint, accelerateEndpoint = false, fipsEndpoint = false, tlsCompatible = true, bucketName, clientPartition = "aws", } = options;
|
|
33
|
+
validateArnEndpointOptions({ pathStyleEndpoint, accelerateEndpoint, tlsCompatible });
|
|
34
|
+
const { service, partition, accountId, region, resource } = bucketName;
|
|
37
35
|
validateService(service);
|
|
38
|
-
validatePartition(partition, { clientPartition
|
|
36
|
+
validatePartition(partition, { clientPartition });
|
|
39
37
|
validateAccountId(accountId);
|
|
40
|
-
|
|
38
|
+
const { accesspointName, outpostId } = getArnResources(resource);
|
|
41
39
|
if (service === "s3-object-lambda") {
|
|
42
|
-
return getEndpointFromObjectLambdaArn(
|
|
40
|
+
return getEndpointFromObjectLambdaArn({ ...options, tlsCompatible, bucketName, accesspointName, hostnameSuffix });
|
|
43
41
|
}
|
|
44
42
|
if (region === "") {
|
|
45
|
-
return getEndpointFromMRAPArn(
|
|
43
|
+
return getEndpointFromMRAPArn({ ...options, clientRegion, mrapAlias: accesspointName, hostnameSuffix });
|
|
46
44
|
}
|
|
47
45
|
if (outpostId) {
|
|
48
|
-
return getEndpointFromOutpostArn(
|
|
46
|
+
return getEndpointFromOutpostArn({ ...options, clientRegion, outpostId, accesspointName, hostnameSuffix });
|
|
49
47
|
}
|
|
50
|
-
return getEndpointFromAccessPointArn(
|
|
48
|
+
return getEndpointFromAccessPointArn({ ...options, clientRegion, accesspointName, hostnameSuffix });
|
|
51
49
|
};
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
var accountId = bucketName.accountId, region = bucketName.region, service = bucketName.service;
|
|
50
|
+
const getEndpointFromObjectLambdaArn = ({ dualstackEndpoint = false, fipsEndpoint = false, tlsCompatible = true, useArnRegion, clientRegion, clientSigningRegion = clientRegion, accesspointName, bucketName, hostnameSuffix, }) => {
|
|
51
|
+
const { accountId, region, service } = bucketName;
|
|
55
52
|
validateRegionalClient(clientRegion);
|
|
56
53
|
validateRegion(region, {
|
|
57
|
-
useArnRegion
|
|
58
|
-
clientRegion
|
|
59
|
-
clientSigningRegion
|
|
54
|
+
useArnRegion,
|
|
55
|
+
clientRegion,
|
|
56
|
+
clientSigningRegion,
|
|
60
57
|
allowFipsRegion: true,
|
|
61
58
|
useFipsEndpoint: fipsEndpoint,
|
|
62
59
|
});
|
|
63
60
|
validateNoDualstack(dualstackEndpoint);
|
|
64
|
-
|
|
65
|
-
validateDNSHostLabel(DNSHostLabel, { tlsCompatible
|
|
66
|
-
|
|
67
|
-
|
|
61
|
+
const DNSHostLabel = `${accesspointName}-${accountId}`;
|
|
62
|
+
validateDNSHostLabel(DNSHostLabel, { tlsCompatible });
|
|
63
|
+
const endpointRegion = useArnRegion ? region : clientRegion;
|
|
64
|
+
const signingRegion = useArnRegion ? region : clientSigningRegion;
|
|
68
65
|
return {
|
|
69
66
|
bucketEndpoint: true,
|
|
70
|
-
hostname:
|
|
71
|
-
signingRegion
|
|
67
|
+
hostname: `${DNSHostLabel}.${service}${fipsEndpoint ? "-fips" : ""}.${endpointRegion}.${hostnameSuffix}`,
|
|
68
|
+
signingRegion,
|
|
72
69
|
signingService: service,
|
|
73
70
|
};
|
|
74
71
|
};
|
|
75
|
-
|
|
76
|
-
var disableMultiregionAccessPoints = _a.disableMultiregionAccessPoints, _b = _a.dualstackEndpoint, dualstackEndpoint = _b === void 0 ? false : _b, isCustomEndpoint = _a.isCustomEndpoint, mrapAlias = _a.mrapAlias, hostnameSuffix = _a.hostnameSuffix;
|
|
72
|
+
const getEndpointFromMRAPArn = ({ disableMultiregionAccessPoints, dualstackEndpoint = false, isCustomEndpoint, mrapAlias, hostnameSuffix, }) => {
|
|
77
73
|
if (disableMultiregionAccessPoints === true) {
|
|
78
74
|
throw new Error("SDK is attempting to use a MRAP ARN. Please enable to feature.");
|
|
79
75
|
}
|
|
@@ -81,50 +77,48 @@ var getEndpointFromMRAPArn = function (_a) {
|
|
|
81
77
|
validateNoDualstack(dualstackEndpoint);
|
|
82
78
|
return {
|
|
83
79
|
bucketEndpoint: true,
|
|
84
|
-
hostname:
|
|
80
|
+
hostname: `${mrapAlias}${isCustomEndpoint ? "" : `.accesspoint.s3-global`}.${hostnameSuffix}`,
|
|
85
81
|
signingRegion: "*",
|
|
86
82
|
};
|
|
87
83
|
};
|
|
88
|
-
|
|
89
|
-
var useArnRegion = _a.useArnRegion, clientRegion = _a.clientRegion, _b = _a.clientSigningRegion, clientSigningRegion = _b === void 0 ? clientRegion : _b, bucketName = _a.bucketName, outpostId = _a.outpostId, _c = _a.dualstackEndpoint, dualstackEndpoint = _c === void 0 ? false : _c, _d = _a.fipsEndpoint, fipsEndpoint = _d === void 0 ? false : _d, _e = _a.tlsCompatible, tlsCompatible = _e === void 0 ? true : _e, accesspointName = _a.accesspointName, isCustomEndpoint = _a.isCustomEndpoint, hostnameSuffix = _a.hostnameSuffix;
|
|
84
|
+
const getEndpointFromOutpostArn = ({ useArnRegion, clientRegion, clientSigningRegion = clientRegion, bucketName, outpostId, dualstackEndpoint = false, fipsEndpoint = false, tlsCompatible = true, accesspointName, isCustomEndpoint, hostnameSuffix, }) => {
|
|
90
85
|
validateRegionalClient(clientRegion);
|
|
91
|
-
validateRegion(bucketName.region, { useArnRegion
|
|
92
|
-
|
|
93
|
-
validateDNSHostLabel(DNSHostLabel, { tlsCompatible
|
|
94
|
-
|
|
95
|
-
|
|
86
|
+
validateRegion(bucketName.region, { useArnRegion, clientRegion, clientSigningRegion, useFipsEndpoint: fipsEndpoint });
|
|
87
|
+
const DNSHostLabel = `${accesspointName}-${bucketName.accountId}`;
|
|
88
|
+
validateDNSHostLabel(DNSHostLabel, { tlsCompatible });
|
|
89
|
+
const endpointRegion = useArnRegion ? bucketName.region : clientRegion;
|
|
90
|
+
const signingRegion = useArnRegion ? bucketName.region : clientSigningRegion;
|
|
96
91
|
validateOutpostService(bucketName.service);
|
|
97
|
-
validateDNSHostLabel(outpostId, { tlsCompatible
|
|
92
|
+
validateDNSHostLabel(outpostId, { tlsCompatible });
|
|
98
93
|
validateNoDualstack(dualstackEndpoint);
|
|
99
94
|
validateNoFIPS(fipsEndpoint);
|
|
100
|
-
|
|
95
|
+
const hostnamePrefix = `${DNSHostLabel}.${outpostId}`;
|
|
101
96
|
return {
|
|
102
97
|
bucketEndpoint: true,
|
|
103
|
-
hostname:
|
|
104
|
-
signingRegion
|
|
98
|
+
hostname: `${hostnamePrefix}${isCustomEndpoint ? "" : `.s3-outposts.${endpointRegion}`}.${hostnameSuffix}`,
|
|
99
|
+
signingRegion,
|
|
105
100
|
signingService: "s3-outposts",
|
|
106
101
|
};
|
|
107
102
|
};
|
|
108
|
-
|
|
109
|
-
var useArnRegion = _a.useArnRegion, clientRegion = _a.clientRegion, _b = _a.clientSigningRegion, clientSigningRegion = _b === void 0 ? clientRegion : _b, bucketName = _a.bucketName, _c = _a.dualstackEndpoint, dualstackEndpoint = _c === void 0 ? false : _c, _d = _a.fipsEndpoint, fipsEndpoint = _d === void 0 ? false : _d, _e = _a.tlsCompatible, tlsCompatible = _e === void 0 ? true : _e, accesspointName = _a.accesspointName, isCustomEndpoint = _a.isCustomEndpoint, hostnameSuffix = _a.hostnameSuffix;
|
|
103
|
+
const getEndpointFromAccessPointArn = ({ useArnRegion, clientRegion, clientSigningRegion = clientRegion, bucketName, dualstackEndpoint = false, fipsEndpoint = false, tlsCompatible = true, accesspointName, isCustomEndpoint, hostnameSuffix, }) => {
|
|
110
104
|
validateRegionalClient(clientRegion);
|
|
111
105
|
validateRegion(bucketName.region, {
|
|
112
|
-
useArnRegion
|
|
113
|
-
clientRegion
|
|
114
|
-
clientSigningRegion
|
|
106
|
+
useArnRegion,
|
|
107
|
+
clientRegion,
|
|
108
|
+
clientSigningRegion,
|
|
115
109
|
allowFipsRegion: true,
|
|
116
110
|
useFipsEndpoint: fipsEndpoint,
|
|
117
111
|
});
|
|
118
|
-
|
|
119
|
-
validateDNSHostLabel(hostnamePrefix, { tlsCompatible
|
|
120
|
-
|
|
121
|
-
|
|
112
|
+
const hostnamePrefix = `${accesspointName}-${bucketName.accountId}`;
|
|
113
|
+
validateDNSHostLabel(hostnamePrefix, { tlsCompatible });
|
|
114
|
+
const endpointRegion = useArnRegion ? bucketName.region : clientRegion;
|
|
115
|
+
const signingRegion = useArnRegion ? bucketName.region : clientSigningRegion;
|
|
122
116
|
validateS3Service(bucketName.service);
|
|
123
117
|
return {
|
|
124
118
|
bucketEndpoint: true,
|
|
125
|
-
hostname:
|
|
119
|
+
hostname: `${hostnamePrefix}${isCustomEndpoint
|
|
126
120
|
? ""
|
|
127
|
-
:
|
|
128
|
-
signingRegion
|
|
121
|
+
: `.s3-accesspoint${fipsEndpoint ? "-fips" : ""}${dualstackEndpoint ? ".dualstack" : ""}.${endpointRegion}`}.${hostnameSuffix}`,
|
|
122
|
+
signingRegion,
|
|
129
123
|
};
|
|
130
124
|
};
|
|
@@ -1,28 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
};
|
|
20
|
-
export var getSuffixForArnEndpoint = function (hostname) {
|
|
21
|
-
return S3_US_EAST_1_ALTNAME_PATTERN.test(hostname)
|
|
22
|
-
? [hostname.replace(".".concat(AWS_PARTITION_SUFFIX), ""), AWS_PARTITION_SUFFIX]
|
|
23
|
-
: getRegionalSuffix(hostname);
|
|
24
|
-
};
|
|
25
|
-
export var validateArnEndpointOptions = function (options) {
|
|
1
|
+
const DOMAIN_PATTERN = /^[a-z0-9][a-z0-9\.\-]{1,61}[a-z0-9]$/;
|
|
2
|
+
const IP_ADDRESS_PATTERN = /(\d+\.){3}\d+/;
|
|
3
|
+
const DOTS_PATTERN = /\.\./;
|
|
4
|
+
export const DOT_PATTERN = /\./;
|
|
5
|
+
export const S3_HOSTNAME_PATTERN = /^(.+\.)?s3(-fips)?(\.dualstack)?[.-]([a-z0-9-]+)\./;
|
|
6
|
+
const S3_US_EAST_1_ALTNAME_PATTERN = /^s3(-external-1)?\.amazonaws\.com$/;
|
|
7
|
+
const AWS_PARTITION_SUFFIX = "amazonaws.com";
|
|
8
|
+
export const isBucketNameOptions = (options) => typeof options.bucketName === "string";
|
|
9
|
+
export const isDnsCompatibleBucketName = (bucketName) => DOMAIN_PATTERN.test(bucketName) && !IP_ADDRESS_PATTERN.test(bucketName) && !DOTS_PATTERN.test(bucketName);
|
|
10
|
+
const getRegionalSuffix = (hostname) => {
|
|
11
|
+
const parts = hostname.match(S3_HOSTNAME_PATTERN);
|
|
12
|
+
return [parts[4], hostname.replace(new RegExp(`^${parts[0]}`), "")];
|
|
13
|
+
};
|
|
14
|
+
export const getSuffix = (hostname) => S3_US_EAST_1_ALTNAME_PATTERN.test(hostname) ? ["us-east-1", AWS_PARTITION_SUFFIX] : getRegionalSuffix(hostname);
|
|
15
|
+
export const getSuffixForArnEndpoint = (hostname) => S3_US_EAST_1_ALTNAME_PATTERN.test(hostname)
|
|
16
|
+
? [hostname.replace(`.${AWS_PARTITION_SUFFIX}`, ""), AWS_PARTITION_SUFFIX]
|
|
17
|
+
: getRegionalSuffix(hostname);
|
|
18
|
+
export const validateArnEndpointOptions = (options) => {
|
|
26
19
|
if (options.pathStyleEndpoint) {
|
|
27
20
|
throw new Error("Path-style S3 endpoint is not supported when bucket is an ARN");
|
|
28
21
|
}
|
|
@@ -33,27 +26,27 @@ export var validateArnEndpointOptions = function (options) {
|
|
|
33
26
|
throw new Error("HTTPS is required when bucket is an ARN");
|
|
34
27
|
}
|
|
35
28
|
};
|
|
36
|
-
export
|
|
29
|
+
export const validateService = (service) => {
|
|
37
30
|
if (service !== "s3" && service !== "s3-outposts" && service !== "s3-object-lambda") {
|
|
38
31
|
throw new Error("Expect 's3' or 's3-outposts' or 's3-object-lambda' in ARN service component");
|
|
39
32
|
}
|
|
40
33
|
};
|
|
41
|
-
export
|
|
34
|
+
export const validateS3Service = (service) => {
|
|
42
35
|
if (service !== "s3") {
|
|
43
36
|
throw new Error("Expect 's3' in Accesspoint ARN service component");
|
|
44
37
|
}
|
|
45
38
|
};
|
|
46
|
-
export
|
|
39
|
+
export const validateOutpostService = (service) => {
|
|
47
40
|
if (service !== "s3-outposts") {
|
|
48
41
|
throw new Error("Expect 's3-posts' in Outpost ARN service component");
|
|
49
42
|
}
|
|
50
43
|
};
|
|
51
|
-
export
|
|
44
|
+
export const validatePartition = (partition, options) => {
|
|
52
45
|
if (partition !== options.clientPartition) {
|
|
53
|
-
throw new Error(
|
|
46
|
+
throw new Error(`Partition in ARN is incompatible, got "${partition}" but expected "${options.clientPartition}"`);
|
|
54
47
|
}
|
|
55
48
|
};
|
|
56
|
-
export
|
|
49
|
+
export const validateRegion = (region, options) => {
|
|
57
50
|
if (region === "") {
|
|
58
51
|
throw new Error("ARN region is empty");
|
|
59
52
|
}
|
|
@@ -62,37 +55,36 @@ export var validateRegion = function (region, options) {
|
|
|
62
55
|
throw new Error("FIPS region is not supported");
|
|
63
56
|
}
|
|
64
57
|
else if (!isEqualRegions(region, options.clientRegion)) {
|
|
65
|
-
throw new Error(
|
|
58
|
+
throw new Error(`Client FIPS region ${options.clientRegion} doesn't match region ${region} in ARN`);
|
|
66
59
|
}
|
|
67
60
|
}
|
|
68
61
|
if (!options.useArnRegion &&
|
|
69
62
|
!isEqualRegions(region, options.clientRegion || "") &&
|
|
70
63
|
!isEqualRegions(region, options.clientSigningRegion || "")) {
|
|
71
|
-
throw new Error(
|
|
64
|
+
throw new Error(`Region in ARN is incompatible, got ${region} but expected ${options.clientRegion}`);
|
|
72
65
|
}
|
|
73
66
|
};
|
|
74
|
-
export
|
|
67
|
+
export const validateRegionalClient = (region) => {
|
|
75
68
|
if (["s3-external-1", "aws-global"].includes(region)) {
|
|
76
|
-
throw new Error(
|
|
69
|
+
throw new Error(`Client region ${region} is not regional`);
|
|
77
70
|
}
|
|
78
71
|
};
|
|
79
|
-
|
|
80
|
-
export
|
|
72
|
+
const isEqualRegions = (regionA, regionB) => regionA === regionB;
|
|
73
|
+
export const validateAccountId = (accountId) => {
|
|
81
74
|
if (!/[0-9]{12}/.exec(accountId)) {
|
|
82
75
|
throw new Error("Access point ARN accountID does not match regex '[0-9]{12}'");
|
|
83
76
|
}
|
|
84
77
|
};
|
|
85
|
-
export
|
|
86
|
-
if (options === void 0) { options = { tlsCompatible: true }; }
|
|
78
|
+
export const validateDNSHostLabel = (label, options = { tlsCompatible: true }) => {
|
|
87
79
|
if (label.length >= 64 ||
|
|
88
80
|
!/^[a-z0-9][a-z0-9.-]*[a-z0-9]$/.test(label) ||
|
|
89
81
|
/(\d+\.){3}\d+/.test(label) ||
|
|
90
82
|
/[.-]{2}/.test(label) ||
|
|
91
|
-
(
|
|
92
|
-
throw new Error(
|
|
83
|
+
(options?.tlsCompatible && DOT_PATTERN.test(label))) {
|
|
84
|
+
throw new Error(`Invalid DNS label ${label}`);
|
|
93
85
|
}
|
|
94
86
|
};
|
|
95
|
-
export
|
|
87
|
+
export const validateCustomEndpoint = (options) => {
|
|
96
88
|
if (options.isCustomEndpoint) {
|
|
97
89
|
if (options.dualstackEndpoint)
|
|
98
90
|
throw new Error("Dualstack endpoint is not supported with custom endpoint");
|
|
@@ -100,41 +92,41 @@ export var validateCustomEndpoint = function (options) {
|
|
|
100
92
|
throw new Error("Accelerate endpoint is not supported with custom endpoint");
|
|
101
93
|
}
|
|
102
94
|
};
|
|
103
|
-
export
|
|
104
|
-
|
|
105
|
-
|
|
95
|
+
export const getArnResources = (resource) => {
|
|
96
|
+
const delimiter = resource.includes(":") ? ":" : "/";
|
|
97
|
+
const [resourceType, ...rest] = resource.split(delimiter);
|
|
106
98
|
if (resourceType === "accesspoint") {
|
|
107
99
|
if (rest.length !== 1 || rest[0] === "") {
|
|
108
|
-
throw new Error(
|
|
100
|
+
throw new Error(`Access Point ARN should have one resource accesspoint${delimiter}{accesspointname}`);
|
|
109
101
|
}
|
|
110
102
|
return { accesspointName: rest[0] };
|
|
111
103
|
}
|
|
112
104
|
else if (resourceType === "outpost") {
|
|
113
105
|
if (!rest[0] || rest[1] !== "accesspoint" || !rest[2] || rest.length !== 3) {
|
|
114
|
-
throw new Error(
|
|
106
|
+
throw new Error(`Outpost ARN should have resource outpost${delimiter}{outpostId}${delimiter}accesspoint${delimiter}{accesspointName}`);
|
|
115
107
|
}
|
|
116
|
-
|
|
117
|
-
return { outpostId
|
|
108
|
+
const [outpostId, _, accesspointName] = rest;
|
|
109
|
+
return { outpostId, accesspointName };
|
|
118
110
|
}
|
|
119
111
|
else {
|
|
120
|
-
throw new Error(
|
|
112
|
+
throw new Error(`ARN resource should begin with 'accesspoint${delimiter}' or 'outpost${delimiter}'`);
|
|
121
113
|
}
|
|
122
114
|
};
|
|
123
|
-
export
|
|
115
|
+
export const validateNoDualstack = (dualstackEndpoint) => {
|
|
124
116
|
if (dualstackEndpoint)
|
|
125
117
|
throw new Error("Dualstack endpoint is not supported with Outpost or Multi-region Access Point ARN.");
|
|
126
118
|
};
|
|
127
|
-
export
|
|
119
|
+
export const validateNoFIPS = (useFipsEndpoint) => {
|
|
128
120
|
if (useFipsEndpoint)
|
|
129
|
-
throw new Error(
|
|
121
|
+
throw new Error(`FIPS region is not supported with Outpost.`);
|
|
130
122
|
};
|
|
131
|
-
export
|
|
123
|
+
export const validateMrapAlias = (name) => {
|
|
132
124
|
try {
|
|
133
|
-
name.split(".").forEach(
|
|
125
|
+
name.split(".").forEach((label) => {
|
|
134
126
|
validateDNSHostLabel(label);
|
|
135
127
|
});
|
|
136
128
|
}
|
|
137
129
|
catch (e) {
|
|
138
|
-
throw new Error("
|
|
130
|
+
throw new Error(`"${name}" is not a DNS compatible name.`);
|
|
139
131
|
}
|
|
140
132
|
};
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
import { __assign } from "tslib";
|
|
2
1
|
export function resolveBucketEndpointConfig(input) {
|
|
3
|
-
|
|
4
|
-
return
|
|
2
|
+
const { bucketEndpoint = false, forcePathStyle = false, useAccelerateEndpoint = false, useArnRegion = false, disableMultiregionAccessPoints = false, } = input;
|
|
3
|
+
return {
|
|
4
|
+
...input,
|
|
5
|
+
bucketEndpoint,
|
|
6
|
+
forcePathStyle,
|
|
7
|
+
useAccelerateEndpoint,
|
|
8
|
+
useArnRegion: typeof useArnRegion === "function" ? useArnRegion : () => Promise.resolve(useArnRegion),
|
|
9
|
+
disableMultiregionAccessPoints: typeof disableMultiregionAccessPoints === "function"
|
|
5
10
|
? disableMultiregionAccessPoints
|
|
6
|
-
:
|
|
11
|
+
: () => Promise.resolve(disableMultiregionAccessPoints),
|
|
12
|
+
};
|
|
7
13
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aws-sdk/middleware-bucket-endpoint",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.183.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"build": "concurrently 'yarn:build:cjs' 'yarn:build:es' 'yarn:build:types'",
|
|
6
6
|
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
@@ -20,15 +20,15 @@
|
|
|
20
20
|
},
|
|
21
21
|
"license": "Apache-2.0",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@aws-sdk/protocol-http": "3.
|
|
24
|
-
"@aws-sdk/types": "3.
|
|
25
|
-
"@aws-sdk/util-arn-parser": "3.
|
|
26
|
-
"@aws-sdk/util-config-provider": "3.
|
|
23
|
+
"@aws-sdk/protocol-http": "3.183.0",
|
|
24
|
+
"@aws-sdk/types": "3.183.0",
|
|
25
|
+
"@aws-sdk/util-arn-parser": "3.183.0",
|
|
26
|
+
"@aws-sdk/util-config-provider": "3.183.0",
|
|
27
27
|
"tslib": "^2.3.1"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@aws-sdk/middleware-stack": "3.
|
|
31
|
-
"@aws-sdk/node-config-provider": "3.
|
|
30
|
+
"@aws-sdk/middleware-stack": "3.183.0",
|
|
31
|
+
"@aws-sdk/node-config-provider": "3.183.0",
|
|
32
32
|
"@tsconfig/recommended": "1.0.1",
|
|
33
33
|
"concurrently": "7.0.0",
|
|
34
34
|
"downlevel-dts": "0.10.1",
|