From 70bdf074a1c3d618c01ed98ecf15dd545ee9d8cd Mon Sep 17 00:00:00 2001 From: Philipp Kunz Date: Mon, 7 Oct 2024 12:29:49 +0200 Subject: [PATCH] fix(networkproxy): Improve error handling for proxy requests --- changelog.md | 27 +++++ ts/00_commitinfo_data.ts | 4 +- ts/smartproxy.classes.networkproxy.ts | 151 +++++++++++++++----------- 3 files changed, 114 insertions(+), 68 deletions(-) create mode 100644 changelog.md diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..c58ae9d --- /dev/null +++ b/changelog.md @@ -0,0 +1,27 @@ +# Changelog + +## 2024-10-07 - 3.0.61 - fix(networkproxy) +Improve error handling for proxy requests + +- Wrapped proxy request logic in a try-catch block to handle errors gracefully. +- Improved error handling for WebSocket communication by checking errors before attempting to send messages. +- Added logging for error cases to aid in debugging. + +## 2024-05-29 - 3.0.60 - various updates +Maintenance updates and adjustments. + +- Updated project description +- Updated tsconfig settings +- Updated npmextra.json with new githost info + +## 2023-07-27 - 3.0.58 to 3.0.59 - core improvements +Improvements and internal restructuring. + +- Switch to a new organizational scheme +- Core updates and adjustments + +## 2022-07-29 - 2.0.16 to 3.0.0 - major transition +This release marks a major transition with several breaking changes. + +- BREAKING CHANGE: switched core to ESM (EcmaScript Module) +- Major core updates diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index f7f1b7e..66332c8 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -1,8 +1,8 @@ /** - * autocreated commitinfo by @pushrocks/commitinfo + * autocreated commitinfo by @push.rocks/commitinfo */ export const commitinfo = { name: '@push.rocks/smartproxy', - version: '3.0.60', + version: '3.0.61', description: 'a proxy for handling high workloads of proxying' } diff --git a/ts/smartproxy.classes.networkproxy.ts b/ts/smartproxy.classes.networkproxy.ts index 7121aa9..1923855 100644 --- a/ts/smartproxy.classes.networkproxy.ts +++ b/ts/smartproxy.classes.networkproxy.ts @@ -186,64 +186,69 @@ JNj2Dr5H0XoLFFnvuvzcRbhlJ9J67JzR+7g= return endOriginReqRes(); } console.log(destinationUrl); - const proxyResponse = await plugins.smartrequest.request( - destinationUrl, - { - method: originRequest.method, - headers: { - ...originRequest.headers, - 'X-Forwarded-Host': originRequest.headers.host, - 'X-Forwarded-Proto': 'https', + try { + const proxyResponse = await plugins.smartrequest.request( + destinationUrl, + { + method: originRequest.method, + headers: { + ...originRequest.headers, + 'X-Forwarded-Host': originRequest.headers.host, + 'X-Forwarded-Proto': 'https', + }, + keepAlive: true, }, - keepAlive: true, - }, - true, // lets make this streaming - (proxyRequest) => { - originRequest.on('data', (data) => { - proxyRequest.write(data); - }); - originRequest.on('end', (data) => { - proxyRequest.end(); - }); - originRequest.on('error', () => { - proxyRequest.end(); - }); - originRequest.on('close', () => { - proxyRequest.end(); - }); - originRequest.on('timeout', () => { - proxyRequest.end(); - originRequest.destroy(); - }); - proxyRequest.on('error', () => { - endOriginReqRes(); - }); + true, // lets make this streaming + (proxyRequest) => { + originRequest.on('data', (data) => { + proxyRequest.write(data); + }); + originRequest.on('end', () => { + proxyRequest.end(); + }); + originRequest.on('error', () => { + proxyRequest.end(); + }); + originRequest.on('close', () => { + proxyRequest.end(); + }); + originRequest.on('timeout', () => { + proxyRequest.end(); + originRequest.destroy(); + }); + proxyRequest.on('error', () => { + endOriginReqRes(); + }); + } + ); + originResponse.statusCode = proxyResponse.statusCode; + console.log(proxyResponse.statusCode); + for (const defaultHeader of Object.keys(this.defaultHeaders)) { + originResponse.setHeader(defaultHeader, this.defaultHeaders[defaultHeader]); } - ); - originResponse.statusCode = proxyResponse.statusCode; - console.log(proxyResponse.statusCode); - for (const defaultHeader of Object.keys(this.defaultHeaders)) { - originResponse.setHeader(defaultHeader, this.defaultHeaders[defaultHeader]); + for (const header of Object.keys(proxyResponse.headers)) { + originResponse.setHeader(header, proxyResponse.headers[header]); + } + proxyResponse.on('data', (data) => { + originResponse.write(data); + }); + proxyResponse.on('end', () => { + originResponse.end(); + }); + proxyResponse.on('error', () => { + originResponse.destroy(); + }); + proxyResponse.on('close', () => { + originResponse.end(); + }); + proxyResponse.on('timeout', () => { + originResponse.end(); + originResponse.destroy(); + }); + } catch (error) { + console.error('Error while processing request:', error); + endOriginReqRes(502, 'Bad Gateway: Error processing the request'); } - for (const header of Object.keys(proxyResponse.headers)) { - originResponse.setHeader(header, proxyResponse.headers[header]); - } - proxyResponse.on('data', (data) => { - originResponse.write(data); - }); - proxyResponse.on('end', () => { - originResponse.end(); - }); - proxyResponse.on('error', () => { - originResponse.destroy(); - }); - proxyResponse.on('close', () => { - originResponse.end(); - }); - proxyResponse.on('timeout', () => { - originResponse.end(); - originResponse.destroy(); - }); } ); @@ -277,30 +282,44 @@ JNj2Dr5H0XoLFFnvuvzcRbhlJ9J67JzR+7g= } wsIncoming.on('message', async (message, isBinary) => { - await outGoingDeferred.promise; - // console.log("client to upstream", message); - wsOutgoing.send(message, { binary: isBinary }); + try { + await outGoingDeferred.promise; + wsOutgoing.send(message, { binary: isBinary }); + } catch (error) { + console.error('Error sending message to wsOutgoing:', error); + } }); wsOutgoing.on('message', async (message, isBinary) => { - // console.log("upstream to client", message); - wsIncoming.send(message, { binary: isBinary }); + try { + wsIncoming.send(message, { binary: isBinary }); + } catch (error) { + console.error('Error sending message to wsIncoming:', error); + } }); + const terminateWsOutgoing = () => { - wsOutgoing.terminate(); - console.log('terminated outgoing ws.'); + if (wsOutgoing) { + wsOutgoing.terminate(); + console.log('terminated outgoing ws.'); + } }; wsIncoming.on('error', () => terminateWsOutgoing()); wsIncoming.on('close', () => terminateWsOutgoing()); const terminateWsIncoming = () => { - wsIncoming.terminate(); - console.log('terminated incoming ws.'); + if (wsIncoming) { + wsIncoming.terminate(); + console.log('terminated incoming ws.'); + } }; wsOutgoing.on('error', () => terminateWsIncoming()); wsOutgoing.on('close', () => terminateWsIncoming()); + + } ); + this.httpsServer.keepAliveTimeout = 600 * 1000; this.httpsServer.headersTimeout = 600 * 1000; @@ -360,7 +379,6 @@ JNj2Dr5H0XoLFFnvuvzcRbhlJ9J67JzR+7g= cert: hostCandidate.publicKey, key: hostCandidate.privateKey, }); - this.httpsServer; } } @@ -379,5 +397,6 @@ JNj2Dr5H0XoLFFnvuvzcRbhlJ9J67JzR+7g= socket.destroy(); }); await done.promise; + console.log('NetworkProxy -> OK: Server has been stopped and all connections closed.'); } -} +} \ No newline at end of file