Skip to main content

lafere_api/
server.rs

1use crate::error::{ApiError, RequestError};
2use crate::message::{Action, FromMessage, IntoMessage, Message};
3use crate::request::{EnableServerRequestsHandler, Request, RequestHandler};
4pub use crate::request_handlers::Data;
5use crate::request_handlers::{RequestHandlers, RequestHandlersBuilder};
6
7pub use lafere::packet::PlainBytes;
8use lafere::packet::{Packet, PacketBytes};
9pub use lafere::server::Config;
10use lafere::server::Connection;
11use lafere::util::{Listener, ListenerExt, SocketAddr};
12
13#[cfg(feature = "encrypted")]
14pub use lafere::packet::EncryptedBytes;
15
16use std::any::{Any, TypeId};
17use std::collections::HashMap;
18use std::io;
19use std::sync::{Arc, Mutex};
20
21#[cfg(feature = "encrypted")]
22use crypto::signature::Keypair;
23
24#[derive(Debug, Default)]
25#[non_exhaustive]
26pub struct ServerConfig {
27	pub log_errors: bool,
28}
29
30pub struct Server<A, B, L, More> {
31	inner: L,
32	requests: RequestHandlersBuilder<A, B>,
33	cfg: Config,
34	more: More,
35}
36
37impl<A, B, L, More> Server<A, B, L, More>
38where
39	A: Action,
40{
41	pub fn register_request<H>(&mut self, handler: H)
42	where
43		H: RequestHandler<B, Action = A> + Send + Sync + 'static,
44	{
45		self.requests.register_request(handler);
46	}
47
48	pub fn register_enable_server_requests<H>(&mut self, handler: H)
49	where
50		H: EnableServerRequestsHandler<B, Action = A> + Send + Sync + 'static,
51	{
52		self.requests.register_enable_server_requests(handler);
53	}
54
55	pub fn register_data<D>(&mut self, data: D)
56	where
57		D: Any + Send + Sync,
58	{
59		self.requests.register_data(data);
60	}
61}
62
63impl<A, B, L, More> Server<A, B, L, More>
64where
65	A: Action,
66	L: Listener,
67{
68	/// optionally or just use run
69	pub fn build(self) -> BuiltServer<A, B, L, More> {
70		BuiltServer {
71			inner: self.inner,
72			requests: self.requests.build(),
73			more: self.more,
74		}
75	}
76}
77
78impl<A, L> Server<A, PlainBytes, L, ()>
79where
80	A: Action,
81	L: Listener,
82{
83	pub fn new(listener: L, cfg: Config) -> Self {
84		Self {
85			inner: listener,
86			requests: RequestHandlersBuilder::new(),
87			cfg,
88			more: (),
89		}
90	}
91
92	pub async fn run(self) -> io::Result<()>
93	where
94		A: Send + Sync + 'static,
95	{
96		let cfg = self.cfg.clone();
97
98		self.build()
99			.run_raw(|_, stream| Connection::new(stream, cfg.clone()))
100			.await
101	}
102}
103
104#[cfg(feature = "encrypted")]
105#[cfg_attr(docsrs, doc(cfg(feature = "encrypted")))]
106impl<A, L> Server<A, EncryptedBytes, L, Keypair>
107where
108	A: Action,
109	L: Listener,
110{
111	pub fn new_encrypted(listener: L, cfg: Config, key: Keypair) -> Self {
112		Self {
113			inner: listener,
114			requests: RequestHandlersBuilder::new(),
115			cfg,
116			more: key,
117		}
118	}
119
120	pub async fn run(self) -> io::Result<()>
121	where
122		A: Send + Sync + 'static,
123	{
124		let cfg = self.cfg.clone();
125
126		self.build()
127			.run_raw(move |key, stream| {
128				Connection::new_encrypted(stream, cfg.clone(), key.clone())
129			})
130			.await
131	}
132}
133
134// impl
135
136pub struct BuiltServer<A, B, L, More> {
137	inner: L,
138	requests: RequestHandlers<A, B>,
139	more: More,
140}
141
142impl<A, B, L, More> BuiltServer<A, B, L, More>
143where
144	A: Action,
145	L: Listener,
146{
147	pub fn get_data<D>(&self) -> Option<&D>
148	where
149		D: Any,
150	{
151		self.requests.get_data::<D>()
152	}
153
154	pub async fn request<R>(
155		&self,
156		r: R,
157		session: &Arc<Session>,
158	) -> Result<R::Response, R::Error>
159	where
160		R: Request<Action = A>,
161		R: IntoMessage<A, B>,
162		R::Response: FromMessage<A, B>,
163		R::Error: FromMessage<A, B>,
164		B: PacketBytes,
165	{
166		let mut msg = r.into_message().map_err(R::Error::from_message_error)?;
167		msg.header_mut().set_action(R::ACTION);
168
169		// handle the request
170		let action = *msg.action().unwrap();
171
172		let handler = match self.requests.get_handler(&action) {
173			Some(handler) => handler,
174			// todo once we bump the version again
175			// we need to pass our own errors via packets
176			// not only those from the api users
177			None => {
178				tracing::error!("no handler for {:?}", action);
179				return Err(R::Error::from_request_error(
180					RequestError::NoResponse,
181				));
182			}
183		};
184
185		let r = handler.handle(msg, self.requests.data(), session).await;
186
187		let res = match r {
188			Ok(mut msg) => {
189				msg.header_mut().set_action(action);
190				msg
191			}
192			Err(e) => {
193				// todo once we bump the version again
194				// we need to pass our own errors via packets
195				// not only those from the api users
196				tracing::error!("handler returned an error {:?}", e);
197
198				return Err(R::Error::from_request_error(
199					RequestError::NoResponse,
200				));
201			}
202		};
203
204		// now deserialize the response
205		if res.is_success() {
206			R::Response::from_message(res).map_err(R::Error::from_message_error)
207		} else {
208			R::Error::from_message(res)
209				.map(Err)
210				.map_err(R::Error::from_message_error)?
211		}
212	}
213
214	async fn run_raw<F>(&mut self, new_connection: F) -> io::Result<()>
215	where
216		A: Action + Send + Sync + 'static,
217		B: PacketBytes + Send + 'static,
218		F: Fn(&More, L::Stream) -> Connection<Message<A, B>>,
219	{
220		loop {
221			// should we fail here??
222			let (stream, addr) = self.inner.accept().await?;
223
224			let mut con = new_connection(&self.more, stream);
225			let session = Arc::new(Session::new(addr));
226			session.set(con.configurator());
227
228			let requests = self.requests.clone();
229			tokio::spawn(async move {
230				requests
231					.handle_connection(
232						session,
233						con.clone_sender_unchecked(),
234						con.take_receiver().unwrap(),
235					)
236					.await;
237			});
238		}
239	}
240}
241
242pub struct Session {
243	// (SocketAddr, S)
244	addr: SocketAddr,
245	data: Mutex<HashMap<TypeId, Box<dyn Any + Send + Sync>>>,
246}
247
248impl Session {
249	pub fn new(addr: SocketAddr) -> Self {
250		Self {
251			addr,
252			data: Mutex::new(HashMap::new()),
253		}
254	}
255
256	pub fn addr(&self) -> &SocketAddr {
257		&self.addr
258	}
259
260	pub fn set<D>(&self, data: D)
261	where
262		D: Any + Send + Sync,
263	{
264		self.data
265			.lock()
266			.unwrap()
267			.insert(data.type_id(), Box::new(data));
268	}
269
270	pub fn get<D>(&self) -> Option<D>
271	where
272		D: Any + Clone + Send + Sync,
273	{
274		self.data
275			.lock()
276			.unwrap()
277			.get(&TypeId::of::<D>())
278			.and_then(|d| d.downcast_ref())
279			.map(Clone::clone)
280	}
281
282	pub fn take<D>(&self) -> Option<D>
283	where
284		D: Any + Send + Sync,
285	{
286		self.data
287			.lock()
288			.unwrap()
289			.remove(&TypeId::of::<D>())
290			.and_then(|d| d.downcast().ok())
291			.map(|b| *b)
292	}
293}
294
295#[cfg(all(test, feature = "json"))]
296mod json_tests {
297	use super::*;
298
299	use crate::error;
300	use crate::message;
301	use crate::request::Request;
302	use codegen::{FromMessage, IntoMessage, api};
303
304	use std::fmt;
305
306	use lafere::util::testing::PanicListener;
307
308	use serde::{Deserialize, Serialize};
309
310	#[derive(Debug, Serialize, Deserialize, IntoMessage, FromMessage)]
311	#[message(json)]
312	struct TestReq {
313		hello: u64,
314	}
315
316	#[derive(Debug, Serialize, Deserialize, IntoMessage, FromMessage)]
317	#[message(json)]
318	struct TestReq2 {
319		hello: u64,
320	}
321
322	#[derive(Debug, Serialize, Deserialize, IntoMessage, FromMessage)]
323	#[message(json)]
324	struct TestResp {
325		hi: u64,
326	}
327
328	#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
329	pub enum Action {
330		Empty,
331	}
332
333	#[derive(
334		Debug, Clone, Serialize, Deserialize, IntoMessage, FromMessage,
335	)]
336	#[message(json)]
337	pub enum Error {
338		RequestError(String),
339		MessageError(String),
340	}
341
342	impl fmt::Display for Error {
343		fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
344			fmt::Debug::fmt(self, fmt)
345		}
346	}
347
348	impl std::error::Error for Error {}
349
350	impl error::ApiError for Error {
351		fn from_request_error(e: error::RequestError) -> Self {
352			Self::RequestError(e.to_string())
353		}
354
355		fn from_message_error(e: error::MessageError) -> Self {
356			Self::MessageError(e.to_string())
357		}
358	}
359
360	impl message::Action for Action {
361		fn from_u16(_num: u16) -> Option<Self> {
362			todo!()
363		}
364		fn as_u16(&self) -> u16 {
365			todo!()
366		}
367	}
368
369	impl Request for TestReq {
370		type Action = Action;
371		type Response = TestResp;
372		type Error = Error;
373
374		const ACTION: Action = Action::Empty;
375	}
376
377	impl Request for TestReq2 {
378		type Action = Action;
379		type Response = TestResp;
380		type Error = Error;
381
382		const ACTION: Action = Action::Empty;
383	}
384
385	#[api(TestReq)]
386	async fn test(req: TestReq) -> Result<TestResp, Error> {
387		println!("req {:?}", req);
388		Ok(TestResp { hi: req.hello })
389	}
390
391	#[api(TestReq2)]
392	async fn test_2(req: TestReq2) -> Result<TestResp, Error> {
393		println!("req {:?}", req);
394		Ok(TestResp { hi: req.hello })
395	}
396
397	#[tokio::test]
398	async fn test_direct_request() {
399		let mut server = Server::new(
400			PanicListener::new(),
401			Config {
402				timeout: std::time::Duration::from_millis(10),
403				body_limit: 4096,
404			},
405		);
406
407		server.register_data(String::from("global String"));
408
409		server.register_request(test);
410		server.register_request(test_2);
411
412		let server = server.build();
413		let session = Arc::new(Session::new(SocketAddr::V4(
414			"127.0.0.1:8080".parse().unwrap(),
415		)));
416
417		let r = server
418			.request(TestReq { hello: 100 }, &session)
419			.await
420			.unwrap();
421		assert_eq!(r.hi, 100);
422
423		let r = server
424			.request(TestReq2 { hello: 100 }, &session)
425			.await
426			.unwrap();
427		assert_eq!(r.hi, 100);
428
429		assert_eq!(server.get_data::<String>().unwrap(), "global String");
430	}
431}
432
433#[cfg(all(test, feature = "protobuf"))]
434mod protobuf_tests {
435	use codegen::{FromMessage, IntoMessage};
436
437	use protopuffer::{DecodeMessage, EncodeMessage};
438
439	#[derive(
440		Debug, Default, EncodeMessage, DecodeMessage, IntoMessage, FromMessage,
441	)]
442	#[message(protobuf)]
443	#[allow(dead_code)]
444	struct TestReq {
445		#[field(1)]
446		hello: u64,
447	}
448
449	#[derive(
450		Debug, Default, EncodeMessage, DecodeMessage, IntoMessage, FromMessage,
451	)]
452	#[message(protobuf)]
453	#[allow(dead_code)]
454	struct TestReq2 {
455		#[field(1)]
456		hello: u64,
457	}
458}