@@ -24,6 +24,7 @@ var url = require('url');
2424var util = require ( 'util' ) ;
2525var EventEmitter = require ( 'events' ) . EventEmitter ;
2626var ClientRequest = require ( '_http_client' ) . ClientRequest ;
27+ var debug = util . debuglog ( 'http' ) ;
2728
2829// New Agent code.
2930
@@ -44,7 +45,12 @@ function Agent(options) {
4445 EventEmitter . call ( this ) ;
4546
4647 var self = this ;
48+
49+ self . defaultPort = 80 ;
50+ self . protocol = 'http:' ;
51+
4752 self . options = util . _extend ( { } , options ) ;
53+
4854 // don't confuse net and make it think that we're connecting to a pipe
4955 self . options . path = null ;
5056 self . requests = { } ;
@@ -54,11 +60,9 @@ function Agent(options) {
5460 self . keepAlive = self . options . keepAlive || false ;
5561 self . maxSockets = self . options . maxSockets || Agent . defaultMaxSockets ;
5662
57- self . on ( 'free' , function ( socket , host , port , localAddress ) {
58- var name = host + ':' + port ;
59- if ( localAddress ) {
60- name += ':' + localAddress ;
61- }
63+ self . on ( 'free' , function ( socket , options ) {
64+ var name = self . getName ( options ) ;
65+ debug ( 'agent.on(free)' , name ) ;
6266
6367 if ( ! socket . destroyed &&
6468 self . requests [ name ] && self . requests [ name ] . length ) {
@@ -103,18 +107,38 @@ exports.Agent = Agent;
103107Agent . defaultMaxSockets = Infinity ;
104108
105109Agent . prototype . createConnection = net . createConnection ;
106- Agent . prototype . defaultPort = 80 ;
107- Agent . prototype . protocol = 'http:' ;
108- Agent . prototype . addRequest = function ( req , host , port , localAddress ) {
109- var name = host + ':' + port ;
110- if ( localAddress ) {
111- name += ':' + localAddress ;
112- }
110+
111+ // Get the key for a given set of request options
112+ Agent . prototype . getName = function ( options ) {
113+ var name = '' ;
114+
115+ if ( options . host )
116+ name += options . host ;
117+ else
118+ name += 'localhost' ;
119+
120+ name += ':' ;
121+ if ( options . port )
122+ name += options . port ;
123+ name += ':' ;
124+ if ( options . localAddress )
125+ name += options . localAddress ;
126+ name += ':' ;
127+ return name ;
128+ } ;
129+
130+ Agent . prototype . addRequest = function ( req , options ) {
131+ var host = options . host ;
132+ var port = options . port ;
133+ var localAddress = options . localAddress ;
134+
135+ var name = this . getName ( options ) ;
113136 if ( ! this . sockets [ name ] ) {
114137 this . sockets [ name ] = [ ] ;
115138 }
116139
117140 if ( this . freeSockets [ name ] && this . freeSockets [ name ] . length ) {
141+ debug ( 'have free socket' ) ;
118142 // we have a free socket, so use that.
119143 var socket = this . freeSockets [ name ] . shift ( ) ;
120144
@@ -125,9 +149,11 @@ Agent.prototype.addRequest = function(req, host, port, localAddress) {
125149 socket . ref ( ) ;
126150 req . onSocket ( socket ) ;
127151 } else if ( this . sockets [ name ] . length < this . maxSockets ) {
152+ debug ( 'call onSocket' ) ;
128153 // If we are under maxSockets create a new one.
129- req . onSocket ( this . createSocket ( name , host , port , localAddress , req ) ) ;
154+ req . onSocket ( this . createSocket ( req , options ) ) ;
130155 } else {
156+ debug ( 'wait for socket' ) ;
131157 // We are over limit so we'll add it to the queue.
132158 if ( ! this . requests [ name ] ) {
133159 this . requests [ name ] = [ ] ;
@@ -136,45 +162,49 @@ Agent.prototype.addRequest = function(req, host, port, localAddress) {
136162 }
137163} ;
138164
139- Agent . prototype . createSocket = function ( name , host , port , localAddress , req ) {
165+ Agent . prototype . createSocket = function ( req , options ) {
140166 var self = this ;
141- var options = util . _extend ( { } , self . options ) ;
142- options . port = port ;
143- options . host = host ;
144- options . localAddress = localAddress ;
167+ options = util . _extend ( { } , options ) ;
168+ options = util . _extend ( options , self . options ) ;
145169
146- options . servername = host ;
170+ options . servername = options . host ;
147171 if ( req ) {
148172 var hostHeader = req . getHeader ( 'host' ) ;
149173 if ( hostHeader ) {
150174 options . servername = hostHeader . replace ( / : .* $ / , '' ) ;
151175 }
152176 }
153177
178+ var name = self . getName ( options ) ;
179+
180+ debug ( 'createConnection' , name , options ) ;
154181 var s = self . createConnection ( options ) ;
155182 if ( ! self . sockets [ name ] ) {
156183 self . sockets [ name ] = [ ] ;
157184 }
158185 this . sockets [ name ] . push ( s ) ;
186+ debug ( 'sockets' , name , this . sockets [ name ] . length ) ;
159187
160188 function onFree ( ) {
161- self . emit ( 'free' , s , host , port , localAddress ) ;
189+ self . emit ( 'free' , s , options ) ;
162190 }
163191 s . on ( 'free' , onFree ) ;
164192
165193 function onClose ( err ) {
194+ debug ( 'CLIENT socket onClose' ) ;
166195 // This is the only place where sockets get removed from the Agent.
167196 // If you want to remove a socket from the pool, just close it.
168197 // All socket errors end in a close event anyway.
169- self . removeSocket ( s , name , host , port , localAddress ) ;
198+ self . removeSocket ( s , options ) ;
170199 }
171200 s . on ( 'close' , onClose ) ;
172201
173202 function onRemove ( ) {
174203 // We need this function for cases like HTTP 'upgrade'
175- // (defined by WebSockets) where we need to remove a socket from the pool
176- // because it'll be locked up indefinitely
177- self . removeSocket ( s , name , host , port , localAddress ) ;
204+ // (defined by WebSockets) where we need to remove a socket from the
205+ // pool because it'll be locked up indefinitely
206+ debug ( 'CLIENT socket onRemove' ) ;
207+ self . removeSocket ( s , options ) ;
178208 s . removeListener ( 'close' , onClose ) ;
179209 s . removeListener ( 'free' , onFree ) ;
180210 s . removeListener ( 'agentRemove' , onRemove ) ;
@@ -183,7 +213,9 @@ Agent.prototype.createSocket = function(name, host, port, localAddress, req) {
183213 return s ;
184214} ;
185215
186- Agent . prototype . removeSocket = function ( s , name , host , port , localAddress ) {
216+ Agent . prototype . removeSocket = function ( s , options ) {
217+ var name = this . getName ( options ) ;
218+ debug ( 'removeSocket' , name ) ;
187219 if ( this . sockets [ name ] ) {
188220 var index = this . sockets [ name ] . indexOf ( s ) ;
189221 if ( index !== - 1 ) {
@@ -195,9 +227,10 @@ Agent.prototype.removeSocket = function(s, name, host, port, localAddress) {
195227 }
196228 }
197229 if ( this . requests [ name ] && this . requests [ name ] . length ) {
230+ debug ( 'removeSocket, have a request, make a socket' ) ;
198231 var req = this . requests [ name ] [ 0 ] ;
199- // If we have pending requests and a socket gets closed a new one
200- this . createSocket ( name , host , port , localAddress , req ) . emit ( 'free' ) ;
232+ // If we have pending requests and a socket gets closed make a new one
233+ this . createSocket ( req , options ) . emit ( 'free' ) ;
201234 }
202235} ;
203236
@@ -216,6 +249,10 @@ Agent.prototype.request = function(options, cb) {
216249 if ( typeof options === 'string' ) {
217250 options = url . parse ( options ) ;
218251 }
252+ // don't try to do dns lookups of foo.com:8080, just foo.com
253+ if ( options . hostname ) {
254+ options . host = options . hostname ;
255+ }
219256
220257 if ( options && options . path && / / . test ( options . path ) ) {
221258 // The actual regex is more like /[^A-Za-z0-9\-._~!$&'()*+,;=/:@]/
@@ -229,11 +266,16 @@ Agent.prototype.request = function(options, cb) {
229266 throw new Error ( 'Protocol:' + options . protocol + ' not supported.' ) ;
230267 }
231268
232- options = util . _extend ( { agent : this , keepAlive : false } , options ) ;
269+ options = util . _extend ( {
270+ agent : this ,
271+ keepAlive : this . keepAlive
272+ } , options ) ;
233273
274+ // if it's false, then make a new one, just like this one.
234275 if ( options . agent === false )
235- options . agent = new Agent ( options ) ;
276+ options . agent = new this . constructor ( options ) ;
236277
278+ debug ( 'agent.request' , options ) ;
237279 return new ClientRequest ( options , cb ) ;
238280} ;
239281
0 commit comments