Skip to content

Commit d6bbb19

Browse files
committed
http, https: don't depend on globalAgent
For the `request()` and `get()` functions. I could never really understand why these two functions go through agent first... Especially since the user could be passing `agent: false` or a different Agent instance completely, in which `globalAgent` will be completely bypassed. Moved the relevant logic from `Agent#request()` into the `ClientRequest` constructor. Incidentally, this commit fixes nodejs#7012 (which was the original intent of this commit).
1 parent d307beb commit d6bbb19

3 files changed

Lines changed: 43 additions & 10 deletions

File tree

lib/_http_client.js

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
var util = require('util');
2323
var net = require('net');
24+
var url = require('url');
2425
var EventEmitter = require('events').EventEmitter;
2526
var HTTPParser = process.binding('http_parser').HTTPParser;
2627
var assert = require('assert').ok;
@@ -35,17 +36,39 @@ var debug = common.debug;
3536
var IncomingMessage = require('_http_incoming').IncomingMessage;
3637
var OutgoingMessage = require('_http_outgoing').OutgoingMessage;
3738

38-
var agent = require('_http_agent');
39-
var globalAgent = agent.globalAgent;
39+
var Agent = require('_http_agent');
4040

4141

4242
function ClientRequest(options, cb) {
4343
var self = this;
4444
OutgoingMessage.call(self);
4545

46-
options = util._extend({}, options);
46+
if (util.isString(options)) {
47+
options = url.parse(options);
48+
} else {
49+
options = util._extend({}, options);
50+
}
4751

48-
self.agent = util.isUndefined(options.agent) ? globalAgent : options.agent;
52+
var agent = options.agent;
53+
var defaultAgent = options._defaultAgent || Agent.globalAgent;
54+
if (agent === false) {
55+
agent = new defaultAgent.constructor();
56+
} else if (util.isNullOrUndefined(agent)) {
57+
agent = defaultAgent;
58+
}
59+
self.agent = agent;
60+
61+
if (options.path && / /.test(options.path)) {
62+
// The actual regex is more like /[^A-Za-z0-9\-._~!$&'()*+,;=/:@]/
63+
// with an additional rule for ignoring percentage-escaped characters
64+
// but that's a) hard to capture in a regular expression that performs
65+
// well, and b) possibly too restrictive for real-world usage. That's
66+
// why it only scans for spaces because those are guaranteed to create
67+
// an invalid request.
68+
throw new TypeError('Request path contains unescaped characters.');
69+
} else if (options.protocol && options.protocol !== self.agent.protocol) {
70+
throw new Error('Protocol:' + options.protocol + ' not supported.');
71+
}
4972

5073
var defaultPort = options.defaultPort || self.agent.defaultPort;
5174

@@ -114,8 +137,7 @@ function ClientRequest(options, cb) {
114137
// but only if the Agent will actually reuse the connection!
115138
// If it's not a keepAlive agent, and the maxSockets==Infinity, then
116139
// there's never a case where this socket will actually be reused
117-
var agent = self.agent;
118-
if (!agent.keepAlive && !Number.isFinite(agent.maxSockets)) {
140+
if (!self.agent.keepAlive && !Number.isFinite(self.agent.maxSockets)) {
119141
self._last = true;
120142
self.shouldKeepAlive = false;
121143
} else {

lib/http.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,13 @@ var client = require('_http_client');
4949
var ClientRequest = exports.ClientRequest = client.ClientRequest;
5050

5151
exports.request = function(options, cb) {
52-
return globalAgent.request(options, cb);
52+
return new ClientRequest(options, cb);
5353
};
5454

5555
exports.get = function(options, cb) {
56-
return globalAgent.get(options, cb);
56+
var req = exports.request(options, cb);
57+
req.end();
58+
return req;
5759
};
5860

5961
exports._connectionListener = server._connectionListener;

lib/https.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
// USE OR OTHER DEALINGS IN THE SOFTWARE.
2121

2222
var tls = require('tls');
23+
var url = require('url');
2324
var http = require('http');
2425
var util = require('util');
2526
var inherits = require('util').inherits;
@@ -126,9 +127,17 @@ exports.globalAgent = globalAgent;
126127
exports.Agent = Agent;
127128

128129
exports.request = function(options, cb) {
129-
return globalAgent.request(options, cb);
130+
if (util.isString(options)) {
131+
options = url.parse(options);
132+
} else {
133+
options = util._extend({}, options);
134+
}
135+
options._defaultAgent = globalAgent;
136+
return http.request(options, cb);
130137
};
131138

132139
exports.get = function(options, cb) {
133-
return globalAgent.get(options, cb);
140+
var req = exports.request(options, cb);
141+
req.end();
142+
return req;
134143
};

0 commit comments

Comments
 (0)