@@ -44,7 +44,7 @@ function Agent(options) {
4444 var name = self . getName ( options ) ;
4545 debug ( 'agent.on(free)' , name ) ;
4646
47- if ( ! socket . destroyed &&
47+ if ( socket . writable &&
4848 self . requests [ name ] && self . requests [ name ] . length ) {
4949 self . requests [ name ] . shift ( ) . onSocket ( socket ) ;
5050 if ( self . requests [ name ] . length === 0 ) {
@@ -57,7 +57,7 @@ function Agent(options) {
5757 var req = socket . _httpMessage ;
5858 if ( req &&
5959 req . shouldKeepAlive &&
60- ! socket . destroyed &&
60+ socket . writable &&
6161 self . keepAlive ) {
6262 var freeSockets = self . freeSockets [ name ] ;
6363 var freeLen = freeSockets ? freeSockets . length : 0 ;
@@ -138,7 +138,15 @@ Agent.prototype.addRequest = function(req, options) {
138138 } else if ( sockLen < this . maxSockets ) {
139139 debug ( 'call onSocket' , sockLen , freeLen ) ;
140140 // If we are under maxSockets create a new one.
141- req . onSocket ( this . createSocket ( req , options ) ) ;
141+ this . createSocket ( req , options , function ( err , newSocket ) {
142+ if ( err ) {
143+ process . nextTick ( function ( ) {
144+ req . emit ( 'error' , err ) ;
145+ } ) ;
146+ return ;
147+ }
148+ req . onSocket ( newSocket ) ;
149+ } ) ;
142150 } else {
143151 debug ( 'wait for socket' ) ;
144152 // We are over limit so we'll add it to the queue.
@@ -149,18 +157,16 @@ Agent.prototype.addRequest = function(req, options) {
149157 }
150158} ;
151159
152- Agent . prototype . createSocket = function ( req , options ) {
160+ Agent . prototype . createSocket = function ( req , options , cb ) {
153161 var self = this ;
154162 options = util . _extend ( { } , options ) ;
155163 options = util . _extend ( options , self . options ) ;
156164
157165 if ( ! options . servername ) {
158166 options . servername = options . host ;
159- if ( req ) {
160- var hostHeader = req . getHeader ( 'host' ) ;
161- if ( hostHeader ) {
162- options . servername = hostHeader . replace ( / : .* $ / , '' ) ;
163- }
167+ const hostHeader = req . getHeader ( 'host' ) ;
168+ if ( hostHeader ) {
169+ options . servername = hostHeader . replace ( / : .* $ / , '' ) ;
164170 }
165171 }
166172
@@ -169,48 +175,58 @@ Agent.prototype.createSocket = function(req, options) {
169175
170176 debug ( 'createConnection' , name , options ) ;
171177 options . encoding = null ;
172- var s = self . createConnection ( options ) ;
173- if ( ! self . sockets [ name ] ) {
174- self . sockets [ name ] = [ ] ;
175- }
176- this . sockets [ name ] . push ( s ) ;
177- debug ( 'sockets' , name , this . sockets [ name ] . length ) ;
178+ var called = false ;
179+ const newSocket = self . createConnection ( options , oncreate ) ;
180+ if ( newSocket )
181+ oncreate ( null , newSocket ) ;
182+ function oncreate ( err , s ) {
183+ if ( called )
184+ return ;
185+ called = true ;
186+ if ( err )
187+ return cb ( err ) ;
188+ if ( ! self . sockets [ name ] ) {
189+ self . sockets [ name ] = [ ] ;
190+ }
191+ self . sockets [ name ] . push ( s ) ;
192+ debug ( 'sockets' , name , self . sockets [ name ] . length ) ;
178193
179- function onFree ( ) {
180- self . emit ( 'free' , s , options ) ;
181- }
182- s . on ( 'free' , onFree ) ;
183-
184- function onClose ( err ) {
185- debug ( 'CLIENT socket onClose' ) ;
186- // This is the only place where sockets get removed from the Agent.
187- // If you want to remove a socket from the pool, just close it.
188- // All socket errors end in a close event anyway.
189- self . removeSocket ( s , options ) ;
190- }
191- s . on ( 'close' , onClose ) ;
192-
193- function onRemove ( ) {
194- // We need this function for cases like HTTP 'upgrade'
195- // (defined by WebSockets) where we need to remove a socket from the
196- // pool because it'll be locked up indefinitely
197- debug ( 'CLIENT socket onRemove' ) ;
198- self . removeSocket ( s , options ) ;
199- s . removeListener ( 'close' , onClose ) ;
200- s . removeListener ( 'free' , onFree ) ;
201- s . removeListener ( 'agentRemove' , onRemove ) ;
194+ function onFree ( ) {
195+ self . emit ( 'free' , s , options ) ;
196+ }
197+ s . on ( 'free' , onFree ) ;
198+
199+ function onClose ( err ) {
200+ debug ( 'CLIENT socket onClose' ) ;
201+ // This is the only place where sockets get removed from the Agent.
202+ // If you want to remove a socket from the pool, just close it.
203+ // All socket errors end in a close event anyway.
204+ self . removeSocket ( s , options ) ;
205+ }
206+ s . on ( 'close' , onClose ) ;
207+
208+ function onRemove ( ) {
209+ // We need this function for cases like HTTP 'upgrade'
210+ // (defined by WebSockets) where we need to remove a socket from the
211+ // pool because it'll be locked up indefinitely
212+ debug ( 'CLIENT socket onRemove' ) ;
213+ self . removeSocket ( s , options ) ;
214+ s . removeListener ( 'close' , onClose ) ;
215+ s . removeListener ( 'free' , onFree ) ;
216+ s . removeListener ( 'agentRemove' , onRemove ) ;
217+ }
218+ s . on ( 'agentRemove' , onRemove ) ;
219+ cb ( null , s ) ;
202220 }
203- s . on ( 'agentRemove' , onRemove ) ;
204- return s ;
205221} ;
206222
207223Agent . prototype . removeSocket = function ( s , options ) {
208224 var name = this . getName ( options ) ;
209- debug ( 'removeSocket' , name , 'destroyed :' , s . destroyed ) ;
225+ debug ( 'removeSocket' , name , 'writable :' , s . writable ) ;
210226 var sets = [ this . sockets ] ;
211227
212228 // If the socket was destroyed, remove it from the free buffers too.
213- if ( s . destroyed )
229+ if ( ! s . writable )
214230 sets . push ( this . freeSockets ) ;
215231
216232 for ( var sk = 0 ; sk < sets . length ; sk ++ ) {
@@ -231,7 +247,15 @@ Agent.prototype.removeSocket = function(s, options) {
231247 debug ( 'removeSocket, have a request, make a socket' ) ;
232248 var req = this . requests [ name ] [ 0 ] ;
233249 // If we have pending requests and a socket gets closed make a new one
234- this . createSocket ( req , options ) . emit ( 'free' ) ;
250+ this . createSocket ( req , options , function ( err , newSocket ) {
251+ if ( err ) {
252+ process . nextTick ( function ( ) {
253+ req . emit ( 'error' , err ) ;
254+ } ) ;
255+ return ;
256+ }
257+ newSocket . emit ( 'free' ) ;
258+ } ) ;
235259 }
236260} ;
237261
0 commit comments