Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more HTTPS tests #1430

Merged
merged 12 commits into from
Sep 2, 2020
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
"@types/express": "^4.17.7",
"@types/node": "^14.6.0",
"@types/node-fetch": "^2.5.7",
"@types/pem": "^1.9.5",
"@types/pify": "^3.0.2",
"@types/request": "^2.48.5",
"@types/sinon": "^9.0.5",
"@types/tough-cookie": "^4.0.0",
Expand All @@ -81,6 +83,8 @@
"np": "^6.4.0",
"nyc": "^15.1.0",
"p-event": "^4.2.0",
"pem": "^1.14.4",
"pify": "^5.0.0",
"sinon": "^9.0.3",
"slow-stream": "0.0.4",
"tempy": "^0.6.0",
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ For browser usage, we recommend [Ky](https://github.com/sindresorhus/ky) by the
- [Errors with metadata](#errors)
- [JSON mode](#json-mode)
- [WHATWG URL support](#url)
- [HTTPS API](#https)
- [HTTPS API](#advanced-https-api)
- [Hooks](#hooks)
- [Instances with custom defaults](#instances)
- [Types](#types)
Expand Down
72 changes: 72 additions & 0 deletions test/helpers/create-https-test-server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import https = require('https');
import net = require('net');
import express = require('express');
import pify = require('pify');
import pem = require('pem');

export type HttpsServerOptions = {
commonName?: string;
days?: number;
};

export interface ExtendedHttpsTestServer extends express.Express {
https: https.Server;
caKey: Buffer;
caCert: Buffer;
url: string;
port: number;
close: () => Promise<any>;
}

const createHttpsTestServer = async (options: HttpsServerOptions = {}): Promise<ExtendedHttpsTestServer> => {
const createCSR = pify(pem.createCSR);
szmarczak marked this conversation as resolved.
Show resolved Hide resolved
const createCertificate = pify(pem.createCertificate);

const caCSRResult = await createCSR({commonName: 'authority'});
const caResult = await createCertificate({
csr: caCSRResult.csr,
clientKey: caCSRResult.clientKey,
selfSigned: true
});
const caKey = caResult.clientKey;
const caCert = caResult.certificate;

const serverCSRResult = await createCSR({commonName: options.commonName ?? 'localhost'});
const serverResult = await createCertificate({
csr: serverCSRResult.csr,
clientKey: serverCSRResult.clientKey,
serviceKey: caKey,
serviceCertificate: caCert,
days: options.days ?? 365
});
const serverKey = serverResult.clientKey;
const serverCert = serverResult.certificate;

const server = express() as ExtendedHttpsTestServer;
server.https = https.createServer(
szmarczak marked this conversation as resolved.
Show resolved Hide resolved
{
key: serverKey,
cert: serverCert,
ca: caCert,
requestCert: true,
rejectUnauthorized: false // This should be checked by the test
},
server
);

server.set('etag', false);

await pify(server.https.listen.bind(server.https))();

server.caKey = caKey;
server.caCert = caCert;
server.port = (server.https.address() as net.AddressInfo).port;
server.url = `https://localhost:${(server.port)}`;

server.close = async () =>
pify(server.https.close.bind(server.https))();

return server;
};

export default createHttpsTestServer;
26 changes: 25 additions & 1 deletion test/helpers/with-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import * as test from 'ava';
import is from '@sindresorhus/is';
import http = require('http');
import tempy = require('tempy');
import createHttpsTestServer, {ExtendedHttpsTestServer, HttpsServerOptions} from './create-https-test-server';
import createTestServer = require('create-test-server');
import FakeTimers = require('@sinonjs/fake-timers');
import got, {InstanceDefaults} from '../../source';
import {ExtendedGot, ExtendedHttpServer, ExtendedTestServer, GlobalClock, InstalledClock} from './types';

export type RunTestWithServer = (t: test.ExecutionContext, server: ExtendedTestServer, got: ExtendedGot, clock: GlobalClock) => Promise<void> | void;
export type RunTestWithHttpsServer = (t: test.ExecutionContext, server: ExtendedHttpsTestServer, got: ExtendedGot) => Promise<void> | void;
export type RunTestWithSocket = (t: test.ExecutionContext, server: ExtendedHttpServer) => Promise<void> | void;

const generateHook = ({install, options: testServerOptions}: {install?: boolean; options?: unknown}): test.Macro<[RunTestWithServer]> => async (t, run) => {
Expand Down Expand Up @@ -43,8 +45,8 @@ const generateHook = ({install, options: testServerOptions}: {install?: boolean;

const preparedGot = got.extend({prefixUrl: server.url, ...options}) as ExtendedGot;
preparedGot.secure = got.extend({prefixUrl: server.sslUrl, ...options});

server.hostname = (new URL(server.url)).hostname;

server.sslHostname = (new URL(server.sslUrl)).hostname;

try {
Expand All @@ -63,6 +65,28 @@ export default generateHook({install: false});

export const withServerAndFakeTimers = generateHook({install: true});

const generateHttpsHook = (options?: HttpsServerOptions): test.Macro<[RunTestWithHttpsServer]> => async (t, run) => {
const server = await createHttpsTestServer(options);

const preparedGot = got.extend({
// @ts-expect-error Augmenting for test detection
avaTest: t.title,
prefixUrl: server.url,
https: {
certificateAuthority: (server as any).caCert,
rejectUnauthorized: true
}
}) as ExtendedGot;

try {
await run(t, server, preparedGot);
} finally {
await server.close();
}
};

export const withHttpsServer = generateHttpsHook;

// TODO: remove this when `create-test-server` supports custom listen
export const withSocketServer: test.Macro<[RunTestWithSocket]> = async (t, run) => {
const socketPath = tempy.file({extension: 'socket'});
Expand Down
Loading