Skip to content

Commit 40e9265

Browse files
committedJul 10, 2013
http: Add agent.get/request methods
1 parent 9fc9b87 commit 40e9265

File tree

5 files changed

+136
-29
lines changed

5 files changed

+136
-29
lines changed
 

‎lib/_http_agent.js

+37-4
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
// USE OR OTHER DEALINGS IN THE SOFTWARE.
2121

2222
var net = require('net');
23+
var url = require('url');
2324
var util = require('util');
2425
var EventEmitter = require('events').EventEmitter;
26+
var ClientRequest = require('_http_client').ClientRequest;
2527

2628
// New Agent code.
2729

@@ -42,7 +44,9 @@ function Agent(options) {
4244
EventEmitter.call(this);
4345

4446
var self = this;
45-
self.options = options || {};
47+
self.options = util._extend({}, options);
48+
// don't confuse net and make it think that we're connecting to a pipe
49+
self.options.path = null;
4650
self.requests = {};
4751
self.sockets = {};
4852
self.freeSockets = {};
@@ -91,15 +95,16 @@ function Agent(options) {
9195
}
9296
}
9397
});
94-
self.createConnection = net.createConnection;
9598
}
9699

97100
util.inherits(Agent, EventEmitter);
98101
exports.Agent = Agent;
99102

100103
Agent.defaultMaxSockets = Infinity;
101104

105+
Agent.prototype.createConnection = net.createConnection;
102106
Agent.prototype.defaultPort = 80;
107+
Agent.prototype.protocol = 'http:';
103108
Agent.prototype.addRequest = function(req, host, port, localAddress) {
104109
var name = host + ':' + port;
105110
if (localAddress) {
@@ -207,5 +212,33 @@ Agent.prototype.destroy = function() {
207212
});
208213
};
209214

210-
var globalAgent = new Agent();
211-
exports.globalAgent = globalAgent;
215+
Agent.prototype.request = function(options, cb) {
216+
if (typeof options === 'string') {
217+
options = url.parse(options);
218+
}
219+
220+
if (options && options.path && / /.test(options.path)) {
221+
// The actual regex is more like /[^A-Za-z0-9\-._~!$&'()*+,;=/:@]/
222+
// with an additional rule for ignoring percentage-escaped characters
223+
// but that's a) hard to capture in a regular expression that performs
224+
// well, and b) possibly too restrictive for real-world usage. That's
225+
// why it only scans for spaces because those are guaranteed to create
226+
// an invalid request.
227+
throw new TypeError('Request path contains unescaped characters.');
228+
} else if (options.protocol && options.protocol !== this.protocol) {
229+
throw new Error('Protocol:' + options.protocol + ' not supported.');
230+
}
231+
232+
options = util._extend({ agent: this, keepAlive: false }, options);
233+
234+
if (options.agent === false)
235+
options.agent = new Agent(options);
236+
237+
return new ClientRequest(options, cb);
238+
};
239+
240+
Agent.prototype.get = function(options, cb) {
241+
var req = this.request(options, cb);
242+
req.end();
243+
return req;
244+
};

‎lib/http.js

+4-24
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
// USE OR OTHER DEALINGS IN THE SOFTWARE.
2121

2222
var util = require('util');
23-
var url = require('url');
2423
var EventEmitter = require('events').EventEmitter;
2524

2625

@@ -42,40 +41,21 @@ exports.STATUS_CODES = server.STATUS_CODES;
4241

4342

4443
var agent = require('_http_agent');
45-
4644
var Agent = exports.Agent = agent.Agent;
47-
var globalAgent = exports.globalAgent = agent.globalAgent;
45+
var globalAgent = new Agent();
46+
exports.globalAgent = globalAgent;
4847

4948
var client = require('_http_client');
5049
var ClientRequest = exports.ClientRequest = client.ClientRequest;
5150

