mockttp
Version:
Mock HTTP server for testing HTTP clients and stubbing webservices
154 lines • 7.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WsStepDefinitionLookup = exports.DelayStep = exports.TimeoutStep = exports.ResetConnectionStep = exports.CloseConnectionStep = exports.RejectWebSocketStep = exports.ListenWebSocketStep = exports.EchoWebSocketStep = exports.PassThroughWebSocketStep = void 0;
const _ = require("lodash");
const serialization_1 = require("../../serialization/serialization");
const request_step_definitions_1 = require("../requests/request-step-definitions");
Object.defineProperty(exports, "CloseConnectionStep", { enumerable: true, get: function () { return request_step_definitions_1.CloseConnectionStep; } });
Object.defineProperty(exports, "DelayStep", { enumerable: true, get: function () { return request_step_definitions_1.DelayStep; } });
Object.defineProperty(exports, "ResetConnectionStep", { enumerable: true, get: function () { return request_step_definitions_1.ResetConnectionStep; } });
Object.defineProperty(exports, "TimeoutStep", { enumerable: true, get: function () { return request_step_definitions_1.TimeoutStep; } });
const match_replace_1 = require("../match-replace");
class PassThroughWebSocketStep extends serialization_1.Serializable {
constructor(options = {}) {
super();
this.type = 'ws-passthrough';
this.ignoreHostHttpsErrors = [];
this.extraCACertificates = [];
this.ignoreHostHttpsErrors = options.ignoreHostHttpsErrors || [];
if (!Array.isArray(this.ignoreHostHttpsErrors) && typeof this.ignoreHostHttpsErrors !== 'boolean') {
throw new Error("ignoreHostHttpsErrors must be an array or a boolean");
}
this.lookupOptions = options.lookupOptions;
this.proxyConfig = options.proxyConfig;
this.simulateConnectionErrors = !!options.simulateConnectionErrors;
this.extraCACertificates = options.additionalTrustedCAs || [];
this.clientCertificateHostMap = options.clientCertificateHostMap || {};
if (options.transformRequest) {
if (options.transformRequest.setProtocol && !['ws', 'wss'].includes(options.transformRequest.setProtocol)) {
throw new Error(`Invalid request protocol "${options.transformRequest.setProtocol}" must be "ws" or "wss"`);
}
if ([
options.transformRequest.replaceHost,
options.transformRequest.matchReplaceHost
].filter(o => !!o).length > 1) {
throw new Error("Only one request host transform can be specified at a time");
}
if (options.transformRequest.replaceHost) {
const { targetHost } = options.transformRequest.replaceHost;
if (targetHost.includes('/')) {
throw new Error(`Request transform replacement hosts cannot include a path or protocol, but "${targetHost}" does`);
}
}
if (options.transformRequest.matchReplaceHost) {
const values = Object.values(options.transformRequest.matchReplaceHost.replacements);
for (let replacementValue of values) {
if (replacementValue.includes('/')) {
throw new Error(`Request transform replacement hosts cannot include a path or protocol, but "${replacementValue}" does`);
}
}
}
this.transformRequest = options.transformRequest;
}
}
explain() {
const { targetHost } = this.transformRequest?.replaceHost || {};
return targetHost
? `forward the websocket to ${targetHost}`
: 'pass the websocket through to the target host';
}
/**
* @internal
*/
serialize(channel) {
return {
type: this.type,
...this.transformRequest?.replaceHost ? {
// Backward compat:
forwarding: this.transformRequest?.replaceHost
} : {},
lookupOptions: this.lookupOptions,
proxyConfig: (0, serialization_1.serializeProxyConfig)(this.proxyConfig, channel),
simulateConnectionErrors: this.simulateConnectionErrors,
ignoreHostCertificateErrors: this.ignoreHostHttpsErrors,
extraCACertificates: this.extraCACertificates.map((certObject) => {
// We use toString to make sure that buffers always end up as
// as UTF-8 string, to avoid serialization issues. Strings are an
// easy safe format here, since it's really all just plain-text PEM
// under the hood.
if ('cert' in certObject) {
return { cert: certObject.cert.toString('utf8') };
}
else {
return certObject;
}
}),
clientCertificateHostMap: _.mapValues(this.clientCertificateHostMap, ({ pfx, passphrase }) => ({ pfx: (0, serialization_1.serializeBuffer)(pfx), passphrase })),
transformRequest: this.transformRequest ? {
...this.transformRequest,
matchReplaceHost: !!this.transformRequest?.matchReplaceHost
? {
...this.transformRequest.matchReplaceHost,
replacements: (0, match_replace_1.serializeMatchReplaceConfiguration)(this.transformRequest.matchReplaceHost.replacements)
}
: undefined,
matchReplacePath: !!this.transformRequest?.matchReplacePath
? (0, match_replace_1.serializeMatchReplaceConfiguration)(this.transformRequest.matchReplacePath)
: undefined,
matchReplaceQuery: !!this.transformRequest?.matchReplaceQuery
? (0, match_replace_1.serializeMatchReplaceConfiguration)(this.transformRequest.matchReplaceQuery)
: undefined
} : undefined,
};
}
}
exports.PassThroughWebSocketStep = PassThroughWebSocketStep;
PassThroughWebSocketStep.isFinal = true;
class EchoWebSocketStep extends serialization_1.Serializable {
constructor() {
super(...arguments);
this.type = 'ws-echo';
}
explain() {
return "echo all websocket messages";
}
}
exports.EchoWebSocketStep = EchoWebSocketStep;
EchoWebSocketStep.isFinal = true;
class ListenWebSocketStep extends serialization_1.Serializable {
constructor() {
super(...arguments);
this.type = 'ws-listen';
}
explain() {
return "silently accept websocket messages without responding";
}
}
exports.ListenWebSocketStep = ListenWebSocketStep;
ListenWebSocketStep.isFinal = true;
class RejectWebSocketStep extends serialization_1.Serializable {
constructor(statusCode, statusMessage = 'WebSocket rejected', headers = {}, body = '') {
super();
this.statusCode = statusCode;
this.statusMessage = statusMessage;
this.headers = headers;
this.body = body;
this.type = 'ws-reject';
}
explain() {
return `explicitly reject the websocket upgrade with status ${this.statusCode}`;
}
}
exports.RejectWebSocketStep = RejectWebSocketStep;
RejectWebSocketStep.isFinal = true;
exports.WsStepDefinitionLookup = {
'ws-passthrough': PassThroughWebSocketStep,
'ws-echo': EchoWebSocketStep,
'ws-listen': ListenWebSocketStep,
'ws-reject': RejectWebSocketStep,
'close-connection': request_step_definitions_1.CloseConnectionStep,
'reset-connection': request_step_definitions_1.ResetConnectionStep,
'timeout': request_step_definitions_1.TimeoutStep,
'delay': request_step_definitions_1.DelayStep
};
//# sourceMappingURL=websocket-step-definitions.js.map