tiny_http/
connection.rs
1#[cfg(unix)]
4use std::os::unix::net as unix_net;
5use std::{
6 net::{Shutdown, SocketAddr, TcpListener, TcpStream, ToSocketAddrs},
7 path::PathBuf,
8};
9
10pub enum Listener {
12 Tcp(TcpListener),
13 #[cfg(unix)]
14 Unix(unix_net::UnixListener),
15}
16impl Listener {
17 pub(crate) fn local_addr(&self) -> std::io::Result<ListenAddr> {
18 match self {
19 Self::Tcp(l) => l.local_addr().map(ListenAddr::from),
20 #[cfg(unix)]
21 Self::Unix(l) => l.local_addr().map(ListenAddr::from),
22 }
23 }
24
25 pub(crate) fn accept(&self) -> std::io::Result<(Connection, Option<SocketAddr>)> {
26 match self {
27 Self::Tcp(l) => l
28 .accept()
29 .map(|(conn, addr)| (Connection::from(conn), Some(addr))),
30 #[cfg(unix)]
31 Self::Unix(l) => l.accept().map(|(conn, _)| (Connection::from(conn), None)),
32 }
33 }
34}
35impl From<TcpListener> for Listener {
36 fn from(s: TcpListener) -> Self {
37 Self::Tcp(s)
38 }
39}
40#[cfg(unix)]
41impl From<unix_net::UnixListener> for Listener {
42 fn from(s: unix_net::UnixListener) -> Self {
43 Self::Unix(s)
44 }
45}
46
47#[derive(Debug)]
49pub(crate) enum Connection {
50 Tcp(TcpStream),
51 #[cfg(unix)]
52 Unix(unix_net::UnixStream),
53}
54impl std::io::Read for Connection {
55 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
56 match self {
57 Self::Tcp(s) => s.read(buf),
58 #[cfg(unix)]
59 Self::Unix(s) => s.read(buf),
60 }
61 }
62}
63impl std::io::Write for Connection {
64 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
65 match self {
66 Self::Tcp(s) => s.write(buf),
67 #[cfg(unix)]
68 Self::Unix(s) => s.write(buf),
69 }
70 }
71
72 fn flush(&mut self) -> std::io::Result<()> {
73 match self {
74 Self::Tcp(s) => s.flush(),
75 #[cfg(unix)]
76 Self::Unix(s) => s.flush(),
77 }
78 }
79}
80impl Connection {
81 pub(crate) fn peer_addr(&mut self) -> std::io::Result<Option<SocketAddr>> {
83 match self {
84 Self::Tcp(s) => s.peer_addr().map(Some),
85 #[cfg(unix)]
86 Self::Unix(_) => Ok(None),
87 }
88 }
89
90 pub(crate) fn shutdown(&self, how: Shutdown) -> std::io::Result<()> {
91 match self {
92 Self::Tcp(s) => s.shutdown(how),
93 #[cfg(unix)]
94 Self::Unix(s) => s.shutdown(how),
95 }
96 }
97
98 pub(crate) fn try_clone(&self) -> std::io::Result<Self> {
99 match self {
100 Self::Tcp(s) => s.try_clone().map(Self::from),
101 #[cfg(unix)]
102 Self::Unix(s) => s.try_clone().map(Self::from),
103 }
104 }
105}
106impl From<TcpStream> for Connection {
107 fn from(s: TcpStream) -> Self {
108 Self::Tcp(s)
109 }
110}
111#[cfg(unix)]
112impl From<unix_net::UnixStream> for Connection {
113 fn from(s: unix_net::UnixStream) -> Self {
114 Self::Unix(s)
115 }
116}
117
118#[derive(Debug, Clone)]
119pub enum ConfigListenAddr {
120 IP(Vec<SocketAddr>),
121 #[cfg(unix)]
122 Unix(std::path::PathBuf),
124}
125impl ConfigListenAddr {
126 pub fn from_socket_addrs<A: ToSocketAddrs>(addrs: A) -> std::io::Result<Self> {
127 addrs.to_socket_addrs().map(|it| Self::IP(it.collect()))
128 }
129
130 #[cfg(unix)]
131 pub fn unix_from_path<P: Into<PathBuf>>(path: P) -> Self {
132 Self::Unix(path.into())
133 }
134
135 pub(crate) fn bind(&self) -> std::io::Result<Listener> {
136 match self {
137 Self::IP(a) => TcpListener::bind(a.as_slice()).map(Listener::from),
138 #[cfg(unix)]
139 Self::Unix(a) => unix_net::UnixListener::bind(a).map(Listener::from),
140 }
141 }
142}
143
144#[derive(Debug, Clone)]
146pub enum ListenAddr {
147 IP(SocketAddr),
148 #[cfg(unix)]
149 Unix(unix_net::SocketAddr),
150}
151impl ListenAddr {
152 pub fn to_ip(self) -> Option<SocketAddr> {
153 match self {
154 Self::IP(s) => Some(s),
155 #[cfg(unix)]
156 Self::Unix(_) => None,
157 }
158 }
159
160 #[cfg(unix)]
164 pub fn to_unix(self) -> Option<unix_net::SocketAddr> {
165 match self {
166 Self::IP(_) => None,
167 Self::Unix(s) => Some(s),
168 }
169 }
170 #[cfg(not(unix))]
171 pub fn to_unix(self) -> Option<SocketAddr> {
172 None
173 }
174}
175impl From<SocketAddr> for ListenAddr {
176 fn from(s: SocketAddr) -> Self {
177 Self::IP(s)
178 }
179}
180#[cfg(unix)]
181impl From<unix_net::SocketAddr> for ListenAddr {
182 fn from(s: unix_net::SocketAddr) -> Self {
183 Self::Unix(s)
184 }
185}
186impl std::fmt::Display for ListenAddr {
187 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
188 match self {
189 Self::IP(s) => s.fmt(f),
190 #[cfg(unix)]
191 Self::Unix(s) => std::fmt::Debug::fmt(s, f),
192 }
193 }
194}