// Connection configuration and TLS policy for the PostgreSQL client package.
///|
/// Controls how the client negotiates TLS when opening a TCP connection.
///
/// The modes are intentionally strict:
/// plaintext is opt-in via `Disable`, while TLS-using callers choose between
/// certificate-chain verification with or without endpoint identity checks.
pub(all) enum SslMode {
/// Explicit plaintext mode.
///
/// The client skips PostgreSQL SSL negotiation, does not encrypt traffic,
/// and does not verify the server's identity.
Disable
/// Require TLS and verify the server certificate chain.
///
/// This mode never falls back to plaintext. It validates the certificate
/// chain against the configured trust roots, **but it does not verify that the
/// certificate matches the requested hostname or IP address!**
///
/// Its security can approach `VerifyFull` only when a private CA issues
/// certificates exclusively for the intended PostgreSQL endpoints.
VerifyCa
/// Require TLS, verify the certificate chain, and verify endpoint identity.
///
/// This mode never falls back to plaintext. It validates both the server
/// certificate chain and the requested hostname or IP address, and is the
/// default and recommended mode.
VerifyFull
} derive(Debug, Eq)
///|
/// Controls whether SCRAM channel binding is disabled, preferred, or required.
///
/// This setting controls whether the connection must complete SCRAM channel
/// binding. It does not enable TLS by itself.
/// It is also unrelated to TLS `sslmode`: this package still does not support
/// the removed libpq-style TLS aliases `sslmode=prefer` or `sslmode=require`.
///
/// `Disable` always uses plain `SCRAM-SHA-256`.
/// `Prefer` uses `SCRAM-SHA-256-PLUS` when the TLS transport exposes a
/// supported binding and the server advertises it, otherwise it falls back to
/// plain `SCRAM-SHA-256`.
/// `Require` insists on `SCRAM-SHA-256-PLUS` and fails when TLS or server
/// support is missing. Because non-SCRAM authentication methods cannot employ
/// PostgreSQL channel binding, `Require` rejects them before sending
/// authentication credentials.
pub(all) enum ChannelBinding {
Disable
Prefer
Require
} derive(Debug, Eq)
///|
/// Immutable configuration used by `connect` to establish a PostgreSQL session.
///
/// The same value is also retained inside the client runtime so that later
/// features, such as cancellation, can reopen a control connection with the
/// exact same host and port.
pub struct Config {
/// Hostname used for TLS verification and default server-name handling.
host : String
/// Optional concrete address used for the TCP socket connection.
hostaddr : String?
/// TCP port for the PostgreSQL server.
port : Int
/// Login role used during startup authentication.
user : String
/// Database selected in the startup packet.
database : String
/// Optional password consumed by password-based authentication methods.
/// PostgreSQL chooses the authentication method at startup; cleartext
/// password and SCRAM authentication require this field to be present.
password : String?
/// TLS negotiation policy.
ssl_mode : SslMode
/// Root certificate file used to verify the server certificate chain.
///
/// `None` keeps the platform default trust-store behavior. The special value
/// `"system"` also selects the platform trust store and requires
/// `ssl_mode == SslMode::VerifyFull`.
ssl_root_cert : String?
/// Channel-binding preference for SCRAM authentication.
channel_binding : ChannelBinding
/// Value sent as PostgreSQL `application_name`.
application_name : String
/// Optional PostgreSQL `options` startup parameter.
options : String?
/// Optional end-to-end connection timeout in milliseconds.
connect_timeout_ms : Int?
/// Whether TCP keepalive should be enabled on the socket.
keepalives : Bool?
/// Idle time in seconds before the first TCP keepalive probe.
keepalives_idle_s : Int?
} derive(Debug, Eq)
///|
/// Build a configuration with PostgreSQL-friendly defaults.
///
/// Defaults are chosen to keep secure TLS on the main path: port `5432`,
/// `ssl_mode = SslMode::VerifyFull`, and database name equal to the user name.
/// Callers pass `application_name` explicitly.
pub fn Config::new(
host : String,
hostaddr? : String,
port? : Int = 5432,
user~ : String,
database? : String = user,
password? : String,
ssl_mode? : SslMode = VerifyFull,
ssl_root_cert? : String,
channel_binding? : ChannelBinding = Disable,
application_name~ : String,
options? : String,
connect_timeout_ms? : Int,
keepalives? : Bool,
keepalives_idle_s? : Int,
) -> Config {
{
host,
hostaddr,
port,
user,
database,
password,
ssl_mode,
ssl_root_cert,
channel_binding,
application_name,
options,
connect_timeout_ms,
keepalives,
keepalives_idle_s,
}
}
///|
/// Construct a fully resolved single-target config from explicit parts.
pub fn Config::from_parts(
host : String,
hostaddr : String?,
port : Int,
user : String,
database : String,
password : String?,
ssl_mode : SslMode,
ssl_root_cert : String?,
channel_binding : ChannelBinding,
application_name : String,
options : String?,
connect_timeout_ms : Int?,
keepalives : Bool?,
keepalives_idle_s : Int?,
) -> Config {
{
host,
hostaddr,
port,
user,
database,
password,
ssl_mode,
ssl_root_cert,
channel_binding,
application_name,
options,
connect_timeout_ms,
keepalives,
keepalives_idle_s,
}
}