diff --git a/clients/client-s3-control/src/S3ControlClient.ts b/clients/client-s3-control/src/S3ControlClient.ts index d4aaf8afc24a..f84075f8aa95 100644 --- a/clients/client-s3-control/src/S3ControlClient.ts +++ b/clients/client-s3-control/src/S3ControlClient.ts @@ -12,6 +12,7 @@ import { getLoggerPlugin } from "@aws-sdk/middleware-logger"; import { getRecursionDetectionPlugin } from "@aws-sdk/middleware-recursion-detection"; import { getRetryPlugin, resolveRetryConfig, RetryInputConfig, RetryResolvedConfig } from "@aws-sdk/middleware-retry"; import { + getHostPrefixDeduplicationPlugin, resolveS3ControlConfig, S3ControlInputConfig, S3ControlResolvedConfig, @@ -569,6 +570,7 @@ export class S3ControlClient extends __Client< this.middlewareStack.use(getLoggerPlugin(this.config)); this.middlewareStack.use(getRecursionDetectionPlugin(this.config)); this.middlewareStack.use(getAwsAuthPlugin(this.config)); + this.middlewareStack.use(getHostPrefixDeduplicationPlugin(this.config)); this.middlewareStack.use(getUserAgentPlugin(this.config)); } diff --git a/clients/client-s3/src/commands/CreateBucketCommand.ts b/clients/client-s3/src/commands/CreateBucketCommand.ts index c53fb445720d..0354e6d65b4c 100644 --- a/clients/client-s3/src/commands/CreateBucketCommand.ts +++ b/clients/client-s3/src/commands/CreateBucketCommand.ts @@ -202,6 +202,7 @@ export class CreateBucketCommand extends $Command< public static getEndpointParameterInstructions(): EndpointParameterInstructions { return { + DisableAccessPoints: { type: "staticContextParams", value: true }, Bucket: { type: "contextParams", name: "Bucket" }, ForcePathStyle: { type: "clientContextParams", name: "forcePathStyle" }, UseArnRegion: { type: "clientContextParams", name: "useArnRegion" }, diff --git a/clients/client-s3/src/commands/WriteGetObjectResponseCommand.ts b/clients/client-s3/src/commands/WriteGetObjectResponseCommand.ts index 79dfbb0b58fb..6ce9440d6150 100644 --- a/clients/client-s3/src/commands/WriteGetObjectResponseCommand.ts +++ b/clients/client-s3/src/commands/WriteGetObjectResponseCommand.ts @@ -82,6 +82,7 @@ export class WriteGetObjectResponseCommand extends $Command< public static getEndpointParameterInstructions(): EndpointParameterInstructions { return { + UseObjectLambdaEndpoint: { type: "staticContextParams", value: true }, ForcePathStyle: { type: "clientContextParams", name: "forcePathStyle" }, UseArnRegion: { type: "clientContextParams", name: "useArnRegion" }, DisableMultiRegionAccessPoints: { type: "clientContextParams", name: "disableMultiregionAccessPoints" }, diff --git a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddS3ControlDependency.java b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddS3ControlDependency.java index e9bd143ae4b4..dc15730c5bcb 100644 --- a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddS3ControlDependency.java +++ b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddS3ControlDependency.java @@ -54,6 +54,11 @@ public List getClientPlugins() { .withConventions(AwsDependency.S3_CONTROL_MIDDLEWARE.dependency, "S3Control", HAS_CONFIG) .servicePredicate((m, s) -> isS3Control(s)) .build(), + RuntimeClientPlugin.builder() + .withConventions(AwsDependency.S3_CONTROL_MIDDLEWARE.dependency, + "HostPrefixDeduplication", HAS_MIDDLEWARE) + .servicePredicate((m, s) -> isS3Control(s)) + .build(), RuntimeClientPlugin.builder() .withConventions( AwsDependency.S3_CONTROL_MIDDLEWARE.dependency, diff --git a/packages/middleware-sdk-s3-control/src/host-prefix-deduplication/deduplicateHostPrefix.spec.ts b/packages/middleware-sdk-s3-control/src/host-prefix-deduplication/deduplicateHostPrefix.spec.ts new file mode 100644 index 000000000000..a3a74c7b6cf3 --- /dev/null +++ b/packages/middleware-sdk-s3-control/src/host-prefix-deduplication/deduplicateHostPrefix.spec.ts @@ -0,0 +1,18 @@ +import { deduplicateHostPrefix } from "./deduplicateHostPrefix"; + +describe(deduplicateHostPrefix.name, () => { + it("should deduplicate host name prefixes", () => { + expect(deduplicateHostPrefix("a.a.host.com")).toEqual("a.host.com"); + expect(deduplicateHostPrefix("1234567890.1234567890.host.com")).toEqual("1234567890.host.com"); + expect(deduplicateHostPrefix("abcdefgh.abcdefgh.host.com")).toEqual("abcdefgh.host.com"); + }), + it("should do nothing if no duplication exists in the first two positions", () => { + expect(deduplicateHostPrefix("b.a.host.com")).toEqual("b.a.host.com"); + expect(deduplicateHostPrefix("0123456789.1234567890.host.com")).toEqual("0123456789.1234567890.host.com"); + expect(deduplicateHostPrefix("zabcdefg.abcdefgh.host.com")).toEqual("zabcdefg.abcdefgh.host.com"); + + expect(deduplicateHostPrefix("12345.abcdefgh.12345.12345.host.com")).toEqual( + "12345.abcdefgh.12345.12345.host.com" + ); + }); +}); diff --git a/packages/middleware-sdk-s3-control/src/host-prefix-deduplication/deduplicateHostPrefix.ts b/packages/middleware-sdk-s3-control/src/host-prefix-deduplication/deduplicateHostPrefix.ts new file mode 100644 index 000000000000..5a2559dedb3b --- /dev/null +++ b/packages/middleware-sdk-s3-control/src/host-prefix-deduplication/deduplicateHostPrefix.ts @@ -0,0 +1,11 @@ +/** + * @example + * 12345.12345.____.com should become 12345.____.com. + */ +export const deduplicateHostPrefix = (hostname: string): string => { + const [prefix1, prefix2, ...rest] = hostname.split("."); + if (prefix1 === prefix2) { + return [prefix1, ...rest].join("."); + } + return hostname; +}; diff --git a/packages/middleware-sdk-s3-control/src/host-prefix-deduplication/hostPrefixDeduplicationMiddleware.ts b/packages/middleware-sdk-s3-control/src/host-prefix-deduplication/hostPrefixDeduplicationMiddleware.ts new file mode 100644 index 000000000000..4c929546a26c --- /dev/null +++ b/packages/middleware-sdk-s3-control/src/host-prefix-deduplication/hostPrefixDeduplicationMiddleware.ts @@ -0,0 +1,52 @@ +import { + EndpointV2, + HandlerExecutionContext, + Pluggable, + RelativeMiddlewareOptions, + SerializeHandler, + SerializeHandlerArguments, + SerializeHandlerOutput, + SerializeMiddleware, +} from "@aws-sdk/types"; + +import { deduplicateHostPrefix } from "./deduplicateHostPrefix"; + +/** + * @internal + * This customization handles an edge case where + * a hostprefix may be duplicated in the endpoint ruleset resolution + * and hostPrefix serialization via the pre-endpoints 2.0 trait, + * and which cannot be reconciled automatically. + */ +export const hostPrefixDeduplicationMiddleware = (): SerializeMiddleware => { + return (next: SerializeHandler, context: HandlerExecutionContext): SerializeHandler => + async (args: SerializeHandlerArguments): Promise> => { + const endpoint: EndpointV2 | undefined = context.endpointV2; + if (endpoint?.url?.hostname) { + endpoint.url.hostname = deduplicateHostPrefix(endpoint.url.hostname); + } else { + throw new Error("Endpoint w/ url.hostname not found in hostPrefixDeduplicationMiddleware."); + } + return next(args); + }; +}; + +/** + * @internal + */ +export const hostPrefixDeduplicationMiddlewareOptions: RelativeMiddlewareOptions = { + tags: ["HOST_PREFIX_DEDUPLICATION", "ENDPOINT_V2", "ENDPOINT"], + toMiddleware: "endpointV2Middleware", + relation: "after", + name: "hostPrefixDeduplicationMiddleware", + override: true, +}; + +/** + * @internal + */ +export const getHostPrefixDeduplicationPlugin = (config?: T): Pluggable => ({ + applyToStack: (clientStack) => { + clientStack.add(hostPrefixDeduplicationMiddleware(), hostPrefixDeduplicationMiddlewareOptions); + }, +}); diff --git a/packages/middleware-sdk-s3-control/src/index.ts b/packages/middleware-sdk-s3-control/src/index.ts index b856f310168b..8320152ff69b 100644 --- a/packages/middleware-sdk-s3-control/src/index.ts +++ b/packages/middleware-sdk-s3-control/src/index.ts @@ -6,4 +6,5 @@ export { updateArnablesRequestMiddlewareOptions, getProcessArnablesPlugin, } from "./process-arnables-plugin"; +export * from "./host-prefix-deduplication/hostPrefixDeduplicationMiddleware"; export * from "./redirect-from-postid";