🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@smithy/core

Package Overview
Dependencies
Maintainers
2
Versions
147
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@smithy/core - npm Package Compare versions

Comparing version
3.27.0
to
3.28.0
+92
dist-es/submodules...gionConfig/getInstanceMetadataRegion.js
import { ENV_IMDS_DISABLED, IMDS_REGION_PATH, IMDS_TOKEN_PATH, X_AWS_EC2_METADATA_TOKEN, X_AWS_EC2_METADATA_TOKEN_TTL, } from "../../defaults-mode/constants";
const TIMEOUT_MS = 1000;
const NEG_CACHE_TTL_MS = 60_000;
let negativeCacheUntil = 0;
export const getInstanceMetadataRegion = async () => {
if (process.env[ENV_IMDS_DISABLED]) {
return undefined;
}
if (Date.now() < negativeCacheUntil) {
return undefined;
}
try {
const endpoint = resolveImdsEndpoint();
const token = (await imdsRequest({
...endpoint,
path: IMDS_TOKEN_PATH,
method: "PUT",
headers: {
[X_AWS_EC2_METADATA_TOKEN_TTL]: "21600",
},
})).toString();
const region = (await imdsRequest({
...endpoint,
path: IMDS_REGION_PATH,
method: "GET",
headers: {
[X_AWS_EC2_METADATA_TOKEN]: token,
},
}))
.toString()
.trim();
return region || cacheNegativeAndReturnUndefined();
}
catch {
return cacheNegativeAndReturnUndefined();
}
};
const cacheNegativeAndReturnUndefined = () => {
negativeCacheUntil = Date.now() + NEG_CACHE_TTL_MS;
return undefined;
};
const resolveImdsEndpoint = () => {
const envEndpoint = process.env.AWS_EC2_METADATA_SERVICE_ENDPOINT;
if (envEndpoint) {
const url = new URL(envEndpoint);
return {
hostname: url.hostname.replace(/^\[(.+)]$/, "$1"),
port: url.port ? Number(url.port) : undefined,
};
}
if (process.env.AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE === "IPv6") {
return { hostname: "fd00:ec2::254" };
}
return { hostname: "169.254.169.254" };
};
const imdsRequest = async (options) => {
const { request } = await import("node:http");
return new Promise((resolve, reject) => {
const req = request({
hostname: options.hostname,
port: options.port,
path: options.path,
method: options.method,
headers: options.headers,
timeout: TIMEOUT_MS,
signal: AbortSignal.timeout(TIMEOUT_MS),
});
req.on("error", (err) => {
reject(err);
req.destroy();
});
req.on("timeout", () => {
reject(new Error("TimeoutError from instance metadata service"));
req.destroy();
});
req.on("response", (res) => {
const { statusCode = 400 } = res;
if (statusCode < 200 || statusCode >= 300) {
reject(Object.assign(new Error("Error response received from instance metadata service"), { statusCode }));
req.destroy();
return;
}
const chunks = [];
res.on("data", (chunk) => chunks.push(chunk));
res.on("end", () => {
resolve(Buffer.concat(chunks));
req.destroy();
});
});
req.end();
});
};
/**
* Returns the region of the host from the EC2 Instance Metadata Service (IMDSv2),
* or undefined if unavailable.
*
* @internal
*/
export declare const getInstanceMetadataRegion: () => Promise<string | undefined>;
+4
-1

@@ -130,4 +130,7 @@ const { toUint8Array, concatBytes } = require("@smithy/core/serde");

}
digestSync() {
return (this.checksum ^ ONES) >>> 0;
}
async digest() {
const value = (this.checksum ^ ONES) >>> 0;
const value = this.digestSync();
const out = new Uint8Array(4);

@@ -134,0 +137,0 @@ new DataView(out.buffer).setUint32(0, value, false);

@@ -220,4 +220,7 @@ const { createReadStream } = require("node:fs");

}
digestSync() {
return (this.checksum ^ ONES) >>> 0;
}
async digest() {
const value = (this.checksum ^ ONES) >>> 0;
const value = this.digestSync();
const out = new Uint8Array(4);

@@ -241,5 +244,8 @@ new DataView(out.buffer).setUint32(0, value, false);

}
digestSync() {
return this.value >>> 0;
}
async digest() {
const out = new Uint8Array(4);
new DataView(out.buffer).setUint32(0, this.value >>> 0, false);
new DataView(out.buffer).setUint32(0, this.digestSync(), false);
return out;

@@ -246,0 +252,0 @@ }

