feat: add --allow-file-access flag for file:// URL support (#375)

* feat: add --allow-file-access flag for file:// URL support

Adds the ability to open and interact with local files using file:// URLs.
This enables use cases like viewing local PDFs, testing local HTML files,
and allowing JavaScript to access other local files via XHR.

The flag adds Chromium's --allow-file-access-from-files and --allow-file-access
launch arguments. Only supported in Chromium browsers.

Fixes #345

* fix: add cli_allow_file_access tracking to prevent spurious warning

When --allow-file-access is set via AGENT_BROWSER_ALLOW_FILE_ACCESS env var
(not CLI), don't warn about the flag being ignored when daemon is already running.
This commit is contained in:
Chris Tate
2026-02-05 00:24:28 -06:00
committed by GitHub
parent 74be667c80
commit 07c2372766
12 changed files with 262 additions and 5 deletions
+2
View File
@@ -1427,6 +1427,7 @@ mod tests {
user_agent: None,
provider: None,
ignore_https_errors: false,
allow_file_access: false,
device: None,
cli_executable_path: false,
cli_extensions: false,
@@ -1436,6 +1437,7 @@ mod tests {
cli_user_agent: false,
cli_proxy: false,
cli_proxy_bypass: false,
cli_allow_file_access: false,
}
}
+9
View File
@@ -213,6 +213,7 @@ pub fn ensure_daemon(
proxy: Option<&str>,
proxy_bypass: Option<&str>,
ignore_https_errors: bool,
allow_file_access: bool,
profile: Option<&str>,
state: Option<&str>,
provider: Option<&str>,
@@ -337,6 +338,10 @@ pub fn ensure_daemon(
cmd.env("AGENT_BROWSER_IGNORE_HTTPS_ERRORS", "1");
}
if allow_file_access {
cmd.env("AGENT_BROWSER_ALLOW_FILE_ACCESS", "1");
}
if let Some(prof) = profile {
cmd.env("AGENT_BROWSER_PROFILE", prof);
}
@@ -412,6 +417,10 @@ pub fn ensure_daemon(
cmd.env("AGENT_BROWSER_IGNORE_HTTPS_ERRORS", "1");
}
if allow_file_access {
cmd.env("AGENT_BROWSER_ALLOW_FILE_ACCESS", "1");
}
if let Some(prof) = profile {
cmd.env("AGENT_BROWSER_PROFILE", prof);
}
+9
View File
@@ -18,6 +18,7 @@ pub struct Flags {
pub user_agent: Option<String>,
pub provider: Option<String>,
pub ignore_https_errors: bool,
pub allow_file_access: bool,
pub device: Option<String>,
// Track which launch-time options were explicitly passed via CLI
@@ -30,6 +31,7 @@ pub struct Flags {
pub cli_user_agent: bool,
pub cli_proxy: bool,
pub cli_proxy_bypass: bool,
pub cli_allow_file_access: bool,
}
pub fn parse_flags(args: &[String]) -> Flags {
@@ -61,6 +63,7 @@ pub fn parse_flags(args: &[String]) -> Flags {
user_agent: env::var("AGENT_BROWSER_USER_AGENT").ok(),
provider: env::var("AGENT_BROWSER_PROVIDER").ok(),
ignore_https_errors: false,
allow_file_access: env::var("AGENT_BROWSER_ALLOW_FILE_ACCESS").is_ok(),
device: env::var("AGENT_BROWSER_IOS_DEVICE").ok(),
// Track CLI-passed flags (default false, set to true when flag is passed)
cli_executable_path: false,
@@ -71,6 +74,7 @@ pub fn parse_flags(args: &[String]) -> Flags {
cli_user_agent: false,
cli_proxy: false,
cli_proxy_bypass: false,
cli_allow_file_access: false,
};
let mut i = 0;
@@ -161,6 +165,10 @@ pub fn parse_flags(args: &[String]) -> Flags {
}
}
"--ignore-https-errors" => flags.ignore_https_errors = true,
"--allow-file-access" => {
flags.allow_file_access = true;
flags.cli_allow_file_access = true;
}
"--device" => {
if let Some(d) = args.get(i + 1) {
flags.device = Some(d.clone());
@@ -185,6 +193,7 @@ pub fn clean_args(args: &[String]) -> Vec<String> {
"--headed",
"--debug",
"--ignore-https-errors",
"--allow-file-access",
];
// Global flags that take a value (need to skip the next arg too)
const GLOBAL_FLAGS_WITH_VALUE: &[&str] = &[
+8 -1
View File
@@ -205,6 +205,7 @@ fn main() {
flags.proxy.as_deref(),
flags.proxy_bypass.as_deref(),
flags.ignore_https_errors,
flags.allow_file_access,
flags.profile.as_deref(),
flags.state.as_deref(),
flags.provider.as_deref(),
@@ -267,6 +268,7 @@ fn main() {
None
},
flags.ignore_https_errors.then(|| "--ignore-https-errors"),
flags.cli_allow_file_access.then(|| "--allow-file-access"),
]
.into_iter()
.flatten()
@@ -417,7 +419,8 @@ fn main() {
|| flags.state.is_some()
|| flags.proxy.is_some()
|| flags.args.is_some()
|| flags.user_agent.is_some())
|| flags.user_agent.is_some()
|| flags.allow_file_access)
&& flags.cdp.is_none()
&& flags.provider.is_none()
{
@@ -470,6 +473,10 @@ fn main() {
launch_cmd["ignoreHTTPSErrors"] = json!(true);
}
if flags.allow_file_access {
launch_cmd["allowFileAccess"] = json!(true);
}
match send_command(launch_cmd, &flags.session) {
Ok(resp) if !resp.success => {
// Launch command failed (e.g., invalid state file, profile error)
+1
View File
@@ -1771,6 +1771,7 @@ Options:
--proxy-bypass <hosts> Bypass proxy for these hosts (or AGENT_BROWSER_PROXY_BYPASS)
e.g., --proxy-bypass "localhost,*.internal.com"
--ignore-https-errors Ignore HTTPS certificate errors
--allow-file-access Allow file:// URLs to access local files (Chromium only)
-p, --provider <name> Browser provider: ios, browserbase, kernel, browseruse
--device <name> iOS device name (e.g., "iPhone 15 Pro")
--json JSON output