botserver/src/basic/keywords/get.rs

85 lines
2.7 KiB
Rust
Raw Normal View History

2025-10-11 12:29:03 -03:00
use crate::shared::models::UserSession;
use crate::shared::state::AppState;
use log::info;
2025-10-06 10:30:17 -03:00
use reqwest::{self, Client};
use rhai::{Dynamic, Engine};
use std::error::Error;
pub fn get_keyword(state: &AppState, _user: UserSession, engine: &mut Engine) {
let state_clone = state.clone();
2025-10-11 12:29:03 -03:00
engine
.register_custom_syntax(&["GET", "$expr$"], false, move |context, inputs| {
let url = context.eval_expression_tree(&inputs[0])?;
let url_str = url.to_string();
if url_str.contains("..") {
return Err("URL contains invalid path traversal sequences like '..'.".into());
}
let state_for_async = state_clone.clone();
let url_for_async = url_str.clone();
if url_str.starts_with("https://") {
info!("HTTPS GET request: {}", url_for_async);
let fut = execute_get(&url_for_async);
let result =
tokio::task::block_in_place(|| tokio::runtime::Handle::current().block_on(fut))
.map_err(|e| format!("HTTP request failed: {}", e))?;
Ok(Dynamic::from(result))
} else {
info!("Local file GET request from bucket: {}", url_for_async);
let fut = get_from_bucket(&state_for_async, &url_for_async);
let result =
tokio::task::block_in_place(|| tokio::runtime::Handle::current().block_on(fut))
.map_err(|e| format!("Bucket GET failed: {}", e))?;
Ok(Dynamic::from(result))
}
})
2025-10-11 12:29:03 -03:00
.unwrap();
2025-10-06 10:30:17 -03:00
}
pub async fn execute_get(url: &str) -> Result<String, Box<dyn Error + Send + Sync>> {
info!("Starting execute_get with URL: {}", url);
let client = Client::builder()
.danger_accept_invalid_certs(true)
.build()?;
let response = client.get(url).send().await?;
2025-10-11 12:29:03 -03:00
let content = response.text().await?;
2025-10-06 10:30:17 -03:00
2025-10-11 12:29:03 -03:00
Ok(content)
2025-10-06 10:30:17 -03:00
}
pub async fn get_from_bucket(
state: &AppState,
file_path: &str,
) -> Result<String, Box<dyn Error + Send + Sync>> {
info!("Getting file from bucket: {}", file_path);
if let Some(s3_client) = &state.s3_client {
2025-10-15 10:37:04 -03:00
let bucket_name = std::env::var("DRIVE_ORG_PREFIX")
.map(|v| format!("{}-default", v))
.unwrap_or_else(|_| "org-default".to_string());
let response = s3_client
.get_object()
.bucket(&bucket_name)
.key(file_path)
.send()
.await?;
let data = response.body.collect().await?;
let content = String::from_utf8(data.into_bytes().to_vec())?;
Ok(content)
} else {
Err("S3 client not configured".into())
}
}