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}