/
ProxyAgent.ts
59 lines (44 loc) · 1.65 KB
/
ProxyAgent.ts
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
import { Context, Next } from 'koa';
import FormData from 'form-data';
import { createReadStream } from 'fs';
import { request } from '@tech_query/node-toolkit';
function buildData({ method, request: { type, body, files = {} } }: Context) {
if (/^Head|Get|Delete$/.test(method)) return '';
if (type !== 'multipart/form-data') return body;
const form = new FormData();
for (const key in body) form.append(key, body[key]);
for (const [key, data] of Object.entries(files)) {
const files = data instanceof Array ? data : [data];
for (const { filepath, originalFilename } of files)
form.append(key, createReadStream(filepath), originalFilename);
}
return form;
}
async function pipe(URL: string, context: Context) {
const { host, ...headers } = context.header;
const response = await request(
URL,
context.method,
headers,
buildData(context)
);
(context.status = response.statusCode),
(context.message = response.statusMessage);
for (const key in response.headers)
if (key !== 'status')
context.set(
key.replace(/^\w|-\w/g, char => char.toUpperCase()),
response.headers[key]
);
return (context.body = response);
}
export function ProxyAgent(proxyMap: Record<string, RegExp>) {
return async function (context: Context, next: Next) {
const URL = context.path + context.request.search;
for (const path in proxyMap) {
const final = URL.replace(proxyMap[path], path);
if (final !== URL) return pipe(final, context);
}
await next();
};
}