Merge pull request #17 from ben1009/feat/support-file-urls
feat: support file:// URL scheme for local HTML testing
This commit is contained in:
2 files changed
+51
-4
No files matched your search
@@ -551,13 +551,17 @@ fn glob_match(pattern: &str, url: &str) -> bool {
|
||||
|
||||
fn validate_fetch_url(url: &url::Url) -> Result<(), String> {
|
||||
let scheme = url.scheme();
|
||||
if scheme != "http" && scheme != "https" {
|
||||
if scheme != "http" && scheme != "https" && scheme != "file" {
|
||||
return Err(format!(
|
||||
"Forbidden URL scheme '{}' - only http and https are allowed",
|
||||
"Forbidden URL scheme '{}' - only http, https, and file are allowed",
|
||||
scheme
|
||||
));
|
||||
}
|
||||
|
||||
if scheme == "file" {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if let Some(host) = url.host() {
|
||||
match host {
|
||||
url::Host::Ipv4(ip) => {
|
||||
|
||||
@@ -66,13 +66,17 @@ pub type ResponseCallback = Arc<dyn Fn(&RequestInfo, &Response) + Send + Sync>;
|
||||
|
||||
fn validate_url(url: &Url) -> Result<(), ObscuraNetError> {
|
||||
let scheme = url.scheme();
|
||||
if scheme != "http" && scheme != "https" {
|
||||
if scheme != "http" && scheme != "https" && scheme != "file" {
|
||||
return Err(ObscuraNetError::Network(format!(
|
||||
"Forbidden URL scheme '{}' - only http and https are allowed",
|
||||
"Forbidden URL scheme '{}' - only http, https, and file are allowed",
|
||||
scheme
|
||||
)));
|
||||
}
|
||||
|
||||
if scheme == "file" {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if let Some(host) = url.host() {
|
||||
match host {
|
||||
url::Host::Ipv4(ip) => {
|
||||
@@ -115,6 +119,41 @@ fn validate_url(url: &Url) -> Result<(), ObscuraNetError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn fetch_file_url(url: &Url) -> Result<Response, ObscuraNetError> {
|
||||
let path = url
|
||||
.to_file_path()
|
||||
.map_err(|_| ObscuraNetError::Network("Invalid file URL".to_string()))?;
|
||||
let body = tokio::fs::read(&path)
|
||||
.await
|
||||
.map_err(|e| ObscuraNetError::Network(format!("Failed to read file: {}", e)))?;
|
||||
|
||||
let mut headers = HashMap::new();
|
||||
if let Some(ext) = path.extension().and_then(|e| e.to_str()) {
|
||||
let ct = match ext.to_lowercase().as_str() {
|
||||
"html" | "htm" => "text/html",
|
||||
"css" => "text/css",
|
||||
"js" | "mjs" => "application/javascript",
|
||||
"json" => "application/json",
|
||||
"png" => "image/png",
|
||||
"jpg" | "jpeg" => "image/jpeg",
|
||||
"gif" => "image/gif",
|
||||
"svg" => "image/svg+xml",
|
||||
"webp" => "image/webp",
|
||||
"ico" => "image/x-icon",
|
||||
_ => "application/octet-stream",
|
||||
};
|
||||
headers.insert("content-type".to_string(), ct.to_string());
|
||||
}
|
||||
|
||||
Ok(Response {
|
||||
url: url.clone(),
|
||||
status: 200,
|
||||
headers,
|
||||
body,
|
||||
redirected_from: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
pub struct ObscuraHttpClient {
|
||||
client: tokio::sync::OnceCell<Client>,
|
||||
proxy_url: Option<String>,
|
||||
@@ -190,6 +229,10 @@ impl ObscuraHttpClient {
|
||||
) -> Result<Response, ObscuraNetError> {
|
||||
validate_url(url)?;
|
||||
|
||||
if url.scheme() == "file" {
|
||||
return fetch_file_url(url).await;
|
||||
}
|
||||
|
||||
let mut method = initial_method;
|
||||
let mut body = initial_body;
|
||||
if self.block_trackers {
|
||||
|
||||
Reference in new issue
Block a user