Files
tuliprox/src/api/api_utils.rs
T

76 lines
3.5 KiB
Rust
Raw Normal View History

use std::collections::HashMap;
2023-10-27 19:03:29 +02:00
use std::path::{Path};
use actix_web::http::header::{CACHE_CONTROL, HeaderValue};
use actix_web::{HttpRequest, HttpResponse, web};
use log::{debug, error};
use url::Url;
2023-10-25 09:57:44 +02:00
use crate::api::api_model::{AppState, UserApiRequest};
2024-05-03 01:47:41 +02:00
use crate::model::api_proxy::{ApiProxyServerInfo, ProxyUserCredentials};
use crate::model::config::{Config, ConfigTarget, ConfigInput};
use crate::utils::request_utils;
2024-11-04 18:46:56 +01:00
pub async fn serve_file(file_path: &Path, req: &HttpRequest, mime_type: mime::Mime) -> HttpResponse {
if file_path.exists() {
2023-12-01 21:38:23 +01:00
if let Ok(file) = actix_files::NamedFile::open_async(file_path).await {
let mut result = file.set_content_type(mime_type)
2023-12-01 21:38:23 +01:00
.disable_content_disposition().into_response(req);
let headers = result.headers_mut();
2024-11-04 18:46:56 +01:00
headers.insert(CACHE_CONTROL, HeaderValue::from_bytes(b"no-cache").unwrap());
2023-12-01 21:38:23 +01:00
return result;
}
}
2023-12-01 21:38:23 +01:00
HttpResponse::NoContent().finish()
}
2024-11-04 18:46:56 +01:00
pub fn get_user_target_by_credentials<'a>(username: &str, password: &str, api_req: &'a UserApiRequest,
2024-05-03 01:47:41 +02:00
app_state: &'a web::Data<AppState>) -> Option<(ProxyUserCredentials, &'a ConfigTarget)> {
if !username.is_empty() && !password.is_empty() {
2023-12-01 21:38:23 +01:00
app_state.config.get_target_for_user(username, password)
} else {
2023-10-25 21:07:38 +02:00
let token = api_req.token.as_str().trim();
2024-05-10 12:01:48 +02:00
if token.is_empty() {
None
2024-05-10 12:01:48 +02:00
} else {
app_state.config.get_target_for_user_by_token(token)
}
}
2023-11-22 21:06:58 +01:00
}
2024-11-04 18:46:56 +01:00
pub fn get_user_target<'a>(api_req: &'a UserApiRequest, app_state: &'a web::Data<AppState>) -> Option<(ProxyUserCredentials, &'a ConfigTarget)> {
2023-11-22 21:06:58 +01:00
let username = api_req.username.as_str().trim();
let password = api_req.password.as_str().trim();
get_user_target_by_credentials(username, password, api_req, app_state)
}
2024-11-04 18:46:56 +01:00
pub fn get_user_server_info(cfg: &Config, user: &ProxyUserCredentials) -> ApiProxyServerInfo {
2024-05-10 12:01:48 +02:00
let server_info_list = cfg.t_api_proxy.read().unwrap().as_ref().unwrap().server.clone();
2024-11-04 18:46:56 +01:00
let server_info_name = user.server.as_ref().map_or("default", |server_name| server_name.as_str());
server_info_list.iter().find(|c| c.name.eq(server_info_name)).map_or_else(|| server_info_list.first().unwrap().clone(), std::clone::Clone::clone)
}
2024-11-04 18:46:56 +01:00
pub async fn stream_response(stream_url: &str, req: &HttpRequest, input: Option<&ConfigInput>) -> HttpResponse {
let req_headers: HashMap<&str, &[u8]> = req.headers().iter().map(|(k, v)| (k.as_str(), v.as_bytes())).collect();
debug!("Try to open stream {}", stream_url);
if let Ok(url) = Url::parse(stream_url) {
let client = request_utils::get_client_request(input, &url, Some(&req_headers));
match client.send().await {
Ok(response) => {
if response.status().is_success() {
let mut response_builder = HttpResponse::Ok();
response.headers().iter().for_each(|(k, v)| {
response_builder.insert_header((k.as_str(), v.as_ref()));
});
return response_builder.body(actix_web::body::BodyStream::new(response.bytes_stream()));
}
2024-05-10 12:01:48 +02:00
debug!("Failed to open stream got status {} for {}", response.status(), stream_url);
}
Err(err) => {
2024-05-10 12:01:48 +02:00
error!("Received failure from server {}: {}", stream_url, err);
}
}
} else {
2024-05-10 12:01:48 +02:00
error!("Url is malformed {}", &stream_url);
}
HttpResponse::BadRequest().finish()
}