diff --git a/Cargo.lock b/Cargo.lock index 87a5fff795..3a0b7475cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5256,7 +5256,6 @@ dependencies = [ "etcd-client", "flatten-json-object", "futures", - "futures-util", "get_if_addrs", "glob", "http-auth-basic", diff --git a/Cargo.toml b/Cargo.toml index f000fc67ed..acffae3ea2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,7 +70,6 @@ env_logger = "0.10" etcd-client = { version = "0.10.2", features = ["tls"] } flatten-json-object = "0.6.1" futures = "0.3" -futures-util = "0.3.25" get_if_addrs = "0.5.3" glob = "0.3.0" http-auth-basic = "0.3.3" diff --git a/src/handler/http/router/mod.rs b/src/handler/http/router/mod.rs index 10f306d25c..2f72dd8e72 100644 --- a/src/handler/http/router/mod.rs +++ b/src/handler/http/router/mod.rs @@ -13,8 +13,10 @@ // limitations under the License. use actix_cors::Cors; -use actix_web::{http::header, web}; +use actix_web::dev::{Service, ServiceResponse}; +use actix_web::{body::MessageBody, http::header, web, HttpResponse}; use actix_web_httpauth::middleware::HttpAuthentication; +use futures::FutureExt; use std::sync::Arc; use utoipa::OpenApi; use utoipa_swagger_ui::{SwaggerUi, Url}; @@ -65,14 +67,31 @@ pub fn get_basic_routes(cfg: &mut web::ServiceConfig) { if CONFIG.common.ui_enabled { cfg.service(web::redirect("/", "./web/")); - cfg.service(web::redirect("/web/alerts/alerts", "../alerts")); - cfg.service(web::redirect("/web/alerts/destinations", "../alerts")); - cfg.service(web::redirect("/web/alerts/templates", "../alerts")); - cfg.service(web::redirect("/web/ingestion/curl", "../ingestion")); - cfg.service(web::redirect("/web/ingestion/fluentbit", "../ingestion")); - cfg.service(web::redirect("/web/ingestion/fluentd", "../ingestion")); - cfg.service(web::redirect("/web/ingestion/vector", "../ingestion")); - cfg.service(ui::serve); + cfg.service(web::redirect("/web", "./web/")); + cfg.service( + web::scope("/web") + .wrap_fn(|req, srv| { + let prefix = format!("{}/web/", CONFIG.common.base_uri); + let path = req.path().strip_prefix(&prefix).unwrap().to_string(); + srv.call(req).map(move |res| { + if ui::UI_PAGES.contains(&path.as_str()) { + let res = res.unwrap(); + let req = res.request().clone(); + let body = res.into_body(); + let body = body.try_into_bytes().unwrap(); + let body = String::from_utf8(body.to_vec()).unwrap(); + let body = body.replace( + r#""#, + format!(r#""#, prefix).as_str(), + ); + Ok(ServiceResponse::new(req, HttpResponse::Ok().body(body))) + } else { + res + } + }) + }) + .service(ui::serve), + ); } } diff --git a/src/handler/http/router/ui.rs b/src/handler/http/router/ui.rs index 86d05969d7..8d2897ba06 100644 --- a/src/handler/http/router/ui.rs +++ b/src/handler/http/router/ui.rs @@ -22,7 +22,8 @@ use rust_embed_for_web::RustEmbed; #[folder = "web/dist/"] struct WebAssets; -pub const UI_PAGES: [&str; 19] = [ +pub const UI_PAGES: [&str; 22] = [ + "", "login", "logout", "about", @@ -31,6 +32,8 @@ pub const UI_PAGES: [&str; 19] = [ "dashboards", "viewDashboard", "addPanel", + "dashboards/view", + "dashboards/addPanel", "logstreams", "functions", "alerts", @@ -44,18 +47,12 @@ pub const UI_PAGES: [&str; 19] = [ "ingestion/vector", ]; -#[route("/web/{path:.*}", method = "GET", method = "HEAD")] +#[route("/{path:.*}", method = "GET", method = "HEAD")] pub async fn serve(path: web::Path) -> EmbedResponse { - let mut path = if path.is_empty() { - "index.html" - } else { - path.as_str() - }; - + let mut path = path.as_str(); if UI_PAGES.contains(&path) { path = "index.html"; } - WebAssets::get(path) .into_response() .use_compression(Compress::Never) diff --git a/src/service/search/datafusion/exec.rs b/src/service/search/datafusion/exec.rs index 3c1de5db23..757952f5ad 100644 --- a/src/service/search/datafusion/exec.rs +++ b/src/service/search/datafusion/exec.rs @@ -396,19 +396,32 @@ fn merge_rewrite_sql(sql: &str, schema: Arc) -> Result { let sql_chars_len = sql_chars.len(); let mut start_pos = 0; let mut in_word = false; - let mut bracket = 0; + let mut brackets = 0; + let mut quotes = 0; + let mut quote_now = '\"'; for i in 0..sql_chars_len { let c = sql_chars.get(i).unwrap(); if *c == '(' { - bracket += 1; + brackets += 1; continue; } if *c == ')' { - bracket -= 1; + brackets -= 1; continue; } + if *c == '"' || *c == '\'' { + if quotes == 0 { + quotes += 1; + quote_now = *c; + continue; + } + if quotes == 1 && quote_now == *c { + quotes = 0; + continue; + } + } if *c == ',' || *c == ' ' { - if bracket > 0 { + if brackets > 0 || quotes > 0 { continue; } if in_word { diff --git a/web/index.html b/web/index.html index b2ac75bfb5..d1069da4cd 100644 --- a/web/index.html +++ b/web/index.html @@ -6,6 +6,7 @@ ZincObserve +