Skip to content

Commit f005ba1

Browse files
committed
Add support for HTK TLS config in client send API
1 parent f35ccab commit f005ba1

File tree

2 files changed

+65
-8
lines changed

2 files changed

+65
-8
lines changed

src/api/rest-api.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,20 @@ export function exposeRestAPI(
8888
if (!request) throw new StatusError(400, "No request definition provided");
8989
if (!options) throw new StatusError(400, "No request options provided");
9090

91-
const abortController = new AbortController();
91+
// Various buffers are serialized as base64 (for both requests & responses)
92+
request.rawBody = Buffer.from(request.rawBody ?? '', 'base64');
93+
if (options.trustAdditionalCAs) {
94+
options.trustAdditionalCAs = options.trustAdditionalCAs.map(
95+
({ cert }: { cert: string }) => Buffer.from(cert, 'base64')
96+
);
97+
}
98+
if (options.clientCertificate) {
99+
options.clientCertificate.pfx = Buffer.from(options.clientCertificate.pfx, 'base64');
100+
}
92101

93-
const resultStream = apiModel.sendRequest({
94-
...request,
95-
// Body buffers are serialized as base64 (for both requests & responses)
96-
rawBody: Buffer.from(request.rawBody ?? '', 'base64')
97-
}, {
102+
// Start actually sending the request:
103+
const abortController = new AbortController();
104+
const resultStream = apiModel.sendRequest(request, {
98105
...options,
99106
abortSignal: abortController.signal
100107
});

src/client/client.ts

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import * as stream from 'stream';
2-
import * as net from 'net';
2+
import * as tls from 'tls';
33
import * as http from 'http';
44
import * as https from 'https';
5+
import {
6+
shouldUseStrictHttps,
7+
UPSTREAM_TLS_OPTIONS
8+
} from 'mockttp/dist/rules/passthrough-handling';
59

610
export type RawHeaders = Array<[key: string, value: string]>;
711

@@ -22,6 +26,34 @@ export interface RequestDefinition {
2226
}
2327

2428
export interface RequestOptions {
29+
/**
30+
* A list of hostnames for which server certificate and TLS version errors
31+
* should be ignored (none, by default).
32+
*
33+
* If set to 'true', HTTPS errors will be ignored for all hosts. WARNING:
34+
* Use this at your own risk. Setting this to `true` can open your
35+
* application to MITM attacks and should never be used over any network
36+
* that is not completed trusted end-to-end.
37+
*/
38+
ignoreHostHttpsErrors?: string[] | boolean;
39+
40+
/**
41+
* An array of additional certificates, which should be trusted as certificate
42+
* authorities for upstream hosts, in addition to Node.js's built-in certificate
43+
* authorities.
44+
*
45+
* Each certificate should be an object with either a `cert` key and a string
46+
* or buffer value containing the PEM certificate, or a `certPath` key and a
47+
* string value containing the local path to the PEM certificate.
48+
*/
49+
trustAdditionalCAs?: Array<{ cert: Buffer }>;
50+
51+
/**
52+
* A client certificate that should be used for the connection, if the server
53+
* requests one during the TLS handshake.
54+
*/
55+
clientCertificate?: { pfx: Buffer, passphrase?: string };
56+
2557
/**
2658
* An abort signal, which can be used to cancel the in-process request if
2759
* required.
@@ -67,9 +99,27 @@ export function sendRequest(
6799
): stream.Readable {
68100
const url = new URL(requestDefn.url);
69101

102+
const strictHttpsChecks = shouldUseStrictHttps(url.hostname!, url.port!, options.ignoreHostHttpsErrors ?? []);
103+
const caConfig = options.trustAdditionalCAs
104+
? {
105+
ca: tls.rootCertificates.concat(
106+
options.trustAdditionalCAs.map(({ cert }) => cert.toString('utf8'))
107+
)
108+
}
109+
: {};
110+
70111
const request = (url.protocol === 'https' ? https : http).request(requestDefn.url, {
71112
method: requestDefn.method,
72-
signal: options.abortSignal
113+
signal: options.abortSignal,
114+
115+
// TLS options (should be effectively identical to Mockttp's passthrough config)
116+
...UPSTREAM_TLS_OPTIONS,
117+
minVersion: strictHttpsChecks
118+
? tls.DEFAULT_MIN_VERSION
119+
: 'TLSv1', // Allow TLSv1, if !strict
120+
rejectUnauthorized: strictHttpsChecks,
121+
...caConfig,
122+
...options.clientCertificate
73123
});
74124

75125
options.abortSignal?.addEventListener('abort', () => {

0 commit comments

Comments
 (0)