@@ -23,6 +23,16 @@ function run(cmd, args, options = {}) {
2323 }
2424}
2525
26+ function isBenignSocketError ( err ) {
27+ return err && ( err . code === 'ECONNRESET' || err . code === 'EPIPE' || err . code === 'ERR_STREAM_PREMATURE_CLOSE' ) ;
28+ }
29+
30+ function ignoreBenignSocketErrors ( stream ) {
31+ stream . on ( 'error' , err => {
32+ if ( ! isBenignSocketError ( err ) ) throw err ;
33+ } ) ;
34+ }
35+
2636function listen ( server , host = '127.0.0.1' ) {
2737 return new Promise ( ( resolve , reject ) => {
2838 server . once ( 'error' , reject ) ;
@@ -102,6 +112,8 @@ class SocketReader {
102112
103113function createTargetServer ( requests ) {
104114 const server = http . createServer ( ( req , res ) => {
115+ ignoreBenignSocketErrors ( req ) ;
116+ ignoreBenignSocketErrors ( res ) ;
105117 requests . push ( { url : req . url , method : req . method , host : req . headers . host || '' , userAgent : req . headers [ 'user-agent' ] || '' , cookie : req . headers . cookie || '' , contentType : req . headers [ 'content-type' ] || '' } ) ;
106118 const url = new URL ( req . url , 'http://target.local' ) ;
107119 if ( url . pathname === '/' ) {
@@ -296,6 +308,12 @@ function createTargetServer(requests) {
296308 res . writeHead ( 404 , { 'Content-Type' : 'text/plain; charset=utf-8' } ) ;
297309 res . end ( 'not found' ) ;
298310 } ) ;
311+ server . on ( 'clientError' , ( err , socket ) => {
312+ if ( ! socket . destroyed ) {
313+ if ( isBenignSocketError ( err ) ) socket . destroy ( ) ;
314+ else socket . end ( 'HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n' ) ;
315+ }
316+ } ) ;
299317 server . on ( 'upgrade' , ( req , socket ) => handleWebSocketUpgrade ( req , socket , requests ) ) ;
300318 return server ;
301319}
@@ -313,6 +331,7 @@ function handleWebSocketUpgrade(req, socket, requests) {
313331 }
314332 const accept = crypto . createHash ( 'sha1' ) . update ( key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11' ) . digest ( 'base64' ) ;
315333 const requestedProtocol = String ( req . headers [ 'sec-websocket-protocol' ] || '' ) . split ( ',' ) . map ( s => s . trim ( ) ) . filter ( Boolean ) [ 0 ] || '' ;
334+ ignoreBenignSocketErrors ( socket ) ;
316335 socket . write ( 'HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: ' + accept + ( requestedProtocol ? '\r\nSec-WebSocket-Protocol: ' + requestedProtocol : '' ) + '\r\n\r\n' ) ;
317336 let buffered = Buffer . alloc ( 0 ) ;
318337 socket . on ( 'data' , chunk => {
@@ -388,6 +407,7 @@ function createSocks5Server(resolveHost) {
388407}
389408
390409async function handleSocks ( socket , resolveHost ) {
410+ socket . on ( 'error' , err => { if ( ! isBenignSocketError ( err ) ) socket . destroy ( err ) ; } ) ;
391411 const reader = new SocketReader ( socket ) ;
392412 const greeting = await reader . read ( 2 ) ;
393413 assert . equal ( greeting [ 0 ] , 0x05 ) ;
@@ -419,6 +439,9 @@ async function handleSocks(socket, resolveHost) {
419439 upstream . once ( 'connect' , resolve ) ;
420440 upstream . once ( 'error' , reject ) ;
421441 } ) ;
442+ upstream . on ( 'error' , err => {
443+ if ( ! isBenignSocketError ( err ) ) socket . destroy ( err ) ;
444+ } ) ;
422445 socket . write ( Buffer . from ( [ 0x05 , 0x00 , 0x00 , 0x01 , 0 , 0 , 0 , 0 , 0 , 0 ] ) ) ;
423446 if ( reader . buf . length ) upstream . write ( reader . buf ) ;
424447 socket . pipe ( upstream ) ;
0 commit comments