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