5251
exports.request = function(options, cb) {
53-
if (typeof options === 'string') {
54-
options = url.parse(options);
55-
} else if (options && options.path && / /.test(options.path)) {
56-
// The actual regex is more like /[^A-Za-z0-9\-._~!$&'()*+,;=/:@]/
57-
// with an additional rule for ignoring percentage-escaped characters
58-
// but that's a) hard to capture in a regular expression that performs
59-
// well, and b) possibly too restrictive for real-world usage. That's
60-
// why it only scans for spaces because those are guaranteed to create
61-
// an invalid request.
62-
throw new TypeError('Request path contains unescaped characters.');
63-
}
64-
65-
if (options.protocol && options.protocol !== 'http:') {
66-
throw new Error('Protocol:' + options.protocol + ' not supported.');
67-
}
68-
69-
return new ClientRequest(options, cb);
52+
return globalAgent.request(options, cb);
7053
};
7154

7255
exports.get = function(options, cb) {
73-
var req = exports.request(options, cb);
74-
req.end();
75-
return req;
56+
return globalAgent.get(options, cb);
7657
};
7758

78-
7959
var httpSocketSetup = common.httpSocketSetup;
8060

8161
exports._connectionListener = server._connectionListener;

‎lib/https.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,11 @@ function createConnection(port, host, options) {
8383

8484
function Agent(options) {
8585
http.Agent.call(this, options);
86-
this.createConnection = createConnection;
8786
}
8887
inherits(Agent, http.Agent);
8988
Agent.prototype.defaultPort = 443;
89+
Agent.prototype.protocol = 'https:';
90+
Agent.prototype.createConnection = createConnection;
9091

9192
var globalAgent = new Agent();
9293

‎lib/net.js

+2
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ exports.createServer = function() {
7777
//
7878
exports.connect = exports.createConnection = function() {
7979
var args = normalizeConnectArgs(arguments);
80+
debug('createConnection', args);
8081
var s = new Socket(args[0]);
8182
return Socket.prototype.connect.apply(s, args);
8283
};
@@ -832,6 +833,7 @@ Socket.prototype.connect = function(options, cb) {
832833

833834
var self = this;
834835
var pipe = !!options.path;
836+
debug('pipe', pipe, options.path);
835837

836838
if (!this._handle) {
837839
this._handle = pipe ? createPipe() : createTCP();
+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Copyright Joyent, Inc. and other Node contributors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a
4+
// copy of this software and associated documentation files (the
5+
// "Software"), to deal in the Software without restriction, including
6+
// without limitation the rights to use, copy, modify, merge, publish,
7+
// distribute, sublicense, and/or sell copies of the Software, and to permit
8+
// persons to whom the Software is furnished to do so, subject to the
9+
// following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included
12+
// in all copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17+
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20+
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
22+
var common = require('../common');
23+
var assert = require('assert');
24+
25+
var http = require('http');
26+
27+
28+
var serverSocket = null;
29+
var server = http.createServer(function(req, res) {
30+
// They should all come in on the same server socket.
31+
if (serverSocket) {
32+
assert.equal(req.socket, serverSocket);
33+
} else {
34+
serverSocket = req.socket;
35+
}
36+
37+
res.end(req.url);
38+
});
39+
server.listen(common.PORT);
40+
41+
var agent = http.Agent({ keepAlive: true });
42+
43+
44+
var clientSocket = null;
45+
var expectRequests = 10;
46+
var actualRequests = 0;
47+
48+
49+
makeRequest(expectRequests);
50+
function makeRequest(n) {
51+
if (n === 0) {
52+
server.close();
53+
agent.destroy();
54+
return;
55+
}
56+
57+
var req = agent.request({
58+
port: common.PORT,
59+
path: '/' + n
60+
});
61+
62+
req.end();
63+
64+
req.on('socket', function(sock) {
65+
if (clientSocket) {
66+
assert.equal(sock, clientSocket);
67+
} else {
68+
clientSocket = sock;
69+
}
70+
});
71+
72+
req.on('response', function(res) {
73+
var data = '';
74+
res.setEncoding('utf8');
75+
res.on('data', function(c) {
76+
data += c;
77+
});
78+
res.on('end', function() {
79+
assert.equal(data, '/' + n);
80+
setTimeout(function() {
81+
actualRequests++;
82+
makeRequest(n - 1);
83+
}, 1);
84+
});
85+
});
86+
}
87+
88+
process.on('exit', function() {
89+
assert.equal(actualRequests, expectRequests)
90+
console.log('ok');
91+
});

0 commit comments

Comments
 (0)
Please sign in to comment.