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:
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user