Skip to main content

steamkit/steam/cdn/
server.rs

1//! A Steam content (Steampipe) server.
2
3use std::fmt;
4use std::net::SocketAddr;
5
6/// The protocol used to connect to a content server.
7#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
8pub enum ConnectionProtocol {
9    /// The server doesn't advertise HTTPS, so connect over HTTP.
10    #[default]
11    Http,
12    /// The server supports HTTPS.
13    Https,
14}
15
16/// A Steam content (Steampipe) server.
17#[derive(Clone, Debug, Default)]
18pub struct Server {
19    /// The protocol used to connect to this server.
20    pub(crate) protocol: ConnectionProtocol,
21    /// The hostname of the server.
22    pub(crate) host: Option<String>,
23    /// The virtual hostname of the server.
24    pub(crate) v_host: Option<String>,
25    /// The port of the server.
26    pub(crate) port: i32,
27    /// The type of the server (`type` is a keyword, hence the name).
28    pub(crate) server_type: Option<String>,
29    /// The SourceID this server belongs to.
30    pub(crate) source_id: i32,
31    /// The CellID this server belongs to.
32    pub(crate) cell_id: u32,
33    /// The load value associated with this server.
34    pub(crate) load: i32,
35    /// The weighted load.
36    pub(crate) weighted_load: f32,
37    /// The number of entries this server is worth.
38    pub(crate) num_entries: i32,
39    /// Whether this server is for Steam China only.
40    pub(crate) steam_china_only: bool,
41    /// Whether this server is a download proxy.
42    pub(crate) use_as_proxy: bool,
43    /// The transformation template applied to request paths.
44    pub(crate) proxy_request_path_template: Option<String>,
45    /// The list of app ids this server can be used with.
46    pub(crate) allowed_app_ids: Vec<u32>,
47    /// The list of bypass proxies.
48    pub(crate) bypass_proxies_of_type: Vec<String>,
49}
50
51impl Server {
52    /// Creates a server from a socket address. Port 443 means HTTPS, anything
53    /// else HTTP.
54    pub fn from_socket_addr(end_point: SocketAddr) -> Self {
55        let host = end_point.ip().to_string();
56
57        Server {
58            protocol: if end_point.port() == 443 {
59                ConnectionProtocol::Https
60            } else {
61                ConnectionProtocol::Http
62            },
63            host: Some(host.clone()),
64            v_host: Some(host),
65            port: i32::from(end_point.port()),
66            ..Server::default()
67        }
68    }
69
70    /// Creates a server from a host name and port. Port 443 means HTTPS,
71    /// anything else HTTP.
72    pub fn from_dns_end_point(host: &str, port: u16) -> Self {
73        Server {
74            protocol: if port == 443 {
75                ConnectionProtocol::Https
76            } else {
77                ConnectionProtocol::Http
78            },
79            host: Some(host.to_string()),
80            v_host: Some(host.to_string()),
81            port: i32::from(port),
82            ..Server::default()
83        }
84    }
85
86    /// The connection protocol the server supports.
87    pub fn protocol(&self) -> ConnectionProtocol {
88        self.protocol
89    }
90
91    /// The host name of the server.
92    pub fn host(&self) -> Option<&str> {
93        self.host.as_deref()
94    }
95
96    /// The virtual host name of the server.
97    pub fn v_host(&self) -> Option<&str> {
98        self.v_host.as_deref()
99    }
100
101    /// The port of the server.
102    pub fn port(&self) -> i32 {
103        self.port
104    }
105
106    /// The type of the server.
107    pub fn server_type(&self) -> Option<&str> {
108        self.server_type.as_deref()
109    }
110
111    /// The SourceID this server belongs to.
112    pub fn source_id(&self) -> i32 {
113        self.source_id
114    }
115
116    /// The CellID this server belongs to.
117    pub fn cell_id(&self) -> u32 {
118        self.cell_id
119    }
120
121    /// The load value of this server.
122    pub fn load(&self) -> i32 {
123        self.load
124    }
125
126    /// The weighted load.
127    pub fn weighted_load(&self) -> f32 {
128        self.weighted_load
129    }
130
131    /// The number of entries this server is worth.
132    pub fn num_entries(&self) -> i32 {
133        self.num_entries
134    }
135
136    /// Whether this server is for Steam China only.
137    pub fn steam_china_only(&self) -> bool {
138        self.steam_china_only
139    }
140
141    /// Whether this server is a download proxy.
142    pub fn use_as_proxy(&self) -> bool {
143        self.use_as_proxy
144    }
145
146    /// The template applied to request paths.
147    pub fn proxy_request_path_template(&self) -> Option<&str> {
148        self.proxy_request_path_template.as_deref()
149    }
150
151    /// The app ids this server can be used for.
152    pub fn allowed_app_ids(&self) -> &[u32] {
153        &self.allowed_app_ids
154    }
155
156    /// The list of bypass proxies.
157    pub fn bypass_proxies_of_type(&self) -> &[String] {
158        &self.bypass_proxies_of_type
159    }
160}
161
162impl From<SocketAddr> for Server {
163    /// Same as [`Server::from_socket_addr`].
164    fn from(end_point: SocketAddr) -> Self {
165        Server::from_socket_addr(end_point)
166    }
167}
168
169impl fmt::Display for Server {
170    /// Formats the server as `host:port (type)`.
171    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172        write!(
173            f,
174            "{}:{} ({})",
175            self.host.as_deref().unwrap_or_default(),
176            self.port,
177            self.server_type.as_deref().unwrap_or_default()
178        )
179    }
180}