Skip to content

Commit 534e028

Browse files
authored
chore(middleware-user-agent): detect cbor, retry, account id features (#6552)
* chore(middleware-user-agent): use authScheme identity instead of credentials provider * chore: calculate user agent in websocket * test: update integ test assertions for user agents
1 parent 6e61f0e commit 534e028

File tree

4 files changed

+46
-12
lines changed

4 files changed

+46
-12
lines changed

packages/middleware-flexible-checksums/src/middleware-flexible-checksums.integ.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ describe("middleware-flexible-checksums", () => {
137137

138138
requireRequestsFrom(client).toMatch({
139139
headers: {
140-
"user-agent": new RegExp(`(.*?) m\/${id}$`),
140+
"user-agent": new RegExp(`(.*?) m\/${id},E$`),
141141
},
142142
});
143143

packages/middleware-sdk-s3/src/s3-express/middleware-s3-express.integ.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ describe("middleware-s3-express", () => {
9393

9494
requireRequestsFrom(client).toMatch({
9595
headers: {
96-
"user-agent": /(.*?) m\/J$/,
96+
"user-agent": /(.*?) m\/J,E$/,
9797
},
9898
});
9999

packages/middleware-user-agent/src/check-features.ts

+35-2
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,28 @@ import type {
66
AwsSdkCredentialsFeatures,
77
} from "@aws-sdk/types";
88
import type { IHttpRequest } from "@smithy/protocol-http";
9-
import type { AwsCredentialIdentityProvider, BuildHandlerArguments, Provider } from "@smithy/types";
9+
import type {
10+
AwsCredentialIdentityProvider,
11+
BuildHandlerArguments,
12+
Provider,
13+
RetryStrategy,
14+
RetryStrategyV2,
15+
} from "@smithy/types";
1016

1117
/**
1218
* @internal
1319
*/
1420
type PreviouslyResolved = Partial<{
1521
credentials?: AwsCredentialIdentityProvider;
1622
accountIdEndpointMode?: Provider<AccountIdEndpointMode>;
23+
retryStrategy?: Provider<RetryStrategy | RetryStrategyV2>;
1724
}>;
1825

26+
/**
27+
* @internal
28+
*/
29+
const ACCOUNT_ID_ENDPOINT_REGEX = /\d{12}\.ddb/;
30+
1931
/**
2032
* @internal
2133
* Check for features that don't have a middleware activation site but
@@ -26,9 +38,30 @@ export async function checkFeatures(
2638
config: PreviouslyResolved,
2739
args: BuildHandlerArguments<any>
2840
): Promise<void> {
29-
// eslint-disable-next-line
3041
const request = args.request as IHttpRequest;
42+
43+
if (request?.headers?.["smithy-protocol"] === "rpc-v2-cbor") {
44+
setFeature(context, "PROTOCOL_RPC_V2_CBOR", "M");
45+
}
46+
47+
if (typeof config.retryStrategy === "function") {
48+
const retryStrategy = await config.retryStrategy();
49+
if (typeof (retryStrategy as RetryStrategyV2).acquireInitialRetryToken === "function") {
50+
if (retryStrategy.constructor?.name?.includes("Adaptive")) {
51+
setFeature(context, "RETRY_MODE_ADAPTIVE", "F");
52+
} else {
53+
setFeature(context, "RETRY_MODE_STANDARD", "E");
54+
}
55+
} else {
56+
setFeature(context, "RETRY_MODE_LEGACY", "D");
57+
}
58+
}
59+
3160
if (typeof config.accountIdEndpointMode === "function") {
61+
const endpointV2 = context.endpointV2;
62+
if (String(endpointV2?.url?.hostname).match(ACCOUNT_ID_ENDPOINT_REGEX)) {
63+
setFeature(context, "ACCOUNT_ID_ENDPOINT", "O");
64+
}
3265
switch (await config.accountIdEndpointMode?.()) {
3366
case "disabled":
3467
setFeature(context, "ACCOUNT_ID_MODE_DISABLED", "Q");

packages/middleware-user-agent/src/middleware-user-agent.integ.spec.ts

+9-8
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,25 @@ describe("middleware-user-agent", () => {
2727
});
2828

2929
describe("features", () => {
30-
it("should detect DDB mapper, and account id mode", async () => {
30+
it("should detect DDB mapper, account id, and account id mode", async () => {
3131
const client = new DynamoDB({
32-
credentials: {
33-
accessKeyId: "",
34-
secretAccessKey: "",
35-
accountId: "123",
36-
},
37-
accountIdEndpointMode: async () => "preferred" as const,
32+
accountIdEndpointMode: async () => "required" as const,
3833
});
3934

4035
const doc = DynamoDBDocument.from(client);
4136

4237
requireRequestsFrom(doc).toMatch({
4338
headers: {
44-
"user-agent": /(.*?) m\/d,P$/,
39+
"user-agent": /(.*?) m\/d,E,O,R$/,
4540
},
4641
});
4742

43+
client.config.credentials = async () => ({
44+
accessKeyId: "",
45+
secretAccessKey: "",
46+
accountId: "123456789012",
47+
});
48+
4849
await doc.get({
4950
TableName: "table",
5051
Key: {

0 commit comments

Comments
 (0)