Merge branch 'DioxusLabs:master' into make-clone-repo-err-clear
This commit is contained in:
7 files changed
+623
-279
No files matched your search
Generated
+487
-264
File diff suppressed because it is too large.
Load diff
+2
-1
@@ -41,7 +41,7 @@ indicatif = "0.17.0-rc.11"
|
|||||||
subprocess = "0.2.9"
|
subprocess = "0.2.9"
|
||||||
|
|
||||||
axum = { version = "0.5.1", features = ["ws", "headers"] }
|
axum = { version = "0.5.1", features = ["ws", "headers"] }
|
||||||
tower-http = { version = "0.2.2", features = ["fs", "trace"] }
|
tower-http = { version = "0.2.2", features = ["full"] }
|
||||||
headers = "0.3.7"
|
headers = "0.3.7"
|
||||||
|
|
||||||
walkdir = "2"
|
walkdir = "2"
|
||||||
@@ -82,6 +82,7 @@ dioxus-html = { version = "0.3", features = ["hot-reload-context"] }
|
|||||||
dioxus-core = { version = "0.3", features = ["serialize"] }
|
dioxus-core = { version = "0.3", features = ["serialize"] }
|
||||||
dioxus-autofmt = "0.3.0"
|
dioxus-autofmt = "0.3.0"
|
||||||
rsx-rosetta = { version = "0.3" }
|
rsx-rosetta = { version = "0.3" }
|
||||||
|
open = "4.1.0"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|||||||
@@ -46,4 +46,26 @@ You can use `--example {name}` to start a example code.
|
|||||||
```
|
```
|
||||||
# build `example/test` code
|
# build `example/test` code
|
||||||
dioxus serve --exmaple test
|
dioxus serve --exmaple test
|
||||||
|
```
|
||||||
|
|
||||||
|
## Open Browser
|
||||||
|
|
||||||
|
You can add `--open` flag to open system default browser when server startup.
|
||||||
|
|
||||||
|
```
|
||||||
|
dioxus serve --open
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Cross Origin Policy
|
||||||
|
|
||||||
|
use `cross-origin-policy` can change corss-origin header in serverside.
|
||||||
|
|
||||||
|
```
|
||||||
|
Cross-Origin-Opener-Policy: same-origin
|
||||||
|
Cross-Origin-Embedder-Policy: require-corp
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
dioxus serve --corss-origin-policy
|
||||||
```
|
```
|
||||||
@@ -45,6 +45,11 @@ pub struct ConfigOptsServe {
|
|||||||
#[clap(default_value_t = 8080)]
|
#[clap(default_value_t = 8080)]
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
|
|
||||||
|
/// Open the app in the default browser [default: false]
|
||||||
|
#[clap(long)]
|
||||||
|
#[serde(default)]
|
||||||
|
pub open: bool,
|
||||||
|
|
||||||
/// Build a example [default: ""]
|
/// Build a example [default: ""]
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub example: Option<String>,
|
pub example: Option<String>,
|
||||||
@@ -72,6 +77,12 @@ pub struct ConfigOptsServe {
|
|||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub hot_reload: bool,
|
pub hot_reload: bool,
|
||||||
|
|
||||||
|
/// Set cross-origin-policy to same-origin [default: false]
|
||||||
|
#[clap(name="cross-origin-policy")]
|
||||||
|
#[clap(long)]
|
||||||
|
#[serde(default)]
|
||||||
|
pub cross_origin_policy: bool,
|
||||||
|
|
||||||
/// Space separated list of features to activate
|
/// Space separated list of features to activate
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub features: Option<Vec<String>>,
|
pub features: Option<Vec<String>>,
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ impl Serve {
|
|||||||
|
|
||||||
// change the relase state.
|
// change the relase state.
|
||||||
crate_config.with_hot_reload(self.serve.hot_reload);
|
crate_config.with_hot_reload(self.serve.hot_reload);
|
||||||
|
crate_config.with_cross_origin_policy(self.serve.cross_origin_policy);
|
||||||
crate_config.with_release(self.serve.release);
|
crate_config.with_release(self.serve.release);
|
||||||
crate_config.with_verbose(self.serve.verbose);
|
crate_config.with_verbose(self.serve.verbose);
|
||||||
|
|
||||||
@@ -68,7 +69,7 @@ impl Serve {
|
|||||||
Serve::regen_dev_page(&crate_config)?;
|
Serve::regen_dev_page(&crate_config)?;
|
||||||
|
|
||||||
// start the develop server
|
// start the develop server
|
||||||
server::startup(self.serve.port, crate_config.clone()).await?;
|
server::startup(self.serve.port, crate_config.clone(), self.serve.open).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,6 +146,7 @@ pub struct CrateConfig {
|
|||||||
pub dioxus_config: DioxusConfig,
|
pub dioxus_config: DioxusConfig,
|
||||||
pub release: bool,
|
pub release: bool,
|
||||||
pub hot_reload: bool,
|
pub hot_reload: bool,
|
||||||
|
pub cross_origin_policy: bool,
|
||||||
pub verbose: bool,
|
pub verbose: bool,
|
||||||
pub custom_profile: Option<String>,
|
pub custom_profile: Option<String>,
|
||||||
pub features: Option<Vec<String>>,
|
pub features: Option<Vec<String>>,
|
||||||
@@ -213,6 +214,7 @@ impl CrateConfig {
|
|||||||
release,
|
release,
|
||||||
dioxus_config,
|
dioxus_config,
|
||||||
hot_reload,
|
hot_reload,
|
||||||
|
cross_origin_policy: false,
|
||||||
custom_profile,
|
custom_profile,
|
||||||
features,
|
features,
|
||||||
verbose,
|
verbose,
|
||||||
@@ -234,6 +236,11 @@ impl CrateConfig {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_cross_origin_policy(&mut self, cross_origin_policy: bool) -> &mut Self {
|
||||||
|
self.cross_origin_policy = cross_origin_policy;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn with_verbose(&mut self, verbose: bool) -> &mut Self {
|
pub fn with_verbose(&mut self, verbose: bool) -> &mut Self {
|
||||||
self.verbose = verbose;
|
self.verbose = verbose;
|
||||||
self
|
self
|
||||||
|
|||||||
+92
-13
@@ -2,7 +2,10 @@ use crate::{builder, plugin::PluginManager, serve::Serve, BuildResult, CrateConf
|
|||||||
use axum::{
|
use axum::{
|
||||||
body::{Full, HttpBody},
|
body::{Full, HttpBody},
|
||||||
extract::{ws::Message, Extension, TypedHeader, WebSocketUpgrade},
|
extract::{ws::Message, Extension, TypedHeader, WebSocketUpgrade},
|
||||||
http::{Response, StatusCode},
|
http::{
|
||||||
|
header::{HeaderName, HeaderValue},
|
||||||
|
Method, Response, StatusCode,
|
||||||
|
},
|
||||||
response::IntoResponse,
|
response::IntoResponse,
|
||||||
routing::{get, get_service},
|
routing::{get, get_service},
|
||||||
Router,
|
Router,
|
||||||
@@ -22,7 +25,10 @@ use std::{
|
|||||||
use tokio::sync::broadcast;
|
use tokio::sync::broadcast;
|
||||||
use tower::ServiceBuilder;
|
use tower::ServiceBuilder;
|
||||||
use tower_http::services::fs::{ServeDir, ServeFileSystemResponseBody};
|
use tower_http::services::fs::{ServeDir, ServeFileSystemResponseBody};
|
||||||
|
use tower_http::{
|
||||||
|
cors::{Any, CorsLayer},
|
||||||
|
ServiceBuilderExt,
|
||||||
|
};
|
||||||
mod proxy;
|
mod proxy;
|
||||||
|
|
||||||
pub struct BuildManager {
|
pub struct BuildManager {
|
||||||
@@ -55,7 +61,7 @@ struct WsReloadState {
|
|||||||
update: broadcast::Sender<()>,
|
update: broadcast::Sender<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn startup(port: u16, config: CrateConfig) -> Result<()> {
|
pub async fn startup(port: u16, config: CrateConfig, start_browser: bool) -> Result<()> {
|
||||||
// ctrl-c shutdown checker
|
// ctrl-c shutdown checker
|
||||||
let crate_config = config.clone();
|
let crate_config = config.clone();
|
||||||
let _ = ctrlc::set_handler(move || {
|
let _ = ctrlc::set_handler(move || {
|
||||||
@@ -64,10 +70,11 @@ pub async fn startup(port: u16, config: CrateConfig) -> Result<()> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let ip = get_ip().unwrap_or(String::from("0.0.0.0"));
|
let ip = get_ip().unwrap_or(String::from("0.0.0.0"));
|
||||||
|
|
||||||
if config.hot_reload {
|
if config.hot_reload {
|
||||||
startup_hot_reload(ip, port, config).await?
|
startup_hot_reload(ip, port, config, start_browser).await?
|
||||||
} else {
|
} else {
|
||||||
startup_default(ip, port, config).await?
|
startup_default(ip, port, config, start_browser).await?
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -129,7 +136,7 @@ pub async fn hot_reload_handler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_assignments)]
|
#[allow(unused_assignments)]
|
||||||
pub async fn startup_hot_reload(ip: String, port: u16, config: CrateConfig) -> Result<()> {
|
pub async fn startup_hot_reload(ip: String, port: u16, config: CrateConfig, start_browser: bool) -> Result<()> {
|
||||||
let first_build_result = crate::builder::build(&config, false)?;
|
let first_build_result = crate::builder::build(&config, false)?;
|
||||||
|
|
||||||
log::info!("🚀 Starting development server...");
|
log::info!("🚀 Starting development server...");
|
||||||
@@ -264,8 +271,35 @@ pub async fn startup_hot_reload(ip: String, port: u16, config: CrateConfig) -> R
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let cors = CorsLayer::new()
|
||||||
|
// allow `GET` and `POST` when accessing the resource
|
||||||
|
.allow_methods([Method::GET, Method::POST])
|
||||||
|
// allow requests from any origin
|
||||||
|
.allow_origin(Any)
|
||||||
|
.allow_headers(Any);
|
||||||
|
|
||||||
|
let (coep, coop) = if config.cross_origin_policy {
|
||||||
|
(
|
||||||
|
HeaderValue::from_static("require-corp"),
|
||||||
|
HeaderValue::from_static("same-origin"),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(
|
||||||
|
HeaderValue::from_static("unsafe-none"),
|
||||||
|
HeaderValue::from_static("unsafe-none"),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
let file_service_config = config.clone();
|
let file_service_config = config.clone();
|
||||||
let file_service = ServiceBuilder::new()
|
let file_service = ServiceBuilder::new()
|
||||||
|
.override_response_header(
|
||||||
|
HeaderName::from_static("cross-origin-embedder-policy"),
|
||||||
|
coep,
|
||||||
|
)
|
||||||
|
.override_response_header(
|
||||||
|
HeaderName::from_static("cross-origin-opener-policy"),
|
||||||
|
coop,
|
||||||
|
)
|
||||||
.and_then(
|
.and_then(
|
||||||
move |response: Response<ServeFileSystemResponseBody>| async move {
|
move |response: Response<ServeFileSystemResponseBody>| async move {
|
||||||
let response = if file_service_config
|
let response = if file_service_config
|
||||||
@@ -316,17 +350,29 @@ pub async fn startup_hot_reload(ip: String, port: u16, config: CrateConfig) -> R
|
|||||||
|
|
||||||
let router = router
|
let router = router
|
||||||
.route("/_dioxus/hot_reload", get(hot_reload_handler))
|
.route("/_dioxus/hot_reload", get(hot_reload_handler))
|
||||||
|
.layer(cors)
|
||||||
.layer(Extension(ws_reload_state))
|
.layer(Extension(ws_reload_state))
|
||||||
.layer(Extension(hot_reload_state));
|
.layer(Extension(hot_reload_state));
|
||||||
|
|
||||||
axum::Server::bind(&format!("0.0.0.0:{}", port).parse().unwrap())
|
let addr = format!("0.0.0.0:{}", port).parse().unwrap();
|
||||||
.serve(router.into_make_service())
|
|
||||||
.await?;
|
let server = axum::Server::bind(&addr).serve(router.into_make_service());
|
||||||
|
|
||||||
|
if start_browser {
|
||||||
|
let _ = open::that(format!("http://{}", addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
server.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn startup_default(ip: String, port: u16, config: CrateConfig) -> Result<()> {
|
pub async fn startup_default(
|
||||||
|
ip: String,
|
||||||
|
port: u16,
|
||||||
|
config: CrateConfig,
|
||||||
|
start_browser: bool,
|
||||||
|
) -> Result<()> {
|
||||||
let first_build_result = crate::builder::build(&config, false)?;
|
let first_build_result = crate::builder::build(&config, false)?;
|
||||||
|
|
||||||
log::info!("🚀 Starting development server...");
|
log::info!("🚀 Starting development server...");
|
||||||
@@ -409,8 +455,35 @@ pub async fn startup_default(ip: String, port: u16, config: CrateConfig) -> Resu
|
|||||||
|
|
||||||
PluginManager::on_serve_start(&config)?;
|
PluginManager::on_serve_start(&config)?;
|
||||||
|
|
||||||
|
let cors = CorsLayer::new()
|
||||||
|
// allow `GET` and `POST` when accessing the resource
|
||||||
|
.allow_methods([Method::GET, Method::POST])
|
||||||
|
// allow requests from any origin
|
||||||
|
.allow_origin(Any)
|
||||||
|
.allow_headers(Any);
|
||||||
|
|
||||||
|
let (coep, coop) = if config.cross_origin_policy {
|
||||||
|
(
|
||||||
|
HeaderValue::from_static("require-corp"),
|
||||||
|
HeaderValue::from_static("same-origin"),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(
|
||||||
|
HeaderValue::from_static("unsafe-none"),
|
||||||
|
HeaderValue::from_static("unsafe-none"),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
let file_service_config = config.clone();
|
let file_service_config = config.clone();
|
||||||
let file_service = ServiceBuilder::new()
|
let file_service = ServiceBuilder::new()
|
||||||
|
.override_response_header(
|
||||||
|
HeaderName::from_static("cross-origin-embedder-policy"),
|
||||||
|
coep,
|
||||||
|
)
|
||||||
|
.override_response_header(
|
||||||
|
HeaderName::from_static("cross-origin-opener-policy"),
|
||||||
|
coop,
|
||||||
|
)
|
||||||
.and_then(
|
.and_then(
|
||||||
move |response: Response<ServeFileSystemResponseBody>| async move {
|
move |response: Response<ServeFileSystemResponseBody>| async move {
|
||||||
let response = if file_service_config
|
let response = if file_service_config
|
||||||
@@ -459,11 +532,17 @@ pub async fn startup_default(ip: String, port: u16, config: CrateConfig) -> Resu
|
|||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
.layer(cors)
|
||||||
.layer(Extension(ws_reload_state));
|
.layer(Extension(ws_reload_state));
|
||||||
|
|
||||||
axum::Server::bind(&format!("0.0.0.0:{}", port).parse().unwrap())
|
let addr = format!("0.0.0.0:{}", port).parse().unwrap();
|
||||||
.serve(router.into_make_service())
|
let server = axum::Server::bind(&addr).serve(router.into_make_service());
|
||||||
.await?;
|
|
||||||
|
if start_browser {
|
||||||
|
let _ = open::that(format!("http://{}", addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
server.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user