pub struct ServerAddress { /* private fields */ }Expand description
The address of a Lightstreamer server, parsed and checked at construction.
A Lightstreamer server is reached at a host and port, and this crate speaks to it over a WebSocket. Both spellings are accepted, because deployments publish their endpoint either way:
| You write | Meaning |
|---|---|
wss://push.example.com | WebSocket over TLS |
https://push.example.com | the same thing |
ws://localhost:8080 | WebSocket, no TLS |
http://localhost:8080 | the same thing |
wss://[::1]:8080 | an IPv6 literal, which must be bracketed |
§What an address may and may not contain
The address is a scheme, a host and an optional port, optionally followed by a base path. Everything else is refused here rather than somewhere further down, where the failure would be a connection error instead of a configuration one:
| Rejected | Why |
|---|---|
wss://user:secret@host | userinfo is a credential, and a credential in an address ends up in every log line that mentions the address |
wss://host?a=b, wss://host#f | TLCP defines no query or fragment on the endpoint; carrying one would silently change what is requested |
wss://host/a/../b | a .. segment makes the composed endpoint depend on path normalisation this crate does not perform |
wss://host:0, wss://host:99999 | not a port |
wss:// host | not a host |
§The endpoint path
The TLCP endpoint path is not part of the address: this crate appends
the /lightstreamer path the protocol fixes
[docs/spec/01-foundations.md §6.2.1]. An address that already ends in
/lightstreamer is accepted and not doubled. A base path is accepted too,
for a server published behind a reverse proxy, and the fixed path is
appended to it — https://example.com/push reaches
/push/lightstreamer.
§Canonical form
ServerAddress::as_str returns the address with the scheme lowercased
and any trailing / removed; the host is left in the caller’s own
spelling. Because userinfo is refused, the canonical form is also the
redacted form: it is safe to log.
§Examples
use lightstreamer_rs::ServerAddress;
let address = ServerAddress::try_new("https://push.lightstreamer.com")?;
assert!(address.is_secure());A missing scheme is rejected rather than guessed at, because guessing
https for an address the caller meant as plain http would silently
change the security properties of the connection:
use lightstreamer_rs::ServerAddress;
assert!(ServerAddress::try_new("push.lightstreamer.com").is_err());Implementations§
Source§impl ServerAddress
impl ServerAddress
Sourcepub fn try_new(address: impl Into<String>) -> Result<Self, ConfigError>
pub fn try_new(address: impl Into<String>) -> Result<Self, ConfigError>
Parses and checks a server address.
§Errors
ConfigError::EmptyServerAddressif the text is empty or only whitespace.ConfigError::MissingSchemeif there is no://.ConfigError::UnsupportedSchemeif the scheme is not one ofws,wss,httporhttps.ConfigError::MissingHostif nothing follows the scheme.ConfigError::AddressHasUserinfoif the authority carries auser:password@prefix.ConfigError::InvalidHostif the host is empty or contains whitespace, a control character, or an unbracketed:.ConfigError::InvalidPortif the port is not a number in1..=65535.ConfigError::InvalidAddressPathif a query, a fragment, a..segment, whitespace or a control character follows the authority.
§Examples
use lightstreamer_rs::{ConfigError, ServerAddress};
assert!(matches!(
ServerAddress::try_new("ftp://push.example.com"),
Err(ConfigError::UnsupportedScheme { .. })
));
// A credential in an address would reach every log line that mentions it.
assert!(matches!(
ServerAddress::try_new("wss://alice:hunter2@push.example.com"),
Err(ConfigError::AddressHasUserinfo)
));Trait Implementations§
Source§impl Clone for ServerAddress
impl Clone for ServerAddress
Source§fn clone(&self) -> ServerAddress
fn clone(&self) -> ServerAddress
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more