rtc/peer_connection/transport/ice/
server.rs1use serde::{Deserialize, Serialize};
2
3use shared::error::{Error, Result};
4
5#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Hash)]
14pub struct RTCIceServer {
15 pub urls: Vec<String>,
16 pub username: String,
17 pub credential: String,
18}
19
20impl RTCIceServer {
21 pub(crate) fn parse_url(&self, url_str: &str) -> Result<ice::url::Url> {
22 ice::url::Url::parse_url(url_str)
23 }
24
25 pub(crate) fn validate(&self) -> Result<()> {
26 self.urls()?;
27 Ok(())
28 }
29
30 pub(crate) fn urls(&self) -> Result<Vec<ice::url::Url>> {
31 let mut urls = vec![];
32
33 for url_str in &self.urls {
34 let mut url = self.parse_url(url_str)?;
35 if url.scheme == ice::url::SchemeType::Turn || url.scheme == ice::url::SchemeType::Turns
36 {
37 if self.username.is_empty() || self.credential.is_empty() {
39 return Err(Error::ErrNoTurnCredentials);
40 }
41
42 url.username.clone_from(&self.username);
43 url.password.clone_from(&self.credential);
44 }
45
46 urls.push(url);
47 }
48
49 Ok(urls)
50 }
51}
52
53#[cfg(test)]
54mod test {
55 use super::*;
56
57 #[test]
58 fn test_ice_server_validate_success() {
59 let tests = vec![
60 (
61 RTCIceServer {
62 urls: vec!["turn:192.158.29.39?transport=udp".to_owned()],
63 username: "unittest".to_owned(),
64 credential: "placeholder".to_owned(),
65 },
66 true,
67 ),
68 (
69 RTCIceServer {
70 urls: vec!["turn:[2001:db8:1234:5678::1]?transport=udp".to_owned()],
71 username: "unittest".to_owned(),
72 credential: "placeholder".to_owned(),
73 },
74 true,
75 ),
76 ];
86
87 for (ice_server, expected_validate) in tests {
88 let result = ice_server.urls();
89 assert_eq!(result.is_ok(), expected_validate);
90 }
91 }
92
93 #[test]
94 fn test_ice_server_validate_failure() {
95 let tests = vec![
96 (
97 RTCIceServer {
98 urls: vec!["turn:192.158.29.39?transport=udp".to_owned()],
99 ..Default::default()
100 },
101 Error::ErrNoTurnCredentials,
102 ),
103 (
104 RTCIceServer {
105 urls: vec!["turn:192.158.29.39?transport=udp".to_owned()],
106 username: "unittest".to_owned(),
107 credential: String::new(),
108 },
109 Error::ErrNoTurnCredentials,
110 ),
111 (
112 RTCIceServer {
113 urls: vec!["turn:192.158.29.39?transport=udp".to_owned()],
114 username: "unittest".to_owned(),
115 credential: String::new(),
116 },
117 Error::ErrNoTurnCredentials,
118 ),
119 (
120 RTCIceServer {
121 urls: vec!["turn:192.158.29.39?transport=udp".to_owned()],
122 username: "unittest".to_owned(),
123 credential: String::new(),
124 },
125 Error::ErrNoTurnCredentials,
126 ),
127 ];
128
129 for (ice_server, expected_err) in tests {
130 if let Err(err) = ice_server.urls() {
131 assert_eq!(err, expected_err, "{ice_server:?} with err {err:?}");
132 } else {
133 panic!("expected error, but got ok");
134 }
135 }
136 }
137
138 #[test]
139 fn test_ice_server_validate_failure_err_stun_query() {
140 let tests = vec![(
141 RTCIceServer {
142 urls: vec!["stun:google.de?transport=udp".to_owned()],
143 username: "unittest".to_owned(),
144 credential: String::new(),
145 },
146 Error::ErrStunQuery,
147 )];
148
149 for (ice_server, expected_err) in tests {
150 if let Err(err) = ice_server.urls() {
151 assert_eq!(err, expected_err, "{ice_server:?} with err {err:?}");
152 } else {
153 panic!("expected error, but got ok");
154 }
155 }
156 }
157}