1use std::collections::HashMap;
2
3use crate::{errors::ProtocolError, locator::Locator, properties::Properties, protocol::EndPointType, proxy::Proxy, proxy_parser::{DirectProxyData, ProxyStringType, parse_proxy_string}, ssl::SslTransport, tcp::TcpTransport};
4
5pub struct ProxyFactory {
6 locator: Option<Locator>
7}
8
9impl ProxyFactory {
10 pub async fn create_proxy(proxy_data: DirectProxyData, properties: &Properties, context: Option<HashMap<String, String>>) -> Result<Proxy, Box<dyn std::error::Error + Sync + Send>> {
11 let mut proxy = match proxy_data.endpoint {
12 EndPointType::TCP(endpoint) => {
13 Proxy::new(
14 Box::new(TcpTransport::new(&format!("{}:{}", endpoint.host, endpoint.port)).await?),
15 &proxy_data.ident,
16 &endpoint.host,
17 endpoint.port,
18 context
19 )
20 }
21 EndPointType::SSL(endpoint) => {
22 Proxy::new(
23 Box::new(SslTransport::new(&format!("{}:{}", endpoint.host, endpoint.port), properties).await?),
24 &proxy_data.ident,
25 &endpoint.host,
26 endpoint.port,
27 context
28 )
29 }
30 _ => return Err(Box::new(ProtocolError::new(&format!("Error creating proxy"))))
31 };
32
33 proxy.await_validate_connection_message().await?;
34
35 Ok(proxy)
36 }
37
38 pub async fn new(properties: &Properties) -> Result<ProxyFactory, Box<dyn std::error::Error + Sync + Send>> {
39 Ok(ProxyFactory {
40 locator: match properties.get("Ice.Default.Locator") {
41 Some(locator_proxy) => {
42 match parse_proxy_string(locator_proxy) {
43 Ok(proxy_type) => {
44 match proxy_type {
45 ProxyStringType::DirectProxy(data) => {
46 Some(Locator::from(ProxyFactory::create_proxy(data, properties, None).await?))
47 }
48 _ => None
49 }
50 },
51 _ => None
52 }
53 },
54 _ => None
55 }
56 })
57 }
58
59 pub async fn create(&mut self, proxy_string: &str, properties: &Properties) -> Result<Proxy, Box<dyn std::error::Error + Sync + Send>> {
60 match parse_proxy_string(proxy_string)? {
61 ProxyStringType::DirectProxy(data) => {
62 ProxyFactory::create_proxy(data, properties, None).await
63 }
64 ProxyStringType::IndirectProxy(data) => {
65 match self.locator.as_mut() {
66 Some(locator) => {
67 let data = locator.locate(data).await?;
68 ProxyFactory::create_proxy(data, properties, None).await
69 }
70 _ => Err(Box::new(ProtocolError::new(&format!("No locator set up to resolve indirect proxy"))))
71 }
72 }
73 }
74 }
75}