From 58ca4e64971433f4d9b8d13fd2cad6215b07b67f Mon Sep 17 00:00:00 2001 From: George Fu Date: Tue, 8 Oct 2024 18:23:27 +0000 Subject: [PATCH 1/3] chore(middleware-user-agent): use authScheme identity instead of credentials provider --- .../src/check-features.ts | 9 +++++++++ .../src/middleware-user-agent.integ.spec.ts | 17 +++++++++-------- .../src/user-agent-middleware.ts | 18 +++++++++--------- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/packages/middleware-user-agent/src/check-features.ts b/packages/middleware-user-agent/src/check-features.ts index 18b41d24ac4e..d76b6fceb06b 100644 --- a/packages/middleware-user-agent/src/check-features.ts +++ b/packages/middleware-user-agent/src/check-features.ts @@ -16,6 +16,11 @@ type PreviouslyResolved = Partial<{ accountIdEndpointMode?: Provider; }>; +/** + * @internal + */ +const ACCOUNT_ID_ENDPOINT_REGEX = /\d{12}\.ddb/; + /** * @internal * Check for features that don't have a middleware activation site but @@ -29,6 +34,10 @@ export async function checkFeatures( // eslint-disable-next-line const request = args.request as IHttpRequest; if (typeof config.accountIdEndpointMode === "function") { + const endpointV2 = context.endpointV2; + if (String(endpointV2?.url?.hostname).match(ACCOUNT_ID_ENDPOINT_REGEX)) { + setFeature(context, "ACCOUNT_ID_ENDPOINT", "O"); + } switch (await config.accountIdEndpointMode?.()) { case "disabled": setFeature(context, "ACCOUNT_ID_MODE_DISABLED", "Q"); diff --git a/packages/middleware-user-agent/src/middleware-user-agent.integ.spec.ts b/packages/middleware-user-agent/src/middleware-user-agent.integ.spec.ts index ca98caeec642..04ba7015c472 100644 --- a/packages/middleware-user-agent/src/middleware-user-agent.integ.spec.ts +++ b/packages/middleware-user-agent/src/middleware-user-agent.integ.spec.ts @@ -27,24 +27,25 @@ describe("middleware-user-agent", () => { }); describe("features", () => { - it("should detect DDB mapper, and account id mode", async () => { + it("should detect DDB mapper, account id, and account id mode", async () => { const client = new DynamoDB({ - credentials: { - accessKeyId: "", - secretAccessKey: "", - accountId: "123", - }, - accountIdEndpointMode: async () => "preferred" as const, + accountIdEndpointMode: async () => "required" as const, }); const doc = DynamoDBDocument.from(client); requireRequestsFrom(doc).toMatch({ headers: { - "user-agent": /(.*?) m\/d,P$/, + "user-agent": /(.*?) m\/d,O,R$/, }, }); + client.config.credentials = async () => ({ + accessKeyId: "", + secretAccessKey: "", + accountId: "123456789012", + }); + await doc.get({ TableName: "table", Key: { diff --git a/packages/middleware-user-agent/src/user-agent-middleware.ts b/packages/middleware-user-agent/src/user-agent-middleware.ts index 4438ede668d0..42c915d8526c 100644 --- a/packages/middleware-user-agent/src/user-agent-middleware.ts +++ b/packages/middleware-user-agent/src/user-agent-middleware.ts @@ -3,10 +3,10 @@ import { getUserAgentPrefix } from "@aws-sdk/util-endpoints"; import { HttpRequest } from "@smithy/protocol-http"; import { AbsoluteLocation, - BuildHandler, - BuildHandlerArguments, - BuildHandlerOptions, - BuildHandlerOutput, + FinalizeHandler, + FinalizeHandlerArguments, + FinalizeHandlerOutput, + FinalizeRequestHandlerOptions, HandlerExecutionContext, MetadataBearer, Pluggable, @@ -41,10 +41,10 @@ import { encodeFeatures } from "./encode-features"; export const userAgentMiddleware = (options: UserAgentResolvedConfig) => ( - next: BuildHandler, + next: FinalizeHandler, context: HandlerExecutionContext | AwsHandlerExecutionContext - ): BuildHandler => - async (args: BuildHandlerArguments): Promise> => { + ): FinalizeHandler => + async (args: FinalizeHandlerArguments): Promise> => { const { request } = args; if (!HttpRequest.isInstance(request)) { return next(args); @@ -130,9 +130,9 @@ const escapeUserAgent = (userAgentPair: UserAgentPair): string => { }, "") as string; }; -export const getUserAgentMiddlewareOptions: BuildHandlerOptions & AbsoluteLocation = { +export const getUserAgentMiddlewareOptions: FinalizeRequestHandlerOptions & AbsoluteLocation = { name: "getUserAgentMiddleware", - step: "build", + step: "finalizeRequest", priority: "low", tags: ["SET_USER_AGENT", "USER_AGENT"], override: true, From 4ffcd4bd7b13bfe41b9925d09f89c1c483594453 Mon Sep 17 00:00:00 2001 From: George Fu Date: Tue, 8 Oct 2024 20:03:38 +0000 Subject: [PATCH 2/3] chore: calculate user agent in websocket --- .../src/check-features.ts | 27 ++++++++++++++++++- .../src/user-agent-middleware.ts | 18 ++++++------- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/packages/middleware-user-agent/src/check-features.ts b/packages/middleware-user-agent/src/check-features.ts index d76b6fceb06b..c87cf4f00a76 100644 --- a/packages/middleware-user-agent/src/check-features.ts +++ b/packages/middleware-user-agent/src/check-features.ts @@ -6,7 +6,13 @@ import type { AwsSdkCredentialsFeatures, } from "@aws-sdk/types"; import type { IHttpRequest } from "@smithy/protocol-http"; -import type { AwsCredentialIdentityProvider, BuildHandlerArguments, Provider } from "@smithy/types"; +import type { + AwsCredentialIdentityProvider, + BuildHandlerArguments, + Provider, + RetryStrategy, + RetryStrategyV2, +} from "@smithy/types"; /** * @internal @@ -14,6 +20,7 @@ import type { AwsCredentialIdentityProvider, BuildHandlerArguments, Provider } f type PreviouslyResolved = Partial<{ credentials?: AwsCredentialIdentityProvider; accountIdEndpointMode?: Provider; + retryStrategy?: Provider; }>; /** @@ -33,6 +40,24 @@ export async function checkFeatures( ): Promise { // eslint-disable-next-line const request = args.request as IHttpRequest; + + if (request.headers?.["smithy-protocol"] === "rpc-v2-cbor") { + setFeature(context, "PROTOCOL_RPC_V2_CBOR", "M"); + } + + if (typeof config.retryStrategy === "function") { + const retryStrategy = await config.retryStrategy(); + if (typeof (retryStrategy as RetryStrategyV2).acquireInitialRetryToken === "function") { + if (retryStrategy.constructor?.name?.includes("Adaptive")) { + setFeature(context, "RETRY_MODE_ADAPTIVE", "F"); + } else { + setFeature(context, "RETRY_MODE_STANDARD", "E"); + } + } else { + setFeature(context, "RETRY_MODE_LEGACY", "D"); + } + } + if (typeof config.accountIdEndpointMode === "function") { const endpointV2 = context.endpointV2; if (String(endpointV2?.url?.hostname).match(ACCOUNT_ID_ENDPOINT_REGEX)) { diff --git a/packages/middleware-user-agent/src/user-agent-middleware.ts b/packages/middleware-user-agent/src/user-agent-middleware.ts index 42c915d8526c..4438ede668d0 100644 --- a/packages/middleware-user-agent/src/user-agent-middleware.ts +++ b/packages/middleware-user-agent/src/user-agent-middleware.ts @@ -3,10 +3,10 @@ import { getUserAgentPrefix } from "@aws-sdk/util-endpoints"; import { HttpRequest } from "@smithy/protocol-http"; import { AbsoluteLocation, - FinalizeHandler, - FinalizeHandlerArguments, - FinalizeHandlerOutput, - FinalizeRequestHandlerOptions, + BuildHandler, + BuildHandlerArguments, + BuildHandlerOptions, + BuildHandlerOutput, HandlerExecutionContext, MetadataBearer, Pluggable, @@ -41,10 +41,10 @@ import { encodeFeatures } from "./encode-features"; export const userAgentMiddleware = (options: UserAgentResolvedConfig) => ( - next: FinalizeHandler, + next: BuildHandler, context: HandlerExecutionContext | AwsHandlerExecutionContext - ): FinalizeHandler => - async (args: FinalizeHandlerArguments): Promise> => { + ): BuildHandler => + async (args: BuildHandlerArguments): Promise> => { const { request } = args; if (!HttpRequest.isInstance(request)) { return next(args); @@ -130,9 +130,9 @@ const escapeUserAgent = (userAgentPair: UserAgentPair): string => { }, "") as string; }; -export const getUserAgentMiddlewareOptions: FinalizeRequestHandlerOptions & AbsoluteLocation = { +export const getUserAgentMiddlewareOptions: BuildHandlerOptions & AbsoluteLocation = { name: "getUserAgentMiddleware", - step: "finalizeRequest", + step: "build", priority: "low", tags: ["SET_USER_AGENT", "USER_AGENT"], override: true, From 306327aeb44d1765f6c28ff76082188fbaf9f38a Mon Sep 17 00:00:00 2001 From: George Fu Date: Tue, 8 Oct 2024 20:47:41 +0000 Subject: [PATCH 3/3] test: update integ test assertions for user agents --- .../src/middleware-flexible-checksums.integ.spec.ts | 2 +- .../src/s3-express/middleware-s3-express.integ.spec.ts | 2 +- packages/middleware-user-agent/src/check-features.ts | 3 +-- .../src/middleware-user-agent.integ.spec.ts | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/middleware-flexible-checksums/src/middleware-flexible-checksums.integ.spec.ts b/packages/middleware-flexible-checksums/src/middleware-flexible-checksums.integ.spec.ts index 027e8ad74b1f..40b0d1a045d2 100644 --- a/packages/middleware-flexible-checksums/src/middleware-flexible-checksums.integ.spec.ts +++ b/packages/middleware-flexible-checksums/src/middleware-flexible-checksums.integ.spec.ts @@ -137,7 +137,7 @@ describe("middleware-flexible-checksums", () => { requireRequestsFrom(client).toMatch({ headers: { - "user-agent": new RegExp(`(.*?) m\/${id}$`), + "user-agent": new RegExp(`(.*?) m\/${id},E$`), }, }); diff --git a/packages/middleware-sdk-s3/src/s3-express/middleware-s3-express.integ.spec.ts b/packages/middleware-sdk-s3/src/s3-express/middleware-s3-express.integ.spec.ts index a73facfe5d8c..e969678effe7 100644 --- a/packages/middleware-sdk-s3/src/s3-express/middleware-s3-express.integ.spec.ts +++ b/packages/middleware-sdk-s3/src/s3-express/middleware-s3-express.integ.spec.ts @@ -93,7 +93,7 @@ describe("middleware-s3-express", () => { requireRequestsFrom(client).toMatch({ headers: { - "user-agent": /(.*?) m\/J$/, + "user-agent": /(.*?) m\/J,E$/, }, }); diff --git a/packages/middleware-user-agent/src/check-features.ts b/packages/middleware-user-agent/src/check-features.ts index c87cf4f00a76..6272b3085d78 100644 --- a/packages/middleware-user-agent/src/check-features.ts +++ b/packages/middleware-user-agent/src/check-features.ts @@ -38,10 +38,9 @@ export async function checkFeatures( config: PreviouslyResolved, args: BuildHandlerArguments ): Promise { - // eslint-disable-next-line const request = args.request as IHttpRequest; - if (request.headers?.["smithy-protocol"] === "rpc-v2-cbor") { + if (request?.headers?.["smithy-protocol"] === "rpc-v2-cbor") { setFeature(context, "PROTOCOL_RPC_V2_CBOR", "M"); } diff --git a/packages/middleware-user-agent/src/middleware-user-agent.integ.spec.ts b/packages/middleware-user-agent/src/middleware-user-agent.integ.spec.ts index 04ba7015c472..2ee442d5bf28 100644 --- a/packages/middleware-user-agent/src/middleware-user-agent.integ.spec.ts +++ b/packages/middleware-user-agent/src/middleware-user-agent.integ.spec.ts @@ -36,7 +36,7 @@ describe("middleware-user-agent", () => { requireRequestsFrom(doc).toMatch({ headers: { - "user-agent": /(.*?) m\/d,O,R$/, + "user-agent": /(.*?) m\/d,E,O,R$/, }, });