Bläddra i källkod

refactor: do not proxy dev server when using localhost on iOS/Android

Lucas Nogueira 10 månader sedan
förälder
incheckning
7c6bb5dfd7

+ 2 - 7
crates/tauri-cli/src/mobile/android/dev.rs

@@ -103,7 +103,7 @@ impl From<Options> for DevOptions {
       no_dev_server: options.no_dev_server,
       port: options.port,
       release_mode: options.release_mode,
-      host: None,
+      host: options.host.unwrap_or_default(),
     }
   }
 }
@@ -197,12 +197,7 @@ fn run_dev(
   noise_level: NoiseLevel,
 ) -> Result<()> {
   // when running on an actual device we must use the network IP
-  if options.host.is_some()
-    || device
-      .as_ref()
-      .map(|device| !device.serial_no().starts_with("emulator"))
-      .unwrap_or(false)
-  {
+  if options.host.is_some() {
     use_network_address_for_dev_url(&tauri_config, &mut dev_options, options.force_ip_prompt)?;
   }
 

+ 15 - 0
crates/tauri/src/manager/mod.rs

@@ -6,6 +6,7 @@ use std::{
   borrow::Cow,
   collections::HashMap,
   fmt,
+  net::Ipv4Addr,
   sync::{Arc, Mutex, MutexGuard},
 };
 
@@ -332,6 +333,20 @@ impl<R: Runtime> AppManager<R> {
     self.config.build.dev_url.as_ref()
   }
 
+  pub(crate) fn proxy_dev_server_url(&self) -> Option<Url> {
+    let proxy = cfg!(mobile)
+      && cfg!(dev)
+      && self.config.build.dev_url.as_ref().map_or(false, |url| {
+        url.host().map_or(false, |host| match host {
+          url::Host::Domain(d) => d != "localhost",
+          url::Host::Ipv4(ip) => ip != Ipv4Addr::LOCALHOST,
+          _ => false,
+        })
+      });
+
+    proxy.then(|| self.get_url().into_owned())
+  }
+
   pub(crate) fn protocol_url(&self) -> Cow<'_, Url> {
     if cfg!(windows) || cfg!(target_os = "android") {
       Cow::Owned(Url::parse("http://tauri.localhost").unwrap())

+ 4 - 8
crates/tauri/src/manager/webview.rs

@@ -34,12 +34,6 @@ use super::{
   AppManager,
 };
 
-// we need to proxy the dev server on mobile because we can't use `localhost`, so we use the local IP address
-// and we do not get a secure context without the custom protocol that proxies to the dev server
-// additionally, we need the custom protocol to inject the initialization scripts on Android
-// must also keep in sync with the `let mut response` assignment in prepare_uri_scheme_protocol
-pub(crate) const PROXY_DEV_SERVER: bool = cfg!(all(dev, mobile));
-
 pub(crate) const PROCESS_IPC_MESSAGE_FN: &str =
   include_str!("../../scripts/process-ipc-message-fn.js");
 
@@ -403,10 +397,12 @@ impl<R: Runtime> WebviewManager<R> {
 
     let app_manager = manager.manager();
 
+    let proxy_dev_server = app_manager.proxy_dev_server_url().is_some();
+
     #[allow(unused_mut)] // mut url only for the data-url parsing
     let mut url = match &pending.webview_attributes.url {
       WebviewUrl::App(path) => {
-        let url = if PROXY_DEV_SERVER {
+        let url = if proxy_dev_server {
           Cow::Owned(Url::parse("tauri://localhost").unwrap())
         } else {
           app_manager.get_url()
@@ -426,7 +422,7 @@ impl<R: Runtime> WebviewManager<R> {
         let config_url = app_manager.get_url();
         let is_local = config_url.make_relative(url).is_some();
         let mut url = url.clone();
-        if is_local && PROXY_DEV_SERVER {
+        if is_local && proxy_dev_server {
           url.set_scheme("tauri").unwrap();
           url.set_host(Some("localhost")).unwrap();
         }

+ 11 - 28
crates/tauri/src/protocol/tauri.rs

@@ -7,15 +7,13 @@ use std::{borrow::Cow, sync::Arc};
 use http::{header::CONTENT_TYPE, Request, Response as HttpResponse, StatusCode};
 
 use crate::{
-  manager::{webview::PROXY_DEV_SERVER, AppManager},
+  manager::AppManager,
   webview::{UriSchemeProtocolHandler, WebResourceRequestHandler},
   Runtime,
 };
 
-#[cfg(all(dev, mobile))]
 use std::{collections::HashMap, sync::Mutex};
 
-#[cfg(all(dev, mobile))]
 #[derive(Clone)]
 struct CachedResponse {
   status: http::StatusCode,
@@ -28,18 +26,8 @@ pub fn get<R: Runtime>(
   window_origin: &str,
   web_resource_request_handler: Option<Box<WebResourceRequestHandler>>,
 ) -> UriSchemeProtocolHandler {
-  #[cfg(all(dev, mobile))]
-  let url = {
-    let mut url = manager.get_url().as_str().to_string();
-    if url.ends_with('/') {
-      url.pop();
-    }
-    url
-  };
-
   let window_origin = window_origin.to_string();
 
-  #[cfg(all(dev, mobile))]
   let response_cache = Arc::new(Mutex::new(HashMap::new()));
 
   Box::new(move |request, responder| {
@@ -48,8 +36,7 @@ pub fn get<R: Runtime>(
       &manager,
       &window_origin,
       web_resource_request_handler.as_deref(),
-      #[cfg(all(dev, mobile))]
-      (&url, &response_cache),
+      &response_cache,
     ) {
       Ok(response) => responder.respond(response),
       Err(e) => responder.respond(
@@ -66,16 +53,15 @@ pub fn get<R: Runtime>(
 
 fn get_response<R: Runtime>(
   request: Request<Vec<u8>>,
-  #[allow(unused_variables)] manager: &AppManager<R>,
+  manager: &AppManager<R>,
   window_origin: &str,
   web_resource_request_handler: Option<&WebResourceRequestHandler>,
-  #[cfg(all(dev, mobile))] (url, response_cache): (
-    &str,
-    &Arc<Mutex<HashMap<String, CachedResponse>>>,
-  ),
+  response_cache: &Arc<Mutex<HashMap<String, CachedResponse>>>,
 ) -> Result<HttpResponse<Cow<'static, [u8]>>, Box<dyn std::error::Error>> {
+  let proxy_dev_server_url = manager.proxy_dev_server_url();
+
   // use the entire URI as we are going to proxy the request
-  let path = if PROXY_DEV_SERVER {
+  let path = if proxy_dev_server_url.is_some() {
     request.uri().to_string()
   } else {
     // ignore query string and fragment
@@ -97,14 +83,13 @@ fn get_response<R: Runtime>(
 
   let mut builder = HttpResponse::builder().header("Access-Control-Allow-Origin", window_origin);
 
-  #[cfg(all(dev, mobile))]
-  let mut response = {
+  let mut response = if let Some(proxy_dev_server_url) = proxy_dev_server_url {
     let decoded_path = percent_encoding::percent_decode(path.as_bytes())
       .decode_utf8_lossy()
       .to_string();
     let url = format!(
       "{}/{}",
-      url.trim_end_matches('/'),
+      proxy_dev_server_url.as_str().trim_end_matches('/'),
       decoded_path.trim_start_matches('/')
     );
 
@@ -148,10 +133,7 @@ fn get_response<R: Runtime>(
         return Err(Box::new(e));
       }
     }
-  };
-
-  #[cfg(not(all(dev, mobile)))]
-  let mut response = {
+  } else {
     let asset = manager.get_asset(path)?;
     builder = builder.header(CONTENT_TYPE, &asset.mime_type);
     if let Some(csp) = &asset.csp_header {
@@ -159,6 +141,7 @@ fn get_response<R: Runtime>(
     }
     builder.body(asset.bytes.into())?
   };
+
   if let Some(handler) = &web_resource_request_handler {
     handler(request, &mut response);
   }