|
1 | | -use crate::rsip_ext::RsipResponseExt; |
| 1 | +use crate::rsip_ext::{destination_from_request, RsipResponseExt}; |
2 | 2 | use crate::transaction::key::{TransactionKey, TransactionRole}; |
3 | 3 | use crate::transaction::transaction::Transaction; |
4 | 4 | use crate::transport::udp::UdpConnection; |
@@ -167,6 +167,54 @@ Content-Length: 0\r\n\r\n"; |
167 | 167 | Ok(()) |
168 | 168 | } |
169 | 169 |
|
| 170 | +#[tokio::test] |
| 171 | +async fn test_make_ack_accepts_comma_separated_record_route() -> Result<()> { |
| 172 | + let endpoint = super::create_test_endpoint(None).await?; |
| 173 | + |
| 174 | + let raw_response = "SIP/2.0 200 OK\r\n\ |
| 175 | +Via: SIP/2.0/UDP uac.example.com:5060;branch=z9hG4bK1\r\n\ |
| 176 | +Record-Route: <sip:3.4.5.6:24364;r2=on;lr;ftag=Xq5kaQn5;did=9e8.3362>,<sip:3.4.5.6:21827;r2=on;lr;ftag=Xq5kaQn5;did=9e8.3362>,<sip:1.2.40.7:21827;lr;ftag=Xq5kaQn5;did=9e8.ab21>\r\n\ |
| 177 | +From: <sip:alice@example.com>;tag=from-tag\r\n\ |
| 178 | +To: <sip:bob@example.com>;tag=to-tag\r\n\ |
| 179 | +Call-ID: callid@example.com\r\n\ |
| 180 | +CSeq: 1 INVITE\r\n\ |
| 181 | +Contact: <sip:uas@192.0.2.55:5080;transport=udp>\r\n\ |
| 182 | +Content-Length: 0\r\n\r\n"; |
| 183 | + |
| 184 | + let response = Response::try_from(raw_response)?; |
| 185 | + let request_uri = response.remote_uri(None)?; |
| 186 | + let ack = endpoint.inner.make_ack(&response, request_uri)?; |
| 187 | + |
| 188 | + let routes: Vec<String> = ack |
| 189 | + .headers |
| 190 | + .iter() |
| 191 | + .filter_map(|header| match header { |
| 192 | + Header::Route(route) => Some(route.value().to_string()), |
| 193 | + _ => None, |
| 194 | + }) |
| 195 | + .collect(); |
| 196 | + |
| 197 | + assert_eq!( |
| 198 | + routes, |
| 199 | + vec![ |
| 200 | + "<sip:1.2.40.7:21827;lr;ftag=Xq5kaQn5;did=9e8.ab21>".to_string(), |
| 201 | + "<sip:3.4.5.6:21827;r2=on;lr;ftag=Xq5kaQn5;did=9e8.3362>".to_string(), |
| 202 | + "<sip:3.4.5.6:24364;r2=on;lr;ftag=Xq5kaQn5;did=9e8.3362>".to_string(), |
| 203 | + ], |
| 204 | + "ACK Route headers must follow the reversed Record-Route order" |
| 205 | + ); |
| 206 | + |
| 207 | + let destination = |
| 208 | + destination_from_request(&ack).expect("route-enabled ACK should resolve to a destination"); |
| 209 | + let expected_destination = Uri::try_from("sip:1.2.40.7:21827;lr;ftag=Xq5kaQn5;did=9e8.ab21")?; |
| 210 | + assert_eq!( |
| 211 | + &*destination, &expected_destination, |
| 212 | + "First Route entry must determine the transport destination", |
| 213 | + ); |
| 214 | + |
| 215 | + Ok(()) |
| 216 | +} |
| 217 | + |
170 | 218 | #[tokio::test] |
171 | 219 | async fn test_make_ack_uses_contact_with_ob() -> Result<()> { |
172 | 220 | let endpoint = super::create_test_endpoint(None).await?; |
|
0 commit comments