-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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: client certificates fixes (#34873) and URL pattern support #34939
base: main
Are you sure you want to change the base?
feat: client certificates fixes (#34873) and URL pattern support #34939
Conversation
This comment has been minimized.
This comment has been minimized.
@@ -357,3 +431,181 @@ export function rewriteOpenSSLErrorIfNeeded(error: Error): Error { | |||
'You could probably modernize the certificate by following the steps at https://github.com/nodejs/node/issues/40672#issuecomment-1243648223', | |||
].join('\n')); | |||
} | |||
|
|||
/* | |||
Pattern is a pattern that matches a URL. Based on the Chromium |
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 consider using URLPattern as it becomes a standard.
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, also it solves the parsing which I really wanted to avoid. I tried it and ended up discarding it, there was something I was missing I cannot remember now. Let me check that and get back.
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! URLPattern would do the job nicely for this and most cases where playwright needs to do url matching. However, it has been available in Node.js current (23.x) only since last month, on the browser is also early and experimental, it is still missing in firefox and people is discussing APIs to match url lists due to performance concerns.
Said that, there is an alternative which is ditching [.] in favor of {.}?, which would make it work as a subset of URLPattern instead of following the chromium patterns. That would make sense if the project is looking forward to adopt URLPattern broadly, in the meantime I opted for the chromium patterns as 1) it was the only I knew was used for this, it pops out when people search about auto selecting client certs, 2) it is fairly simple to implement.
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.
For reference: #34915
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.
Please stay away from URLPattern.
@microsoft-github-policy-service agree |
1da0b4e
to
bfe6e65
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
- ALPNCache uses proxy and secure context. - Allow using resolve fixtures for client cert proxy and ALPN cache.
0223cc7
to
87c3cb9
Compare
Test results for "tests 1"5 flaky38672 passed, 793 skipped Merge workflow run. |
@@ -549,7 +549,7 @@ Does not enforce fixed viewport, allows resizing window in the headed mode. | |||
|
|||
## context-option-clientCertificates | |||
- `clientCertificates` <[Array]<[Object]>> | |||
- `origin` <[string]> Exact origin that the certificate is valid for. Origin includes `https` protocol, a hostname and optionally a port. | |||
- `origin` <[string]> Exact origin or chromium enterprise policy style URL pattern that the certificate is valid for. Origin includes `https` protocol, a hostname and optionally a port. |
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.
Adding yet another pattern will definitely slow things down. If you absolutely need a pattern, use regex.
@@ -39,10 +39,15 @@ function loadDummyServerCertsIfNeeded() { | |||
dummyServerTlsOptions = { key, cert }; | |||
} | |||
|
|||
type ALPNCacheOptions = { | |||
socket?: stream.Duplex | undefined; |
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.
nit: we would drop | undefined
and use ?
notation for both properties unless this would be a refactoring that needs to update all the call sites.
} | ||
} | ||
|
||
// Only used for fixtures | ||
type SocksProxyConnectionOptions = { |
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.
You are in the server non-user-facing code, you can introduce a property fooForTest if you need it.
this.internal = new stream.Duplex({ | ||
read: () => {}, | ||
write: (data, encoding, callback) => { | ||
this.socksProxy._socksProxy.sendSocketData({ uid: this.uid, data }); | ||
callback(); | ||
} | ||
}); | ||
this.socksProxy.alpnCache.get(rewriteToLocalhostIfNeeded(this.host), this.port, alpnProtocolChosenByServer => { | ||
const secureContext = this.socksProxy.secureContextForOrigin(new URL(`https://${this.host}:${this.port}`).origin); |
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.
We don't do more than one thing in a single PR. Your changes look reasonable, but reviewing them together is a bit hard, especially since they touch user-facing API. Please split it into fixes for those!
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 are essentially 2 things here + things that were needed just to test them. First, there is the fix to #34873 which straightens the ALPN behavior, this one can be indeed isolated. Although, it does fix more than one thing, for example, apart from not using the proxy to figure the protocol, it did not used the secure context either. As they touched the same parts and required some changes to be tested, if separated I could make a couple of dependants PRs.
Then there is the patterns, that one is very isolated with the only problem that in order to be tested it required changes done in the previous part. I just tried to avoid having dependant PRs.
Would that split make sense of you would go even smaller? I could do one addressing all of the ALPNCache issues, just ensuring it reaches out hosts in the same way the client would and another one for the patterns depending on the first.
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 separated I could make a couple of dependants PRs.
I'd very much prefer that.
Would that split make sense of you would go even smaller?
I need to understand the PR in order to review it. Making it about one thing helps keep track of things. I don't have a question of "Ok, this line changed, which of the 4 things this PR does did it change for?". Does not need to be a PR per line, but proper scoping would minimize the amount of questions and friction during the review.
@@ -357,3 +431,181 @@ export function rewriteOpenSSLErrorIfNeeded(error: Error): Error { | |||
'You could probably modernize the certificate by following the steps at https://github.com/nodejs/node/issues/40672#issuecomment-1243648223', | |||
].join('\n')); | |||
} | |||
|
|||
/* | |||
Pattern is a pattern that matches a URL. Based on the Chromium |
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.
Please stay away from URLPattern.
Bug Fixes
Fix for #34873
Support for patterns in clientCertificates
https://chromeenterprise.google/policies/url-patterns/
https://source.chromium.org/chromium/chromium/src/+/main:components/content_settings/core/common/content_settings_pattern.h;l=248;drc=20799f4c32d950ce93d495f44eec648400f38a19
For example: