Skip to content

Commit be87dcc

Browse files
authored
Merge pull request #41 from yeoleobun/patch0
fix: fix accept_with_public_contact
2 parents 1f24be2 + c59ab57 commit be87dcc

File tree

2 files changed

+98
-11
lines changed

2 files changed

+98
-11
lines changed

src/dialog/dialog.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -631,22 +631,17 @@ impl DialogInner {
631631
}
632632
}
633633

634+
self.local_contact
635+
.as_ref()
636+
.map(|c| resp_headers.push(Contact::from(c.clone()).into()));
637+
634638
if let Some(headers) = headers {
635639
for header in headers {
636640
resp_headers.unique_push(header);
637641
}
638642
}
639643

640-
resp_headers.retain(|h| {
641-
!matches!(
642-
h,
643-
Header::Contact(_) | Header::ContentLength(_) | Header::UserAgent(_)
644-
)
645-
});
646-
647-
self.local_contact
648-
.as_ref()
649-
.map(|c| resp_headers.push(Contact::from(c.clone()).into()));
644+
resp_headers.retain(|h| !matches!(h, Header::ContentLength(_) | Header::UserAgent(_)));
650645

651646
resp_headers.push(Header::ContentLength(
652647
body.as_ref().map_or(0u32, |b| b.len() as u32).into(),

src/dialog/tests/test_server_dialog.rs

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
use rsip::prelude::{HeadersExt, ToTypedHeader};
2+
use std::net::{IpAddr, Ipv4Addr};
3+
use std::sync::Arc;
24
use tokio::sync::mpsc::unbounded_channel;
35

46
use crate::{
57
dialog::{
68
dialog::DialogInner,
9+
server_dialog::ServerInviteDialog,
710
tests::test_dialog_states::{create_invite_request, create_test_endpoint},
811
DialogId,
912
},
10-
transaction::key::TransactionRole,
13+
transaction::{key::TransactionRole, transaction::TransactionEvent},
14+
transport::SipAddr,
1115
};
1216

1317
#[tokio::test]
@@ -67,3 +71,91 @@ async fn test_dialog_make_request() -> crate::Result<()> {
6771
);
6872
Ok(())
6973
}
74+
75+
#[tokio::test]
76+
async fn test_accept_with_public_contact_preserves_contact_header() -> crate::Result<()> {
77+
// Create dialog ID
78+
let dialog_id = DialogId {
79+
call_id: "test-call-id-contact".to_string(),
80+
from_tag: "alice-tag-456".to_string(),
81+
to_tag: "bob-tag-789".to_string(),
82+
};
83+
84+
let endpoint = create_test_endpoint().await?;
85+
let (tu_sender, mut tu_receiver) = unbounded_channel();
86+
let (state_sender, _state_receiver) = unbounded_channel();
87+
88+
// Create INVITE request
89+
let invite_req = create_invite_request("alice-tag-456", "", "test-call-id-contact");
90+
91+
// Create server dialog inner
92+
let dialog_inner = DialogInner::new(
93+
TransactionRole::Server,
94+
dialog_id.clone(),
95+
invite_req,
96+
endpoint.inner.clone(),
97+
state_sender,
98+
None,
99+
None,
100+
tu_sender,
101+
)
102+
.expect("Failed to create dialog inner");
103+
104+
let server_dialog = ServerInviteDialog {
105+
inner: Arc::new(dialog_inner),
106+
};
107+
108+
// Define the public address we want to use
109+
let public_address = Some(rsip::HostWithPort {
110+
host: IpAddr::V4(Ipv4Addr::new(203, 0, 113, 1)).into(),
111+
port: Some(5060.into()),
112+
});
113+
114+
// Define local address as fallback
115+
let local_address: SipAddr = rsip::HostWithPort::try_from("127.0.0.1:5060")?.into();
116+
117+
// Accept with public contact
118+
server_dialog.accept_with_public_contact(
119+
"bob",
120+
public_address.clone(),
121+
&local_address,
122+
None,
123+
None,
124+
)?;
125+
126+
// Receive the response from the transaction event channel
127+
let event = tu_receiver
128+
.recv()
129+
.await
130+
.expect("Should receive transaction event");
131+
132+
match event {
133+
TransactionEvent::Respond(response) => {
134+
// Verify status code is 200 OK
135+
assert_eq!(response.status_code, rsip::StatusCode::OK);
136+
137+
// Extract and verify Contact header
138+
let contact_header = response
139+
.contact_header()
140+
.expect("Response should have Contact header")
141+
.typed()
142+
.expect("Contact header should be parseable");
143+
144+
// Verify the Contact URI matches the public address we provided
145+
assert_eq!(
146+
contact_header.uri.host_with_port.host,
147+
public_address.as_ref().unwrap().host
148+
);
149+
assert_eq!(
150+
contact_header.uri.host_with_port.port,
151+
public_address.as_ref().unwrap().port
152+
);
153+
154+
// Verify the username in the Contact URI
155+
assert_eq!(contact_header.uri.auth.as_ref().unwrap().user, "bob");
156+
}
157+
_other => panic!("Expected TransactionEvent::Respond, got different event type"),
158+
}
159+
160+
Ok(())
161+
}

0 commit comments

Comments
 (0)