Skip to content
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(proxy): unify local network proxy behavior #10719

Merged
merged 9 commits into from Dec 10, 2021

Conversation

rwoll
Copy link
Member

@rwoll rwoll commented Dec 4, 2021

When configuring a proxy, Chromium requires a magic tokens to get some
local network requests to go through the proxy. This has tripped up a
few users, so we make the behavior default to the expected: proxy
everything including the local requests. This matches the other vendors
as well.

NB: This can be disabled via
PLAYWRIGHT_DISABLE_FORCED_CHROMIUM_PROXIED_LOOPBACK=1

Supercedes: #8345
Fixes: #10631

@rwoll
Copy link
Member Author

rwoll commented Dec 4, 2021

/cc @pavelfeldman Opening this as WIP. Need to look into FF behavior (and clean up a bit). Can you mark CQ1 so I can see if there are any platform-specific quirks (esp. w/ the non-CR browsers…looking at you WK)? Thanks!

@rwoll
Copy link
Member Author

rwoll commented Dec 4, 2021

Looks like the FF failures have to do with my test, and not PW impl. Looks like our proxyServer is too naïve for FF to startup properly (if used at the launch- but not context-level). The following blows up the newPage call in a funny way logging Error: Parse Error: Invalid method encountered. The only request I see hit the proxy before that is maybe an OCSP related one to http://ocsp.digicert.com/. Need to dig in later…

it.only('debug', async ({ browserType, server, proxyServer }) => {
  server.setRoute('/target.html', async (req, res) => {
    res.end('<html><title>Served by the proxy</title></html>');
  });
  proxyServer.forwardTo(server.PORT);
  const browser = await browserType.launch({
    proxy: { server: `localhost:${proxyServer.PORT}` }
  });
  const page = await browser.newPage();
  await browser.close();
});

@rwoll
Copy link
Member Author

rwoll commented Dec 5, 2021

Looks like the FF failures have to do with my test, and not PW impl. Looks like our proxyServer is too naïve for FF to startup properly (if used at the launch- but not context-level). The following blows up the newPage call in a funny way logging Error: Parse Error: Invalid method encountered. The only request I see hit the proxy before that is maybe an OCSP related one to http://ocsp.digicert.com/. Need to dig in later…

it.only('debug', async ({ browserType, server, proxyServer }) => {
  server.setRoute('/target.html', async (req, res) => {
    res.end('<html><title>Served by the proxy</title></html>');
  });
  proxyServer.forwardTo(server.PORT);
  const browser = await browserType.launch({
    proxy: { server: `localhost:${proxyServer.PORT}` }
  });
  const page = await browser.newPage();
  await browser.close();
});

Looks like the issue is with trying to proxy the HTTPS/connect requests in proxyServer which originate from browser startup.

@rwoll
Copy link
Member Author

rwoll commented Dec 5, 2021

Looks like the FF failures have to do with my test, and not PW impl. Looks like our proxyServer is too naïve for FF to startup properly (if used at the launch- but not context-level). The following blows up the newPage call in a funny way logging Error: Parse Error: Invalid method encountered. The only request I see hit the proxy before that is maybe an OCSP related one to http://ocsp.digicert.com/. Need to dig in later…

it.only('debug', async ({ browserType, server, proxyServer }) => {
  server.setRoute('/target.html', async (req, res) => {
    res.end('<html><title>Served by the proxy</title></html>');
  });
  proxyServer.forwardTo(server.PORT);
  const browser = await browserType.launch({
    proxy: { server: `localhost:${proxyServer.PORT}` }
  });
  const page = await browser.newPage();
  await browser.close();
});

Looks like the issue is with trying to proxy the HTTPS/connect requests in proxyServer which originate from browser startup.

Pushed a workaround in latest commit. (Skips rewriting some HTTPS requests FF requires for startup so we don't have to deal with MITMing them better just for the tests.)

@rwoll rwoll force-pushed the feat/unify-proxy-behavior branch 2 times, most recently from ea7801f to 36ad482 Compare December 5, 2021 22:39
@rwoll rwoll marked this pull request as ready for review December 6, 2021 00:35
tests/browsercontext-proxy.spec.ts Outdated Show resolved Hide resolved
}
]) {
it(`${params.description}`, async ({ platform, browserName, contextFactory, server, proxyServer }) => {
it.fail(platform !== 'linux' && browserName === 'webkit' && additionalBypass && ['localhost', '127.0.0.1'].includes(params.target), 'WK fails to proxy 127.0.0.1 and localhost if additional bypasses are present');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, style: given the complexity of the fail predicate, I'd copy-paste this test 3 times instead.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, style: given the complexity of the fail predicate, I'd copy-paste this test 3 times instead.

@pavelfeldman how strong of a nit is this? Hehe

I found the more complex fail predicate much easier to read/maintain/edit than trying to find the subtle differences in the otherwise lots of setup in each of the cases.

Mind if I revert d307a87 before merging?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how strong of a nit is this?

Not too strong, do it the way you like.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to merge as is if this is ready.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @pavelfeldman! Just reverted! Ready for a merge whenever assuming tests pass.

@mxschmitt mxschmitt added CQ1 and removed CQ1 labels Dec 8, 2021
@rwoll
Copy link
Member Author

rwoll commented Dec 8, 2021

Fixed up the tests based on the CQ1 run. Ready for another run. (Ran all the proxy tests locally {macOS, Linux/Docker} x {headless, head full}. Don’t have a windows box to verifies this will pass now, but they should :)

@mxschmitt mxschmitt added CQ1 and removed CQ1 labels Dec 8, 2021
@rwoll
Copy link
Member Author

rwoll commented Dec 8, 2021

@mxschmitt Thanks for toggling the label. Looks like npm ci exploded on a lot of the bots and didn’t even run the tests. Is that just runner flakiness, or should I rebase and try again?

@mxschmitt
Copy link
Member

@mxschmitt Thanks for toggling the label. Looks like npm ci exploded on a lot of the bots and didn’t even run the tests. Is that just runner flakiness, or should I rebase and try again?

Seems like a temporary GitHub/NPM outage, I'd recommend to rebase.

When configuring a proxy, Chromium requires a magic tokens to get some
local network requests to go through the proxy. This has tripped up a
few users, so we make the behavior default to the expected: proxy
everything including the local requests. This matches the other vendors
as well.

NB: This can be disabled via
`PLAYWRIGHT_DISABLE_FORCED_CHROMIUM_PROXIED_LOOPBACK=1`

Supercedes: microsoft#8345
Fixes: microsoft#10631
@mxschmitt mxschmitt added CQ1 and removed CQ1 labels Dec 9, 2021
@rwoll
Copy link
Member Author

rwoll commented Dec 9, 2021

Thanks for the re-trigger! Everything passed on the rebase except one unrelated test (https://github.com/microsoft/playwright/runs/4464958397?check_suite_focus=true)

So should be good to merge! 🎉

cc: @pavelfeldman

@mxschmitt mxschmitt merged commit fde427d into microsoft:main Dec 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] HTTP requests to localhost not going through proxy with Chrome
3 participants