@@ -130,4 +130,7 @@ const { toUint8Array, concatBytes, fromBase64 } = require("@smithy/core/serde");

}
digestSync() {
return (this.checksum ^ ONES) >>> 0;
}
async digest() {
const value = (this.checksum ^ ONES) >>> 0;
const value = this.digestSync();
const out = new Uint8Array(4);

@@ -134,0 +137,0 @@ new DataView(out.buffer).setUint32(0, value, false);

+108
-63

@@ -473,2 +473,104 @@ const { homedir } = require("node:os");

const AWS_EXECUTION_ENV = "AWS_EXECUTION_ENV";
const AWS_REGION_ENV = "AWS_REGION";
const AWS_DEFAULT_REGION_ENV = "AWS_DEFAULT_REGION";
const ENV_IMDS_DISABLED = "AWS_EC2_METADATA_DISABLED";
const DEFAULTS_MODE_OPTIONS = ["in-region", "cross-region", "mobile", "standard", "legacy"];
const IMDS_REGION_PATH = "/latest/meta-data/placement/region";
const IMDS_TOKEN_PATH = "/latest/api/token";
const X_AWS_EC2_METADATA_TOKEN = "x-aws-ec2-metadata-token";
const X_AWS_EC2_METADATA_TOKEN_TTL = "x-aws-ec2-metadata-token-ttl-seconds";
const TIMEOUT_MS = 1000;
const NEG_CACHE_TTL_MS = 60_000;
let negativeCacheUntil = 0;
const getInstanceMetadataRegion = async () => {
if (process.env[ENV_IMDS_DISABLED]) {
return undefined;
}
if (Date.now() < negativeCacheUntil) {
return undefined;
}
try {
const endpoint = resolveImdsEndpoint();
const token = (await imdsRequest({
...endpoint,
path: IMDS_TOKEN_PATH,
method: "PUT",
headers: {
[X_AWS_EC2_METADATA_TOKEN_TTL]: "21600",
},
})).toString();
const region = (await imdsRequest({
...endpoint,
path: IMDS_REGION_PATH,
method: "GET",
headers: {
[X_AWS_EC2_METADATA_TOKEN]: token,
},
}))
.toString()
.trim();
return region || cacheNegativeAndReturnUndefined();
}
catch {
return cacheNegativeAndReturnUndefined();
}
};
const cacheNegativeAndReturnUndefined = () => {
negativeCacheUntil = Date.now() + NEG_CACHE_TTL_MS;
return undefined;
};
const resolveImdsEndpoint = () => {
const envEndpoint = process.env.AWS_EC2_METADATA_SERVICE_ENDPOINT;
if (envEndpoint) {
const url = new URL(envEndpoint);
return {
hostname: url.hostname.replace(/^\[(.+)]$/, "$1"),
port: url.port ? Number(url.port) : undefined,
};
}
if (process.env.AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE === "IPv6") {
return { hostname: "fd00:ec2::254" };
}
return { hostname: "169.254.169.254" };
};
const imdsRequest = async (options) => {
const { request } = require('node:http');
return new Promise((resolve, reject) => {
const req = request({
hostname: options.hostname,
port: options.port,
path: options.path,
method: options.method,
headers: options.headers,
timeout: TIMEOUT_MS,
signal: AbortSignal.timeout(TIMEOUT_MS),
});
req.on("error", (err) => {
reject(err);
req.destroy();
});
req.on("timeout", () => {
reject(new Error("TimeoutError from instance metadata service"));
req.destroy();
});
req.on("response", (res) => {
const { statusCode = 400 } = res;
if (statusCode < 200 || statusCode >= 300) {
reject(Object.assign(new Error("Error response received from instance metadata service"), { statusCode }));
req.destroy();
return;
}
const chunks = [];
res.on("data", (chunk) => chunks.push(chunk));
res.on("end", () => {
resolve(Buffer.concat(chunks));
req.destroy();
});
});
req.end();
});
};
const REGION_ENV_NAME = "AWS_REGION";

@@ -479,3 +581,7 @@ const REGION_INI_NAME = "region";

configFileSelector: (profile) => profile[REGION_INI_NAME],
default: () => {
default: async () => {
const region = await getInstanceMetadataRegion();
if (region) {
return region;
}
throw new Error("Region is missing");

@@ -582,9 +688,2 @@ },

const AWS_EXECUTION_ENV = "AWS_EXECUTION_ENV";
const AWS_REGION_ENV = "AWS_REGION";
const AWS_DEFAULT_REGION_ENV = "AWS_DEFAULT_REGION";
const ENV_IMDS_DISABLED = "AWS_EC2_METADATA_DISABLED";
const DEFAULTS_MODE_OPTIONS = ["in-region", "cross-region", "mobile", "standard", "legacy"];
const IMDS_REGION_PATH = "/latest/meta-data/placement/region";
const AWS_DEFAULTS_MODE_ENV = "AWS_DEFAULTS_MODE";

@@ -639,58 +738,4 @@ const AWS_DEFAULTS_MODE_CONFIG = "defaults_mode";

}
if (!process.env[ENV_IMDS_DISABLED]) {
try {
const endpoint = await getImdsEndpoint();
return (await imdsHttpGet({ hostname: endpoint.hostname, path: IMDS_REGION_PATH })).toString();
}
catch (e) {
}
}
return getInstanceMetadataRegion();
};
const getImdsEndpoint = async () => {
const envEndpoint = process.env.AWS_EC2_METADATA_SERVICE_ENDPOINT;
if (envEndpoint) {
const url = new URL(envEndpoint);
return { hostname: url.hostname, path: url.pathname };
}
const envMode = process.env.AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE;
if (envMode === "IPv6") {
return { hostname: "fd00:ec2::254", path: "/" };
}
return { hostname: "169.254.169.254", path: "/" };
};
const imdsHttpGet = async ({ hostname, path }) => {
const { request } = require('node:http');
return new Promise((resolve, reject) => {
const req = request({
method: "GET",
hostname: hostname.replace(/^\[(.+)]$/, "$1"),
path,
timeout: 1000,
signal: AbortSignal.timeout(1000),
});
req.on("error", (err) => {
reject(err);
req.destroy();
});
req.on("timeout", () => {
reject(new Error("TimeoutError from instance metadata service"));
req.destroy();
});
req.on("response", (res) => {
const { statusCode = 400 } = res;
if (statusCode < 200 || 300 <= statusCode) {
reject(Object.assign(new Error("Error response received from instance metadata service"), { statusCode }));
req.destroy();
return;
}
const chunks = [];
res.on("data", (chunk) => chunks.push(chunk));
res.on("end", () => {
resolve(Buffer.concat(chunks));
req.destroy();
});
});
req.end();
});
};

