@depup/aws-sdk__middleware-sdk-s3 3.972.20-depup.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.
Files changed (65) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +34 -0
  3. package/changes.json +22 -0
  4. package/dist-cjs/index.js +570 -0
  5. package/dist-es/bucket-endpoint-middleware.js +36 -0
  6. package/dist-es/check-content-length-header.js +32 -0
  7. package/dist-es/index.js +8 -0
  8. package/dist-es/region-redirect-endpoint-middleware.js +41 -0
  9. package/dist-es/region-redirect-middleware.js +42 -0
  10. package/dist-es/s3-expires-middleware.js +33 -0
  11. package/dist-es/s3-express/classes/S3ExpressIdentityCache.js +39 -0
  12. package/dist-es/s3-express/classes/S3ExpressIdentityCacheEntry.js +14 -0
  13. package/dist-es/s3-express/classes/S3ExpressIdentityProviderImpl.js +49 -0
  14. package/dist-es/s3-express/classes/SignatureV4S3Express.js +41 -0
  15. package/dist-es/s3-express/constants.js +13 -0
  16. package/dist-es/s3-express/functions/s3ExpressHttpSigningMiddleware.js +38 -0
  17. package/dist-es/s3-express/functions/s3ExpressMiddleware.js +41 -0
  18. package/dist-es/s3-express/functions/signS3Express.js +7 -0
  19. package/dist-es/s3-express/index.js +7 -0
  20. package/dist-es/s3-express/interfaces/S3ExpressIdentity.js +1 -0
  21. package/dist-es/s3-express/interfaces/S3ExpressIdentityProvider.js +1 -0
  22. package/dist-es/s3Configuration.js +17 -0
  23. package/dist-es/throw-200-exceptions.js +67 -0
  24. package/dist-es/validate-bucket-name.js +25 -0
  25. package/dist-types/bucket-endpoint-middleware.d.ts +13 -0
  26. package/dist-types/check-content-length-header.d.ts +16 -0
  27. package/dist-types/index.d.ts +8 -0
  28. package/dist-types/region-redirect-endpoint-middleware.d.ts +10 -0
  29. package/dist-types/region-redirect-middleware.d.ts +20 -0
  30. package/dist-types/s3-expires-middleware.d.ts +26 -0
  31. package/dist-types/s3-express/classes/S3ExpressIdentityCache.d.ts +16 -0
  32. package/dist-types/s3-express/classes/S3ExpressIdentityCacheEntry.d.ts +16 -0
  33. package/dist-types/s3-express/classes/S3ExpressIdentityProviderImpl.d.ts +32 -0
  34. package/dist-types/s3-express/classes/SignatureV4S3Express.d.ts +17 -0
  35. package/dist-types/s3-express/constants.d.ts +37 -0
  36. package/dist-types/s3-express/functions/s3ExpressHttpSigningMiddleware.d.ts +27 -0
  37. package/dist-types/s3-express/functions/s3ExpressMiddleware.d.ts +32 -0
  38. package/dist-types/s3-express/functions/signS3Express.d.ts +9 -0
  39. package/dist-types/s3-express/index.d.ts +9 -0
  40. package/dist-types/s3-express/interfaces/S3ExpressIdentity.d.ts +6 -0
  41. package/dist-types/s3-express/interfaces/S3ExpressIdentityProvider.d.ts +12 -0
  42. package/dist-types/s3Configuration.d.ts +79 -0
  43. package/dist-types/throw-200-exceptions.d.ts +20 -0
  44. package/dist-types/ts3.4/bucket-endpoint-middleware.d.ts +9 -0
  45. package/dist-types/ts3.4/check-content-length-header.d.ts +13 -0
  46. package/dist-types/ts3.4/index.d.ts +8 -0
  47. package/dist-types/ts3.4/region-redirect-endpoint-middleware.d.ts +6 -0
  48. package/dist-types/ts3.4/region-redirect-middleware.d.ts +17 -0
  49. package/dist-types/ts3.4/s3-expires-middleware.d.ts +14 -0
  50. package/dist-types/ts3.4/s3-express/classes/S3ExpressIdentityCache.d.ts +14 -0
  51. package/dist-types/ts3.4/s3-express/classes/S3ExpressIdentityCacheEntry.d.ts +12 -0
  52. package/dist-types/ts3.4/s3-express/classes/S3ExpressIdentityProviderImpl.d.ts +31 -0
  53. package/dist-types/ts3.4/s3-express/classes/SignatureV4S3Express.d.ts +19 -0
  54. package/dist-types/ts3.4/s3-express/constants.d.ts +11 -0
  55. package/dist-types/ts3.4/s3-express/functions/s3ExpressHttpSigningMiddleware.d.ts +40 -0
  56. package/dist-types/ts3.4/s3-express/functions/s3ExpressMiddleware.d.ts +27 -0
  57. package/dist-types/ts3.4/s3-express/functions/signS3Express.d.ts +21 -0
  58. package/dist-types/ts3.4/s3-express/index.d.ts +17 -0
  59. package/dist-types/ts3.4/s3-express/interfaces/S3ExpressIdentity.d.ts +2 -0
  60. package/dist-types/ts3.4/s3-express/interfaces/S3ExpressIdentityProvider.d.ts +8 -0
  61. package/dist-types/ts3.4/s3Configuration.d.ts +33 -0
  62. package/dist-types/ts3.4/throw-200-exceptions.d.ts +17 -0
  63. package/dist-types/ts3.4/validate-bucket-name.d.ts +13 -0
  64. package/dist-types/validate-bucket-name.d.ts +14 -0
  65. package/package.json +106 -0
