| 
									
										
										
										
											2017-05-17 14:06:24 -06:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function getRespBody(err, debug) { | 
					
						
							|  |  |  |   if (debug) { | 
					
						
							|  |  |  |     return err.toString(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (err.code === 'ECONNREFUSED') { | 
					
						
							|  |  |  |     return 'The connection was refused. Most likely the service being connected to ' | 
					
						
							|  |  |  |       + 'has stopped running or the configuration is wrong.'; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return 'Bad Gateway: ' + err.code; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function sendBadGateway(conn, err, debug) { | 
					
						
							|  |  |  |   var body = getRespBody(err, debug); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   conn.write([ | 
					
						
							|  |  |  |     'HTTP/1.1 502 Bad Gateway' | 
					
						
							|  |  |  |   , 'Date: ' + (new Date()).toUTCString() | 
					
						
							|  |  |  |   , 'Connection: close' | 
					
						
							|  |  |  |   , 'Content-Type: text/html' | 
					
						
							|  |  |  |   , 'Content-Length: ' + body.length | 
					
						
							|  |  |  |   , '' | 
					
						
							|  |  |  |   , body | 
					
						
							|  |  |  |   ].join('\r\n')); | 
					
						
							|  |  |  |   conn.end(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports.getRespBody = getRespBody; | 
					
						
							|  |  |  | module.exports.sendBadGateway = sendBadGateway; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports.create = function (deps, config) { | 
					
						
							| 
									
										
										
										
											2017-10-30 15:57:18 -06:00
										 |  |  |   function proxy(conn, newConnOpts, firstChunk, decrypt) { | 
					
						
							| 
									
										
										
										
											2017-05-17 14:06:24 -06:00
										 |  |  |     var connected = false; | 
					
						
							| 
									
										
										
										
											2017-05-29 12:50:29 -06:00
										 |  |  |     newConnOpts.allowHalfOpen = true; | 
					
						
							| 
									
										
										
										
											2017-05-17 14:06:24 -06:00
										 |  |  |     var newConn = deps.net.createConnection(newConnOpts, function () { | 
					
						
							|  |  |  |       connected = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (firstChunk) { | 
					
						
							|  |  |  |         newConn.write(firstChunk); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       newConn.pipe(conn); | 
					
						
							|  |  |  |       conn.pipe(newConn); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 14:14:44 -06:00
										 |  |  |     // Listening for this largely to prevent uncaught exceptions.
 | 
					
						
							|  |  |  |     conn.on('error', function (err) { | 
					
						
							|  |  |  |       console.log('proxy client error', err); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2017-05-17 14:06:24 -06:00
										 |  |  |     newConn.on('error', function (err) { | 
					
						
							|  |  |  |       if (connected) { | 
					
						
							|  |  |  |         // Not sure how to report this to a user or a client. We can assume that some data
 | 
					
						
							|  |  |  |         // has already been exchanged, so we can't really be sure what we can send in addition
 | 
					
						
							|  |  |  |         // that wouldn't result in a parse error.
 | 
					
						
							|  |  |  |         console.log('proxy remote error', err); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         console.log('proxy connection error', err); | 
					
						
							|  |  |  |         if (decrypt) { | 
					
						
							|  |  |  |           sendBadGateway(decrypt(conn), err, config.debug); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           sendBadGateway(conn, err, config.debug); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 14:14:44 -06:00
										 |  |  |     // Make sure that once one side closes, no I/O activity will happen on the other side.
 | 
					
						
							|  |  |  |     conn.on('close', function () { | 
					
						
							|  |  |  |       newConn.destroy(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     newConn.on('close', function () { | 
					
						
							|  |  |  |       conn.destroy(); | 
					
						
							| 
									
										
										
										
											2017-05-17 14:06:24 -06:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2017-10-30 15:57:18 -06:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   proxy.getRespBody = getRespBody; | 
					
						
							|  |  |  |   proxy.sendBadGateway = sendBadGateway; | 
					
						
							|  |  |  |   return proxy; | 
					
						
							| 
									
										
										
										
											2017-05-17 14:06:24 -06:00
										 |  |  | }; |