Skip to main content

soup/
server.rs

1use crate::{Server, ServerMessage, WebsocketConnection, prelude::*};
2use glib::translate::*;
3use std::boxed::Box as Box_;
4use std::collections::HashMap;
5
6mod sealed {
7    pub trait Sealed {}
8    impl<T: super::IsA<crate::Server>> Sealed for T {}
9}
10
11pub trait ServerExtManual: IsA<Server> + sealed::Sealed + 'static {
12    #[doc(alias = "soup_server_add_early_handler")]
13    fn add_early_handler<P: Fn(&Server, &ServerMessage, &str, HashMap<&str, &str>) + 'static>(
14        &self,
15        path: Option<&str>,
16        callback: P,
17    ) {
18        let callback_data: Box_<P> = Box_::new(callback);
19        unsafe extern "C" fn callback_func<
20            P: Fn(&Server, &ServerMessage, &str, HashMap<&str, &str>) + 'static,
21        >(
22            server: *mut ffi::SoupServer,
23            msg: *mut ffi::SoupServerMessage,
24            path: *const libc::c_char,
25            query: *mut glib::ffi::GHashTable,
26            user_data: glib::ffi::gpointer,
27        ) {
28            unsafe {
29                let server = from_glib_borrow(server);
30                let msg: Borrowed<ServerMessage> = from_glib_borrow(msg);
31                let path: Borrowed<glib::GString> = from_glib_borrow(path);
32                let query_map = query_map_from_hash_table(query);
33                let callback: &P = &*(user_data as *mut _);
34                (*callback)(&server, &msg, path.as_str(), query_map);
35            }
36        }
37        let callback = Some(callback_func::<P> as _);
38        unsafe extern "C" fn destroy_func<
39            P: Fn(&Server, &ServerMessage, &str, HashMap<&str, &str>) + 'static,
40        >(
41            data: glib::ffi::gpointer,
42        ) {
43            unsafe {
44                let _callback: Box_<P> = Box_::from_raw(data as *mut _);
45            }
46        }
47        let destroy_call6 = Some(destroy_func::<P> as _);
48        let super_callback0: Box_<P> = callback_data;
49        unsafe {
50            ffi::soup_server_add_early_handler(
51                self.as_ref().to_glib_none().0,
52                path.to_glib_none().0,
53                callback,
54                Box_::into_raw(super_callback0) as *mut _,
55                destroy_call6,
56            );
57        }
58    }
59
60    #[doc(alias = "soup_server_add_handler")]
61    fn add_handler<P: Fn(&Server, &ServerMessage, &str, HashMap<&str, &str>) + 'static>(
62        &self,
63        path: Option<&str>,
64        callback: P,
65    ) {
66        let callback_data: Box_<P> = Box_::new(callback);
67        unsafe extern "C" fn callback_func<
68            P: Fn(&Server, &ServerMessage, &str, HashMap<&str, &str>) + 'static,
69        >(
70            server: *mut ffi::SoupServer,
71            msg: *mut ffi::SoupServerMessage,
72            path: *const libc::c_char,
73            query: *mut glib::ffi::GHashTable,
74            user_data: glib::ffi::gpointer,
75        ) {
76            unsafe {
77                let server = from_glib_borrow(server);
78                let msg: Borrowed<ServerMessage> = from_glib_borrow(msg);
79                let path: Borrowed<glib::GString> = from_glib_borrow(path);
80                let query_map = query_map_from_hash_table(query);
81                let callback: &P = &*(user_data as *mut _);
82                (*callback)(&server, &msg, path.as_str(), query_map);
83            }
84        }
85        let callback = Some(callback_func::<P> as _);
86        unsafe extern "C" fn destroy_func<
87            P: Fn(&Server, &ServerMessage, &str, HashMap<&str, &str>) + 'static,
88        >(
89            data: glib::ffi::gpointer,
90        ) {
91            unsafe {
92                let _callback: Box_<P> = Box_::from_raw(data as *mut _);
93            }
94        }
95        let destroy_call6 = Some(destroy_func::<P> as _);
96        let super_callback0: Box_<P> = callback_data;
97        unsafe {
98            ffi::soup_server_add_handler(
99                self.as_ref().to_glib_none().0,
100                path.to_glib_none().0,
101                callback,
102                Box_::into_raw(super_callback0) as *mut _,
103                destroy_call6,
104            );
105        }
106    }
107
108    #[doc(alias = "soup_server_add_websocket_handler")]
109    fn add_websocket_handler<
110        P: Fn(&Server, &ServerMessage, &str, &WebsocketConnection) + 'static,
111    >(
112        &self,
113        path: Option<&str>,
114        origin: Option<&str>,
115        protocols: &[&str],
116        callback: P,
117    ) {
118        let callback_data: Box_<P> = Box_::new(callback);
119        unsafe extern "C" fn callback_func<
120            P: Fn(&Server, &ServerMessage, &str, &WebsocketConnection) + 'static,
121        >(
122            server: *mut ffi::SoupServer,
123            msg: *mut ffi::SoupServerMessage,
124            path: *const libc::c_char,
125            connection: *mut ffi::SoupWebsocketConnection,
126            user_data: glib::ffi::gpointer,
127        ) {
128            unsafe {
129                let server = from_glib_borrow(server);
130                let msg: Borrowed<ServerMessage> = from_glib_borrow(msg);
131                let path: Borrowed<glib::GString> = from_glib_borrow(path);
132                let connection = from_glib_borrow(connection);
133                let callback: &P = &*(user_data as *mut _);
134                (*callback)(&server, &msg, path.as_str(), &connection);
135            }
136        }
137        let callback = Some(callback_func::<P> as _);
138        unsafe extern "C" fn destroy_func<
139            P: Fn(&Server, &ServerMessage, &str, &WebsocketConnection) + 'static,
140        >(
141            data: glib::ffi::gpointer,
142        ) {
143            unsafe {
144                let _callback: Box_<P> = Box_::from_raw(data as *mut _);
145            }
146        }
147        let destroy_call6 = Some(destroy_func::<P> as _);
148        let super_callback0: Box_<P> = callback_data;
149        unsafe {
150            ffi::soup_server_add_websocket_handler(
151                self.as_ref().to_glib_none().0,
152                path.to_glib_none().0,
153                origin.to_glib_none().0,
154                protocols.to_glib_none().0,
155                callback,
156                Box_::into_raw(super_callback0) as *mut _,
157                destroy_call6,
158            );
159        }
160    }
161}
162
163impl<O: IsA<Server>> ServerExtManual for O {}
164
165unsafe fn query_map_from_hash_table<'a>(
166    query: *mut glib::ffi::GHashTable,
167) -> HashMap<&'a str, &'a str> {
168    if query.is_null() {
169        return HashMap::new();
170    }
171    unsafe extern "C" fn read_query_hash_table(
172        key: glib::ffi::gpointer,
173        value: glib::ffi::gpointer,
174        hash_map: glib::ffi::gpointer,
175    ) {
176        unsafe {
177            let key = glib::GStr::from_ptr_checked(key as *const libc::c_char);
178            let value = glib::GStr::from_ptr_checked(value as *const libc::c_char);
179            let hash_map: &mut HashMap<&str, &str> = &mut *(hash_map as *mut HashMap<&str, &str>);
180            if let (Some(k), Some(v)) = (key, value) {
181                hash_map.insert(k.as_str(), v.as_str());
182            }
183        }
184    }
185    unsafe {
186        let mut query_map = HashMap::with_capacity(glib::ffi::g_hash_table_size(query) as usize);
187        glib::ffi::g_hash_table_foreach(
188            query,
189            Some(read_query_hash_table),
190            &mut query_map as *mut HashMap<&str, &str> as *mut _,
191        );
192        query_map
193    }
194}