dbus_bytestream/
address.rs1use std::io;
2use std::net::{SocketAddr, ToSocketAddrs};
3use std::path::{Path, PathBuf};
4use std::string;
5use std::str::FromStr;
6use std::str::Split;
7use std::vec;
8
9use rustc_serialize::hex::{FromHex,FromHexError};
10
11#[derive(Debug, PartialEq)]
12pub enum UnescapeError {
13 ShortEscapeSequence,
14 EscapeNotUtf8,
15 HexConversionError
16}
17
18impl From<FromHexError> for UnescapeError {
19 fn from(_: FromHexError) -> Self {
20 UnescapeError::HexConversionError
21 }
22}
23
24impl From<string::FromUtf8Error> for UnescapeError {
25 fn from(_: string::FromUtf8Error) -> Self {
26 UnescapeError::EscapeNotUtf8
27 }
28}
29
30fn dbus_unescape(buf: &[u8]) -> Result<Vec<u8>, UnescapeError> {
31 let mut out = Vec::with_capacity(buf.len());
32 let mut i = buf.iter();
33 while let Some(c) = i.next() {
34 if *c == b'%' {
35 let c1 = *try!(i.next().ok_or(UnescapeError::ShortEscapeSequence));
36 let c2 = *try!(i.next().ok_or(UnescapeError::ShortEscapeSequence));
37 let x = try!(String::from_utf8(vec!(c1, c2)));
38 out.push(*try!(x.from_hex()).get(0).unwrap());
39 } else {
40 out.push(*c);
41 }
42 }
43 Ok(out)
44}
45
46fn dbus_unescape_str(s: &str) -> Result<String, UnescapeError> {
47 let vec = try!(dbus_unescape(s.as_bytes()));
48 String::from_utf8(vec).map_err(From::from)
49}
50
51#[derive(Debug, PartialEq)]
52pub enum Error {
53 UnescapeError(UnescapeError),
54 BadTransportSeparator,
55 MalformedKeyValue,
56 UnknownTransport,
57 UnknownOption,
58 MissingOption,
59 ConflictingOptions,
60}
61
62pub type ServerAddressError = (Error, String);
63
64impl From<UnescapeError> for ServerAddressError {
65 fn from(e: UnescapeError) -> Self {
66 (Error::UnescapeError(e), "".to_owned())
67 }
68}
69
70
71struct AddrKeyVals<'a> {
73 str: Split<'a, char>,
74}
75
76impl<'a> AddrKeyVals<'a> {
77 fn new(s: &'a str) -> Self {
78 AddrKeyVals { str: s.split(',') }
79 }
80
81 fn get_next(&mut self) -> Option<&'a str> {
82 loop {
83 let kvs = self.str.next();
84 if kvs.is_none() || kvs.unwrap() != "" {
85 return kvs;
86 }
87 }
88 }
89}
90
91impl<'a> Iterator for AddrKeyVals<'a> {
92 type Item = Result<(String, String), ServerAddressError>;
93
94 fn next(&mut self) -> Option<Self::Item> {
95 let kvs = self.get_next();
96 if kvs.is_none() {
97 return None;
98 }
99 let mut keyval = kvs.unwrap().split('=');
100 if keyval.clone().count() != 2 {
101 return Some(Err((Error::MalformedKeyValue, kvs.unwrap().to_owned())));
102 }
103
104 let key = dbus_unescape_str(keyval.next().unwrap());
105 if let Err(e) = key {
106 return Some(Err(From::from(e)));
107 }
108 let val = dbus_unescape_str(keyval.next().unwrap());
109 if let Err(e) = val {
110 return Some(Err(From::from(e)));
111 }
112 Some(Ok((key.unwrap(), val.unwrap())))
114 }
115}
116
117#[derive(Debug)]
119pub struct UnixAddress {
120 path: PathBuf,
121}
122
123impl<'a> UnixAddress {
124 pub fn path(&'a self) -> &'a Path {
126 self.path.as_path()
127 }
128}
129
130impl FromStr for UnixAddress {
131 type Err = ServerAddressError;
132
133 fn from_str(opts: &str) -> Result<Self, ServerAddressError> {
135 let keyvals = AddrKeyVals::new(opts);
136 let mut path = None;
137 let mut abs = false;
138 for kv in keyvals {
139 let kv = try!(kv);
140
141 match kv.0.as_ref() {
142 "path" | "abstract" => {
143 if path.is_none() {
144 path = Some(kv.1);
145 } else {
146 return Err((Error::ConflictingOptions,
147 "Duplicate path/abstract specified".to_owned()));
148 }
149 },
150 "guid" => {}, _ => return Err((Error::UnknownOption, kv.0))
152 }
153 if kv.0 == "abstract" {
154 abs = true;
155 }
156 }
157 if path == None {
158 Err((Error::MissingOption, "No path for unix socket".to_owned()))
159 } else {
160 let mut path = path.unwrap();
161 if abs {
162 path = "\0".to_owned() + &path;
163 }
164 Ok(UnixAddress { path: PathBuf::from(path) })
165 }
166 }
167}
168
169#[derive(Debug)]
171pub struct TcpAddress {
172 host: String,
173 port: String,
174}
175
176impl ToSocketAddrs for TcpAddress {
177 type Iter = vec::IntoIter<SocketAddr>;
178 fn to_socket_addrs(&self) -> io::Result<Self::Iter> {
180 (self.host.clone() + ":" + &self.port).to_socket_addrs()
181 }
182}
183
184impl FromStr for TcpAddress {
185 type Err = ServerAddressError;
186
187 fn from_str(opts: &str) -> Result<Self, ServerAddressError> {
189 let mut host = None;
190 let mut port = None;
191 for kv in AddrKeyVals::new(opts) {
192 let kv = try!(kv);
193
194 match kv.0.as_ref() {
195 "host" => {
196 if host.is_none() {
197 host = Some(kv.1);
198 } else {
199 return Err((Error::ConflictingOptions,
200 "Duplicate host specified".to_owned()));
201 }
202 },
203 "port" => {
204 if port.is_none() {
205 port = Some(kv.1);
206 } else {
207 return Err((Error::ConflictingOptions,
208 "Duplicate port specified".to_owned()));
209 }
210 },
211 "guid" => {}, _ => return Err((Error::UnknownOption, kv.0))
213 }
214 }
215 if host == None {
216 Err((Error::MissingOption, "No host for tcp socket".to_owned()))
217 } else if port == None {
218 Err((Error::MissingOption, "No port for tcp socket".to_owned()))
219 } else {
220 Ok(TcpAddress { host: host.unwrap(), port: port.unwrap() })
221 }
222 }
223}
224
225#[derive(Debug)]
226pub enum ServerAddress {
227 Unix(UnixAddress),
228 Tcp(TcpAddress),
229}
230
231impl FromStr for ServerAddress {
232 type Err = ServerAddressError;
233
234 fn from_str(s: &str) -> Result<Self, Self::Err> {
235 let mut sp = s.split(':');
236 if sp.clone().count() != 2 {
237 return Err((Error::BadTransportSeparator, s.to_owned()));
238 }
239 let transport = sp.next().unwrap();
241 let opts = sp.next().unwrap();
242
243 match transport {
244 "unix" => Ok(ServerAddress::Unix(try!(UnixAddress::from_str(opts)))),
245 "tcp" => Ok(ServerAddress::Tcp(try!(TcpAddress::from_str(opts)))),
246 _ => Err((Error::UnknownTransport, transport.to_owned())),
247 }
248 }
249}
250
251#[test]
252fn test_unescape() {
253 assert_eq!(dbus_unescape(b"hello").unwrap(), b"hello");
254 assert_eq!(dbus_unescape(b"\\").unwrap(), b"\\");
255 assert_eq!(dbus_unescape(b"%61").unwrap(), b"a");
256 assert_eq!(dbus_unescape(b"%5c").unwrap(), b"\\");
257 assert_eq!(dbus_unescape(b"%").unwrap_err(), UnescapeError::ShortEscapeSequence);
258 assert_eq!(dbus_unescape(b"%1").unwrap_err(), UnescapeError::ShortEscapeSequence);
259}
260
261#[test]
262fn test_key_vals() {
263 let mut a = AddrKeyVals::new("one=two").map(Result::unwrap);
264 assert_eq!(a.next().unwrap(), ("one".to_string(), "two".to_string()));
265 assert_eq!(a.next(), None);
266
267 let mut a = AddrKeyVals::new("foo=bar,").map(Result::unwrap);
268 assert_eq!(a.next().unwrap(), ("foo".to_string(), "bar".to_string()));
269 assert_eq!(a.next(), None);
270
271 let mut a = AddrKeyVals::new("foo=bar,a=b").map(Result::unwrap);
272 assert_eq!(a.next().unwrap(), ("foo".to_string(), "bar".to_string()));
273 assert_eq!(a.next().unwrap(), ("a".to_string(), "b".to_string()));
274 assert_eq!(a.next(), None);
275
276 let mut a = AddrKeyVals::new("foobar,a=b");
277 assert_eq!(a.next().unwrap().unwrap_err().0, Error::MalformedKeyValue);
278}
279
280#[test]
281fn test_server_address() {
282 assert_eq!(ServerAddress::from_str("unix").unwrap_err().0, Error::BadTransportSeparator);
283 ServerAddress::from_str("unix:path=/var/run/dbus/system_bus_socket").unwrap();
284 assert_eq!(ServerAddress::from_str("unix:path=/var/run/dbus/system_bus_socket,foo=bar").unwrap_err().0, Error::UnknownOption);
285 assert_eq!(ServerAddress::from_str("unix:").unwrap_err().0, Error::MissingOption);
286}