mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-24 10:21:37 +01:00
URL path placeholders
This commit is contained in:
7
src-tauri/Cargo.lock
generated
7
src-tauri/Cargo.lock
generated
@@ -6738,6 +6738,12 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "urlencoding"
|
||||
version = "2.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
|
||||
|
||||
[[package]]
|
||||
name = "urlpattern"
|
||||
version = "0.2.0"
|
||||
@@ -7568,6 +7574,7 @@ dependencies = [
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"urlencoding",
|
||||
"uuid",
|
||||
"yaak_grpc",
|
||||
"yaak_models",
|
||||
|
||||
@@ -58,6 +58,7 @@ tokio-stream = "0.1.15"
|
||||
uuid = "1.7.0"
|
||||
thiserror = "1.0.61"
|
||||
mime_guess = "2.0.5"
|
||||
urlencoding = "2.1.3"
|
||||
|
||||
[workspace.dependencies]
|
||||
yaak_models = { path = "yaak_models" }
|
||||
|
||||
@@ -23,7 +23,7 @@ use tauri::{Manager, Runtime, WebviewWindow};
|
||||
use tokio::sync::oneshot;
|
||||
use tokio::sync::watch::Receiver;
|
||||
use yaak_models::models::{
|
||||
Cookie, CookieJar, Environment, HttpRequest, HttpResponse, HttpResponseHeader,
|
||||
Cookie, CookieJar, Environment, HttpRequest, HttpResponse, HttpResponseHeader, HttpUrlParameter,
|
||||
};
|
||||
use yaak_models::queries::{get_workspace, update_response_if_id, upsert_cookie_jar};
|
||||
|
||||
@@ -40,13 +40,8 @@ pub async fn send_http_request<R: Runtime>(
|
||||
.expect("Failed to get Workspace");
|
||||
let cb = &*window.app_handle().state::<PluginTemplateCallback>();
|
||||
let cb = cb.for_send();
|
||||
let rendered_request = render_http_request(
|
||||
&request,
|
||||
&workspace,
|
||||
environment.as_ref(),
|
||||
&cb,
|
||||
)
|
||||
.await;
|
||||
let rendered_request =
|
||||
render_http_request(&request, &workspace, environment.as_ref(), &cb).await;
|
||||
|
||||
let mut url_string = rendered_request.url;
|
||||
|
||||
@@ -101,6 +96,23 @@ pub async fn send_http_request<R: Runtime>(
|
||||
|
||||
let client = client_builder.build().expect("Failed to build client");
|
||||
|
||||
// Render query parameters
|
||||
let mut query_params = Vec::new();
|
||||
for p in rendered_request.url_parameters {
|
||||
if !p.enabled || p.name.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Replace path parameters with values from URL parameters
|
||||
let old_url_string = url_string.clone();
|
||||
url_string = replace_path_placeholder(&p, url_string.as_str());
|
||||
|
||||
// Treat as regular param if wasn't used as path param
|
||||
if old_url_string == url_string {
|
||||
query_params.push((p.name, p.value));
|
||||
}
|
||||
}
|
||||
|
||||
let uri = match http::Uri::from_str(url_string.as_str()) {
|
||||
Ok(u) => u,
|
||||
Err(e) => {
|
||||
@@ -127,7 +139,7 @@ pub async fn send_http_request<R: Runtime>(
|
||||
|
||||
let m = Method::from_bytes(rendered_request.method.to_uppercase().as_bytes())
|
||||
.expect("Failed to create method");
|
||||
let mut request_builder = client.request(m, url);
|
||||
let mut request_builder = client.request(m, url).query(&query_params);
|
||||
|
||||
let mut headers = HeaderMap::new();
|
||||
headers.insert(USER_AGENT, HeaderValue::from_static("yaak"));
|
||||
@@ -210,15 +222,6 @@ pub async fn send_http_request<R: Runtime>(
|
||||
}
|
||||
}
|
||||
|
||||
let mut query_params = Vec::new();
|
||||
for p in rendered_request.url_parameters {
|
||||
if !p.enabled || p.name.is_empty() {
|
||||
continue;
|
||||
}
|
||||
query_params.push((p.name, p.value));
|
||||
}
|
||||
request_builder = request_builder.query(&query_params);
|
||||
|
||||
let request_body = rendered_request.body;
|
||||
if let Some(body_type) = &rendered_request.body_type {
|
||||
if request_body.contains_key("text") {
|
||||
@@ -489,3 +492,119 @@ fn get_str_h<'a>(v: &'a HashMap<String, Value>, key: &str) -> &'a str {
|
||||
Some(v) => v.as_str().unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn replace_path_placeholder(p: &HttpUrlParameter, url: &str) -> String {
|
||||
if !p.enabled {
|
||||
return url.to_string();
|
||||
}
|
||||
|
||||
let re = regex::Regex::new(format!("(/){}([/?#]|$)", p.name).as_str()).unwrap();
|
||||
let result = re
|
||||
.replace_all(url, |cap: ®ex::Captures| {
|
||||
format!(
|
||||
"{}{}{}",
|
||||
cap[1].to_string(),
|
||||
urlencoding::encode(p.value.as_str()),
|
||||
cap[2].to_string()
|
||||
)
|
||||
})
|
||||
.into_owned();
|
||||
result
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::http_request::replace_path_placeholder;
|
||||
use yaak_models::models::HttpUrlParameter;
|
||||
|
||||
#[test]
|
||||
fn placeholder_middle() {
|
||||
let p = HttpUrlParameter {
|
||||
name: ":foo".into(),
|
||||
value: "xxx".into(),
|
||||
enabled: true,
|
||||
};
|
||||
assert_eq!(
|
||||
replace_path_placeholder(&p, "https://example.com/:foo/bar"),
|
||||
"https://example.com/xxx/bar",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn placeholder_end() {
|
||||
let p = HttpUrlParameter {
|
||||
name: ":foo".into(),
|
||||
value: "xxx".into(),
|
||||
enabled: true,
|
||||
};
|
||||
assert_eq!(
|
||||
replace_path_placeholder(&p, "https://example.com/:foo"),
|
||||
"https://example.com/xxx",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn placeholder_query() {
|
||||
let p = HttpUrlParameter {
|
||||
name: ":foo".into(),
|
||||
value: "xxx".into(),
|
||||
enabled: true,
|
||||
};
|
||||
assert_eq!(
|
||||
replace_path_placeholder(&p, "https://example.com/:foo?:foo"),
|
||||
"https://example.com/xxx?:foo",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn placeholder_missing() {
|
||||
let p = HttpUrlParameter {
|
||||
enabled: true,
|
||||
name: "".to_string(),
|
||||
value: "".to_string(),
|
||||
};
|
||||
assert_eq!(
|
||||
replace_path_placeholder(&p, "https://example.com/:missing"),
|
||||
"https://example.com/:missing",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn placeholder_disabled() {
|
||||
let p = HttpUrlParameter {
|
||||
enabled: false,
|
||||
name: ":foo".to_string(),
|
||||
value: "xxx".to_string(),
|
||||
};
|
||||
assert_eq!(
|
||||
replace_path_placeholder(&p, "https://example.com/:foo"),
|
||||
"https://example.com/:foo",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn placeholder_prefix() {
|
||||
let p = HttpUrlParameter {
|
||||
name: ":foo".into(),
|
||||
value: "xxx".into(),
|
||||
enabled: true,
|
||||
};
|
||||
assert_eq!(
|
||||
replace_path_placeholder(&p, "https://example.com/:foooo"),
|
||||
"https://example.com/:foooo",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn placeholder_encode() {
|
||||
let p = HttpUrlParameter {
|
||||
name: ":foo".into(),
|
||||
value: "Hello World".into(),
|
||||
enabled: true,
|
||||
};
|
||||
assert_eq!(
|
||||
replace_path_placeholder(&p, "https://example.com/:foo"),
|
||||
"https://example.com/Hello%20World",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user