Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
http: Add agent.get/request methods
Browse files Browse the repository at this point in the history
  • Loading branch information
isaacs committed Jul 10, 2013
1 parent 9fc9b87 commit 40e9265
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 29 deletions.
41 changes: 37 additions & 4 deletions lib/_http_agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var net = require('net');
var url = require('url');
var util = require('util');
var EventEmitter = require('events').EventEmitter;
var ClientRequest = require('_http_client').ClientRequest;

// New Agent code.

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

var self = this;
self.options = options || {};
self.options = util._extend({}, options);
// don't confuse net and make it think that we're connecting to a pipe
self.options.path = null;
self.requests = {};
self.sockets = {};
self.freeSockets = {};
Expand Down Expand Up @@ -91,15 +95,16 @@ function Agent(options) {
}
}
});
self.createConnection = net.createConnection;
}

util.inherits(Agent, EventEmitter);
exports.Agent = Agent;

Agent.defaultMaxSockets = Infinity;

Agent.prototype.createConnection = net.createConnection;
Agent.prototype.defaultPort = 80;
Agent.prototype.protocol = 'http:';
Agent.prototype.addRequest = function(req, host, port, localAddress) {
var name = host + ':' + port;
if (localAddress) {
Expand Down Expand Up @@ -207,5 +212,33 @@ Agent.prototype.destroy = function() {
});
};

var globalAgent = new Agent();
exports.globalAgent = globalAgent;
Agent.prototype.request = function(options, cb) {
if (typeof options === 'string') {
options = url.parse(options);
}

if (options && options.path && / /.test(options.path)) {
// The actual regex is more like /[^A-Za-z0-9\-._~!$&'()*+,;=/:@]/
// with an additional rule for ignoring percentage-escaped characters
// but that's a) hard to capture in a regular expression that performs
// well, and b) possibly too restrictive for real-world usage. That's
// why it only scans for spaces because those are guaranteed to create
// an invalid request.
throw new TypeError('Request path contains unescaped characters.');
} else if (options.protocol && options.protocol !== this.protocol) {
throw new Error('Protocol:' + options.protocol + ' not supported.');
}

options = util._extend({ agent: this, keepAlive: false }, options);

if (options.agent === false)
options.agent = new Agent(options);

return new ClientRequest(options, cb);
};

Agent.prototype.get = function(options, cb) {
var req = this.request(options, cb);
req.end();
return req;
};
28 changes: 4 additions & 24 deletions lib/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var util = require('util');
var url = require('url');
var EventEmitter = require('events').EventEmitter;


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


var agent = require('_http_agent');

var Agent = exports.Agent = agent.Agent;
var globalAgent = exports.globalAgent = agent.globalAgent;
var globalAgent = new Agent();
exports.globalAgent = globalAgent;

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

exports.request = function(options, cb) {
if (typeof options === 'string') {
options = url.parse(options);
} else if (options && options.path && / /.test(options.path)) {
// The actual regex is more like /[^A-Za-z0-9\-._~!$&'()*+,;=/:@]/
// with an additional rule for ignoring percentage-escaped characters
// but that's a) hard to capture in a regular expression that performs
// well, and b) possibly too restrictive for real-world usage. That's
// why it only scans for spaces because those are guaranteed to create
// an invalid request.
throw new TypeError('Request path contains unescaped characters.');
}

if (options.protocol && options.protocol !== 'http:') {
throw new Error('Protocol:' + options.protocol + ' not supported.');
}

return new ClientRequest(options, cb);
return globalAgent.request(options, cb);
};

exports.get = function(options, cb) {
var req = exports.request(options, cb);
req.end();
return req;
return globalAgent.get(options, cb);
};


var httpSocketSetup = common.httpSocketSetup;

exports._connectionListener = server._connectionListener;
Expand Down
3 changes: 2 additions & 1 deletion lib/https.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,11 @@ function createConnection(port, host, options) {

function Agent(options) {
http.Agent.call(this, options);
this.createConnection = createConnection;
}
inherits(Agent, http.Agent);
Agent.prototype.defaultPort = 443;
Agent.prototype.protocol = 'https:';
Agent.prototype.createConnection = createConnection;

var globalAgent = new Agent();

Expand Down
2 changes: 2 additions & 0 deletions lib/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ exports.createServer = function() {
//
exports.connect = exports.createConnection = function() {
var args = normalizeConnectArgs(arguments);
debug('createConnection', args);
var s = new Socket(args[0]);
return Socket.prototype.connect.apply(s, args);
};
Expand Down Expand Up @@ -832,6 +833,7 @@ Socket.prototype.connect = function(options, cb) {

var self = this;
var pipe = !!options.path;
debug('pipe', pipe, options.path);

if (!this._handle) {
this._handle = pipe ? createPipe() : createTCP();
Expand Down
91 changes: 91 additions & 0 deletions test/simple/test-http-keepalive-request.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var common = require('../common');
var assert = require('assert');

var http = require('http');


var serverSocket = null;
var server = http.createServer(function(req, res) {
// They should all come in on the same server socket.
if (serverSocket) {
assert.equal(req.socket, serverSocket);
} else {
serverSocket = req.socket;
}

res.end(req.url);
});
server.listen(common.PORT);

var agent = http.Agent({ keepAlive: true });


var clientSocket = null;
var expectRequests = 10;
var actualRequests = 0;


makeRequest(expectRequests);
function makeRequest(n) {
if (n === 0) {
server.close();
agent.destroy();
return;
}

var req = agent.request({
port: common.PORT,
path: '/' + n
});

req.end();

req.on('socket', function(sock) {
if (clientSocket) {
assert.equal(sock, clientSocket);
} else {
clientSocket = sock;
}
});

req.on('response', function(res) {
var data = '';
res.setEncoding('utf8');
res.on('data', function(c) {
data += c;
});
res.on('end', function() {
assert.equal(data, '/' + n);
setTimeout(function() {
actualRequests++;
makeRequest(n - 1);
}, 1);
});
});
}

process.on('exit', function() {
assert.equal(actualRequests, expectRequests)
console.log('ok');
});

0 comments on commit 40e9265

Please sign in to comment.