rocket/listener/
tcp.rs
1use std::io;
13use std::net::{Ipv4Addr, SocketAddr};
14
15use either::{Either, Left, Right};
16
17#[doc(inline)]
18pub use tokio::net::{TcpListener, TcpStream};
19
20use crate::{Ignite, Rocket};
21use crate::listener::{Bind, Connection, Endpoint, Listener};
22
23impl Bind for TcpListener {
24 type Error = Either<figment::Error, io::Error>;
25
26 async fn bind(rocket: &Rocket<Ignite>) -> Result<Self, Self::Error> {
27 let endpoint = Self::bind_endpoint(rocket)?;
28 let addr = endpoint.tcp()
29 .ok_or_else(|| io::Error::other("internal error: invalid endpoint"))
30 .map_err(Right)?;
31
32 Self::bind(addr).await.map_err(Right)
33 }
34
35 fn bind_endpoint(rocket: &Rocket<Ignite>) -> Result<Endpoint, Self::Error> {
36 let figment = rocket.figment();
37 let mut address = Endpoint::fetch(figment, "tcp", "address", |e| {
38 let default = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), 8000);
39 e.map(|e| e.tcp()).unwrap_or(Some(default))
40 }).map_err(Left)?;
41
42 if figment.contains("port") {
43 let port = figment.extract_inner("port").map_err(Left)?;
44 address.set_port(port);
45 }
46
47 Ok(Endpoint::Tcp(address))
48 }
49}
50
51impl Listener for TcpListener {
52 type Accept = Self::Connection;
53
54 type Connection = TcpStream;
55
56 async fn accept(&self) -> io::Result<Self::Accept> {
57 let conn = self.accept().await?.0;
58 let _ = conn.set_nodelay(true);
59 let _ = conn.set_linger(None);
60 Ok(conn)
61 }
62
63 async fn connect(&self, conn: Self::Connection) -> io::Result<Self::Connection> {
64 Ok(conn)
65 }
66
67 fn endpoint(&self) -> io::Result<Endpoint> {
68 self.local_addr().map(Endpoint::Tcp)
69 }
70}
71
72impl Connection for TcpStream {
73 fn endpoint(&self) -> io::Result<Endpoint> {
74 self.peer_addr().map(Endpoint::Tcp)
75 }
76}