You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 7-8.RSVP
Socket
Socket
Sign inDemoInstall

mockttp

Package Overview
Dependencies
Maintainers
1
Versions
122
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.17.1 to 0.17.2

3

dist/rules/handlers.d.ts

@@ -20,2 +20,3 @@ /**

body?: string | Buffer;
response?: CallbackResponseResult;
}

@@ -77,3 +78,3 @@ export interface CallbackResponseResult {

}
interface PassThroughResponse {
export interface PassThroughResponse {
id: string;

@@ -80,0 +81,0 @@ statusCode: number;

@@ -56,2 +56,14 @@ "use strict";

exports.SimpleHandler = SimpleHandler;
function writeResponseFromCallback(result, response) {
if (result.json !== undefined) {
result.headers = _.assign(result.headers || {}, { 'Content-Type': 'application/json' });
result.body = JSON.stringify(result.json);
delete result.json;
}
if (result.headers) {
request_utils_1.setHeaders(response, result.headers);
}
response.writeHead(result.statusCode || result.status || 200, result.statusMessage);
response.end(result.body || "");
}
class CallbackHandler extends serialization_1.Serializable {

@@ -78,18 +90,9 @@ constructor(callback) {

}
if (outResponse.json !== undefined) {
outResponse.headers = _.assign(outResponse.headers || {}, { 'Content-Type': 'application/json' });
outResponse.body = JSON.stringify(outResponse.json);
delete outResponse.json;
}
if (outResponse.headers) {
request_utils_1.setHeaders(response, outResponse.headers);
}
response.writeHead(outResponse.statusCode || outResponse.status || 200, outResponse.statusMessage);
response.end(outResponse.body || "");
writeResponseFromCallback(outResponse, response);
});
}
serialize(channel) {
channel.onRequest((streamMsg) => {
return this.callback.apply(null, streamMsg.args);
});
channel.onRequest((streamMsg) => __awaiter(this, void 0, void 0, function* () {
return serialization_1.withSerializedBodyBuffer(yield this.callback.apply(null, streamMsg.args));
}));
return { type: this.type, name: this.callback.name };

@@ -99,3 +102,3 @@ }

const rpcCallback = (request) => __awaiter(this, void 0, void 0, function* () {
return yield channel.request({ args: [request] });
return serialization_1.withDeserializedBodyBuffer(yield channel.request({ args: [request] }));
});

@@ -214,4 +217,4 @@ // Pass across the name from the real callback, for explain()

// It's our own bodyReader instance. That's not supposed to happen, but
// it's ok, we just need to use its buffer insteead of the whole object
return replacementBody.buffer;
// it's ok, we just need to use the buffer data instead of the whole object
return Buffer.from(replacementBody.buffer);
}

@@ -239,3 +242,3 @@ else if (replacementBody === '') {

with mismatched values, which may be a mistake. The URL is
${reqUrl} bytes, whilst the header was set to ${replacementHost}.
${reqUrl}, whilst the header was set to ${replacementHost}.
`);

@@ -251,3 +254,3 @@ }

// Helper to handle content-length nicely for you when rewriting requests with callbacks
function getCorrectContentLength(body, originalHeaders, replacementHeaders) {
function getCorrectContentLength(body, originalHeaders, replacementHeaders, mismatchAllowed = false) {
// If there was a content-length header, it might now be wrong, and it's annoying

@@ -276,3 +279,5 @@ // to need to set your own content-length override when you just want to change

if (lengthOverride === originalHeaders['content-length'] &&
lengthOverride !== body.length.toString()) {
lengthOverride !== body.length.toString() &&
!mismatchAllowed // Set for HEAD responses
) {
console.warn(common_tags_1.oneLine `

@@ -361,2 +366,7 @@ Passthrough callback overrode the body and the content-length header

})));
if (modifiedReq.response) {
// The callback has provided a full response: don't passthrough at all, just use it.
writeResponseFromCallback(modifiedReq.response, clientRes);
return;
}
method = modifiedReq.method || method;

@@ -420,4 +430,5 @@ reqUrl = modifiedReq.url || reqUrl;

let modifiedRes;
let body;
try {
const body = yield request_utils_1.streamToBuffer(serverRes);
body = yield request_utils_1.streamToBuffer(serverRes);
modifiedRes = yield this.beforeResponse({

@@ -449,4 +460,11 @@ id: clientReq.id,

if (resBodyOverride !== undefined) {
serverHeaders['content-length'] = getCorrectContentLength(resBodyOverride, serverRes.headers, modifiedRes.headers);
serverHeaders['content-length'] = getCorrectContentLength(resBodyOverride, serverRes.headers, modifiedRes.headers, method === 'HEAD' // HEAD responses are allowed mismatched content-length
);
}
else {
// If you don't specify a body override, we need to use the real
// body anyway, because as we've read it already streaming it to
// the response won't work
resBodyOverride = body;
}
serverHeaders = dropUndefinedValues(serverHeaders);

@@ -513,10 +531,10 @@ }

if (this.beforeRequest) {
channel.onRequest('beforeRequest', (req) => {
return this.beforeRequest(serialization_1.withDeserializedBody(req.args[0]));
});
channel.onRequest('beforeRequest', (req) => __awaiter(this, void 0, void 0, function* () {
return serialization_1.withSerializedBodyBuffer(yield this.beforeRequest(serialization_1.withDeserializedBodyReader(req.args[0])));
}));
}
if (this.beforeResponse) {
channel.onRequest('beforeResponse', (req) => {
return this.beforeResponse(serialization_1.withDeserializedBody(req.args[0]));
});
channel.onRequest('beforeResponse', (req) => __awaiter(this, void 0, void 0, function* () {
return serialization_1.withSerializedBodyBuffer(yield this.beforeResponse(serialization_1.withDeserializedBodyReader(req.args[0])));
}));
}

@@ -535,14 +553,14 @@ return {

if (data.hasBeforeRequestCallback) {
beforeRequest = (req) => {
return channel.request('beforeRequest', {
args: [serialization_1.withSerializedBody(req)]
});
};
beforeRequest = (req) => __awaiter(this, void 0, void 0, function* () {
return serialization_1.withDeserializedBodyBuffer(yield channel.request('beforeRequest', {
args: [serialization_1.withSerializedBodyReader(req)]
}));
});
}
if (data.hasBeforeResponseCallback) {
beforeResponse = (res) => {
return channel.request('beforeResponse', {
args: [serialization_1.withSerializedBody(res)]
});
};
beforeResponse = (res) => __awaiter(this, void 0, void 0, function* () {
return serialization_1.withDeserializedBodyBuffer(yield channel.request('beforeResponse', {
args: [serialization_1.withSerializedBodyReader(res)]
}));
});
}

@@ -549,0 +567,0 @@ return new PassThroughHandler({

@@ -223,2 +223,5 @@ /**

* - Request only: `url` (a full URL to send the request to)
* - Request only: `response` (a response callback result: if provided
* this will be used directly, the request will not be passed through
* at all, and any beforeResponse callback will never fire)
* - Response only: `status` (number, will replace the HTTP status code)

@@ -225,0 +228,0 @@ * - Both: `headers` (object with string keys & values, replaces all

@@ -294,2 +294,5 @@ "use strict";

* - Request only: `url` (a full URL to send the request to)
* - Request only: `response` (a response callback result: if provided
* this will be used directly, the request will not be passed through
* at all, and any beforeResponse callback will never fire)
* - Response only: `status` (number, will replace the HTTP status code)

@@ -296,0 +299,0 @@ * - Both: `headers` (object with string keys & values, replaces all

@@ -41,9 +41,19 @@ /// <reference types="node" />

}
export declare function withSerializedBody<T extends {
export declare function withSerializedBodyReader<T extends {
body: CompletedBody;
}>(input: T): Replace<T, 'body', string>;
export declare function withDeserializedBody<T extends {
export declare function withDeserializedBodyReader<T extends {
headers: Headers;
body: CompletedBody;
}>(input: Replace<T, 'body', string>): T;
export declare function withSerializedBodyBuffer<T extends {
body?: CompletedBody | Buffer | ArrayBuffer | string;
}>(input: T): Replace<T, 'body', string | undefined>;
export declare type WithSerializedBodyBuffer<T extends {
body?: any;
}> = Replace<T, 'body', string | undefined>;
export declare function withDeserializedBodyBuffer<T extends {
headers?: Headers;
body?: Buffer | string | undefined;
}>(input: Replace<T, 'body', string | undefined>): T;
export {};

@@ -14,2 +14,3 @@ "use strict";

const uuid = require("uuid/v4");
const base64_arraybuffer_1 = require("base64-arraybuffer");
const request_utils_1 = require("./request-utils");

@@ -61,17 +62,20 @@ function serialize(obj, stream) {

this._readFromRawStream = (rawData) => {
let data;
try {
data = JSON.parse(rawData);
}
catch (e) {
console.log(e);
console.log('Received unparseable message, dropping.', rawData.toString());
return;
}
if (data.topicId === this.topicId) {
if (_.isEqual(data, DISPOSE_MESSAGE))
this.dispose();
else
this.push(data);
}
const stringData = rawData.toString();
stringData.split('\n').filter(d => !!d).forEach((rawDataLine) => {
let data;
try {
data = JSON.parse(rawDataLine);
}
catch (e) {
console.log(e);
console.log('Received unparseable message, dropping.', rawDataLine.toString());
return;
}
if (data.topicId === this.topicId) {
if (_.isEqual(data, DISPOSE_MESSAGE))
this.dispose();
else
this.push(data);
}
});
};

@@ -83,3 +87,3 @@ this.reading = false;

message.topicId = this.topicId;
const chunk = JSON.stringify(message);
const chunk = JSON.stringify(message) + '\n';
if (!this.rawStream.write(chunk, encoding)) {

@@ -170,7 +174,7 @@ this.rawStream.once('drain', callback);

exports.ClientServerChannel = ClientServerChannel;
function withSerializedBody(input) {
function withSerializedBodyReader(input) {
return Object.assign({}, input, { body: input.body.buffer.toString('base64') });
}
exports.withSerializedBody = withSerializedBody;
function withDeserializedBody(input) {
exports.withSerializedBodyReader = withSerializedBodyReader;
function withDeserializedBodyReader(input) {
return Object.assign({}, input, {

@@ -180,3 +184,31 @@ body: request_utils_1.buildBodyReader(Buffer.from(input.body, 'base64'), input.headers)

}
exports.withDeserializedBody = withDeserializedBody;
exports.withDeserializedBodyReader = withDeserializedBodyReader;
function withSerializedBodyBuffer(input) {
let serializedBody;
if (!input.body) {
serializedBody = undefined;
}
else if (_.isString(input.body)) {
serializedBody = Buffer.from(input.body).toString('base64');
}
else if (_.isBuffer(input.body)) {
serializedBody = input.body.toString('base64');
}
else if (_.isArrayBuffer(input.body) || _.isTypedArray(input.body)) {
serializedBody = base64_arraybuffer_1.encode(input.body);
}
else if (input.body.hasOwnProperty('decodedBuffer')) {
serializedBody = input.body.buffer.toString('base64');
}
return Object.assign({}, input, { body: serializedBody });
}
exports.withSerializedBodyBuffer = withSerializedBodyBuffer;
function withDeserializedBodyBuffer(input) {
if (input.body === undefined)
return input;
return Object.assign({}, input, {
body: Buffer.from(input.body, 'base64')
});
}
exports.withDeserializedBodyBuffer = withDeserializedBodyBuffer;
//# sourceMappingURL=serialization.js.map
{
"name": "mockttp",
"version": "0.17.1",
"version": "0.17.2",
"description": "Mock HTTP server for testing HTTP clients and stubbing webservices",

@@ -16,4 +16,3 @@ "main": "dist/main.js",

"custom-typings",
"docs",
"typedoc"
"docs"
],

@@ -20,0 +19,0 @@ "scripts": {

@@ -26,4 +26,7 @@ /**

ClientServerChannel,
withSerializedBody,
withDeserializedBody
withSerializedBodyReader,
withDeserializedBodyReader,
withSerializedBodyBuffer,
withDeserializedBodyBuffer,
WithSerializedBodyBuffer
} from "../util/serialization";

@@ -51,2 +54,4 @@ import { MaybePromise, Replace } from '../util/type-utils';

body?: string | Buffer;
response?: CallbackResponseResult;
}

@@ -115,2 +120,20 @@

function writeResponseFromCallback(result: CallbackResponseResult, response: express.Response) {
if (result.json !== undefined) {
result.headers = _.assign(result.headers || {}, { 'Content-Type': 'application/json' });
result.body = JSON.stringify(result.json);
delete result.json;
}
if (result.headers) {
setHeaders(response, result.headers);
}
response.writeHead(
result.statusCode || result.status || 200,
result.statusMessage
);
response.end(result.body || "");
}
export class CallbackHandler extends Serializable implements RequestHandler {

@@ -141,17 +164,3 @@ readonly type = 'callback';

if (outResponse.json !== undefined) {
outResponse.headers = _.assign(outResponse.headers || {}, { 'Content-Type': 'application/json' });
outResponse.body = JSON.stringify(outResponse.json);
delete outResponse.json;
}
if (outResponse.headers) {
setHeaders(response, outResponse.headers);
}
response.writeHead(
outResponse.statusCode || outResponse.status || 200,
outResponse.statusMessage
);
response.end(outResponse.body || "");
writeResponseFromCallback(outResponse, response);
}

@@ -163,4 +172,6 @@

CallbackResponseResult
>((streamMsg) => {
return this.callback.apply(null, streamMsg.args);
>(async (streamMsg) => {
return withSerializedBodyBuffer(
await this.callback.apply(null, streamMsg.args)
);
});

@@ -173,6 +184,8 @@

const rpcCallback = async (request: CompletedRequest) => {
return await channel.request<
CallbackRequestMessage,
CallbackResponseResult
>({ args: [request] });
return withDeserializedBodyBuffer(
await channel.request<
CallbackRequestMessage,
WithSerializedBodyBuffer<CallbackResponseResult>
>({ args: [request] })
);
};

@@ -317,3 +330,3 @@ // Pass across the name from the real callback, for explain()

interface PassThroughResponse {
export interface PassThroughResponse {
id: string;

@@ -362,4 +375,4 @@ statusCode: number;

// It's our own bodyReader instance. That's not supposed to happen, but
// it's ok, we just need to use its buffer insteead of the whole object
return (replacementBody as CompletedBody).buffer;
// it's ok, we just need to use the buffer data instead of the whole object
return Buffer.from((replacementBody as CompletedBody).buffer);
} else if (replacementBody === '') {

@@ -391,3 +404,3 @@ // For empty bodies, it's slightly more convenient if they're truthy

with mismatched values, which may be a mistake. The URL is
${reqUrl} bytes, whilst the header was set to ${replacementHost}.
${reqUrl}, whilst the header was set to ${replacementHost}.
`);

@@ -408,3 +421,4 @@ }

originalHeaders: Headers,
replacementHeaders: Headers | undefined
replacementHeaders: Headers | undefined,
mismatchAllowed: boolean = false
): string | undefined {

@@ -439,3 +453,4 @@ // If there was a content-length header, it might now be wrong, and it's annoying

lengthOverride === originalHeaders['content-length'] &&
lengthOverride !== body.length.toString()
lengthOverride !== body.length.toString() &&
!mismatchAllowed // Set for HEAD responses
) {

@@ -544,2 +559,8 @@ console.warn(oneLine`

if (modifiedReq.response) {
// The callback has provided a full response: don't passthrough at all, just use it.
writeResponseFromCallback(modifiedReq.response, clientRes);
return;
}
method = modifiedReq.method || method;

@@ -616,4 +637,5 @@ reqUrl = modifiedReq.url || reqUrl;

let modifiedRes: CallbackResponseResult;
let body: Buffer;
try {
const body = await streamToBuffer(serverRes);
body = await streamToBuffer(serverRes);
modifiedRes = await this.beforeResponse({

@@ -650,4 +672,10 @@ id: clientReq.id,

serverRes.headers,
modifiedRes.headers
modifiedRes.headers,
method === 'HEAD' // HEAD responses are allowed mismatched content-length
);
} else {
// If you don't specify a body override, we need to use the real
// body anyway, because as we've read it already streaming it to
// the response won't work
resBodyOverride = body;
}

@@ -724,4 +752,8 @@

CallbackRequestResult
>('beforeRequest', (req) => {
return this.beforeRequest!(withDeserializedBody(req.args[0]));
>('beforeRequest', async (req) => {
return withSerializedBodyBuffer(
await this.beforeRequest!(
withDeserializedBodyReader(req.args[0])
)
);
});

@@ -734,4 +766,8 @@ }

CallbackResponseResult
>('beforeResponse', (req) => {
return this.beforeResponse!(withDeserializedBody(req.args[0]));
>('beforeResponse', async (req) => {
return withSerializedBodyBuffer(
await this.beforeResponse!(
withDeserializedBodyReader(req.args[0])
)
);
});

@@ -754,9 +790,11 @@ }

if (data.hasBeforeRequestCallback) {
beforeRequest = (req: CompletedRequest) => {
return channel.request<
BeforePassthroughRequestRequest,
CallbackRequestResult
>('beforeRequest', {
args: [withSerializedBody(req)]
});
beforeRequest = async (req: CompletedRequest) => {
return withDeserializedBodyBuffer(
await channel.request<
BeforePassthroughRequestRequest,
WithSerializedBodyBuffer<CallbackRequestResult>
>('beforeRequest', {
args: [withSerializedBodyReader(req)]
})
);
};

@@ -766,9 +804,9 @@ }

if (data.hasBeforeResponseCallback) {
beforeResponse = (res: PassThroughResponse) => {
return channel.request<
beforeResponse = async (res: PassThroughResponse) => {
return withDeserializedBodyBuffer(await channel.request<
BeforePassthroughResponseRequest,
CallbackResponseResult
WithSerializedBodyBuffer<CallbackResponseResult>
>('beforeResponse', {
args: [withSerializedBody(res)]
});
args: [withSerializedBodyReader(res)]
}));
};

@@ -775,0 +813,0 @@ }

@@ -402,2 +402,5 @@ /**

* - Request only: `url` (a full URL to send the request to)
* - Request only: `response` (a response callback result: if provided
* this will be used directly, the request will not be passed through
* at all, and any beforeResponse callback will never fire)
* - Response only: `status` (number, will replace the HTTP status code)

@@ -404,0 +407,0 @@ * - Both: `headers` (object with string keys & values, replaces all

import * as _ from 'lodash';
import { Duplex } from 'stream';
import uuid = require('uuid/v4');
import { encode as encodeBase64 } from 'base64-arraybuffer';

@@ -108,3 +109,3 @@ import { MaybePromise, Replace, Omit } from './type-utils';

message.topicId = this.topicId;
const chunk = JSON.stringify(message);
const chunk = JSON.stringify(message) + '\n';

@@ -119,15 +120,18 @@ if (!this.rawStream.write(chunk, encoding)) {

_readFromRawStream = (rawData: any) => {
let data: Message;
try {
data = JSON.parse(rawData);
} catch (e) {
console.log(e);
console.log('Received unparseable message, dropping.', rawData.toString());
return;
}
const stringData: string = rawData.toString();
stringData.split('\n').filter(d => !!d).forEach((rawDataLine) => {
let data: Message;
try {
data = JSON.parse(rawDataLine);
} catch (e) {
console.log(e);
console.log('Received unparseable message, dropping.', rawDataLine.toString());
return;
}
if (data.topicId === this.topicId) {
if (_.isEqual(data, DISPOSE_MESSAGE)) this.dispose();
else this.push(data);
}
if (data.topicId === this.topicId) {
if (_.isEqual(data, DISPOSE_MESSAGE)) this.dispose();
else this.push(data);
}
});
}

@@ -231,10 +235,50 @@

export function withSerializedBody<T extends { body: CompletedBody }>(input: T): Replace<T, 'body', string> {
export function withSerializedBodyReader<T extends {
body: CompletedBody
}>(input: T): Replace<T, 'body', string> {
return Object.assign({}, input, { body: input.body.buffer.toString('base64') });
}
export function withDeserializedBody<T extends { headers: Headers, body: CompletedBody }>(input: Replace<T, 'body', string>) {
export function withDeserializedBodyReader<T extends { headers: Headers, body: CompletedBody }>(
input: Replace<T, 'body', string>
): T {
return <T> Object.assign({}, input as Omit<T, 'body'>, {
body: buildBodyReader(Buffer.from(input.body, 'base64'), input.headers)
})
}
export function withSerializedBodyBuffer<T extends {
body?: CompletedBody | Buffer | ArrayBuffer | string
}>(input: T): Replace<T, 'body', string | undefined> {
let serializedBody: string | undefined;
if (!input.body) {
serializedBody = undefined;
} else if (_.isString(input.body)) {
serializedBody = Buffer.from(input.body).toString('base64');
} else if (_.isBuffer(input.body)) {
serializedBody = input.body.toString('base64');
} else if (_.isArrayBuffer(input.body) || _.isTypedArray(input.body)) {
serializedBody = encodeBase64(input.body as ArrayBuffer);
} else if (input.body.hasOwnProperty('decodedBuffer')) {
serializedBody = input.body.buffer.toString('base64');
}
return Object.assign({}, input, { body: serializedBody });
}
export type WithSerializedBodyBuffer<T extends { body?: any }> =
Replace<T, 'body', string | undefined>;
export function withDeserializedBodyBuffer<T extends {
headers?: Headers,
body?: Buffer | string | undefined
}>(
input: Replace<T, 'body', string | undefined>
): T {
if (input.body === undefined) return input as T;
return <T> Object.assign({}, input as Omit<T, 'body'>, {
body: Buffer.from(input.body, 'base64')
})
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc