hns_browser_loopback_proxy/chromium/
endpoint.rs1use crate::{ProxyAuthorization, ProxyInstanceId};
2use std::fmt;
3use std::net::{IpAddr, Ipv4Addr, SocketAddr};
4use std::sync::Arc;
5
6pub struct ProxyEndpoint {
7 instance: ProxyInstanceId,
8 address: SocketAddr,
9 authorization: Arc<ProxyAuthorization>,
10}
11
12impl ProxyEndpoint {
13 pub(crate) fn new(
14 instance: ProxyInstanceId,
15 address: SocketAddr,
16 authorization: Arc<ProxyAuthorization>,
17 ) -> Self {
18 Self {
19 instance,
20 address,
21 authorization,
22 }
23 }
24
25 pub fn instance(&self) -> &ProxyInstanceId {
26 &self.instance
27 }
28
29 pub fn address(&self) -> SocketAddr {
30 self.address
31 }
32
33 pub fn port(&self) -> u16 {
34 self.address.port()
35 }
36
37 pub fn realm(&self) -> &str {
38 self.authorization.realm()
39 }
40
41 pub fn username(&self) -> &str {
42 self.authorization.username()
43 }
44
45 pub fn password(&self) -> &str {
46 self.authorization.password()
47 }
48
49 pub fn authorization_header_value(&self) -> String {
50 self.authorization.authorization_header_value()
51 }
52
53 pub fn matches_challenge(&self, host: &str, port: u16, realm: &str) -> bool {
54 self.address.ip() == IpAddr::V4(Ipv4Addr::LOCALHOST)
55 && port == self.port()
56 && self.authorization.matches_challenge(host, realm)
57 }
58}
59
60impl fmt::Debug for ProxyEndpoint {
61 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
62 formatter
63 .debug_struct("ProxyEndpoint")
64 .field("instance", &self.instance)
65 .field("address", &self.address)
66 .field("realm", &"[REDACTED]")
67 .field("username", &"[REDACTED]")
68 .field("password", &"[REDACTED]")
69 .finish()
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76 use crate::ProxySessionId;
77
78 #[test]
79 fn endpoint_exposes_capability_only_through_explicit_accessors() {
80 let authorization = Arc::new(ProxyAuthorization::generate().unwrap());
81 let endpoint = ProxyEndpoint::new(
82 ProxyInstanceId::new(ProxySessionId::generate().unwrap(), 4),
83 "127.0.0.1:43123".parse().unwrap(),
84 Arc::clone(&authorization),
85 );
86 let debug = format!("{endpoint:?}");
87
88 assert!(!debug.contains(endpoint.realm()));
89 assert!(!debug.contains(endpoint.username()));
90 assert!(!debug.contains(endpoint.password()));
91 assert!(authorization.verify_header_value(&endpoint.authorization_header_value()));
92 assert!(endpoint.matches_challenge("127.0.0.1", 43123, endpoint.realm()));
93 assert!(!endpoint.matches_challenge("127.0.0.1", 43124, endpoint.realm()));
94 }
95}