-
Notifications
You must be signed in to change notification settings - Fork 160
feat: implement https server support #602
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
- Fix a datarace for error handler - Add a regression test that verify datarace fix - Add TLS defaults for better security
Could you please point me to the changes that are related to the fixes? Thanks. Also, what was wrong with the statistics? |
Don't remember right now for 100%, but few tests failed for |
jirimoravcik
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, had a few comments.
In addition to that, could you please:
- Bump the package version
- Describe all the new things in
README.md(which serves as the primary user-facing documentation)
Thanks
Aslo revert changes in eslint and tsconfig
|
@jirimoravcik @lewis-wow Guys, I've added main logic for TLS overhead bytes. Please take a look 🙏 Gonna polish tests in meantime and push 'em ASAP. |
lewis-wow
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Have nothing to add.
jirimoravcik
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found a few more points for discussion
| if (options.serverType === 'https') { | ||
| if (!options.httpsOptions) { | ||
| throw new Error('httpsOptions is required when serverType is "https"'); | ||
| } | ||
|
|
||
| // Apply secure TLS defaults (user options can override) | ||
| // This prevents users from accidentally configuring insecure TLS settings | ||
| const secureDefaults: https.ServerOptions = { | ||
| ...HTTPS_DEFAULTS, | ||
| honorCipherOrder: true, // Server chooses cipher (prevents downgrade attacks) | ||
| ...options.httpsOptions, // User options override defaults | ||
| }; | ||
|
|
||
| this.server = https.createServer(secureDefaults); | ||
| this.serverType = 'https'; | ||
| } else { | ||
| this.server = http.createServer(); | ||
| this.serverType = 'http'; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe validate if options.serverType is one of http, https? It would make it consistent with the type. I'd also set it to http by default in the constructor parameter. That way you could just do this.serverType = options.serverType
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Gonna add this.
src/server.ts
Outdated
| socket.proxyChainErrorHandled = true; | ||
|
|
||
| // Log errors only if there are no user-provided error handlers | ||
| if (this.listenerCount('error') === 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was === 1 before, why is it === 0 now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand it correctly for previous condition this.listenerCount('error') === 1 (which count server-listeners, not socket) app log error only when there is one server handler. Right?
If I'm correct, then in this case the error will be handled by that one server-handler. For us it might be useful to log here when there are no other server-handlers this.listenerCount('error') === 0.
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So it was broken before, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it was broken before. But I was wrong in my assumptions.
Original code should check socket.listenerCount('error') === 1 instead for this (server). Because socker and server error events aren't interconnected.
Also, we're attaching additional error listeners in our handlers (e.g. direct).
So, basically the flow should be like that:
onConnection()- attach out early handler -socket.listenerCount('error') === 1onReqeust() / onConnect()- prepareRequestHandlingdirect()function called - attaches sourceSocket error handler- Now
socket.listenerCount('error') === 2
If error occurs after step 3: then the direct() handler will log instead our early handler.
If error occurs between steps 1-2: then our early handler will log it.
I'm gonna prepare fix for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jirimoravcik fixed here e6ea53b
This PR implements HTTPS server support to proxy-chain.
Also fixed:
errorevent when we might log same eventsOtherwise my changes should be fully compatible with HTTP server and all the handlers.
Readiness checklist:
Forward via HTTPS upstreamChain via HTTPS upstream_parent, include overhead bytes intosrcXxBytes_parentis present and functional in order to make future Node.js version upgrades saferPlaces where TLS overhead possible: