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
feat(browserServer): forward local ports #6375
feat(browserServer): forward local ports #6375
Conversation
691db25
to
23e9297
Compare
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.
A few comments, in addition to moving stuff from Browser to Playwright in the protocol.
29a5bdb
to
a421fe4
Compare
fe68b9b
to
025829d
Compare
527c221
to
c9ec6c3
Compare
a4e2852
to
bd46c01
Compare
bd46c01
to
1f15b4d
Compare
1f15b4d
to
694336e
Compare
694336e
to
df0e178
Compare
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.
I didn't read the socks implementation thoroughly yet, but I will follow up.
@@ -59,6 +60,8 @@ export class Playwright extends ChannelOwner<channels.PlaywrightChannel, channel | |||
|
|||
this._selectorsOwner = SelectorsOwner.from(initializer.selectors); | |||
this.selectors._addChannel(this._selectorsOwner); | |||
|
|||
this._channel.on('incomingSocksSocket', ({socket}) => SocksSocket.from(socket)); |
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.
Let's save the ports on Playwright object, so that we can validate dstPort on the client side as well.
import { SocksProxyServer, SocksConnectionInfo, SocksInterceptedHandler } from './socksServer'; | ||
import { LaunchOptions } from './types'; | ||
|
||
export class BrowserServerPortForwardingServer extends EventEmitter { |
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.
I'd inline this file into browserServerImpl.ts, and merge SocksSocket with SocksSocketDispatcher right away.
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.
I have the assumption that this get's also in the future used in playwrightclient, so I would keep it separate for now.
src/server/socksServer.ts
Outdated
if (this._authenticated) | ||
this._phase = ConnectionPhases.REQ_CMD; | ||
else | ||
this._phase++; |
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.
I don't quite like incrementing, can we explicitly assign the new phase?
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.
yeah we can do that. Seems then clearer.
src/server/socksServer.ts
Outdated
case ConnectionPhases.METHODS: { | ||
assert(this._authMethods); | ||
chunk.copy(this._authMethods, 0, i, i + chunk.length); | ||
assert(chunk.includes(SOCKS_AUTH_METHOD.NO_AUTH)); |
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.
chunk.includes
-> this._authMethods.includes
?
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.
should work.
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.
Sorry, I was not very clear. I think that chunk
buffer may include a lot more than just methods, so the chance of 00
appearing in chunk
is large, and that defeats the purpose of "assert that we have 'no auth required' in the methods".
case ConnectionPhases.REQ_ATYP: | ||
this._phase = ConnectionPhases.REQ_DSTADDR; | ||
this._addressType = chunk[i]; | ||
assert(this._addressType in SOCKS_ATYP); |
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.
I think we should turn all assert()
code into socket closure?
src/server/socksServer.ts
Outdated
this._methodsp += minLen; | ||
i += minLen; | ||
if (this._methodsp === this._authMethods.length) { | ||
this._phase = ConnectionPhases.VERSION; |
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.
Why do we go back to version?
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.
refactored the handling, should be more readable now. changes:
- introduced a readByte method
- don't jump between the phases
dstSocket.on('error', (err: NodeJS.ErrnoException) => writeSocksSocketError(this._socket, String(err))); | ||
dstSocket.on('connect', () => { | ||
this._socket.write(BUF_REP_INTR_SUCCESS); | ||
this._socket.pipe(dstSocket).pipe(this._socket); |
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.
Interesting! So we are supposed to pipe even the "pass-through" sockets? I was under impression we can just reply with the "BND == DST" and let the client connect on its own, but maybe I misread that.
No description provided.