Skip to main content

rtc_stun/
uri.rs

1#[cfg(test)]
2mod uri_test;
3
4use shared::error::*;
5
6use std::fmt;
7
8// SCHEME definitions from RFC 7064 Section 3.2.
9
10/// The `stun:` URI scheme.
11pub const SCHEME: &str = "stun";
12/// The `stuns:` URI scheme, for STUN over TLS or DTLS.
13pub const SCHEME_SECURE: &str = "stuns";
14
15// URI as defined in RFC 7064.
16#[derive(PartialEq, Eq, Debug)]
17/// A parsed `stun:` or `stuns:` URI.
18pub struct Uri {
19    /// The scheme, `stun` or `stuns`.
20    pub scheme: String,
21    /// The server host name or address.
22    pub host: String,
23    /// The port, if the URI specified one.
24    pub port: Option<u16>,
25}
26
27impl fmt::Display for Uri {
28    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29        let host = if self.host.contains("::") {
30            format!("[{}]", self.host)
31        } else {
32            self.host.clone()
33        };
34
35        if let Some(port) = self.port {
36            write!(f, "{}:{}:{}", self.scheme, host, port)
37        } else {
38            write!(f, "{}:{}", self.scheme, host)
39        }
40    }
41}
42
43impl Uri {
44    /// Parse_uri parses URI from string.
45    pub fn parse_uri(raw: &str) -> Result<Self> {
46        // work around for url crate
47        if raw.contains("//") {
48            return Err(Error::ErrInvalidUrl);
49        }
50
51        let mut s = raw.to_string();
52        let pos = raw.find(':');
53        let p = pos.ok_or(Error::ErrSchemeType)?;
54        s.replace_range(p..p + 1, "://");
55
56        let raw_parts = url::Url::parse(&s)?;
57
58        let scheme = raw_parts.scheme().into();
59        if scheme != SCHEME && scheme != SCHEME_SECURE {
60            return Err(Error::ErrSchemeType);
61        }
62
63        let host = raw_parts
64            .host_str()
65            .ok_or(Error::ErrHost)?
66            .trim()
67            .trim_start_matches('[')
68            .trim_end_matches(']')
69            .to_owned();
70
71        let port = raw_parts.port();
72
73        Ok(Uri { scheme, host, port })
74    }
75}