Skip to main content

datex_native/com_interfaces/http/
http_server.rs

1use datex_core::{derive_setup_data};
2use core::str::FromStr;
3use std::net::SocketAddr;
4use async_tiny::{Response, Server};
5
6use datex_core::network::com_interfaces::default_setup_data::http::http_server::{HTTPServerInterfaceSetupData};
7use datex_core::{
8    network::{
9        com_hub::errors::ComInterfaceCreateError,
10        com_interfaces::com_interface::{
11            factory::{
12                ComInterfaceAsyncFactory, ComInterfaceAsyncFactoryResult,
13            },
14            properties::ComInterfaceProperties,
15        },
16    },
17};
18use datex_core::network::com_interfaces::com_interface::properties::InterfaceDirection;
19use datex_core::global::dxb_block::DXBBlock;
20use datex_core::network::com_interfaces::com_interface::factory::{ComInterfaceConfiguration, SendCallback, SendFailure, SendSuccess, SocketConfiguration, SocketProperties};
21
22derive_setup_data!(HTTPServerInterfaceSetupDataNative, HTTPServerInterfaceSetupData);
23
24impl HTTPServerInterfaceSetupDataNative {
25    async fn create_interface(self) -> Result<ComInterfaceConfiguration, ComInterfaceCreateError> {
26        let addr = SocketAddr::from_str(&self.bind_address)
27            .map_err(ComInterfaceCreateError::invalid_setup_data)?;
28
29        let mut server = Server::http(&addr.to_string(), false).await.map_err(|e| {
30            ComInterfaceCreateError::connection_error_with_details(e)
31        })?;
32
33        println!("HTTP server running on http://{addr}");
34
35        Ok(ComInterfaceConfiguration::new_multi_socket(
36            ComInterfaceProperties {
37                name: Some(addr.to_string()),
38                connectable_interfaces: HTTPServerInterfaceSetupData::get_clients_setup_data(self.0.accept_addresses)?,
39                ..Self::get_default_properties()
40            },
41            async gen move {
42                // create new tmp socket for each new incoming request
43                while let Some(request) = server.next().await {
44                    println!("Accepted new HTTP request: {} {}", request.method(), request.url());
45                    let request_body = request.body().to_vec();
46                    // yield new socket data
47                    yield Ok(SocketConfiguration::new_in_out(
48                        SocketProperties::new(InterfaceDirection::InOut, 1),
49                        // handle request data
50                        async gen move {
51                            yield Ok(request_body);
52                        },
53                        // socket send callback (single send per request)
54                        SendCallback::new_sync_once(move |block: DXBBlock| {
55                            let response = Response::from_data(block.to_bytes());
56                            request.respond(response)
57                                .map_err(|e| {
58                                    println!("HTTP response send error: {:#?}", e);
59                                    SendFailure(Box::new(block))
60                                })
61                                .map(|_| {
62                                    SendSuccess::Sent
63                                })
64                        })
65                    ));
66
67                }
68            }
69        ))
70    }
71}
72
73impl ComInterfaceAsyncFactory for HTTPServerInterfaceSetupDataNative {
74    fn create_interface(self) -> ComInterfaceAsyncFactoryResult {
75        Box::pin(self.create_interface())
76    }
77
78    fn get_default_properties() -> ComInterfaceProperties {
79        HTTPServerInterfaceSetupData::get_default_properties()
80    }
81}