@@ -0,0 +1,42 @@
1
+ import { regionRedirectEndpointMiddleware, regionRedirectEndpointMiddlewareOptions, } from "./region-redirect-endpoint-middleware";
2
+ export function regionRedirectMiddleware(clientConfig) {
3
+ return (next, context) => async (args) => {
4
+ try {
5
+ return await next(args);
6
+ }
7
+ catch (err) {
8
+ if (clientConfig.followRegionRedirects) {
9
+ const statusCode = err?.$metadata?.httpStatusCode;
10
+ const isHeadBucket = context.commandName === "HeadBucketCommand";
11
+ const bucketRegionHeader = err?.$response?.headers?.["x-amz-bucket-region"];
12
+ if (bucketRegionHeader) {
13
+ if (statusCode === 301 ||
14
+ (statusCode === 400 && (err?.name === "IllegalLocationConstraintException" || isHeadBucket))) {
15
+ try {
16
+ const actualRegion = bucketRegionHeader;
17
+ context.logger?.debug(`Redirecting from ${await clientConfig.region()} to ${actualRegion}`);
18
+ context.__s3RegionRedirect = actualRegion;
19
+ }
20
+ catch (e) {
21
+ throw new Error("Region redirect failed: " + e);
22
+ }
23
+ return next(args);
24
+ }
25
+ }
26
+ }
27
+ throw err;
28
+ }
29
+ };
30
+ }
31
+ export const regionRedirectMiddlewareOptions = {
32
+ step: "initialize",
33
+ tags: ["REGION_REDIRECT", "S3"],
34
+ name: "regionRedirectMiddleware",
35
+ override: true,
36
+ };
37
+ export const getRegionRedirectMiddlewarePlugin = (clientConfig) => ({
38
+ applyToStack: (clientStack) => {
39
+ clientStack.add(regionRedirectMiddleware(clientConfig), regionRedirectMiddlewareOptions);
40
+ clientStack.addRelativeTo(regionRedirectEndpointMiddleware(clientConfig), regionRedirectEndpointMiddlewareOptions);
41
+ },
42
+ });
@@ -0,0 +1,33 @@
1
+ import { HttpResponse } from "@smithy/protocol-http";
2
+ import { parseRfc7231DateTime } from "@smithy/smithy-client";
3
+ export const s3ExpiresMiddleware = (config) => {
4
+ return (next, context) => async (args) => {
5
+ const result = await next(args);
6
+ const { response } = result;
7
+ if (HttpResponse.isInstance(response)) {
8
+ if (response.headers.expires) {
9
+ response.headers.expiresstring = response.headers.expires;
10
+ try {
11
+ parseRfc7231DateTime(response.headers.expires);
12
+ }
13
+ catch (e) {
14
+ context.logger?.warn(`AWS SDK Warning for ${context.clientName}::${context.commandName} response parsing (${response.headers.expires}): ${e}`);
15
+ delete response.headers.expires;
16
+ }
17
+ }
18
+ }
19
+ return result;
20
+ };
21
+ };
22
+ export const s3ExpiresMiddlewareOptions = {
23
+ tags: ["S3"],
24
+ name: "s3ExpiresMiddleware",
25
+ override: true,
26
+ relation: "after",
27
+ toMiddleware: "deserializerMiddleware",
28
+ };
29
+ export const getS3ExpiresMiddlewarePlugin = (clientConfig) => ({
30
+ applyToStack: (clientStack) => {
31
+ clientStack.addRelativeTo(s3ExpiresMiddleware(clientConfig), s3ExpiresMiddlewareOptions);
32
+ },
33
+ });
@@ -0,0 +1,39 @@
1
+ export class S3ExpressIdentityCache {
2
+ data;
3
+ lastPurgeTime = Date.now();
4
+ static EXPIRED_CREDENTIAL_PURGE_INTERVAL_MS = 30_000;
5
+ constructor(data = {}) {
6
+ this.data = data;
7
+ }
8
+ get(key) {
9
+ const entry = this.data[key];
10
+ if (!entry) {
11
+ return;
12
+ }
13
+ return entry;
14
+ }
15
+ set(key, entry) {
16
+ this.data[key] = entry;
17
+ return entry;
18
+ }
19
+ delete(key) {
20
+ delete this.data[key];
21
+ }
22
+ async purgeExpired() {
23
+ const now = Date.now();
24
+ if (this.lastPurgeTime + S3ExpressIdentityCache.EXPIRED_CREDENTIAL_PURGE_INTERVAL_MS > now) {
25
+ return;
26
+ }
27
+ for (const key in this.data) {
28
+ const entry = this.data[key];
29
+ if (!entry.isRefreshing) {
30
+ const credential = await entry.identity;
31
+ if (credential.expiration) {
32
+ if (credential.expiration.getTime() < now) {
33
+ delete this.data[key];
34
+ }
35
+ }
36
+ }
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,14 @@
1
+ export class S3ExpressIdentityCacheEntry {
2
+ _identity;
3
+ isRefreshing;
4
+ accessed;
5
+ constructor(_identity, isRefreshing = false, accessed = Date.now()) {
6
+ this._identity = _identity;
7
+ this.isRefreshing = isRefreshing;
8
+ this.accessed = accessed;
9
+ }
10
+ get identity() {
11
+ this.accessed = Date.now();
12
+ return this._identity;
13
+ }
14
+ }
@@ -0,0 +1,49 @@
1
+ import { S3ExpressIdentityCache } from "./S3ExpressIdentityCache";
2
+ import { S3ExpressIdentityCacheEntry } from "./S3ExpressIdentityCacheEntry";
3
+ export class S3ExpressIdentityProviderImpl {
4
+ createSessionFn;
5
+ cache;
6
+ static REFRESH_WINDOW_MS = 60_000;
7
+ constructor(createSessionFn, cache = new S3ExpressIdentityCache()) {
8
+ this.createSessionFn = createSessionFn;
9
+ this.cache = cache;
10
+ }
11
+ async getS3ExpressIdentity(awsIdentity, identityProperties) {
12
+ const key = identityProperties.Bucket;
13
+ const { cache } = this;
14
+ const entry = cache.get(key);
15
+ if (entry) {
16
+ return entry.identity.then((identity) => {
17
+ const isExpired = (identity.expiration?.getTime() ?? 0) < Date.now();
18
+ if (isExpired) {
19
+ return cache.set(key, new S3ExpressIdentityCacheEntry(this.getIdentity(key))).identity;
20
+ }
21
+ const isExpiringSoon = (identity.expiration?.getTime() ?? 0) < Date.now() + S3ExpressIdentityProviderImpl.REFRESH_WINDOW_MS;
22
+ if (isExpiringSoon && !entry.isRefreshing) {
23
+ entry.isRefreshing = true;
24
+ this.getIdentity(key).then((id) => {
25
+ cache.set(key, new S3ExpressIdentityCacheEntry(Promise.resolve(id)));
26
+ });
27
+ }
28
+ return identity;
29
+ });
30
+ }
31
+ return cache.set(key, new S3ExpressIdentityCacheEntry(this.getIdentity(key))).identity;
32
+ }
33
+ async getIdentity(key) {
34
+ await this.cache.purgeExpired().catch((error) => {
35
+ console.warn("Error while clearing expired entries in S3ExpressIdentityCache: \n" + error);
36
+ });
37
+ const session = await this.createSessionFn(key);
38
+ if (!session.Credentials?.AccessKeyId || !session.Credentials?.SecretAccessKey) {
39
+ throw new Error("s3#createSession response credential missing AccessKeyId or SecretAccessKey.");
40
+ }
41
+ const identity = {
42
+ accessKeyId: session.Credentials.AccessKeyId,
43
+ secretAccessKey: session.Credentials.SecretAccessKey,
44
+ sessionToken: session.Credentials.SessionToken,
45
+ expiration: session.Credentials.Expiration ? new Date(session.Credentials.Expiration) : undefined,
46
+ };
47
+ return identity;
48
+ }
49
+ }
@@ -0,0 +1,41 @@
1
+ import { SignatureV4 } from "@smithy/signature-v4";
2
+ import { SESSION_TOKEN_HEADER, SESSION_TOKEN_QUERY_PARAM } from "../constants";
3
+ export class SignatureV4S3Express extends SignatureV4 {
4
+ async signWithCredentials(requestToSign, credentials, options) {
5
+ const credentialsWithoutSessionToken = getCredentialsWithoutSessionToken(credentials);
6
+ requestToSign.headers[SESSION_TOKEN_HEADER] = credentials.sessionToken;
7
+ const privateAccess = this;
8
+ setSingleOverride(privateAccess, credentialsWithoutSessionToken);
9
+ return privateAccess.signRequest(requestToSign, options ?? {});
10
+ }
11
+ async presignWithCredentials(requestToSign, credentials, options) {
12
+ const credentialsWithoutSessionToken = getCredentialsWithoutSessionToken(credentials);
13
+ delete requestToSign.headers[SESSION_TOKEN_HEADER];
14
+ requestToSign.headers[SESSION_TOKEN_QUERY_PARAM] = credentials.sessionToken;
15
+ requestToSign.query = requestToSign.query ?? {};
16
+ requestToSign.query[SESSION_TOKEN_QUERY_PARAM] = credentials.sessionToken;
17
+ const privateAccess = this;
18
+ setSingleOverride(privateAccess, credentialsWithoutSessionToken);
19
+ return this.presign(requestToSign, options);
20
+ }
21
+ }
22
+ function getCredentialsWithoutSessionToken(credentials) {
23
+ const credentialsWithoutSessionToken = {
24
+ accessKeyId: credentials.accessKeyId,
25
+ secretAccessKey: credentials.secretAccessKey,
26
+ expiration: credentials.expiration,
27
+ };
28
+ return credentialsWithoutSessionToken;
29
+ }
30
+ function setSingleOverride(privateAccess, credentialsWithoutSessionToken) {
31
+ const id = setTimeout(() => {
32
+ throw new Error("SignatureV4S3Express credential override was created but not called.");
33
+ }, 10);
34
+ const currentCredentialProvider = privateAccess.credentialProvider;
35
+ const overrideCredentialsProviderOnce = () => {
36
+ clearTimeout(id);
37
+ privateAccess.credentialProvider = currentCredentialProvider;
38
+ return Promise.resolve(credentialsWithoutSessionToken);
39
+ };
40
+ privateAccess.credentialProvider = overrideCredentialsProviderOnce;
41
+ }
@@ -0,0 +1,13 @@
1
+ import { booleanSelector, SelectorType } from "@smithy/util-config-provider";
2
+ export const S3_EXPRESS_BUCKET_TYPE = "Directory";
3
+ export const S3_EXPRESS_BACKEND = "S3Express";
4
+ export const S3_EXPRESS_AUTH_SCHEME = "sigv4-s3express";
5
+ export const SESSION_TOKEN_QUERY_PARAM = "X-Amz-S3session-Token";
6
+ export const SESSION_TOKEN_HEADER = SESSION_TOKEN_QUERY_PARAM.toLowerCase();
7
+ export const NODE_DISABLE_S3_EXPRESS_SESSION_AUTH_ENV_NAME = "AWS_S3_DISABLE_EXPRESS_SESSION_AUTH";
8
+ export const NODE_DISABLE_S3_EXPRESS_SESSION_AUTH_INI_NAME = "s3_disable_express_session_auth";
9
+ export const NODE_DISABLE_S3_EXPRESS_SESSION_AUTH_OPTIONS = {
10
+ environmentVariableSelector: (env) => booleanSelector(env, NODE_DISABLE_S3_EXPRESS_SESSION_AUTH_ENV_NAME, SelectorType.ENV),
11
+ configFileSelector: (profile) => booleanSelector(profile, NODE_DISABLE_S3_EXPRESS_SESSION_AUTH_INI_NAME, SelectorType.CONFIG),
12
+ default: false,
13
+ };
@@ -0,0 +1,38 @@
1
+ import { httpSigningMiddlewareOptions } from "@smithy/core";
2
+ import { HttpRequest } from "@smithy/protocol-http";
3
+ import { getSmithyContext } from "@smithy/util-middleware";
4
+ import { signS3Express } from "./signS3Express";
5
+ const defaultErrorHandler = (signingProperties) => (error) => {
6
+ throw error;
7
+ };
8
+ const defaultSuccessHandler = (httpResponse, signingProperties) => { };
9
+ export const s3ExpressHttpSigningMiddlewareOptions = httpSigningMiddlewareOptions;
10
+ export const s3ExpressHttpSigningMiddleware = (config) => (next, context) => async (args) => {
11
+ if (!HttpRequest.isInstance(args.request)) {
12
+ return next(args);
13
+ }
14
+ const smithyContext = getSmithyContext(context);
15
+ const scheme = smithyContext.selectedHttpAuthScheme;
16
+ if (!scheme) {
17
+ throw new Error(`No HttpAuthScheme was selected: unable to sign request`);
18
+ }
19
+ const { httpAuthOption: { signingProperties = {} }, identity, signer, } = scheme;
20
+ let request;
21
+ if (context.s3ExpressIdentity) {
22
+ request = await signS3Express(context.s3ExpressIdentity, signingProperties, args.request, await config.signer());
23
+ }
24
+ else {
25
+ request = await signer.sign(args.request, identity, signingProperties);
26
+ }
27
+ const output = await next({
28
+ ...args,
29
+ request,
30
+ }).catch((signer.errorHandler || defaultErrorHandler)(signingProperties));
31
+ (signer.successHandler || defaultSuccessHandler)(output.response, signingProperties);
32
+ return output;
33
+ };
34
+ export const getS3ExpressHttpSigningPlugin = (config) => ({
35
+ applyToStack: (clientStack) => {
36
+ clientStack.addRelativeTo(s3ExpressHttpSigningMiddleware(config), httpSigningMiddlewareOptions);
37
+ },
38
+ });
@@ -0,0 +1,41 @@
1
+ import { setFeature } from "@aws-sdk/core";
2
+ import { HttpRequest } from "@smithy/protocol-http";
3
+ import { S3_EXPRESS_AUTH_SCHEME, S3_EXPRESS_BACKEND, S3_EXPRESS_BUCKET_TYPE, SESSION_TOKEN_HEADER } from "../constants";
4
+ export const s3ExpressMiddleware = (options) => {
5
+ return (next, context) => async (args) => {
6
+ if (context.endpointV2) {
7
+ const endpoint = context.endpointV2;
8
+ const isS3ExpressAuth = endpoint.properties?.authSchemes?.[0]?.name === S3_EXPRESS_AUTH_SCHEME;
9
+ const isS3ExpressBucket = endpoint.properties?.backend === S3_EXPRESS_BACKEND ||
10
+ endpoint.properties?.bucketType === S3_EXPRESS_BUCKET_TYPE;
11
+ if (isS3ExpressBucket) {
12
+ setFeature(context, "S3_EXPRESS_BUCKET", "J");
13
+ context.isS3ExpressBucket = true;
14
+ }
15
+ if (isS3ExpressAuth) {
16
+ const requestBucket = args.input.Bucket;
17
+ if (requestBucket) {
18
+ const s3ExpressIdentity = await options.s3ExpressIdentityProvider.getS3ExpressIdentity(await options.credentials(), {
19
+ Bucket: requestBucket,
20
+ });
21
+ context.s3ExpressIdentity = s3ExpressIdentity;
22
+ if (HttpRequest.isInstance(args.request) && s3ExpressIdentity.sessionToken) {
23
+ args.request.headers[SESSION_TOKEN_HEADER] = s3ExpressIdentity.sessionToken;
24
+ }
25
+ }
26
+ }
27
+ }
28
+ return next(args);
29
+ };
30
+ };
31
+ export const s3ExpressMiddlewareOptions = {
32
+ name: "s3ExpressMiddleware",
33
+ step: "build",
34
+ tags: ["S3", "S3_EXPRESS"],
35
+ override: true,
36
+ };
37
+ export const getS3ExpressPlugin = (options) => ({
38
+ applyToStack: (clientStack) => {
39
+ clientStack.add(s3ExpressMiddleware(options), s3ExpressMiddlewareOptions);
40
+ },
41
+ });
@@ -0,0 +1,7 @@
1
+ export const signS3Express = async (s3ExpressIdentity, signingOptions, request, sigV4MultiRegionSigner) => {
2
+ const signedRequest = await sigV4MultiRegionSigner.signWithCredentials(request, s3ExpressIdentity, {});
3
+ if (signedRequest.headers["X-Amz-Security-Token"] || signedRequest.headers["x-amz-security-token"]) {
4
+ throw new Error("X-Amz-Security-Token must not be set for s3-express requests.");
5
+ }
6
+ return signedRequest;
7
+ };
@@ -0,0 +1,7 @@
1
+ export { S3ExpressIdentityCache } from "./classes/S3ExpressIdentityCache";
2
+ export { S3ExpressIdentityCacheEntry } from "./classes/S3ExpressIdentityCacheEntry";
3
+ export { S3ExpressIdentityProviderImpl } from "./classes/S3ExpressIdentityProviderImpl";
4
+ export { SignatureV4S3Express } from "./classes/SignatureV4S3Express";
5
+ export { NODE_DISABLE_S3_EXPRESS_SESSION_AUTH_OPTIONS } from "./constants";
6
+ export { getS3ExpressPlugin, s3ExpressMiddleware, s3ExpressMiddlewareOptions } from "./functions/s3ExpressMiddleware";
7
+ export { getS3ExpressHttpSigningPlugin, s3ExpressHttpSigningMiddleware, s3ExpressHttpSigningMiddlewareOptions, } from "./functions/s3ExpressHttpSigningMiddleware";
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ import { S3ExpressIdentityProviderImpl } from "./s3-express";
2
+ export const resolveS3Config = (input, { session, }) => {
3
+ const [s3ClientProvider, CreateSessionCommandCtor] = session;
4
+ const { forcePathStyle, useAccelerateEndpoint, disableMultiregionAccessPoints, followRegionRedirects, s3ExpressIdentityProvider, bucketEndpoint, expectContinueHeader, } = input;
5
+ return Object.assign(input, {
6
+ forcePathStyle: forcePathStyle ?? false,
7
+ useAccelerateEndpoint: useAccelerateEndpoint ?? false,
8
+ disableMultiregionAccessPoints: disableMultiregionAccessPoints ?? false,
9
+ followRegionRedirects: followRegionRedirects ?? false,
10
+ s3ExpressIdentityProvider: s3ExpressIdentityProvider ??
11
+ new S3ExpressIdentityProviderImpl(async (key) => s3ClientProvider().send(new CreateSessionCommandCtor({
12
+ Bucket: key,
13
+ }))),
14
+ bucketEndpoint: bucketEndpoint ?? false,
15
+ expectContinueHeader: expectContinueHeader ?? 2_097_152,
16
+ });
17
+ };
@@ -0,0 +1,67 @@
1
+ import { HttpResponse } from "@smithy/protocol-http";
2
+ import { headStream, splitStream } from "@smithy/util-stream";
3
+ const THROW_IF_EMPTY_BODY = {
4
+ CopyObjectCommand: true,
5
+ UploadPartCopyCommand: true,
6
+ CompleteMultipartUploadCommand: true,
7
+ };
8
+ const MAX_BYTES_TO_INSPECT = 3000;
9
+ export const throw200ExceptionsMiddleware = (config) => (next, context) => async (args) => {
10
+ const result = await next(args);
11
+ const { response } = result;
12
+ if (!HttpResponse.isInstance(response)) {
13
+ return result;
14
+ }
15
+ const { statusCode, body: sourceBody } = response;
16
+ if (statusCode < 200 || statusCode >= 300) {
17
+ return result;
18
+ }
19
+ const isSplittableStream = typeof sourceBody?.stream === "function" ||
20
+ typeof sourceBody?.pipe === "function" ||
21
+ typeof sourceBody?.tee === "function";
22
+ if (!isSplittableStream) {
23
+ return result;
24
+ }
25
+ let bodyCopy = sourceBody;
26
+ let body = sourceBody;
27
+ if (sourceBody && typeof sourceBody === "object" && !(sourceBody instanceof Uint8Array)) {
28
+ [bodyCopy, body] = await splitStream(sourceBody);
29
+ }
30
+ response.body = body;
31
+ const bodyBytes = await collectBody(bodyCopy, {
32
+ streamCollector: async (stream) => {
33
+ return headStream(stream, MAX_BYTES_TO_INSPECT);
34
+ },
35
+ });
36
+ if (typeof bodyCopy?.destroy === "function") {
37
+ bodyCopy.destroy();
38
+ }
39
+ const bodyStringTail = config.utf8Encoder(bodyBytes.subarray(bodyBytes.length - 16));
40
+ if (bodyBytes.length === 0 && THROW_IF_EMPTY_BODY[context.commandName]) {
41
+ const err = new Error("S3 aborted request");
42
+ err.name = "InternalError";
43
+ throw err;
44
+ }
45
+ if (bodyStringTail && bodyStringTail.endsWith("</Error>")) {
46
+ response.statusCode = 400;
47
+ }
48
+ return result;
49
+ };
50
+ const collectBody = (streamBody = new Uint8Array(), context) => {
51
+ if (streamBody instanceof Uint8Array) {
52
+ return Promise.resolve(streamBody);
53
+ }
54
+ return context.streamCollector(streamBody) || Promise.resolve(new Uint8Array());
55
+ };
56
+ export const throw200ExceptionsMiddlewareOptions = {
57
+ relation: "after",
58
+ toMiddleware: "deserializerMiddleware",
59
+ tags: ["THROW_200_EXCEPTIONS", "S3"],
60
+ name: "throw200ExceptionsMiddleware",
61
+ override: true,
62
+ };
63
+ export const getThrow200ExceptionsPlugin = (config) => ({
64
+ applyToStack: (clientStack) => {
65
+ clientStack.addRelativeTo(throw200ExceptionsMiddleware(config), throw200ExceptionsMiddlewareOptions);
66
+ },
67
+ });
@@ -0,0 +1,25 @@
1
+ import { validate as validateArn } from "@aws-sdk/util-arn-parser";
2
+ import { bucketEndpointMiddleware, bucketEndpointMiddlewareOptions } from "./bucket-endpoint-middleware";
3
+ export function validateBucketNameMiddleware({ bucketEndpoint }) {
4
+ return (next) => async (args) => {
5
+ const { input: { Bucket }, } = args;
6
+ if (!bucketEndpoint && typeof Bucket === "string" && !validateArn(Bucket) && Bucket.indexOf("/") >= 0) {
7
+ const err = new Error(`Bucket name shouldn't contain '/', received '${Bucket}'`);
8
+ err.name = "InvalidBucketName";
9
+ throw err;
10
+ }
11
+ return next({ ...args });
12
+ };
13
+ }
14
+ export const validateBucketNameMiddlewareOptions = {
15
+ step: "initialize",
16
+ tags: ["VALIDATE_BUCKET_NAME"],
17
+ name: "validateBucketNameMiddleware",
18
+ override: true,
19
+ };
20
+ export const getValidateBucketNamePlugin = (options) => ({
21
+ applyToStack: (clientStack) => {
22
+ clientStack.add(validateBucketNameMiddleware(options), validateBucketNameMiddlewareOptions);
23
+ clientStack.addRelativeTo(bucketEndpointMiddleware(options), bucketEndpointMiddlewareOptions);
24
+ },
25
+ });
@@ -0,0 +1,13 @@
1
+ import type { RelativeMiddlewareOptions, SerializeMiddleware } from "@smithy/types";
2
+ interface PreviouslyResolved {
3
+ bucketEndpoint?: boolean;
4
+ }
5
+ /**
6
+ * @internal
7
+ */
8
+ export declare function bucketEndpointMiddleware(options: PreviouslyResolved): SerializeMiddleware<any, any>;
9
+ /**
10
+ * @internal
11
+ */
12
+ export declare const bucketEndpointMiddlewareOptions: RelativeMiddlewareOptions;
13
+ export {};
@@ -0,0 +1,16 @@
1
+ import type { FinalizeRequestHandlerOptions, FinalizeRequestMiddleware, Pluggable } from "@smithy/types";
2
+ /**
3
+ * @internal
4
+ *
5
+ * Log a warning if the input to PutObject is detected to be a Stream of unknown ContentLength and
6
+ * recommend the usage of the @aws-sdk/lib-storage Upload class.
7
+ */
8
+ export declare function checkContentLengthHeader(): FinalizeRequestMiddleware<any, any>;
9
+ /**
10
+ * @internal
11
+ */
12
+ export declare const checkContentLengthHeaderMiddlewareOptions: FinalizeRequestHandlerOptions;
13
+ /**
14
+ * @internal
15
+ */
16
+ export declare const getCheckContentLengthHeaderPlugin: (unused: any) => Pluggable<any, any>;
@@ -0,0 +1,8 @@
1
+ export * from "./check-content-length-header";
2
+ export * from "./region-redirect-endpoint-middleware";
3
+ export * from "./region-redirect-middleware";
4
+ export * from "./s3-expires-middleware";
5
+ export * from "./s3-express/index";
6
+ export * from "./s3Configuration";
7
+ export * from "./throw-200-exceptions";
8
+ export * from "./validate-bucket-name";
@@ -0,0 +1,10 @@
1
+ import type { RelativeMiddlewareOptions, SerializeMiddleware } from "@smithy/types";
2
+ import type { PreviouslyResolved } from "./region-redirect-middleware";
3
+ /**
4
+ * @internal
5
+ */
6
+ export declare const regionRedirectEndpointMiddleware: (config: PreviouslyResolved) => SerializeMiddleware<any, any>;
7
+ /**
8
+ * @internal
9
+ */
10
+ export declare const regionRedirectEndpointMiddlewareOptions: RelativeMiddlewareOptions;
@@ -0,0 +1,20 @@
1
+ import type { InitializeHandlerOptions, InitializeMiddleware, Pluggable, Provider } from "@smithy/types";
2
+ /**
3
+ * @internal
4
+ */
5
+ export interface PreviouslyResolved {
6
+ region: Provider<string>;
7
+ followRegionRedirects: boolean;
8
+ }
9
+ /**
10
+ * @internal
11
+ */
12
+ export declare function regionRedirectMiddleware(clientConfig: PreviouslyResolved): InitializeMiddleware<any, any>;
13
+ /**
14
+ * @internal
15
+ */
16
+ export declare const regionRedirectMiddlewareOptions: InitializeHandlerOptions;
17
+ /**
18
+ * @internal
19
+ */
20
+ export declare const getRegionRedirectMiddlewarePlugin: (clientConfig: PreviouslyResolved) => Pluggable<any, any>;
@@ -0,0 +1,26 @@
1
+ import type { DeserializeMiddleware, Pluggable, RelativeMiddlewareOptions } from "@smithy/types";
2
+ /**
3
+ * @internal
4
+ */
5
+ interface PreviouslyResolved {
6
+ }
7
+ /**
8
+ * @internal
9
+ *
10
+ * From the S3 Expires compatibility spec.
11
+ * A model transform will ensure S3#Expires remains a timestamp shape, though
12
+ * it is deprecated.
13
+ * If a particular object has a non-date string set as the Expires value,
14
+ * the SDK will have the raw string as "ExpiresString" on the response.
15
+ *
16
+ */
17
+ export declare const s3ExpiresMiddleware: (config: PreviouslyResolved) => DeserializeMiddleware<any, any>;
18
+ /**
19
+ * @internal
20
+ */
21
+ export declare const s3ExpiresMiddlewareOptions: RelativeMiddlewareOptions;
22
+ /**
23
+ * @internal
24
+ */
25
+ export declare const getS3ExpiresMiddlewarePlugin: (clientConfig: PreviouslyResolved) => Pluggable<any, any>;
26
+ export {};
@@ -0,0 +1,16 @@
1
+ import type { S3ExpressIdentityCacheEntry } from "./S3ExpressIdentityCacheEntry";
2
+ /**
3
+ * @internal
4
+ *
5
+ * Stores identities by key.
6
+ */
7
+ export declare class S3ExpressIdentityCache {
8
+ private data;
9
+ private lastPurgeTime;
10
+ static EXPIRED_CREDENTIAL_PURGE_INTERVAL_MS: number;
11
+ constructor(data?: Record<string, S3ExpressIdentityCacheEntry>);
12
+ get(key: string): undefined | S3ExpressIdentityCacheEntry;
13
+ set(key: string, entry: S3ExpressIdentityCacheEntry): S3ExpressIdentityCacheEntry;
14
+ delete(key: string): void;
15
+ purgeExpired(): Promise<void>;
16
+ }
@@ -0,0 +1,16 @@
1
+ import type { S3ExpressIdentity } from "../interfaces/S3ExpressIdentity";
2
+ /**
3
+ * @internal
4
+ */
5
+ export declare class S3ExpressIdentityCacheEntry {
6
+ private _identity;
7
+ isRefreshing: boolean;
8
+ accessed: number;
9
+ /**
10
+ * @param identity - stored identity.
11
+ * @param accessed - timestamp of last access in epoch ms.
12
+ * @param isRefreshing - this key is currently in the process of being refreshed (background).
13
+ */
14
+ constructor(_identity: Promise<S3ExpressIdentity>, isRefreshing?: boolean, accessed?: number);
15
+ get identity(): Promise<S3ExpressIdentity>;
16
+ }
@@ -0,0 +1,32 @@
1
+ import type { AwsCredentialIdentity } from "@aws-sdk/types";
2
+ import type { S3ExpressIdentity } from "../interfaces/S3ExpressIdentity";
3
+ import type { S3ExpressIdentityProvider } from "../interfaces/S3ExpressIdentityProvider";
4
+ import { S3ExpressIdentityCache } from "./S3ExpressIdentityCache";
5
+ /**
6
+ * @internal
7
+ *
8
+ * This should match S3::CreateSessionCommandOutput::SessionCredentials
9
+ * but it is not imported since that would create a circular dependency.
10
+ */
11
+ type Credentials = {
12
+ AccessKeyId: string | undefined;
13
+ SecretAccessKey: string | undefined;
14
+ SessionToken: string | undefined;
15
+ Expiration: Date | undefined;
16
+ };
17
+ /**
18
+ * @internal
19
+ */
20
+ export declare class S3ExpressIdentityProviderImpl implements S3ExpressIdentityProvider {
21
+ private createSessionFn;
22
+ private cache;
23
+ static REFRESH_WINDOW_MS: number;
24
+ constructor(createSessionFn: (key: string) => Promise<{
25
+ Credentials: Credentials;
26
+ }>, cache?: S3ExpressIdentityCache);
27
+ getS3ExpressIdentity(awsIdentity: AwsCredentialIdentity, identityProperties: {
28
+ Bucket: string;
29
+ } & Record<string, string>): Promise<S3ExpressIdentity>;
30
+ private getIdentity;
31
+ }
32
+ export {};
@@ -0,0 +1,17 @@
1
+ import type { AwsCredentialIdentity } from "@aws-sdk/types";
2
+ import { SignatureV4 } from "@smithy/signature-v4";
3
+ import type { HttpRequest as IHttpRequest, RequestPresigningArguments, RequestSigningArguments } from "@smithy/types";
4
+ export declare class SignatureV4S3Express extends SignatureV4 {
5
+ /**
6
+ * Signs with alternate provided credentials instead of those provided in the
7
+ * constructor.
8
+ *
9
+ * Additionally omits the credential sessionToken and assigns it to the
10
+ * alternate header field for S3 Express.
11
+ */
12
+ signWithCredentials(requestToSign: IHttpRequest, credentials: AwsCredentialIdentity, options?: RequestSigningArguments): Promise<IHttpRequest>;
13
+ /**
14
+ * Similar to {@link SignatureV4S3Express#signWithCredentials} but for presigning.
15
+ */
16
+ presignWithCredentials(requestToSign: IHttpRequest, credentials: AwsCredentialIdentity, options?: RequestPresigningArguments): Promise<IHttpRequest>;
17
+ }