parse redis ssl_context

This commit is contained in:
Robin Appelman 2025-04-29 18:13:10 +02:00
commit e4bb72fd00
6 changed files with 220 additions and 14 deletions

View file

@ -31,14 +31,41 @@ pub enum RedisConnectionAddr {
TcpTls {
host: String,
port: u16,
insecure: bool,
tls_params: Option<String>,
tls_params: Option<RedisTlsParams>,
},
Unix {
path: PathBuf,
},
}
impl RedisConnectionAddr {
pub fn with_tls(self, tls_params: RedisTlsParams) -> Self {
match self {
RedisConnectionAddr::Tcp { host, port }
| RedisConnectionAddr::TcpTls { host, port, .. } => RedisConnectionAddr::TcpTls {
host,
port,
tls_params: Some(tls_params),
},
unix => unix,
}
}
pub fn with_tls_opt(self, tls_params: Option<RedisTlsParams>) -> Self {
if let Some(params) = tls_params {
self.with_tls(params)
} else {
match self {
RedisConnectionAddr::Tcp { host, port }
| RedisConnectionAddr::TcpTls { host, port, .. } => {
RedisConnectionAddr::Tcp { host, port }
}
unix => unix,
}
}
}
}
#[derive(Clone, Debug)]
pub struct RedisConnectionInfo {
pub addr: RedisConnectionAddr,
@ -47,6 +74,15 @@ pub struct RedisConnectionInfo {
pub password: Option<String>,
}
#[derive(Clone, Debug)]
pub struct RedisTlsParams {
pub local_cert: Option<PathBuf>,
pub local_pk: Option<PathBuf>,
pub ca_file: Option<PathBuf>,
pub accept_invalid_hostname: bool,
pub insecure: bool,
}
impl RedisConfig {
pub fn addr(&self) -> impl Iterator<Item = &RedisConnectionAddr> {
let boxed: Box<dyn Iterator<Item = &RedisConnectionAddr>> = match self {

View file

@ -1,6 +1,6 @@
use crate::{
Config, Database, DbConnect, DbError, Error, NotAConfigError, PhpParseError,
RedisConnectionInfo, Result, SslOptions,
RedisConnectionInfo, RedisTlsParams, Result, SslOptions,
};
use crate::{RedisConfig, RedisConnectionAddr};
use php_literal_parser::Value;
@ -337,6 +337,20 @@ fn parse_redis_options(parsed: &Value) -> RedisConfig {
(redis_options, address)
};
let tls_params = if redis_options["ssl_context"].is_array() {
let ssl_options = &redis_options["ssl_context"];
Some(RedisTlsParams {
local_cert: ssl_options["local_cert"].as_str().map(From::from),
local_pk: ssl_options["local_pk"].as_str().map(From::from),
ca_file: ssl_options["cafile"].as_str().map(From::from),
accept_invalid_hostname: ssl_options["allow_self_signed"] == true
|| ssl_options["verify_peer_name"] == false,
insecure: ssl_options["verify_peer "] == false,
})
} else {
None
};
let db = redis_options["dbindex"].clone().into_int().unwrap_or(0);
let password = redis_options["password"]
.as_str()
@ -349,7 +363,7 @@ fn parse_redis_options(parsed: &Value) -> RedisConfig {
match address {
RedisAddress::Single(addr) => RedisConfig::Single(RedisConnectionInfo {
addr,
addr: addr.with_tls_opt(tls_params),
db,
username,
password,
@ -358,7 +372,7 @@ fn parse_redis_options(parsed: &Value) -> RedisConfig {
addresses
.into_iter()
.map(|addr| RedisConnectionInfo {
addr,
addr: addr.with_tls_opt(tls_params.clone()),
db,
username: username.clone(),
password: password.clone(),