-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathmockhttp.ts
More file actions
99 lines (86 loc) · 2.5 KB
/
Copy pathmockhttp.ts
File metadata and controls
99 lines (86 loc) · 2.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import http from "node:http";
import https from "node:https";
class MockHttp {
server: http.Server | https.Server;
mockConfig: {
responseDelays?: number[],
responseCodes?: number[],
username?: string,
password?: string,
token?: string,
};
numOfRequests: number;
constructor() {
this.reset();
}
reset(mockConfig = {}) {
this.mockConfig = mockConfig;
this.numOfRequests = 0;
}
async start(listenPort: number, secure: boolean = false, options?: Record<string, unknown>) {
const serverCreator = secure ? https.createServer : http.createServer;
// @ts-expect-error - Testing different options, so typing is not important
this.server = serverCreator(options, (req, res) => {
const authFailed = checkAuthHeader(this.mockConfig, req);
const body: Uint8Array[] = [];
req.on("data", (chunk: Uint8Array) => {
body.push(chunk);
});
req.on("end", async () => {
console.info(`Received data: ${Buffer.concat(body)}`);
this.numOfRequests++;
const delay =
this.mockConfig.responseDelays &&
this.mockConfig.responseDelays.length > 0
? this.mockConfig.responseDelays.pop()
: undefined;
if (delay) {
await sleep(delay);
}
const responseCode = authFailed
? 401
: this.mockConfig.responseCodes &&
this.mockConfig.responseCodes.length > 0
? this.mockConfig.responseCodes.pop()
: 204;
res.writeHead(responseCode);
res.end();
});
});
this.server.listen(listenPort, () => {
console.info(`Server is running on port ${listenPort}`);
});
}
async stop() {
if (this.server) {
this.server.close();
}
}
}
function checkAuthHeader(mockConfig, req) {
let authFailed = false;
const header = (req.headers.authorization || "").split(/\s+/);
switch (header[0]) {
case "Basic": {
const auth = Buffer.from(header[1], "base64").toString().split(/:/);
if (mockConfig.username !== auth[0] || mockConfig.password !== auth[1]) {
authFailed = true;
}
break;
}
case "Bearer":
if (mockConfig.token !== header[1]) {
authFailed = true;
}
break;
default:
if (mockConfig.username || mockConfig.password || mockConfig.token) {
authFailed = true;
}
}
return authFailed;
}
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
export { MockHttp };