@@ -697,0 +742,0 @@ exports.CONFIG_PREFIX_SEPARATOR = CONFIG_PREFIX_SEPARATOR;

@@ -1,2 +0,2 @@

const { Crc32 } = require("@aws-crypto/crc32");
const { Crc32 } = require("@smithy/core/checksum");
const { toHex, fromHex, toUtf8, fromUtf8 } = require("@smithy/core/serde");

@@ -247,9 +247,10 @@

const expectedMessageChecksum = view.getUint32(byteLength - CHECKSUM_LENGTH, false);
const checksummer = new Crc32().update(new Uint8Array(buffer, byteOffset, PRELUDE_LENGTH));
if (expectedPreludeChecksum !== checksummer.digest()) {
throw new Error(`The prelude checksum specified in the message (${expectedPreludeChecksum}) does not match the calculated CRC32 checksum (${checksummer.digest()})`);
const checksummer = new Crc32();
checksummer.update(new Uint8Array(buffer, byteOffset, PRELUDE_LENGTH));
if (expectedPreludeChecksum !== checksummer.digestSync()) {
throw new Error(`The prelude checksum specified in the message (${expectedPreludeChecksum}) does not match the calculated CRC32 checksum (${checksummer.digestSync()})`);
}
checksummer.update(new Uint8Array(buffer, byteOffset + PRELUDE_LENGTH, byteLength - (PRELUDE_LENGTH + CHECKSUM_LENGTH)));
if (expectedMessageChecksum !== checksummer.digest()) {
throw new Error(`The message checksum (${checksummer.digest()}) did not match the expected value of ${expectedMessageChecksum}`);
if (expectedMessageChecksum !== checksummer.digestSync()) {
throw new Error(`The message checksum (${checksummer.digestSync()}) did not match the expected value of ${expectedMessageChecksum}`);
}

@@ -310,6 +311,8 @@ return {

view.setUint32(4, headers.byteLength, false);
view.setUint32(8, checksum.update(out.subarray(0, 8)).digest(), false);
checksum.update(out.subarray(0, 8));
view.setUint32(8, checksum.digestSync(), false);
out.set(headers, 12);
out.set(body, headers.byteLength + 12);
view.setUint32(length - 4, checksum.update(out.subarray(8, length - 4)).digest(), false);
checksum.update(out.subarray(8, length - 4));
view.setUint32(length - 4, checksum.digestSync(), false);
return out;

@@ -316,0 +319,0 @@ }

@@ -1,2 +0,2 @@

const { Crc32 } = require("@aws-crypto/crc32");
const { Crc32 } = require("@smithy/core/checksum");
const { toHex, fromHex, toUtf8, fromUtf8 } = require("@smithy/core/serde");

@@ -248,9 +248,10 @@ const { Readable } = require("node:stream");

const expectedMessageChecksum = view.getUint32(byteLength - CHECKSUM_LENGTH, false);
const checksummer = new Crc32().update(new Uint8Array(buffer, byteOffset, PRELUDE_LENGTH));
if (expectedPreludeChecksum !== checksummer.digest()) {
throw new Error(`The prelude checksum specified in the message (${expectedPreludeChecksum}) does not match the calculated CRC32 checksum (${checksummer.digest()})`);
const checksummer = new Crc32();
checksummer.update(new Uint8Array(buffer, byteOffset, PRELUDE_LENGTH));
if (expectedPreludeChecksum !== checksummer.digestSync()) {
throw new Error(`The prelude checksum specified in the message (${expectedPreludeChecksum}) does not match the calculated CRC32 checksum (${checksummer.digestSync()})`);
}
checksummer.update(new Uint8Array(buffer, byteOffset + PRELUDE_LENGTH, byteLength - (PRELUDE_LENGTH + CHECKSUM_LENGTH)));
if (expectedMessageChecksum !== checksummer.digest()) {
throw new Error(`The message checksum (${checksummer.digest()}) did not match the expected value of ${expectedMessageChecksum}`);
if (expectedMessageChecksum !== checksummer.digestSync()) {
throw new Error(`The message checksum (${checksummer.digestSync()}) did not match the expected value of ${expectedMessageChecksum}`);
}

@@ -311,6 +312,8 @@ return {

view.setUint32(4, headers.byteLength, false);
view.setUint32(8, checksum.update(out.subarray(0, 8)).digest(), false);
checksum.update(out.subarray(0, 8));
view.setUint32(8, checksum.digestSync(), false);
out.set(headers, 12);
out.set(body, headers.byteLength + 12);
view.setUint32(length - 4, checksum.update(out.subarray(8, length - 4)).digest(), false);
checksum.update(out.subarray(8, length - 4));
view.setUint32(length - 4, checksum.digestSync(), false);
return out;

@@ -317,0 +320,0 @@ }

@@ -18,4 +18,7 @@ const CRC32_TABLE = new Uint32Array(256);

}
digestSync() {
return (this.checksum ^ ONES) >>> 0;
}
async digest() {
const value = (this.checksum ^ ONES) >>> 0;
const value = this.digestSync();
const out = new Uint8Array(4);

@@ -22,0 +25,0 @@ new DataView(out.buffer).setUint32(0, value, false);

@@ -12,5 +12,8 @@ import * as zlib from "node:zlib";

}
digestSync() {
return this.value >>> 0;
}
async digest() {
const out = new Uint8Array(4);
new DataView(out.buffer).setUint32(0, this.value >>> 0, false);
new DataView(out.buffer).setUint32(0, this.digestSync(), false);
return out;

@@ -17,0 +20,0 @@ }

@@ -0,1 +1,2 @@

import { getInstanceMetadataRegion } from "./getInstanceMetadataRegion";
export const REGION_ENV_NAME = "AWS_REGION";

@@ -6,3 +7,7 @@ export const REGION_INI_NAME = "region";

configFileSelector: (profile) => profile[REGION_INI_NAME],
default: () => {
default: async () => {
const region = await getInstanceMetadataRegion();
if (region) {
return region;
}
throw new Error("Region is missing");

@@ -9,0 +14,0 @@ },

@@ -7,1 +7,4 @@ export const AWS_EXECUTION_ENV = "AWS_EXECUTION_ENV";

export const IMDS_REGION_PATH = "/latest/meta-data/placement/region";
export const IMDS_TOKEN_PATH = "/latest/api/token";
export const X_AWS_EC2_METADATA_TOKEN = "x-aws-ec2-metadata-token";
export const X_AWS_EC2_METADATA_TOKEN_TTL = "x-aws-ec2-metadata-token-ttl-seconds";
import { NODE_REGION_CONFIG_OPTIONS } from "../config-resolver/regionConfig/config";
import { getInstanceMetadataRegion } from "../config-resolver/regionConfig/getInstanceMetadataRegion";
import { loadConfig } from "../node-config-provider/configLoader";
import { memoize } from "../property-provider/memoize";
import { AWS_DEFAULT_REGION_ENV, AWS_EXECUTION_ENV, AWS_REGION_ENV, DEFAULTS_MODE_OPTIONS, ENV_IMDS_DISABLED, IMDS_REGION_PATH, } from "./constants";
import { AWS_DEFAULT_REGION_ENV, AWS_EXECUTION_ENV, AWS_REGION_ENV, DEFAULTS_MODE_OPTIONS } from "./constants";
import { NODE_DEFAULTS_MODE_CONFIG_OPTIONS } from "./defaultsModeConfig";

@@ -43,57 +44,3 @@ export const resolveDefaultsModeConfig = ({ region = loadConfig(NODE_REGION_CONFIG_OPTIONS), defaultsMode = loadConfig(NODE_DEFAULTS_MODE_CONFIG_OPTIONS), } = {}) => memoize(async () => {

}
if (!process.env[ENV_IMDS_DISABLED]) {
try {
const endpoint = await getImdsEndpoint();
return (await imdsHttpGet({ hostname: endpoint.hostname, path: IMDS_REGION_PATH })).toString();
}
catch (e) {
}
}
return getInstanceMetadataRegion();
};
const getImdsEndpoint = async () => {
const envEndpoint = process.env.AWS_EC2_METADATA_SERVICE_ENDPOINT;
if (envEndpoint) {
const url = new URL(envEndpoint);
return { hostname: url.hostname, path: url.pathname };
}
const envMode = process.env.AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE;
if (envMode === "IPv6") {
return { hostname: "fd00:ec2::254", path: "/" };
}
return { hostname: "169.254.169.254", path: "/" };
};
const imdsHttpGet = async ({ hostname, path }) => {
const { request } = await import("node:http");
return new Promise((resolve, reject) => {
const req = request({
method: "GET",
hostname: hostname.replace(/^\[(.+)]$/, "$1"),
path,
timeout: 1000,
signal: AbortSignal.timeout(1000),
});
req.on("error", (err) => {
reject(err);
req.destroy();
});
req.on("timeout", () => {
reject(new Error("TimeoutError from instance metadata service"));
req.destroy();
});
req.on("response", (res) => {
const { statusCode = 400 } = res;
if (statusCode < 200 || 300 <= statusCode) {
reject(Object.assign(new Error("Error response received from instance metadata service"), { statusCode }));
req.destroy();
return;
}
const chunks = [];
res.on("data", (chunk) => chunks.push(chunk));
res.on("end", () => {
resolve(Buffer.concat(chunks));
req.destroy();
});
});
req.end();
});
};

@@ -1,2 +0,2 @@

import { Crc32 } from "@aws-crypto/crc32";
import { Crc32 } from "@smithy/core/checksum";
import { HeaderMarshaller } from "./HeaderMarshaller";

@@ -52,6 +52,8 @@ import { splitMessage } from "./splitMessage";

view.setUint32(4, headers.byteLength, false);
view.setUint32(8, checksum.update(out.subarray(0, 8)).digest(), false);
checksum.update(out.subarray(0, 8));
view.setUint32(8, checksum.digestSync(), false);
out.set(headers, 12);
out.set(body, headers.byteLength + 12);
view.setUint32(length - 4, checksum.update(out.subarray(8, length - 4)).digest(), false);
checksum.update(out.subarray(8, length - 4));
view.setUint32(length - 4, checksum.digestSync(), false);
return out;

@@ -58,0 +60,0 @@ }

@@ -1,2 +0,2 @@

import { Crc32 } from "@aws-crypto/crc32";
import { Crc32 } from "@smithy/core/checksum";
const PRELUDE_MEMBER_LENGTH = 4;

@@ -18,9 +18,10 @@ const PRELUDE_LENGTH = PRELUDE_MEMBER_LENGTH * 2;

const expectedMessageChecksum = view.getUint32(byteLength - CHECKSUM_LENGTH, false);
const checksummer = new Crc32().update(new Uint8Array(buffer, byteOffset, PRELUDE_LENGTH));
if (expectedPreludeChecksum !== checksummer.digest()) {
throw new Error(`The prelude checksum specified in the message (${expectedPreludeChecksum}) does not match the calculated CRC32 checksum (${checksummer.digest()})`);
const checksummer = new Crc32();
checksummer.update(new Uint8Array(buffer, byteOffset, PRELUDE_LENGTH));
if (expectedPreludeChecksum !== checksummer.digestSync()) {
throw new Error(`The prelude checksum specified in the message (${expectedPreludeChecksum}) does not match the calculated CRC32 checksum (${checksummer.digestSync()})`);
}
checksummer.update(new Uint8Array(buffer, byteOffset + PRELUDE_LENGTH, byteLength - (PRELUDE_LENGTH + CHECKSUM_LENGTH)));
if (expectedMessageChecksum !== checksummer.digest()) {
throw new Error(`The message checksum (${checksummer.digest()}) did not match the expected value of ${expectedMessageChecksum}`);
if (expectedMessageChecksum !== checksummer.digestSync()) {
throw new Error(`The message checksum (${checksummer.digestSync()}) did not match the expected value of ${expectedMessageChecksum}`);
}

@@ -27,0 +28,0 @@ return {

@@ -11,4 +11,9 @@ import type { Checksum } from "@smithy/types";

update(data: Uint8Array): void;
/**
* Used by EventStreamCodec.
* @internal
*/
digestSync(): number;
digest(): Promise<Uint8Array>;
reset(): void;
}

@@ -9,2 +9,7 @@ import type { Checksum } from "@smithy/types";

readonly digestLength: 4;
/**
* Used by EventStreamCodec.
* @internal
*/
digestSync(): number;
}

@@ -11,0 +16,0 @@ /**

@@ -25,1 +25,13 @@ /**

export declare const IMDS_REGION_PATH = "/latest/meta-data/placement/region";
/**
* @internal
*/
export declare const IMDS_TOKEN_PATH = "/latest/api/token";
/**
* @internal
*/
export declare const X_AWS_EC2_METADATA_TOKEN = "x-aws-ec2-metadata-token";
/**
* @internal
*/
export declare const X_AWS_EC2_METADATA_TOKEN_TTL = "x-aws-ec2-metadata-token-ttl-seconds";
{
"name": "@smithy/core",
"version": "3.27.0",
"version": "3.28.0",
"scripts": {

@@ -173,3 +173,2 @@ "benchmark:cbor": "node ./scripts/cbor-perf.mjs",

"dependencies": {
"@aws-crypto/crc32": "5.2.0",
"@smithy/types": "^4.15.0",

@@ -176,0 +175,0 @@ "tslib": "^2.6.2"