3 const tls = require('tls');
4 const url = require('url');
5 const http = require('http');
6 const util = require('util');
7 const inherits = util.inherits;
8 const debug = util.debuglog('https');
10 function Server(opts, requestListener) {
11 if (!(this instanceof Server)) return new Server(opts, requestListener);
13 if (process.features.tls_npn && !opts.NPNProtocols) {
14 opts.NPNProtocols = ['http/1.1', 'http/1.0'];
17 tls.Server.call(this, opts, http._connectionListener);
19 this.httpAllowHalfOpen = false;
21 if (requestListener) {
22 this.addListener('request', requestListener);
25 this.addListener('clientError', function(err, conn) {
29 this.timeout = 2 * 60 * 1000;
31 inherits(Server, tls.Server);
32 exports.Server = Server;
34 Server.prototype.setTimeout = http.Server.prototype.setTimeout;
36 exports.createServer = function(opts, requestListener) {
37 return new Server(opts, requestListener);
43 function createConnection(port, host, options) {
44 if (port !== null && typeof port === 'object') {
46 } else if (host !== null && typeof host === 'object') {
48 } else if (options === null || typeof options !== 'object') {
52 if (typeof port === 'number') {
56 if (typeof host === 'string') {
60 debug('createConnection', options);
62 if (options._agentKey) {
63 const session = this._getSession(options._agentKey);
65 debug('reuse session for %j', options._agentKey);
66 options = util._extend({
73 const socket = tls.connect(options, function() {
74 if (!options._agentKey)
77 self._cacheSession(options._agentKey, socket.getSession());
83 function Agent(options) {
84 http.Agent.call(this, options);
85 this.defaultPort = 443;
86 this.protocol = 'https:';
87 this.maxCachedSessions = this.options.maxCachedSessions;
88 if (this.maxCachedSessions === undefined)
89 this.maxCachedSessions = 100;
91 this._sessionCache = {
96 inherits(Agent, http.Agent);
97 Agent.prototype.createConnection = createConnection;
99 Agent.prototype.getName = function(options) {
100 var name = http.Agent.prototype.getName.call(this, options);
108 name += options.cert;
112 name += options.ciphers;
123 if (options.rejectUnauthorized !== undefined)
124 name += options.rejectUnauthorized;
129 Agent.prototype._getSession = function _getSession(key) {
130 return this._sessionCache.map[key];
133 Agent.prototype._cacheSession = function _cacheSession(key, session) {
134 // Fast case - update existing entry
135 if (this._sessionCache.map[key]) {
136 this._sessionCache.map[key] = session;
141 if (this._sessionCache.list.length >= this.maxCachedSessions) {
142 const oldKey = this._sessionCache.list.shift();
143 debug('evicting %j', oldKey);
144 delete this._sessionCache.map[oldKey];
147 this._sessionCache.list.push(key);
148 this._sessionCache.map[key] = session;
151 const globalAgent = new Agent();
153 exports.globalAgent = globalAgent;
154 exports.Agent = Agent;
156 exports.request = function(options, cb) {
157 if (typeof options === 'string') {
158 options = url.parse(options);
160 options = util._extend({}, options);
162 options._defaultAgent = globalAgent;
163 return http.request(options, cb);
166 exports.get = function(options, cb) {
167 var req = exports.request(options, cb);