@aws-sdk/middleware-websocket
Advanced tools
Comparing version 3.489.0 to 3.495.0
@@ -1,6 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.eventStreamPayloadHandlerProvider = void 0; | ||
const EventStreamPayloadHandler_1 = require("./EventStreamPayloadHandler"); | ||
const eventStreamPayloadHandlerProvider = (options) => new EventStreamPayloadHandler_1.EventStreamPayloadHandler(options); | ||
exports.eventStreamPayloadHandlerProvider = eventStreamPayloadHandlerProvider; | ||
module.exports = require("./index.js"); |
@@ -1,35 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.EventStreamPayloadHandler = void 0; | ||
const eventstream_codec_1 = require("@smithy/eventstream-codec"); | ||
const get_event_signing_stream_1 = require("./get-event-signing-stream"); | ||
class EventStreamPayloadHandler { | ||
constructor(options) { | ||
this.messageSigner = options.messageSigner; | ||
this.eventStreamCodec = new eventstream_codec_1.EventStreamCodec(options.utf8Encoder, options.utf8Decoder); | ||
} | ||
async handle(next, args, context = {}) { | ||
const request = args.request; | ||
const { body: payload, headers, query } = request; | ||
if (!(payload instanceof ReadableStream)) { | ||
throw new Error("Eventstream payload must be a ReadableStream."); | ||
} | ||
const placeHolderStream = new TransformStream(); | ||
request.body = placeHolderStream.readable; | ||
let result; | ||
try { | ||
result = await next(args); | ||
} | ||
catch (e) { | ||
request.body.cancel(); | ||
throw e; | ||
} | ||
const match = (headers["authorization"] || "").match(/Signature=([\w]+)$/); | ||
const priorSignature = (match || [])[1] || (query && query["X-Amz-Signature"]) || ""; | ||
const signingStream = (0, get_event_signing_stream_1.getEventSigningTransformStream)(priorSignature, await this.messageSigner(), this.eventStreamCodec); | ||
const signedPayload = payload.pipeThrough(signingStream); | ||
signedPayload.pipeThrough(placeHolderStream); | ||
return result; | ||
} | ||
} | ||
exports.EventStreamPayloadHandler = EventStreamPayloadHandler; | ||
module.exports = require("./index.js"); |
@@ -1,44 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getEventSigningTransformStream = void 0; | ||
const util_hex_encoding_1 = require("@smithy/util-hex-encoding"); | ||
const getEventSigningTransformStream = (initialSignature, messageSigner, eventStreamCodec) => { | ||
let priorSignature = initialSignature; | ||
const transformer = { | ||
start() { }, | ||
async transform(chunk, controller) { | ||
try { | ||
const now = new Date(); | ||
const dateHeader = { | ||
":date": { type: "timestamp", value: now }, | ||
}; | ||
const signedMessage = await messageSigner.sign({ | ||
message: { | ||
body: chunk, | ||
headers: dateHeader, | ||
}, | ||
priorSignature: priorSignature, | ||
}, { | ||
signingDate: now, | ||
}); | ||
priorSignature = signedMessage.signature; | ||
const serializedSigned = eventStreamCodec.encode({ | ||
headers: { | ||
...dateHeader, | ||
":chunk-signature": { | ||
type: "binary", | ||
value: (0, util_hex_encoding_1.fromHex)(signedMessage.signature), | ||
}, | ||
}, | ||
body: chunk, | ||
}); | ||
controller.enqueue(serializedSigned); | ||
} | ||
catch (error) { | ||
controller.error(error); | ||
} | ||
}, | ||
}; | ||
return new TransformStream({ ...transformer }); | ||
}; | ||
exports.getEventSigningTransformStream = getEventSigningTransformStream; | ||
module.exports = require("./index.js"); |
@@ -1,12 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getWebSocketPlugin = void 0; | ||
const middleware_session_id_1 = require("./middleware-session-id"); | ||
const middleware_websocket_endpoint_1 = require("./middleware-websocket-endpoint"); | ||
const getWebSocketPlugin = (config, options) => ({ | ||
applyToStack: (clientStack) => { | ||
clientStack.addRelativeTo((0, middleware_websocket_endpoint_1.websocketEndpointMiddleware)(config, options), middleware_websocket_endpoint_1.websocketEndpointMiddlewareOptions); | ||
clientStack.add((0, middleware_session_id_1.injectSessionIdMiddleware)(), middleware_session_id_1.injectSessionIdMiddlewareOptions); | ||
}, | ||
}); | ||
exports.getWebSocketPlugin = getWebSocketPlugin; | ||
module.exports = require("./index.js"); |
@@ -1,7 +0,390 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const tslib_1 = require("tslib"); | ||
tslib_1.__exportStar(require("./eventstream-payload-handler-provider"), exports); | ||
tslib_1.__exportStar(require("./getWebSocketPlugin"), exports); | ||
tslib_1.__exportStar(require("./websocket-configuration"), exports); | ||
tslib_1.__exportStar(require("./websocket-fetch-handler"), exports); | ||
var __defProp = Object.defineProperty; | ||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
var __getOwnPropNames = Object.getOwnPropertyNames; | ||
var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); | ||
var __export = (target, all) => { | ||
for (var name in all) | ||
__defProp(target, name, { get: all[name], enumerable: true }); | ||
}; | ||
var __copyProps = (to, from, except, desc) => { | ||
if (from && typeof from === "object" || typeof from === "function") { | ||
for (let key of __getOwnPropNames(from)) | ||
if (!__hasOwnProp.call(to, key) && key !== except) | ||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
} | ||
return to; | ||
}; | ||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
// src/index.ts | ||
var src_exports = {}; | ||
__export(src_exports, { | ||
WebSocketFetchHandler: () => WebSocketFetchHandler, | ||
eventStreamPayloadHandlerProvider: () => eventStreamPayloadHandlerProvider, | ||
getWebSocketPlugin: () => getWebSocketPlugin, | ||
resolveWebSocketConfig: () => resolveWebSocketConfig | ||
}); | ||
module.exports = __toCommonJS(src_exports); | ||
// src/EventStreamPayloadHandler.ts | ||
var import_eventstream_codec = require("@smithy/eventstream-codec"); | ||
// src/get-event-signing-stream.ts | ||
var import_util_hex_encoding = require("@smithy/util-hex-encoding"); | ||
var getEventSigningTransformStream = /* @__PURE__ */ __name((initialSignature, messageSigner, eventStreamCodec) => { | ||
let priorSignature = initialSignature; | ||
const transformer = { | ||
start() { | ||
}, | ||
async transform(chunk, controller) { | ||
try { | ||
const now = /* @__PURE__ */ new Date(); | ||
const dateHeader = { | ||
":date": { type: "timestamp", value: now } | ||
}; | ||
const signedMessage = await messageSigner.sign( | ||
{ | ||
message: { | ||
body: chunk, | ||
headers: dateHeader | ||
}, | ||
priorSignature | ||
}, | ||
{ | ||
signingDate: now | ||
} | ||
); | ||
priorSignature = signedMessage.signature; | ||
const serializedSigned = eventStreamCodec.encode({ | ||
headers: { | ||
...dateHeader, | ||
":chunk-signature": { | ||
type: "binary", | ||
value: (0, import_util_hex_encoding.fromHex)(signedMessage.signature) | ||
} | ||
}, | ||
body: chunk | ||
}); | ||
controller.enqueue(serializedSigned); | ||
} catch (error) { | ||
controller.error(error); | ||
} | ||
} | ||
}; | ||
return new TransformStream({ ...transformer }); | ||
}, "getEventSigningTransformStream"); | ||
// src/EventStreamPayloadHandler.ts | ||
var _EventStreamPayloadHandler = class _EventStreamPayloadHandler { | ||
constructor(options) { | ||
this.messageSigner = options.messageSigner; | ||
this.eventStreamCodec = new import_eventstream_codec.EventStreamCodec(options.utf8Encoder, options.utf8Decoder); | ||
} | ||
async handle(next, args, context = {}) { | ||
const request = args.request; | ||
const { body: payload, headers, query } = request; | ||
if (!(payload instanceof ReadableStream)) { | ||
throw new Error("Eventstream payload must be a ReadableStream."); | ||
} | ||
const placeHolderStream = new TransformStream(); | ||
request.body = placeHolderStream.readable; | ||
let result; | ||
try { | ||
result = await next(args); | ||
} catch (e) { | ||
request.body.cancel(); | ||
throw e; | ||
} | ||
const match = (headers["authorization"] || "").match(/Signature=([\w]+)$/); | ||
const priorSignature = (match || [])[1] || query && query["X-Amz-Signature"] || ""; | ||
const signingStream = getEventSigningTransformStream( | ||
priorSignature, | ||
await this.messageSigner(), | ||
this.eventStreamCodec | ||
); | ||
const signedPayload = payload.pipeThrough(signingStream); | ||
signedPayload.pipeThrough(placeHolderStream); | ||
return result; | ||
} | ||
}; | ||
__name(_EventStreamPayloadHandler, "EventStreamPayloadHandler"); | ||
var EventStreamPayloadHandler = _EventStreamPayloadHandler; | ||
// src/eventstream-payload-handler-provider.ts | ||
var eventStreamPayloadHandlerProvider = /* @__PURE__ */ __name((options) => new EventStreamPayloadHandler(options), "eventStreamPayloadHandlerProvider"); | ||
// src/middleware-session-id.ts | ||
var injectSessionIdMiddleware = /* @__PURE__ */ __name(() => (next) => async (args) => { | ||
const requestParams = { | ||
...args.input | ||
}; | ||
const response = await next(args); | ||
const output = response.output; | ||
if (requestParams.SessionId && output.SessionId == null) { | ||
output.SessionId = requestParams.SessionId; | ||
} | ||
return response; | ||
}, "injectSessionIdMiddleware"); | ||
var injectSessionIdMiddlewareOptions = { | ||
step: "initialize", | ||
name: "injectSessionIdMiddleware", | ||
tags: ["WEBSOCKET", "EVENT_STREAM"], | ||
override: true | ||
}; | ||
// src/middleware-websocket-endpoint.ts | ||
var import_protocol_http = require("@smithy/protocol-http"); | ||
var websocketEndpointMiddleware = /* @__PURE__ */ __name((config, options) => (next) => (args) => { | ||
var _a, _b; | ||
const { request } = args; | ||
if (import_protocol_http.HttpRequest.isInstance(request) && ((_b = (_a = config.requestHandler.metadata) == null ? void 0 : _a.handlerProtocol) == null ? void 0 : _b.toLowerCase().includes("websocket"))) { | ||
request.protocol = "wss:"; | ||
request.method = "GET"; | ||
request.path = `${request.path}-websocket`; | ||
const { headers } = request; | ||
delete headers["Content-Type"]; | ||
delete headers["x-amz-content-sha256"]; | ||
for (const name of Object.keys(headers)) { | ||
if (name.indexOf(options.headerPrefix) === 0) { | ||
const chunkedName = name.replace(options.headerPrefix, ""); | ||
request.query[chunkedName] = headers[name]; | ||
} | ||
} | ||
if (headers["x-amz-user-agent"]) { | ||
request.query["user-agent"] = headers["x-amz-user-agent"]; | ||
} | ||
request.headers = { host: headers.host ?? request.hostname }; | ||
} | ||
return next(args); | ||
}, "websocketEndpointMiddleware"); | ||
var websocketEndpointMiddlewareOptions = { | ||
name: "websocketEndpointMiddleware", | ||
tags: ["WEBSOCKET", "EVENT_STREAM"], | ||
relation: "after", | ||
toMiddleware: "eventStreamHeaderMiddleware", | ||
override: true | ||
}; | ||
// src/getWebSocketPlugin.ts | ||
var getWebSocketPlugin = /* @__PURE__ */ __name((config, options) => ({ | ||
applyToStack: (clientStack) => { | ||
clientStack.addRelativeTo(websocketEndpointMiddleware(config, options), websocketEndpointMiddlewareOptions); | ||
clientStack.add(injectSessionIdMiddleware(), injectSessionIdMiddlewareOptions); | ||
} | ||
}), "getWebSocketPlugin"); | ||
// src/WebsocketSignatureV4.ts | ||
// src/utils.ts | ||
var isWebSocketRequest = /* @__PURE__ */ __name((request) => request.protocol === "ws:" || request.protocol === "wss:", "isWebSocketRequest"); | ||
// src/WebsocketSignatureV4.ts | ||
var _WebsocketSignatureV4 = class _WebsocketSignatureV4 { | ||
constructor(options) { | ||
this.signer = options.signer; | ||
} | ||
presign(originalRequest, options = {}) { | ||
return this.signer.presign(originalRequest, options); | ||
} | ||
async sign(toSign, options) { | ||
if (import_protocol_http.HttpRequest.isInstance(toSign) && isWebSocketRequest(toSign)) { | ||
const signedRequest = await this.signer.presign( | ||
{ ...toSign, body: "" }, | ||
{ | ||
...options, | ||
// presigned url must be expired within 1 min. | ||
expiresIn: 60, | ||
// Not to sign headers. Transcribe-streaming WebSocket | ||
// request omits headers except for required 'host' header. If we sign | ||
// the other headers, the signature could be mismatch. | ||
unsignableHeaders: new Set(Object.keys(toSign.headers).filter((header) => header !== "host")) | ||
} | ||
); | ||
return { | ||
...signedRequest, | ||
body: toSign.body | ||
}; | ||
} else { | ||
return this.signer.sign(toSign, options); | ||
} | ||
} | ||
}; | ||
__name(_WebsocketSignatureV4, "WebsocketSignatureV4"); | ||
var WebsocketSignatureV4 = _WebsocketSignatureV4; | ||
// src/websocket-configuration.ts | ||
var resolveWebSocketConfig = /* @__PURE__ */ __name((input) => ({ | ||
...input, | ||
signer: async (authScheme) => { | ||
const signerObj = await input.signer(authScheme); | ||
if (validateSigner(signerObj)) { | ||
return new WebsocketSignatureV4({ signer: signerObj }); | ||
} | ||
throw new Error("Expected WebsocketSignatureV4 signer, please check the client constructor."); | ||
} | ||
}), "resolveWebSocketConfig"); | ||
var validateSigner = /* @__PURE__ */ __name((signer) => !!signer, "validateSigner"); | ||
// src/websocket-fetch-handler.ts | ||
var import_util_format_url = require("@aws-sdk/util-format-url"); | ||
var import_eventstream_serde_browser = require("@smithy/eventstream-serde-browser"); | ||
var import_fetch_http_handler = require("@smithy/fetch-http-handler"); | ||
var DEFAULT_WS_CONNECTION_TIMEOUT_MS = 2e3; | ||
var _WebSocketFetchHandler = class _WebSocketFetchHandler { | ||
constructor(options, httpHandler = new import_fetch_http_handler.FetchHttpHandler()) { | ||
this.metadata = { | ||
handlerProtocol: "websocket/h1.1" | ||
}; | ||
this.sockets = {}; | ||
this.httpHandler = httpHandler; | ||
if (typeof options === "function") { | ||
this.configPromise = options().then((opts) => opts ?? {}); | ||
} else { | ||
this.configPromise = Promise.resolve(options ?? {}); | ||
} | ||
} | ||
/** | ||
* Destroys the WebSocketHandler. | ||
* Closes all sockets from the socket pool. | ||
*/ | ||
destroy() { | ||
for (const [key, sockets] of Object.entries(this.sockets)) { | ||
for (const socket of sockets) { | ||
socket.close(1e3, `Socket closed through destroy() call`); | ||
} | ||
delete this.sockets[key]; | ||
} | ||
} | ||
async handle(request) { | ||
if (!isWebSocketRequest(request)) { | ||
return this.httpHandler.handle(request); | ||
} | ||
const url = (0, import_util_format_url.formatUrl)(request); | ||
const socket = new WebSocket(url); | ||
if (!this.sockets[url]) { | ||
this.sockets[url] = []; | ||
} | ||
this.sockets[url].push(socket); | ||
socket.binaryType = "arraybuffer"; | ||
const { connectionTimeout = DEFAULT_WS_CONNECTION_TIMEOUT_MS } = await this.configPromise; | ||
await this.waitForReady(socket, connectionTimeout); | ||
const { body } = request; | ||
const bodyStream = getIterator(body); | ||
const asyncIterable = this.connect(socket, bodyStream); | ||
const outputPayload = toReadableStream(asyncIterable); | ||
return { | ||
response: new import_protocol_http.HttpResponse({ | ||
statusCode: 200, | ||
// indicates connection success | ||
body: outputPayload | ||
}) | ||
}; | ||
} | ||
/** | ||
* Removes all closing/closed sockets from the socket pool for URL. | ||
*/ | ||
removeNotUsableSockets(url) { | ||
this.sockets[url] = (this.sockets[url] ?? []).filter( | ||
(socket) => ![WebSocket.CLOSING, WebSocket.CLOSED].includes(socket.readyState) | ||
); | ||
} | ||
waitForReady(socket, connectionTimeout) { | ||
return new Promise((resolve, reject) => { | ||
const timeout = setTimeout(() => { | ||
this.removeNotUsableSockets(socket.url); | ||
reject({ | ||
$metadata: { | ||
httpStatusCode: 500 | ||
} | ||
}); | ||
}, connectionTimeout); | ||
socket.onopen = () => { | ||
clearTimeout(timeout); | ||
resolve(); | ||
}; | ||
}); | ||
} | ||
connect(socket, data) { | ||
let streamError = void 0; | ||
let socketErrorOccurred = false; | ||
let reject = /* @__PURE__ */ __name(() => { | ||
}, "reject"); | ||
let resolve = /* @__PURE__ */ __name(() => { | ||
}, "resolve"); | ||
socket.onmessage = (event) => { | ||
resolve({ | ||
done: false, | ||
value: new Uint8Array(event.data) | ||
}); | ||
}; | ||
socket.onerror = (error) => { | ||
socketErrorOccurred = true; | ||
socket.close(); | ||
reject(error); | ||
}; | ||
socket.onclose = () => { | ||
this.removeNotUsableSockets(socket.url); | ||
if (socketErrorOccurred) | ||
return; | ||
if (streamError) { | ||
reject(streamError); | ||
} else { | ||
resolve({ | ||
done: true, | ||
value: void 0 | ||
// unchecked because done=true. | ||
}); | ||
} | ||
}; | ||
const outputStream = { | ||
[Symbol.asyncIterator]: () => ({ | ||
next: () => { | ||
return new Promise((_resolve, _reject) => { | ||
resolve = _resolve; | ||
reject = _reject; | ||
}); | ||
} | ||
}) | ||
}; | ||
const send = /* @__PURE__ */ __name(async () => { | ||
try { | ||
for await (const inputChunk of data) { | ||
socket.send(inputChunk); | ||
} | ||
} catch (err) { | ||
streamError = err; | ||
} finally { | ||
socket.close(1e3); | ||
} | ||
}, "send"); | ||
send(); | ||
return outputStream; | ||
} | ||
}; | ||
__name(_WebSocketFetchHandler, "WebSocketFetchHandler"); | ||
var WebSocketFetchHandler = _WebSocketFetchHandler; | ||
var getIterator = /* @__PURE__ */ __name((stream) => { | ||
if (stream[Symbol.asyncIterator]) { | ||
return stream; | ||
} | ||
if (isReadableStream(stream)) { | ||
return (0, import_eventstream_serde_browser.readableStreamtoIterable)(stream); | ||
} | ||
return { | ||
[Symbol.asyncIterator]: async function* () { | ||
yield stream; | ||
} | ||
}; | ||
}, "getIterator"); | ||
var toReadableStream = /* @__PURE__ */ __name((asyncIterable) => typeof ReadableStream === "function" ? (0, import_eventstream_serde_browser.iterableToReadableStream)(asyncIterable) : asyncIterable, "toReadableStream"); | ||
var isReadableStream = /* @__PURE__ */ __name((payload) => typeof ReadableStream === "function" && payload instanceof ReadableStream, "isReadableStream"); | ||
// Annotate the CommonJS export names for ESM import in node: | ||
0 && (module.exports = { | ||
WebSocketFetchHandler, | ||
eventStreamPayloadHandlerProvider, | ||
getWebSocketPlugin, | ||
resolveWebSocketConfig | ||
}); |
@@ -1,21 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.injectSessionIdMiddlewareOptions = exports.injectSessionIdMiddleware = void 0; | ||
const injectSessionIdMiddleware = () => (next) => async (args) => { | ||
const requestParams = { | ||
...args.input, | ||
}; | ||
const response = await next(args); | ||
const output = response.output; | ||
if (requestParams.SessionId && output.SessionId == null) { | ||
output.SessionId = requestParams.SessionId; | ||
} | ||
return response; | ||
}; | ||
exports.injectSessionIdMiddleware = injectSessionIdMiddleware; | ||
exports.injectSessionIdMiddlewareOptions = { | ||
step: "initialize", | ||
name: "injectSessionIdMiddleware", | ||
tags: ["WEBSOCKET", "EVENT_STREAM"], | ||
override: true, | ||
}; | ||
module.exports = require("./index.js"); |
@@ -1,36 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.websocketEndpointMiddlewareOptions = exports.websocketEndpointMiddleware = void 0; | ||
const protocol_http_1 = require("@smithy/protocol-http"); | ||
const websocketEndpointMiddleware = (config, options) => (next) => (args) => { | ||
var _a, _b, _c; | ||
const { request } = args; | ||
if (protocol_http_1.HttpRequest.isInstance(request) && | ||
((_b = (_a = config.requestHandler.metadata) === null || _a === void 0 ? void 0 : _a.handlerProtocol) === null || _b === void 0 ? void 0 : _b.toLowerCase().includes("websocket"))) { | ||
request.protocol = "wss:"; | ||
request.method = "GET"; | ||
request.path = `${request.path}-websocket`; | ||
const { headers } = request; | ||
delete headers["Content-Type"]; | ||
delete headers["x-amz-content-sha256"]; | ||
for (const name of Object.keys(headers)) { | ||
if (name.indexOf(options.headerPrefix) === 0) { | ||
const chunkedName = name.replace(options.headerPrefix, ""); | ||
request.query[chunkedName] = headers[name]; | ||
} | ||
} | ||
if (headers["x-amz-user-agent"]) { | ||
request.query["user-agent"] = headers["x-amz-user-agent"]; | ||
} | ||
request.headers = { host: (_c = headers.host) !== null && _c !== void 0 ? _c : request.hostname }; | ||
} | ||
return next(args); | ||
}; | ||
exports.websocketEndpointMiddleware = websocketEndpointMiddleware; | ||
exports.websocketEndpointMiddlewareOptions = { | ||
name: "websocketEndpointMiddleware", | ||
tags: ["WEBSOCKET", "EVENT_STREAM"], | ||
relation: "after", | ||
toMiddleware: "eventStreamHeaderMiddleware", | ||
override: true, | ||
}; | ||
module.exports = require("./index.js"); |
@@ -1,5 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isWebSocketRequest = void 0; | ||
const isWebSocketRequest = (request) => request.protocol === "ws:" || request.protocol === "wss:"; | ||
exports.isWebSocketRequest = isWebSocketRequest; | ||
module.exports = require("./index.js"); |
@@ -1,16 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.resolveWebSocketConfig = void 0; | ||
const WebsocketSignatureV4_1 = require("./WebsocketSignatureV4"); | ||
const resolveWebSocketConfig = (input) => ({ | ||
...input, | ||
signer: async (authScheme) => { | ||
const signerObj = await input.signer(authScheme); | ||
if (validateSigner(signerObj)) { | ||
return new WebsocketSignatureV4_1.WebsocketSignatureV4({ signer: signerObj }); | ||
} | ||
throw new Error("Expected WebsocketSignatureV4 signer, please check the client constructor."); | ||
}, | ||
}); | ||
exports.resolveWebSocketConfig = resolveWebSocketConfig; | ||
const validateSigner = (signer) => !!signer; | ||
module.exports = require("./index.js"); |
@@ -1,148 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.WebSocketFetchHandler = void 0; | ||
const util_format_url_1 = require("@aws-sdk/util-format-url"); | ||
const eventstream_serde_browser_1 = require("@smithy/eventstream-serde-browser"); | ||
const fetch_http_handler_1 = require("@smithy/fetch-http-handler"); | ||
const protocol_http_1 = require("@smithy/protocol-http"); | ||
const utils_1 = require("./utils"); | ||
const DEFAULT_WS_CONNECTION_TIMEOUT_MS = 2000; | ||
class WebSocketFetchHandler { | ||
constructor(options, httpHandler = new fetch_http_handler_1.FetchHttpHandler()) { | ||
this.metadata = { | ||
handlerProtocol: "websocket/h1.1", | ||
}; | ||
this.sockets = {}; | ||
this.httpHandler = httpHandler; | ||
if (typeof options === "function") { | ||
this.configPromise = options().then((opts) => opts !== null && opts !== void 0 ? opts : {}); | ||
} | ||
else { | ||
this.configPromise = Promise.resolve(options !== null && options !== void 0 ? options : {}); | ||
} | ||
} | ||
destroy() { | ||
for (const [key, sockets] of Object.entries(this.sockets)) { | ||
for (const socket of sockets) { | ||
socket.close(1000, `Socket closed through destroy() call`); | ||
} | ||
delete this.sockets[key]; | ||
} | ||
} | ||
async handle(request) { | ||
if (!(0, utils_1.isWebSocketRequest)(request)) { | ||
return this.httpHandler.handle(request); | ||
} | ||
const url = (0, util_format_url_1.formatUrl)(request); | ||
const socket = new WebSocket(url); | ||
if (!this.sockets[url]) { | ||
this.sockets[url] = []; | ||
} | ||
this.sockets[url].push(socket); | ||
socket.binaryType = "arraybuffer"; | ||
const { connectionTimeout = DEFAULT_WS_CONNECTION_TIMEOUT_MS } = await this.configPromise; | ||
await this.waitForReady(socket, connectionTimeout); | ||
const { body } = request; | ||
const bodyStream = getIterator(body); | ||
const asyncIterable = this.connect(socket, bodyStream); | ||
const outputPayload = toReadableStream(asyncIterable); | ||
return { | ||
response: new protocol_http_1.HttpResponse({ | ||
statusCode: 200, | ||
body: outputPayload, | ||
}), | ||
}; | ||
} | ||
removeNotUsableSockets(url) { | ||
var _a; | ||
this.sockets[url] = ((_a = this.sockets[url]) !== null && _a !== void 0 ? _a : []).filter((socket) => ![WebSocket.CLOSING, WebSocket.CLOSED].includes(socket.readyState)); | ||
} | ||
waitForReady(socket, connectionTimeout) { | ||
return new Promise((resolve, reject) => { | ||
const timeout = setTimeout(() => { | ||
this.removeNotUsableSockets(socket.url); | ||
reject({ | ||
$metadata: { | ||
httpStatusCode: 500, | ||
}, | ||
}); | ||
}, connectionTimeout); | ||
socket.onopen = () => { | ||
clearTimeout(timeout); | ||
resolve(); | ||
}; | ||
}); | ||
} | ||
connect(socket, data) { | ||
let streamError = undefined; | ||
let socketErrorOccurred = false; | ||
let reject = () => { }; | ||
let resolve = () => { }; | ||
socket.onmessage = (event) => { | ||
resolve({ | ||
done: false, | ||
value: new Uint8Array(event.data), | ||
}); | ||
}; | ||
socket.onerror = (error) => { | ||
socketErrorOccurred = true; | ||
socket.close(); | ||
reject(error); | ||
}; | ||
socket.onclose = () => { | ||
this.removeNotUsableSockets(socket.url); | ||
if (socketErrorOccurred) | ||
return; | ||
if (streamError) { | ||
reject(streamError); | ||
} | ||
else { | ||
resolve({ | ||
done: true, | ||
value: undefined, | ||
}); | ||
} | ||
}; | ||
const outputStream = { | ||
[Symbol.asyncIterator]: () => ({ | ||
next: () => { | ||
return new Promise((_resolve, _reject) => { | ||
resolve = _resolve; | ||
reject = _reject; | ||
}); | ||
}, | ||
}), | ||
}; | ||
const send = async () => { | ||
try { | ||
for await (const inputChunk of data) { | ||
socket.send(inputChunk); | ||
} | ||
} | ||
catch (err) { | ||
streamError = err; | ||
} | ||
finally { | ||
socket.close(1000); | ||
} | ||
}; | ||
send(); | ||
return outputStream; | ||
} | ||
} | ||
exports.WebSocketFetchHandler = WebSocketFetchHandler; | ||
const getIterator = (stream) => { | ||
if (stream[Symbol.asyncIterator]) { | ||
return stream; | ||
} | ||
if (isReadableStream(stream)) { | ||
return (0, eventstream_serde_browser_1.readableStreamtoIterable)(stream); | ||
} | ||
return { | ||
[Symbol.asyncIterator]: async function* () { | ||
yield stream; | ||
}, | ||
}; | ||
}; | ||
const toReadableStream = (asyncIterable) => typeof ReadableStream === "function" ? (0, eventstream_serde_browser_1.iterableToReadableStream)(asyncIterable) : asyncIterable; | ||
const isReadableStream = (payload) => typeof ReadableStream === "function" && payload instanceof ReadableStream; | ||
module.exports = require("./index.js"); |
@@ -1,30 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.WebsocketSignatureV4 = void 0; | ||
const protocol_http_1 = require("@smithy/protocol-http"); | ||
const utils_1 = require("./utils"); | ||
class WebsocketSignatureV4 { | ||
constructor(options) { | ||
this.signer = options.signer; | ||
} | ||
presign(originalRequest, options = {}) { | ||
return this.signer.presign(originalRequest, options); | ||
} | ||
async sign(toSign, options) { | ||
if (protocol_http_1.HttpRequest.isInstance(toSign) && (0, utils_1.isWebSocketRequest)(toSign)) { | ||
const signedRequest = await this.signer.presign({ ...toSign, body: "" }, { | ||
...options, | ||
expiresIn: 60, | ||
unsignableHeaders: new Set(Object.keys(toSign.headers).filter((header) => header !== "host")), | ||
}); | ||
return { | ||
...signedRequest, | ||
body: toSign.body, | ||
}; | ||
} | ||
else { | ||
return this.signer.sign(toSign, options); | ||
} | ||
} | ||
} | ||
exports.WebsocketSignatureV4 = WebsocketSignatureV4; | ||
module.exports = require("./index.js"); |
{ | ||
"name": "@aws-sdk/middleware-websocket", | ||
"version": "3.489.0", | ||
"version": "3.495.0", | ||
"main": "./dist-cjs/index.js", | ||
@@ -9,3 +9,3 @@ "module": "./dist-es/index.js", | ||
"build": "concurrently 'yarn:build:cjs' 'yarn:build:es' 'yarn:build:types'", | ||
"build:cjs": "tsc -p tsconfig.cjs.json", | ||
"build:cjs": "node ../../scripts/compilation/inline middleware-websocket", | ||
"build:es": "tsc -p tsconfig.es.json", | ||
@@ -25,12 +25,12 @@ "build:include:deps": "lerna run --scope $npm_package_name --include-dependencies build", | ||
"dependencies": { | ||
"@aws-sdk/middleware-signing": "3.489.0", | ||
"@aws-sdk/types": "3.489.0", | ||
"@aws-sdk/util-format-url": "3.489.0", | ||
"@smithy/eventstream-codec": "^2.0.0", | ||
"@smithy/eventstream-serde-browser": "^2.0.16", | ||
"@smithy/fetch-http-handler": "^2.3.2", | ||
"@smithy/protocol-http": "^3.0.12", | ||
"@smithy/signature-v4": "^2.0.0", | ||
"@smithy/types": "^2.8.0", | ||
"@smithy/util-hex-encoding": "^2.0.0", | ||
"@aws-sdk/middleware-signing": "3.495.0", | ||
"@aws-sdk/types": "3.495.0", | ||
"@aws-sdk/util-format-url": "3.495.0", | ||
"@smithy/eventstream-codec": "^2.1.0", | ||
"@smithy/eventstream-serde-browser": "^2.1.0", | ||
"@smithy/fetch-http-handler": "^2.4.0", | ||
"@smithy/protocol-http": "^3.1.0", | ||
"@smithy/signature-v4": "^2.1.0", | ||
"@smithy/types": "^2.9.0", | ||
"@smithy/util-hex-encoding": "^2.1.0", | ||
"tslib": "^2.5.0" | ||
@@ -37,0 +37,0 @@ }, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
964
50707
+ Added@aws-sdk/middleware-signing@3.495.0(transitive)
+ Added@aws-sdk/types@3.495.0(transitive)
+ Added@aws-sdk/util-format-url@3.495.0(transitive)
- Removed@aws-sdk/middleware-signing@3.489.0(transitive)
- Removed@aws-sdk/types@3.489.0(transitive)
- Removed@aws-sdk/util-format-url@3.489.0(transitive)
Updated@aws-sdk/types@3.495.0
Updated@smithy/protocol-http@^3.1.0
Updated@smithy/signature-v4@^2.1.0
Updated@smithy/types@^2.9.0