reactive_graph_runtime_web_impl/
web_resource_manager_handler.rs1use std::sync::Arc;
2
3use actix_http::body::BoxBody;
4use actix_web::HttpRequest;
5use actix_web::HttpResponse;
6use actix_web::HttpResponseBuilder;
7use actix_web::web;
8use http::Request;
9use http::Response;
10use http::header::CONTENT_TYPE;
11use log::debug;
12
13use reactive_graph_plugin_api::HttpBody;
14use reactive_graph_runtime_web_api::RootPathInfo;
15use reactive_graph_runtime_web_api::WebResourceManager;
16use reactive_graph_runtime_web_api::WebResourcePathInfo;
17
18pub async fn handle_web_resource(
19 web_resource_manager: web::Data<Arc<dyn WebResourceManager + Send + Sync>>,
20 path_info: web::Path<WebResourcePathInfo>,
21 request: HttpRequest,
22) -> HttpResponse {
23 let context_path = path_info.web_resource_context_path.clone();
24 let path = path_info.path.clone();
25 let uri = request.uri().clone();
26 let http_request = convert_request(request);
27 match web_resource_manager.get(context_path.clone()) {
28 Some(web_resource) => match web_resource.handle_web_resource(path, http_request).await {
29 Ok(response) => convert_response(response),
30 Err(e) => HttpResponse::InternalServerError().body(format!("500 Internal Server Error: {e}")),
31 },
32 None => match web_resource_manager.get_default() {
33 Some(web_resource) => match web_resource.handle_web_resource(format!("{context_path}/{path}"), http_request).await {
34 Ok(response) => convert_response(response),
35 Err(e) => HttpResponse::InternalServerError().body(format!("500 Internal Server Error: {e}")),
36 },
37 None => HttpResponse::NotFound().body(format!("404 Not Found: {uri}")),
38 },
39 }
40}
41
42pub async fn handle_root_web_resource(
43 web_resource_manager: web::Data<Arc<dyn WebResourceManager + Send + Sync>>,
44 path_info: web::Path<RootPathInfo>,
45 request: HttpRequest,
46) -> HttpResponse {
47 let path = path_info.path.clone();
48 let uri = request.uri().clone();
49 debug!("Handle root web resource on path: {path} uri: {uri}");
50 let http_request = convert_request(request);
51 match web_resource_manager.get_default() {
52 Some(web_resource) => match web_resource.handle_web_resource(path, http_request).await {
53 Ok(response) => convert_response(response),
54 Err(e) => HttpResponse::InternalServerError().body(format!("500 Internal Server Error: {e}")),
55 },
56 None => HttpResponse::NotFound().body(format!("404 Not Found: {uri}")),
57 }
58}
59
60fn convert_request(request: HttpRequest) -> Request<HttpBody> {
61 let mut request_builder = http::request::Builder::new()
62 .uri(request.uri())
63 .method(request.method())
64 .version(request.version());
65 if let Some(headers_map) = request_builder.headers_mut() {
66 request.headers().into_iter().for_each(|(header_name, header_value)| {
67 headers_map.insert(header_name, header_value.clone());
68 });
69 }
70 request_builder.body(HttpBody::None).unwrap()
71}
72
73fn convert_response(response: Response<HttpBody>) -> HttpResponse {
74 let mut response_builder = HttpResponseBuilder::new(response.status());
75 if let Some(header) = response.headers().get(CONTENT_TYPE) {
76 response_builder.content_type(header);
77 }
78 response.headers().into_iter().for_each(|header| {
79 response_builder.append_header(header);
80 });
81 response_builder.body(match response.into_body() {
82 HttpBody::None => BoxBody::new(()),
83 HttpBody::Binary(bytes) => BoxBody::new(bytes),
84 HttpBody::Json(value) => BoxBody::new(serde_json::to_string(&value).unwrap_or_default()),
85 HttpBody::PlainText(content) => BoxBody::new(content),
86 })
87}