rust-headless-chrome / rust-headless-chrome

A high-level API to control headless Chrome or Chromium over the DevTools Protocol. It is the Rust equivalent of Puppeteer, a Node library maintained by the Chrome DevTools team.
MIT License
2.27k stars 225 forks source link

Proxy Authentication #417

Open 4r7if3x opened 11 months ago

4r7if3x commented 11 months ago

Since Chromium-based executables do not support hard-coded credentials within the URL passed to the --proxy-server flag, I attempted to pass the authentication when opening the website, using the same approach that worked during the manual testing, but I get the following timeout error: The event waited for never came.

use headless_chrome::{browser, LaunchOptions, Browser, Tab};

// ...

let proxy_url = format!("http://{}:{}", PROXY_HOST, PROXY_PORT);
let proxy = if PROXY_ENABLED { Some(proxy_url.as_str()) } else { None };

let launch_options = LaunchOptions::default_builder()
    .path(Some(browser::default_executable().unwrap()))
    .proxy_server(proxy)
    .build()?;
let browser = Browser::new(launch_options)?;

let tab = browser.new_tab()?;
let tab = tab.navigate_to(URL)?
    .authenticate(Some(PROXY_USER.to_string()), Some(PROXY_PASS.to_string()))? // FIXME
    .wait_until_navigated()?;

let value = tab.wait_for_element(SELECTOR)?
    .get_inner_text()?;

I've also noticed that sometimes I'd get the net::ERR_TUNNEL_CONNECTION_FAILED error on both programmatic approach and manual testing, and it's often persistence.

Do you know a workaround for this issue?

alureon commented 7 months ago

You need to call Tab::enable_fetch with the second argument as Some(true) in order for Chrome to dispatch the "auth required" event. Make sure that whatever URL you visit that triggers the authorization prompt is covered by your request pattern (first arg to enable_fetch).

heyrutvik commented 2 months ago

This will work. However, the sequence of method calls is important. Calling navigate_to before authenticate will result in an error.

tab
    .enable_fetch(None, Some(true))?
    .authenticate(username, password)?
    .navigate_to(url)?
    .wait_until_navigated()?;