-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhttpclient_next.js
More file actions
85 lines (77 loc) · 2.39 KB
/
httpclient_next.js
File metadata and controls
85 lines (77 loc) · 2.39 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
const debug = require('util').debuglog('egg:lib:core:httpclient_next');
const ms = require('humanize-ms');
const SSRF_HTTPCLIENT = Symbol('SSRF_HTTPCLIENT');
const mainNodejsVersion = parseInt(process.versions.node.split('.')[0]);
let HttpClient;
if (mainNodejsVersion >= 20) {
// urllib@4 only works on Node.js >= 20
try {
HttpClient = require('urllib4').HttpClient;
debug('urllib4 enable');
} catch (err) {
debug('require urllib4 error: %s', err);
}
}
if (!HttpClient) {
// fallback to urllib@3
HttpClient = require('urllib-next').HttpClient;
debug('urllib3 enable');
}
class HttpClientNext extends HttpClient {
constructor(app, options) {
normalizeConfig(app);
options = options || {};
options = {
...app.config.httpclient,
...options,
};
super({
app,
defaultArgs: options.request,
allowH2: options.allowH2,
lookup: options.lookup ?? app.config.httpclient?.lookup,
// use on egg-security ssrf
// https://github.com/eggjs/egg-security/blob/master/lib/extend/safe_curl.js#L11
checkAddress: options.checkAddress,
connect: options.connect,
});
this.app = app;
}
async request(url, options) {
options = options || {};
if (options.ctx && options.ctx.tracer) {
options.tracer = options.ctx.tracer;
} else {
options.tracer = options.tracer || this.app.tracer;
}
return await super.request(url, options);
}
async curl(...args) {
return await this.request(...args);
}
async safeCurl(url, options = {}) {
if (!this[SSRF_HTTPCLIENT]) {
const ssrfConfig = this.app.config.security.ssrf;
if (ssrfConfig?.checkAddress) {
options.checkAddress = ssrfConfig.checkAddress;
} else {
this.app.logger.warn('[egg-security] please configure `config.security.ssrf` first');
}
if (!options.lookup && this.app.config.httpclient.lookup) {
options.lookup = this.app.config.httpclient.lookup;
}
this[SSRF_HTTPCLIENT] = new HttpClientNext(this.app, {
checkAddress: ssrfConfig.checkAddress,
lookup: options.lookup,
});
}
return await this[SSRF_HTTPCLIENT].request(url, options);
}
}
function normalizeConfig(app) {
const config = app.config.httpclient;
if (typeof config.request.timeout === 'string') {
config.request.timeout = ms(config.request.timeout);
}
}
module.exports = HttpClientNext;