@@ -103,13 +103,43 @@ var HttpProxy = exports.HttpProxy = function (options) {
103
103
// Inherit from events.EventEmitter
104
104
util . inherits ( HttpProxy , events . EventEmitter ) ;
105
105
106
+ function ReqCanary ( ) {
107
+ this . ___events = [ ] ;
108
+ }
109
+ function ResCanary ( ) {
110
+ this . ___events = [ ] ;
111
+ }
112
+
113
+ var cc = { } ;
114
+
115
+ var logEvt = function ( canary , event ) {
116
+ if ( canary && canary . ___events ) {
117
+ canary . ___events . push ( event ) ;
118
+ } else {
119
+ console . log ( "No canary for event : " + event ) ;
120
+ }
121
+
122
+ if ( ! cc [ event ] ) {
123
+ cc [ event ] = 1 ;
124
+ } else {
125
+ cc [ event ] += 1 ;
126
+ }
127
+
128
+ console . dir ( cc ) ;
129
+ }
130
+
106
131
//
107
132
// ### function proxyRequest (req, res, buffer)
108
133
// #### @req {ServerRequest} Incoming HTTP Request to proxy.
109
134
// #### @res {ServerResponse} Outgoing HTTP Request to write proxied data to.
110
135
// #### @buffer {Object} Result from `httpProxy.buffer(req)`
111
136
//
112
137
HttpProxy . prototype . proxyRequest = function ( req , res , buffer ) {
138
+ req . canary = new ReqCanary ( ) ;
139
+ res . canary = new ResCanary ( ) ;
140
+
141
+ logEvt ( res . canary , "Init" ) ;
142
+
113
143
var self = this ,
114
144
errState = false ,
115
145
outgoing = new ( this . target . base ) ,
@@ -166,6 +196,8 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
166
196
//
167
197
this . emit ( 'start' , req , res , this . target ) ;
168
198
199
+ logEvt ( res . canary , "Start" ) ;
200
+
169
201
//
170
202
// #### function proxyError (err)
171
203
// #### @err {Error} Error contacting the proxy target
@@ -175,6 +207,8 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
175
207
function proxyError ( err ) {
176
208
errState = true ;
177
209
210
+ logEvt ( res . canary , "ProxyError" ) ;
211
+
178
212
//
179
213
// Emit an `error` event, allowing the application to use custom
180
214
// error handling. The error handler should end the response.
@@ -183,6 +217,8 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
183
217
return ;
184
218
}
185
219
220
+ logEvt ( res . canary , "Writing 500" ) ;
221
+
186
222
res . writeHead ( 500 , { 'Content-Type' : 'text/plain' } ) ;
187
223
188
224
if ( req . method !== 'HEAD' ) {
@@ -198,7 +234,23 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
198
234
}
199
235
}
200
236
201
- try { res . end ( ) }
237
+ try {
238
+ res . end ( ) ;
239
+ logEvt ( res . canary , "Ended properly" ) ;
240
+ //CLEANUP
241
+ if ( res ) {
242
+ res . removeAllListeners ( ) ;
243
+ res = null ;
244
+ }
245
+ if ( req ) {
246
+ req . removeAllListeners ( ) ;
247
+ req = null ;
248
+ }
249
+ if ( response ) {
250
+ response . removeAllListeners ( ) ;
251
+ response = null ;
252
+ }
253
+ }
202
254
catch ( ex ) { console . error ( "res.end error: %s" , ex . message ) }
203
255
}
204
256
@@ -213,12 +265,16 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
213
265
outgoing . method = req . method ;
214
266
outgoing . path = req . url ;
215
267
outgoing . headers = req . headers ;
268
+ outgoing . agent = false ;
216
269
217
270
//
218
271
// Open new HTTP request to internal resource with will act
219
272
// as a reverse proxy pass
220
273
//
221
274
reverseProxy = this . target . protocol . request ( outgoing , function ( response ) {
275
+
276
+ logEvt ( res . canary , "Reverse proxying" ) ;
277
+
222
278
//
223
279
// Process the `reverseProxy` `response` when it's received.
224
280
//
@@ -244,6 +300,7 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
244
300
//
245
301
var ended = false ;
246
302
response . on ( 'close' , function ( ) {
303
+ logEvt ( res . canary , "Close, emiting 'end'" ) ;
247
304
if ( ! ended ) { response . emit ( 'end' ) }
248
305
} ) ;
249
306
@@ -255,15 +312,48 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
255
312
// This code makes sure that we flush pending data.
256
313
//
257
314
response . connection . on ( 'end' , function ( ) {
258
- if ( response . readable && response . resume ) {
315
+ if ( res )
316
+ logEvt ( res . canary , 'response connection ended' ) ;
317
+
318
+ if ( response && response . readable && response . resume ) {
319
+ if ( res )
320
+ logEvt ( res . canary , 'response resuming' ) ;
321
+
259
322
response . resume ( ) ;
260
323
}
324
+ // CLEANUP?
325
+ if ( res ) {
326
+ res . removeAllListeners ( ) ;
327
+ res = null ;
328
+ }
329
+ if ( req ) {
330
+ req . removeAllListeners ( ) ;
331
+ req = null ;
332
+ }
333
+ if ( response ) {
334
+ response . removeAllListeners ( ) ;
335
+ response = null ;
336
+ }
261
337
} ) ;
262
338
263
339
response . on ( 'end' , function ( ) {
340
+ logEvt ( res . canary , 'response ended' ) ;
264
341
ended = true ;
265
342
if ( ! errState ) {
266
- try { res . end ( ) }
343
+ try {
344
+ res . end ( ) ;
345
+ logEvt ( res . canary , 'end res' ) ;
346
+ // CLEANUP?
347
+ res . removeAllListeners ( ) ;
348
+ // Note that nulling this will prevent the response resuming' event from
349
+ // coming in, since it won't fire on a null event.
350
+ res = null ;
351
+ req . removeAllListeners ( ) ;
352
+ req = null ;
353
+ response . removeAllListeners ( ) ;
354
+ response = null ;
355
+
356
+ }
267
357
catch ( ex ) { console . error ( "res.end error: %s" , ex . message ) }
268
358
269
359
// Emit the `end` event now that we have completed proxying
@@ -285,13 +375,15 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
285
375
res . writeHead ( response . statusCode ) ;
286
376
287
377
function ondata ( chunk ) {
378
+ logEvt ( res . canary , "Data" ) ;
288
379
if ( res . writable ) {
289
380
// Only pause if the underlying buffers are full,
290
381
// *and* the connection is not in 'closing' state.
291
382
// Otherwise, the pause will cause pending data to
292
383
// be discarded and silently lost.
293
384
if ( false === res . write ( chunk ) && response . pause
294
385
&& response . connection . readable ) {
386
+ logEvt ( res . canary , "Pausing due to full buffer" ) ;
295
387
response . pause ( ) ;
296
388
}
297
389
}
@@ -300,7 +392,9 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
300
392
response . on ( 'data' , ondata ) ;
301
393
302
394
function ondrain ( ) {
395
+ logEvt ( res . canary , "On drain" ) ;
303
396
if ( response . readable && response . resume ) {
397
+ logEvt ( res . canary , "On drain resuming." ) ;
304
398
response . resume ( ) ;
305
399
}
306
400
}
@@ -318,6 +412,7 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
318
412
319
413
// Set a timeout on the socket if `this.timeout` is specified.
320
414
reverseProxy . once ( 'socket' , function ( socket ) {
415
+ logEvt ( res . canary , "Socket" ) ;
321
416
if ( self . timeout ) {
322
417
socket . setTimeout ( self . timeout ) ;
323
418
}
@@ -332,6 +427,7 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
332
427
// If `req` is aborted, we abort our `reverseProxy` request as well.
333
428
//
334
429
req . on ( 'aborted' , function ( ) {
430
+ logEvt ( res . canary , "Aborted" ) ;
335
431
reverseProxy . abort ( ) ;
336
432
} ) ;
337
433
@@ -340,11 +436,13 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
340
436
// `req` write it to the `reverseProxy` request.
341
437
//
342
438
req . on ( 'data' , function ( chunk ) {
439
+ logEvt ( res . canary , 'req data' ) ;
343
440
if ( ! errState ) {
344
441
var flushed = reverseProxy . write ( chunk ) ;
345
442
if ( ! flushed ) {
346
443
req . pause ( ) ;
347
444
reverseProxy . once ( 'drain' , function ( ) {
445
+ logEvt ( res . canary , "Drain" ) ;
348
446
try { req . resume ( ) }
349
447
catch ( er ) { console . error ( "req.resume error: %s" , er . message ) }
350
448
} ) ;
@@ -354,6 +452,7 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
354
452
// happened on its own.
355
453
//
356
454
setTimeout ( function ( ) {
455
+ logEvt ( res . canary , "Force drain" ) ;
357
456
reverseProxy . emit ( 'drain' ) ;
358
457
} , 100 ) ;
359
458
}
@@ -365,22 +464,29 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
365
464
// request unless we have entered an error state.
366
465
//
367
466
req . on ( 'end' , function ( ) {
467
+ logEvt ( res . canary , "Req ended" ) ;
368
468
if ( ! errState ) {
369
469
reverseProxy . end ( ) ;
470
+ } else {
471
+ logEvt ( res . canary , "Req errored end" ) ;
370
472
}
371
473
} ) ;
372
474
373
475
//Aborts reverseProxy if client aborts the connection.
374
476
req . on ( 'close' , function ( ) {
477
+ logEvt ( res . canary , "Req closed" ) ;
375
478
if ( ! errState ) {
376
479
reverseProxy . abort ( ) ;
480
+ } else {
481
+ logEvt ( res . canary , "Req errored close" ) ;
377
482
}
378
483
} ) ;
379
484
380
485
//
381
486
// If we have been passed buffered data, resume it.
382
487
//
383
488
if ( buffer ) {
489
+ logEvt ( res . canary , "Resuming buffer " + errState ? "1" : "0" ) ;
384
490
return ! errState
385
491
? buffer . resume ( )
386
492
: buffer . destroy ( ) ;
0 commit comments