Skip to content

Commit

Permalink
chore(middleware-user-agent): detect cbor, retry, account id features (
Browse files Browse the repository at this point in the history
…#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
  • Loading branch information
kuhe authored Oct 10, 2024
1 parent 6e61f0e commit 534e028
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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$`),
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ describe("middleware-s3-express", () => {

requireRequestsFrom(client).toMatch({
headers: {
"user-agent": /(.*?) m\/J$/,
"user-agent": /(.*?) m\/J,E$/,
},
});

Expand Down
37 changes: 35 additions & 2 deletions packages/middleware-user-agent/src/check-features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,28 @@ 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
*/
type PreviouslyResolved = Partial<{
credentials?: AwsCredentialIdentityProvider;
accountIdEndpointMode?: Provider<AccountIdEndpointMode>;
retryStrategy?: Provider<RetryStrategy | RetryStrategyV2>;
}>;

/**
* @internal
*/
const ACCOUNT_ID_ENDPOINT_REGEX = /\d{12}\.ddb/;

/**
* @internal
* Check for features that don't have a middleware activation site but
Expand All @@ -26,9 +38,30 @@ export async function checkFeatures(
config: PreviouslyResolved,
args: BuildHandlerArguments<any>
): Promise<void> {
// 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)) {
setFeature(context, "ACCOUNT_ID_ENDPOINT", "O");
}
switch (await config.accountIdEndpointMode?.()) {
case "disabled":
setFeature(context, "ACCOUNT_ID_MODE_DISABLED", "Q");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,E,O,R$/,
},
});

client.config.credentials = async () => ({
accessKeyId: "",
secretAccessKey: "",
accountId: "123456789012",
});

await doc.get({
TableName: "table",
Key: {
Expand Down

0 comments on commit 534e028

Please sign in to comment.