333
schangxiang@126.com
2025-09-19 18966e02fb573c7e2bb0c6426ed792b38b910940
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
'use strict';
 
const Agent = require('agentkeepalive');
const HttpsAgent = require('agentkeepalive').HttpsAgent;
const urllib = require('urllib');
const ms = require('humanize-ms');
 
class HttpClient extends urllib.HttpClient2 {
  constructor(app) {
    normalizeConfig(app);
    const config = app.config.httpclient;
    super({
      app,
      defaultArgs: config.request,
      agent: new Agent(config.httpAgent),
      httpsAgent: new HttpsAgent(config.httpsAgent),
    });
    this.app = app;
  }
 
  request(url, args, callback) {
    if (typeof args === 'function') {
      callback = args;
      args = null;
    }
 
    args = args || {};
 
    if (args.ctx && args.ctx.tracer) {
      args.tracer = args.ctx.tracer;
    } else {
      args.tracer = args.tracer || this.app.tracer;
    }
 
    // the callback style
    if (callback) {
      this.app.deprecate('[httpclient] We now support async for this function, so callback isn\'t recommended.');
      super.request(url, args)
        .then(result => process.nextTick(() => callback(null, result.data, result.res)))
        .catch(err => process.nextTick(() => callback(err)));
      return;
    }
 
    // the Promise style
    return super.request(url, args);
  }
 
  curl(url, args, callback) {
    return this.request(url, args, callback);
  }
 
  requestThunk(url, args) {
    this.app.deprecate('[httpclient] Please use `request()` instead of `requestThunk()`');
    return callback => {
      this.request(url, args, (err, data, res) => {
        if (err) {
          return callback(err);
        }
        callback(null, {
          data,
          status: res.status,
          headers: res.headers,
          res,
        });
      });
    };
  }
}
 
function normalizeConfig(app) {
  const config = app.config.httpclient;
 
  // compatibility
  if (typeof config.keepAlive === 'boolean') {
    config.httpAgent.keepAlive = config.keepAlive;
    config.httpsAgent.keepAlive = config.keepAlive;
  }
  if (config.timeout) {
    config.timeout = ms(config.timeout);
    config.httpAgent.timeout = config.timeout;
    config.httpsAgent.timeout = config.timeout;
  }
  // compatibility httpclient.freeSocketKeepAliveTimeout => httpclient.freeSocketTimeout
  if (config.freeSocketKeepAliveTimeout && !config.freeSocketTimeout) {
    config.freeSocketTimeout = config.freeSocketKeepAliveTimeout;
    delete config.freeSocketKeepAliveTimeout;
  }
  if (config.freeSocketTimeout) {
    config.freeSocketTimeout = ms(config.freeSocketTimeout);
    config.httpAgent.freeSocketTimeout = config.freeSocketTimeout;
    config.httpsAgent.freeSocketTimeout = config.freeSocketTimeout;
  } else {
    // compatibility agent.freeSocketKeepAliveTimeout
    if (config.httpAgent.freeSocketKeepAliveTimeout && !config.httpAgent.freeSocketTimeout) {
      config.httpAgent.freeSocketTimeout = config.httpAgent.freeSocketKeepAliveTimeout;
      delete config.httpAgent.freeSocketKeepAliveTimeout;
    }
    if (config.httpsAgent.freeSocketKeepAliveTimeout && !config.httpsAgent.freeSocketTimeout) {
      config.httpsAgent.freeSocketTimeout = config.httpsAgent.freeSocketKeepAliveTimeout;
      delete config.httpsAgent.freeSocketKeepAliveTimeout;
    }
  }
 
  if (typeof config.maxSockets === 'number') {
    config.httpAgent.maxSockets = config.maxSockets;
    config.httpsAgent.maxSockets = config.maxSockets;
  }
  if (typeof config.maxFreeSockets === 'number') {
    config.httpAgent.maxFreeSockets = config.maxFreeSockets;
    config.httpsAgent.maxFreeSockets = config.maxFreeSockets;
  }
 
  if (config.httpAgent.timeout < 30000) {
    app.coreLogger.warn('[egg:httpclient] config.httpclient.httpAgent.timeout(%s) can\'t below 30000, auto reset to 30000',
      config.httpAgent.timeout);
    config.httpAgent.timeout = 30000;
  }
  if (config.httpsAgent.timeout < 30000) {
    app.coreLogger.warn('[egg:httpclient] config.httpclient.httpsAgent.timeout(%s) can\'t below 30000, auto reset to 30000',
      config.httpsAgent.timeout);
    config.httpsAgent.timeout = 30000;
  }
 
  if (typeof config.request.timeout === 'string') {
    config.request.timeout = ms(config.request.timeout);
  }
}
 
module.exports = HttpClient;